From 7a04c1e8017362cea8997bfc43761d9b1d8f3a8d Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 2 Oct 2022 17:19:19 +0200 Subject: [PATCH 01/54] preprocess itself produces a functioning binary --- crates/linker/src/pe.rs | 126 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index bdfbc63ae4..059466713a 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1487,6 +1487,7 @@ mod test { { let dir = tempfile::tempdir().unwrap(); let dir = dir.path(); + let dir = Path::new("/tmp/roc"); runner(dir); @@ -1672,4 +1673,129 @@ mod test { fn preprocessing_wine() { assert_eq!("Hello there\n", wine_test(preprocessing_help)) } + + #[allow(dead_code)] + fn stripped_basics(dir: &Path) { + { + let host_zig = indoc!( + r#" + const std = @import("std"); + + extern fn roc_magic() callconv(.C) u64; + + pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + + var timer = std.time.Timer.start() catch unreachable; + + if (timer.read() == 1234) { + try stdout.print("Hello, {}!\n", .{roc_magic()}); + } else { + try stdout.print("Hello, {}!\n", .{32}); + } + } + "# + ); + let app_zig = indoc!( + r#" + export fn roc_magic() u64 { + return 32; + } + "# + ); + let zig = std::env::var("ROC_ZIG").unwrap_or_else(|_| "zig".into()); + + std::fs::write(dir.join("host.zig"), host_zig.as_bytes()).unwrap(); + std::fs::write(dir.join("app.zig"), app_zig.as_bytes()).unwrap(); + + // we need to compile the app first + let output = std::process::Command::new(&zig) + .current_dir(dir) + .args(&[ + "build-obj", + "app.zig", + "-target", + "x86_64-windows-gnu", + "--strip", + "-rdynamic", + "-OReleaseFast", + ]) + .output() + .unwrap(); + + if !output.status.success() { + use std::io::Write; + + std::io::stdout().write_all(&output.stdout).unwrap(); + std::io::stderr().write_all(&output.stderr).unwrap(); + + panic!("zig build-obj failed"); + } + + // open our app object; we'll copy sections from it later + let file = std::fs::File::open(dir.join("app.obj")).unwrap(); + let roc_app = unsafe { memmap2::Mmap::map(&file) }.unwrap(); + + let roc_app_sections = AppSections::from_data(&*roc_app); + let symbols = roc_app_sections.roc_symbols; + + // make the dummy dylib based on the app object + let names: Vec<_> = symbols.iter().map(|s| s.name.clone()).collect(); + let dylib_bytes = crate::generate_dylib::synthetic_dll(&names); + std::fs::write(dir.join("libapp.obj"), dylib_bytes).unwrap(); + + // now we can compile the host (it uses libapp.obj, hence the order here) + let output = std::process::Command::new(&zig) + .current_dir(dir) + .args(&[ + "build-exe", + "libapp.obj", + "host.zig", + "-lc", + "-target", + "x86_64-windows-gnu", + "-rdynamic", + "--strip", + "-rdynamic", + "-OReleaseFast", + ]) + .output() + .unwrap(); + + if !output.status.success() { + use std::io::Write; + + std::io::stdout().write_all(&output.stdout).unwrap(); + std::io::stderr().write_all(&output.stderr).unwrap(); + + panic!("zig build-exe failed"); + } + + preprocess_windows( + &dir.join("host.exe"), + &dir.join("metadata"), + &dir.join("preprocessedhost"), + false, + false, + ) + .unwrap(); + + std::fs::copy(&dir.join("preprocessedhost"), &dir.join("app.exe")).unwrap(); + + // surgery_pe(&dir.join("app.exe"), &dir.join("metadata"), &*roc_app); + }; + } + + #[cfg(windows)] + #[test] + #[ignore = "does not work yet"] + fn stripped_basics_windows() { + assert_eq!("Hello, 32!\n", windows_test(stripped_basics)) + } + + #[test] + #[ignore] + fn stripped_basics_wine() { + assert_eq!("Hello, 32!\n", wine_test(stripped_basics)) + } } From c3d49ab38b3d21028552fbfd5e21b28dea8d31a0 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 2 Oct 2022 18:21:30 +0200 Subject: [PATCH 02/54] improve write_dummy_sections style --- crates/linker/src/pe.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 059466713a..337dba41c8 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -20,7 +20,8 @@ use roc_collections::{MutMap, VecMap}; use roc_error_macros::internal_error; use crate::{ - generate_dylib::APP_DLL, load_struct_inplace, load_struct_inplace_mut, open_mmap, open_mmap_mut, + generate_dylib::APP_DLL, load_struct_inplace, load_struct_inplace_mut, + load_structs_inplace_mut, open_mmap, open_mmap_mut, }; /// The metadata stores information about/from the host .exe because @@ -602,7 +603,7 @@ impl Preprocessor { result[self.new_headers_size..].copy_from_slice(&data[self.old_headers_size..]); } - fn write_dummy_sections(&self, result: &mut MmapMut, extra_sections: &[[u8; 8]]) { + fn write_dummy_sections(&self, result: &mut MmapMut, extra_section_names: &[[u8; 8]]) { const W: usize = std::mem::size_of::(); let previous_section_header = @@ -614,8 +615,14 @@ impl Preprocessor { let mut next_virtual_address = next_multiple_of(previous_section_header_end as usize, self.section_alignment); - for (i, name) in extra_sections.iter().enumerate() { - let header = ImageSectionHeader { + let extra_section_headers = load_structs_inplace_mut::( + result, + self.extra_sections_start, + extra_section_names.len(), + ); + + for (header, name) in extra_section_headers.iter_mut().zip(extra_section_names) { + *header = ImageSectionHeader { name: *name, // NOTE: the virtual_size CANNOT BE ZERO! the binary is invalid if a section has // zero virtual size. Setting it to 1 works, (because this one byte is not backed @@ -632,10 +639,6 @@ impl Preprocessor { characteristics: Default::default(), }; - let header_array: [u8; W] = unsafe { std::mem::transmute(header) }; - - result[self.extra_sections_start + i * W..][..W].copy_from_slice(&header_array); - next_virtual_address += self.section_alignment; } } From 5dbd1193918a6bcde0fb83a9a1b5af27acd49535 Mon Sep 17 00:00:00 2001 From: Folkert Date: Mon, 3 Oct 2022 21:19:09 +0200 Subject: [PATCH 03/54] WIP --- crates/linker/src/pe.rs | 280 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 274 insertions(+), 6 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 337dba41c8..8789a4d968 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -8,8 +8,8 @@ use bincode::{deserialize_from, serialize_into}; use memmap2::MmapMut; use object::{ pe::{ - self, ImageFileHeader, ImageImportDescriptor, ImageNtHeaders64, ImageSectionHeader, - ImageThunkData64, + self, ImageBaseRelocation, ImageFileHeader, ImageImportDescriptor, ImageNtHeaders64, + ImageSectionHeader, ImageThunkData64, }, read::pe::ImportTable, LittleEndian as LE, Object, RelocationTarget, SectionIndex, @@ -222,6 +222,9 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b let mut section_header_start = md.dynamic_relocations.section_headers_offset_in_file as usize + md.host_section_count * std::mem::size_of::(); + let reloc_section_header_start = + section_header_start - std::mem::size_of::(); + let mut code_bytes_added = 0; let mut data_bytes_added = 0; let mut file_bytes_added = 0; @@ -235,6 +238,16 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b section_alignment, ); + let reloc_section_start = 0x4600; + let new_block_va = 0xb000; + let relocations = &[0]; + let added_reloc_bytes = + write_image_base_relocation(executable, reloc_section_start, new_block_va, relocations); + + let ptr = load_struct_inplace_mut::(executable, reloc_section_header_start); + ptr.virtual_size + .set(LE, ptr.virtual_size.get(LE) + added_reloc_bytes as u32); + for kind in [SectionKind::Text, SectionKind::ReadOnlyData] { let length: usize = app_obj_sections .sections @@ -360,6 +373,8 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b .map(|s| (s.name, s.offset_in_section as u64)) .collect(); + dbg!(&symbols); + redirect_dummy_dll_functions(executable, &symbols, &md.imports, md.thunks_start_offset); } @@ -1084,6 +1099,41 @@ fn write_section_header( data[section_header_start..][..header_array.len()].copy_from_slice(&header_array); } +fn write_image_base_relocation( + mmap: &mut [u8], + reloc_section_start: usize, + new_block_va: u32, + relocations: &[u16], +) -> usize { + let mut next_block_start = reloc_section_start as u32; + + let new_block_start = loop { + let header = + load_struct_inplace_mut::(mmap, next_block_start as usize); + + if header.virtual_address.get(LE) == 0 { + break next_block_start; + } + + next_block_start += header.size_of_block.get(LE); + }; + + let size_of_block = 8 + 2 * relocations.len(); + + let header = load_struct_inplace_mut::(mmap, new_block_start as usize); + *header = ImageBaseRelocation { + virtual_address: object::U32::new(LE, new_block_va), + size_of_block: object::U32::new(LE, size_of_block as u32), + }; + + let destination = + load_structs_inplace_mut::(mmap, new_block_start as usize + 8, relocations.len()); + + destination.copy_from_slice(relocations); + + size_of_block +} + #[cfg(test)] mod test { const PE_DYNHOST: &[u8] = include_bytes!("../dynhost_benchmarks_windows.exe") as &[_]; @@ -1463,6 +1513,7 @@ mod test { { let dir = tempfile::tempdir().unwrap(); let dir = dir.path(); + let dir = Path::new(r"C:\Users\folkert\Documents\GitHub\roc\linktest"); runner(dir); @@ -1686,15 +1737,19 @@ mod test { extern fn roc_magic() callconv(.C) u64; + pub export fn roc_alloc() u64 { + return 123456; + } + pub fn main() !void { const stdout = std.io.getStdOut().writer(); var timer = std.time.Timer.start() catch unreachable; if (timer.read() == 1234) { - try stdout.print("Hello, {}!\n", .{roc_magic()}); - } else { try stdout.print("Hello, {}!\n", .{32}); + } else { + try stdout.print("Hello, {}!\n", .{roc_magic()}); } } "# @@ -1785,13 +1840,226 @@ mod test { std::fs::copy(&dir.join("preprocessedhost"), &dir.join("app.exe")).unwrap(); - // surgery_pe(&dir.join("app.exe"), &dir.join("metadata"), &*roc_app); + { + let executable_path: &Path = &dir.join("app.exe"); + let metadata_path: &Path = &dir.join("metadata"); + let roc_app_bytes = &*roc_app; + let md = PeMetadata::read_from_file(metadata_path); + + let app_obj_sections = AppSections::from_data(roc_app_bytes); + let mut symbols = app_obj_sections.roc_symbols; + + let image_base: u64 = md.image_base; + let file_alignment = md.file_alignment as usize; + let section_alignment = md.section_alignment as usize; + + let app_sections_size: usize = app_obj_sections + .sections + .iter() + .map(|s| { + next_multiple_of(s.file_range.end - s.file_range.start, file_alignment) + }) + .sum(); + + let executable = + &mut open_mmap_mut(executable_path, md.dynhost_file_size + app_sections_size); + + let app_code_section_va = md.last_host_section_address + + next_multiple_of( + md.last_host_section_size as usize, + section_alignment as usize, + ) as u64; + + let mut section_file_offset = md.dynhost_file_size; + let mut virtual_address = (app_code_section_va - image_base) as u32; + + // find the location to write the section headers for our new sections + let mut section_header_start = md.dynamic_relocations.section_headers_offset_in_file + as usize + + md.host_section_count * std::mem::size_of::(); + + let mut code_bytes_added = 0; + let mut data_bytes_added = 0; + let mut file_bytes_added = 0; + + // relocations between the sections of the roc application + // (as opposed to relocations for symbols the app imports from the host) + let inter_app_relocations = process_internal_relocations( + &app_obj_sections.sections, + &app_obj_sections.other_symbols, + (app_code_section_va - image_base) as u32, + section_alignment, + ); + + // 0x3a08 + let reloc_section_start = 0x4600; + let new_block_va = 0x3000; + let relocations = &[0xa03]; + let added_reloc_bytes = write_image_base_relocation( + executable, + reloc_section_start, + new_block_va, + relocations, + ); + + let reloc_section_header_start = + section_header_start - std::mem::size_of::(); + + let ptr = load_struct_inplace_mut::( + executable, + reloc_section_header_start, + ); + ptr.virtual_size + .set(LE, ptr.virtual_size.get(LE) + added_reloc_bytes as u32); + + for kind in [SectionKind::Text, SectionKind::ReadOnlyData] { + let length: usize = app_obj_sections + .sections + .iter() + .filter(|s| s.kind == kind) + .map(|s| s.file_range.end - s.file_range.start) + .sum(); + + // offset_in_section now becomes a proper virtual address + for symbol in symbols.iter_mut() { + if symbol.section_kind == kind { + symbol.offset_in_section += + image_base as usize + virtual_address as usize; + } + } + + let virtual_size = u32::max(1, length as u32); + let size_of_raw_data = next_multiple_of(length, file_alignment) as u32; + + match kind { + SectionKind::Text => { + code_bytes_added += size_of_raw_data; + + write_section_header( + executable, + *b".text1\0\0", + pe::IMAGE_SCN_MEM_READ + | pe::IMAGE_SCN_CNT_CODE + | pe::IMAGE_SCN_MEM_EXECUTE, + section_header_start, + section_file_offset, + virtual_size, + virtual_address, + size_of_raw_data, + ); + } + SectionKind::ReadOnlyData => { + data_bytes_added += size_of_raw_data; + + write_section_header( + executable, + *b".rdata1\0", + pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_CNT_INITIALIZED_DATA, + section_header_start, + section_file_offset, + virtual_size, + virtual_address, + size_of_raw_data, + ); + } + } + + let mut offset = section_file_offset; + let it = app_obj_sections.sections.iter().filter(|s| s.kind == kind); + for section in it { + let slice = + &roc_app_bytes[section.file_range.start..section.file_range.end]; + executable[offset..][..slice.len()].copy_from_slice(slice); + + for (name, app_relocation) in section.relocations.iter() { + let AppRelocation { + offset_in_section, + relocation, + address, + } = app_relocation; + + if let Some(destination) = md.exports.get(name) { + match relocation.kind() { + object::RelocationKind::Relative => { + // we implicitly only do 32-bit relocations + debug_assert_eq!(relocation.size(), 32); + + let delta = destination + - virtual_address as i64 + - *offset_in_section as i64 + + relocation.addend(); + + executable[offset + *offset_in_section as usize..][..4] + .copy_from_slice(&(delta as i32).to_le_bytes()); + } + _ => todo!(), + } + } else if let Some(destination) = inter_app_relocations.get(name) { + // we implicitly only do 32-bit relocations + debug_assert_eq!(relocation.size(), 32); + + let delta = destination + - virtual_address as i64 + - *offset_in_section as i64 + + relocation.addend(); + + executable[offset + *offset_in_section as usize..][..4] + .copy_from_slice(&(delta as i32).to_le_bytes()); + } else { + match relocation.kind() { + object::RelocationKind::Relative => { + // we implicitly only do 32-bit relocations + debug_assert_eq!(relocation.size(), 32); + + let delta = *address as i64 - *offset_in_section as i64 + + relocation.addend(); + + executable[offset + *offset_in_section as usize..][..4] + .copy_from_slice(&(delta as i32).to_le_bytes()); + } + _ => todo!(), + } + } + } + + offset += slice.len(); + } + + section_header_start += std::mem::size_of::(); + section_file_offset += size_of_raw_data as usize; + virtual_address += next_multiple_of(length, section_alignment) as u32; + file_bytes_added += next_multiple_of(length, section_alignment) as u32; + } + + update_optional_header( + executable, + md.optional_header_offset, + code_bytes_added as u32, + file_bytes_added as u32, + data_bytes_added as u32, + ); + + let mut symbols: Vec<_> = symbols + .into_iter() + .map(|s| (s.name, s.offset_in_section as u64)) + .collect(); + + crate::dbg_hex!(&symbols); + symbols[0].1 = 0x140001000; + + crate::dbg_hex!(md.thunks_start_offset); + redirect_dummy_dll_functions( + executable, + &symbols, + &md.imports, + md.thunks_start_offset, + ); + }; }; } #[cfg(windows)] #[test] - #[ignore = "does not work yet"] fn stripped_basics_windows() { assert_eq!("Hello, 32!\n", windows_test(stripped_basics)) } From b3d3e93b97b8e5ead7e7cc3db7c8823acb8a7c3f Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 14 Oct 2022 13:59:21 +0200 Subject: [PATCH 04/54] add os version macos nightly I added the version to the filename for macos x86_64 so I think it's good to add it to the apple silicon release as well for consistency and clarity. Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/nightly_macos_apple_silicon.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly_macos_apple_silicon.yml b/.github/workflows/nightly_macos_apple_silicon.yml index b231217025..141863015c 100644 --- a/.github/workflows/nightly_macos_apple_silicon.yml +++ b/.github/workflows/nightly_macos_apple_silicon.yml @@ -29,7 +29,7 @@ jobs: env: DATE: ${{ env.DATE }} SHA: ${{ env.SHA }} - run: echo "RELEASE_TAR_FILENAME=roc_nightly-macos_apple_silicon-$DATE-$SHA.tar.gz" >> $GITHUB_ENV + run: echo "RELEASE_TAR_FILENAME=roc_nightly-macos_12_apple_silicon-$DATE-$SHA.tar.gz" >> $GITHUB_ENV - name: write version to file run: ./ci/write_version.sh From d511d09c9df603b9e982a11cb87f345c7e5fdb39 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 15 Oct 2022 18:48:29 +0200 Subject: [PATCH 05/54] added link to story commit signing Setting this up can be a bit of a chore so it's nice to provide some motivation :) Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ffc181aa02..338e0867aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,7 @@ Execute `cargo fmt --all` to fix the formatting. - You can find good first issues [here][good-first-issues]. - [Fork](https://github.com/roc-lang/roc/fork) the repo so that you can apply your changes first on your own copy of the roc repo. - It's a good idea to open a draft pull request as you begin working on something. This way, others can see that you're working on it, which avoids duplicate effort, and others can give feedback sooner rather than later if they notice a problem in the direction things are going. Click the button "ready for review" when it's ready. -- All your commits need to be signed to prevent impersonation: +- All your commits need to be signed [to prevent impersonation](https://dev.to/martiliones/how-i-got-linus-torvalds-in-my-contributors-on-github-3k4g): 1. If you have a Yubikey, follow [guide 1](https://dev.to/paulmicheli/using-your-yubikey-to-get-started-with-gpg-3h4k), [guide 2](https://dev.to/paulmicheli/using-your-yubikey-for-signed-git-commits-4l73) and skip the steps below. 2. [Make a key to sign your commits.](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key). 3. [Configure git to use your key.](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key) From 85d774d3e9391c31a2a78b8b66acb4ca683b9796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Fri, 16 Sep 2022 03:57:12 +0200 Subject: [PATCH 06/54] Add default build to flake outputs --- default.nix | 6 +++--- flake.nix | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/default.nix b/default.nix index c2eb6c7b53..514249a69d 100644 --- a/default.nix +++ b/default.nix @@ -1,9 +1,9 @@ -{ rev ? "541a3ca27c9a8220b46f4feb7dd8e94336a77f42", # nixpkgs master +{ rev ? "a7855f2235a1876f97473a76151fec2afa02b287", # nixpkgs master. Keep up to date with flake.lock nixpkgsSource ? builtins.fetchTarball { url = "https://github.com/nixos/nixpkgs/tarball/${rev}"; - sha256 = "sha256:1mxv0zigm98pawf05kd4s8ipvk1pvvdsn1yh978c5an97kz0ck5w"; + sha256 = "sha256-5DGKX81wIPAAiLwUmUYECpA3vop94AHHR7WmGXSsQok="; }, pkgs ? import nixpkgsSource { } -, cargoSha256 ? "sha256-treL2sWPcZ1NBwdab3FOb2FI2wT/Vt9tD4XRfJ8rYWA=", }: +, cargoSha256 ? "sha256-F6UOJZ5oDOZ+80z70A21VzDR0YtmgD0dnEcjPgpicpo=", }: # we only this file to release a nix package, use flake.nix for development let rustPlatform = pkgs.rustPlatform; diff --git a/flake.nix b/flake.nix index 83ebc1647f..9ce8a1cc6d 100644 --- a/flake.nix +++ b/flake.nix @@ -128,5 +128,7 @@ }; formatter = pkgs.nixpkgs-fmt; + + packages.default = import ./. { inherit pkgs; }; }); } From 31eb187960d89c5d761180f2040db7025690083c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Sat, 15 Oct 2022 17:50:10 +0200 Subject: [PATCH 07/54] Adjust to suggestions from comments --- default.nix | 2 +- flake.nix | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default.nix b/default.nix index 514249a69d..863d911a4a 100644 --- a/default.nix +++ b/default.nix @@ -1,4 +1,4 @@ -{ rev ? "a7855f2235a1876f97473a76151fec2afa02b287", # nixpkgs master. Keep up to date with flake.lock +{ rev ? "a7855f2235a1876f97473a76151fec2afa02b287", # nixpkgs master. Keep up to date with "nixpkgs">"locked">"rev" in flake.lock nixpkgsSource ? builtins.fetchTarball { url = "https://github.com/nixos/nixpkgs/tarball/${rev}"; sha256 = "sha256-5DGKX81wIPAAiLwUmUYECpA3vop94AHHR7WmGXSsQok="; diff --git a/flake.nix b/flake.nix index 9ce8a1cc6d..6ab1cee498 100644 --- a/flake.nix +++ b/flake.nix @@ -129,6 +129,7 @@ formatter = pkgs.nixpkgs-fmt; + # You can build this package (the compiler) with the `nix build` command. packages.default = import ./. { inherit pkgs; }; }); } From 7529e10580b755328fa8c7436445627d2fd21e78 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 19:15:56 +0200 Subject: [PATCH 08/54] wip --- crates/cli_utils/Cargo.lock | 3123 ++++------------------------------- crates/linker/src/pe.rs | 78 +- 2 files changed, 354 insertions(+), 2847 deletions(-) diff --git a/crates/cli_utils/Cargo.lock b/crates/cli_utils/Cargo.lock index 07b8777f33..4ef9babc62 100644 --- a/crates/cli_utils/Cargo.lock +++ b/crates/cli_utils/Cargo.lock @@ -2,22 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ab_glyph" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b228f2c198f98d4337ceb560333fb12cbb2f4948a953bf8c57d09deb219603" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser 0.13.2", -] - -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13739d7177fbd22bb0ed28badfff9f372f8bef46c863db4e1c6248f6b223b6e" - [[package]] name = "addr2line" version = "0.17.0" @@ -33,12 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" - [[package]] name = "ahash" version = "0.7.6" @@ -50,46 +28,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "andrew" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4afb09dd642feec8408e33f92f3ffc4052946f6b20f32fb99c1f58cd4fa7cf" -dependencies = [ - "bitflags", - "rusttype", - "walkdir", - "xdg", - "xml-rs", -] - -[[package]] -name = "approx" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" -dependencies = [ - "num-traits", -] - -[[package]] -name = "approx" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" -dependencies = [ - "num-traits", -] - [[package]] name = "arrayvec" version = "0.5.2" @@ -102,15 +40,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" -[[package]] -name = "ash" -version = "0.33.3+1.2.191" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219" -dependencies = [ - "libloading 0.7.1", -] - [[package]] name = "atty" version = "0.2.14" @@ -136,37 +65,13 @@ checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", - "object 0.27.1", + "object", "rustc-demangle", ] -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - [[package]] name = "bitflags" version = "1.3.2" @@ -184,62 +89,14 @@ dependencies = [ [[package]] name = "bitvec" -version = "0.22.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "funty 1.2.0", - "radium 0.6.2", + "funty", + "radium", "tap", - "wyz 0.4.0", -] - -[[package]] -name = "bitvec" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" -dependencies = [ - "funty 2.0.0", - "radium 0.7.0", - "tap", - "wyz 0.5.0", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", + "wyz", ] [[package]] @@ -256,51 +113,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "bytemuck" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "calloop" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b036167e76041694579972c28cf4877b4f92da222560ddb49008937b6a6727c" -dependencies = [ - "log", - "nix 0.18.0", -] +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "cast" @@ -317,34 +132,12 @@ version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - -[[package]] -name = "cgmath" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" -dependencies = [ - "approx 0.4.0", - "num-traits", -] - [[package]] name = "clap" version = "2.33.3" @@ -352,34 +145,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "bitflags", - "textwrap 0.11.0", + "textwrap", "unicode-width", ] -[[package]] -name = "clap" -version = "3.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47582c09be7c8b32c0ab3a6181825ababb713fde6fff20fc573a3870dd45c6a0" -dependencies = [ - "atty", - "bitflags", - "clap_lex", - "indexmap", - "strsim 0.10.0", - "termcolor", - "textwrap 0.15.0", -] - -[[package]] -name = "clap_lex" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "cli_utils" version = "0.1.0" @@ -387,239 +156,16 @@ dependencies = [ "bumpalo", "criterion", "rlimit", - "roc_cli", "roc_collections", "roc_load", "roc_module", + "roc_reporting", "serde", "serde-xml-rs", "strip-ansi-escapes", "tempfile", ] -[[package]] -name = "clipboard-win" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342" -dependencies = [ - "lazy-bytes-cast", - "winapi", -] - -[[package]] -name = "clipboard-win" -version = "4.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8340083d28acb43451166543b98c838299b7e0863621be53a338adceea0ed" -dependencies = [ - "error-code", - "str-buf", - "winapi", -] - -[[package]] -name = "cocoa" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" -dependencies = [ - "bitflags", - "block", - "cocoa-foundation", - "core-foundation 0.9.2", - "core-graphics 0.22.3", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" -dependencies = [ - "bitflags", - "block", - "core-foundation 0.9.2", - "core-graphics-types", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "colored" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" -dependencies = [ - "atty", - "lazy_static", - "winapi", -] - -[[package]] -name = "confy" -version = "0.4.0" -source = "git+https://github.com/rust-cli/confy#664992aecd97b4af0eda8d9d2825885662e1c6b4" -dependencies = [ - "directories-next", - "serde", - "serde_yaml", -] - -[[package]] -name = "const_format" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22bc6cd49b0ec407b680c3e380182b6ac63b73991cb7602de350352fc309b614" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef196d5d972878a48da7decb7686eded338b4858fbabeed513d63a7c98b2b82d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "copyless" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" - -[[package]] -name = "copypasta" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4423d79fed83ebd9ab81ec21fa97144300a961782158287dc9bf7eddac37ff0b" -dependencies = [ - "clipboard-win 3.1.1", - "objc", - "objc-foundation", - "objc_id", - "smithay-clipboard", - "x11-clipboard", -] - -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" -dependencies = [ - "core-foundation-sys 0.8.3", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "core-graphics" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" -dependencies = [ - "bitflags", - "core-foundation 0.7.0", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags", - "core-foundation 0.9.2", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" -dependencies = [ - "bitflags", - "core-foundation 0.9.2", - "foreign-types", - "libc", -] - -[[package]] -name = "core-video-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" -dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", - "libc", - "objc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "criterion" version = "0.3.5" @@ -627,7 +173,7 @@ source = "git+https://github.com/Anton-4/criterion.rs#3e46ad2b234e36928fb5234d36 dependencies = [ "atty", "cast", - "clap 2.33.3", + "clap", "criterion-plot", "csv", "itertools 0.10.1", @@ -656,11 +202,11 @@ dependencies = [ [[package]] name = "crossbeam" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -674,7 +220,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -684,7 +230,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] @@ -695,7 +241,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", "lazy_static", "memoffset", @@ -708,7 +254,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -718,7 +264,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] @@ -730,7 +276,7 @@ checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ "bstr", "csv-core", - "itoa", + "itoa 0.4.8", "ryu", "serde", ] @@ -744,180 +290,18 @@ dependencies = [ "memchr", ] -[[package]] -name = "d3d12" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2daefd788d1e96e0a9d66dee4b828b883509bc3ea9ce30665f04c3246372690c" -dependencies = [ - "bitflags", - "libloading 0.7.1", - "winapi", -] - -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.9.3", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "directories-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - -[[package]] -name = "dirs" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - [[package]] name = "distance" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d9d8664cf849d7d0f3114a3a387d2f5e4303176d746d5a951aaddc66dfe9240" -[[package]] -name = "dlib" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" -dependencies = [ - "libloading 0.6.7", -] - -[[package]] -name = "dlib" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" -dependencies = [ - "libloading 0.7.1", -] - [[package]] name = "doc-comment" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - [[package]] name = "dunce" version = "1.0.2" @@ -932,76 +316,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "error-code" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff" -dependencies = [ - "libc", - "str-buf", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "fd-lock" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a16910e685088843d53132b04e0f10a571fdb193224fc589685b3ba1ce4cb03d" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "windows-sys 0.28.0", -] - -[[package]] -name = "find-crate" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2" -dependencies = [ - "toml", -] - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "miniz_oxide", -] +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "fnv" @@ -1009,168 +326,19 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "fs_extra" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" - -[[package]] -name = "funty" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" - [[package]] name = "funty" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futures" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" - -[[package]] -name = "futures-executor" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" - -[[package]] -name = "futures-macro" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" -dependencies = [ - "autocfg", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" - -[[package]] -name = "futures-task" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" - -[[package]] -name = "futures-util" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" -dependencies = [ - "autocfg", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -1181,96 +349,6 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" -[[package]] -name = "glow" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f04649123493bc2483cbef4daddb45d40bbdae5adb221a63a23efdb0cc99520" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "glyph_brush" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21932fbf719272848eec4583740d978203c6e7da4c4e203358f5b95946c97409" -dependencies = [ - "glyph_brush_draw_cache", - "glyph_brush_layout", - "log", - "ordered-float", - "rustc-hash", - "twox-hash", -] - -[[package]] -name = "glyph_brush_draw_cache" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6010675390f6889e09a21e2c8b575b3ee25667ea8237a8d59423f73cb8c28610" -dependencies = [ - "ab_glyph", - "crossbeam-channel", - "crossbeam-deque", - "linked-hash-map", - "rayon", - "rustc-hash", -] - -[[package]] -name = "glyph_brush_layout" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc32c2334f00ca5ac3695c5009ae35da21da8c62d255b5b96d56e2597a637a38" -dependencies = [ - "ab_glyph", - "approx 0.5.0", - "xi-unicode", -] - -[[package]] -name = "gpu-alloc" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e64cbb8d36508d3e19da95e56e196a84f674fc190881f2cc010000798838aa6" -dependencies = [ - "bitflags", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" -dependencies = [ - "bitflags", -] - -[[package]] -name = "gpu-descriptor" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a237f0419ab10d17006d55c62ac4f689a6bf52c75d3f38b8361d249e8d4b0b" -dependencies = [ - "bitflags", - "gpu-descriptor-types", - "hashbrown 0.9.1", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" -dependencies = [ - "bitflags", -] - [[package]] name = "half" version = "1.8.2" @@ -1279,22 +357,19 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.4.7", + "ahash", + "bumpalo", ] [[package]] -name = "hashbrown" -version = "0.11.2" +name = "heck" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash 0.7.6", - "bumpalo", -] +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -1305,34 +380,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "iced-x86" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e977036f7f5139d580c7f19ad62df9cb8ebd8410bb569e73585226be80a86f" -dependencies = [ - "lazy_static", - "static_assertions 1.1.0", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "im" version = "15.0.0" @@ -1361,64 +408,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown 0.11.2", -] - -[[package]] -name = "inkwell" -version = "0.1.0" -dependencies = [ - "inkwell 0.1.0 (git+https://github.com/rtfeldman/inkwell?branch=master)", -] - -[[package]] -name = "inkwell" -version = "0.1.0" -source = "git+https://github.com/rtfeldman/inkwell?branch=master#accd406858a40ca2a1463ff77d79f3c5e4c96f4e" -dependencies = [ - "either", - "inkwell_internals", - "libc", - "llvm-sys", - "once_cell", - "parking_lot 0.12.0", -] - -[[package]] -name = "inkwell_internals" -version = "0.5.0" -source = "git+https://github.com/rtfeldman/inkwell?branch=master#accd406858a40ca2a1463ff77d79f3c5e4c96f4e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "inplace_it" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90953f308a79fe6d62a4643e51f848fbfddcd05975a38e69fdf4ab86a7baf7ca" - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "itertools" version = "0.9.0" @@ -1444,10 +433,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] -name = "jni-sys" -version = "0.3.0" +name = "itoa" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "js-sys" @@ -1458,22 +447,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "khronos-egl" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" -dependencies = [ - "libc", - "libloading 0.7.1", -] - -[[package]] -name = "lazy-bytes-cast" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" - [[package]] name = "lazy_static" version = "1.4.0" @@ -1486,54 +459,6 @@ version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" -[[package]] -name = "libloading" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" -dependencies = [ - "cfg-if 1.0.0", - "winapi", -] - -[[package]] -name = "libloading" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cf036d15402bea3c5d4de17b3fce76b3e4a56ebc1f577be0e7a72f7c607cf0" -dependencies = [ - "cfg-if 1.0.0", - "winapi", -] - -[[package]] -name = "libmimalloc-sys" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1b8479c593dba88c2741fc50b92e13dbabbbe0bd504d979f244ccc1a5b1c01" -dependencies = [ - "cc", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "llvm-sys" -version = "130.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95eb03b4f7ae21f48ef7c565a3e3aa22c50616aea64645fb1fd7f6f56b51c274" -dependencies = [ - "cc", - "lazy_static", - "libc", - "regex", - "semver 0.11.0", -] - [[package]] name = "lock_api" version = "0.4.7" @@ -1550,57 +475,24 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] -name = "malloc_buf" -version = "0.0.6" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "libc", + "regex-automata", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "memchr" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" -[[package]] -name = "memmap2" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a" -dependencies = [ - "libc", -] - -[[package]] -name = "memmap2" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" -dependencies = [ - "libc", -] - -[[package]] -name = "memmap2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.6.4" @@ -1610,35 +502,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "metal" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0514f491f4cc03632ab399ee01e2c1c1b12d3e1cf2d667c1ff5f87d6dcd2084" -dependencies = [ - "bitflags", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", -] - -[[package]] -name = "mimalloc" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb74897ce508e6c49156fd1476fc5922cbc6e75183c65e399c765a09122e5130" -dependencies = [ - "libmimalloc-sys", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.4.4" @@ -1650,194 +513,12 @@ dependencies = [ ] [[package]] -name = "mio" -version = "0.7.14" +name = "nu-ansi-term" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "mio-misc" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ddf05411bb159cdb5801bb10002afb66cb4572be656044315e363460ce69dc2" -dependencies = [ - "crossbeam", - "crossbeam-queue", - "log", - "mio", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "morphic_lib" -version = "0.1.0" -dependencies = [ - "sha2", - "smallvec", - "thiserror", - "typed-arena", -] - -[[package]] -name = "naga" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda66d09f712e1f0a6ab436137da4fac312f78301f6d4ac7cb8bfe96e988734f" -dependencies = [ - "bit-set", - "bitflags", - "codespan-reporting", - "fxhash", - "hexf-parse", - "indexmap", - "log", - "num-traits", - "spirv", - "thiserror", -] - -[[package]] -name = "ndk" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab" -dependencies = [ - "jni-sys", - "ndk-sys", - "num_enum", - "thiserror", -] - -[[package]] -name = "ndk-glue" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385" -dependencies = [ - "lazy_static", - "libc", - "log", - "ndk", - "ndk-macro", - "ndk-sys", -] - -[[package]] -name = "ndk-macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" -dependencies = [ - "darling", - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ndk-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec", -] - -[[package]] -name = "nix" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" -dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "libc", -] - -[[package]] -name = "nix" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" -dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", - "libc", -] - -[[package]] -name = "nix" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187" -dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", - "libc", - "memoffset", -] - -[[package]] -name = "nix" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" -dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", - "libc", - "memoffset", -] - -[[package]] -name = "nom" -version = "7.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" -dependencies = [ - "memchr", - "minimal-lexical", - "version_check", -] - -[[package]] -name = "nonempty" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" - -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ + "overload", "winapi", ] @@ -1861,76 +542,12 @@ dependencies = [ ] [[package]] -name = "num_enum" -version = "0.5.4" +name = "num_threads" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ - "derivative", - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" -dependencies = [ - "proc-macro-crate 1.1.0", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", - "objc_exception", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] -name = "objc_exception" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" -dependencies = [ - "cc", -] - -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - -[[package]] -name = "object" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" -dependencies = [ - "crc32fast", - "flate2", - "indexmap", - "memchr", + "libc", ] [[package]] @@ -1944,9 +561,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "oorandom" @@ -1955,116 +572,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] -name = "opaque-debug" -version = "0.2.3" +name = "overload" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "ordered-float" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97c9d06878b3a851e8026ef94bf7fef9ba93062cd412601da4d9cf369b1cc62d" -dependencies = [ - "num-traits", -] - -[[package]] -name = "os_str_bytes" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" - -[[package]] -name = "owned_ttf_parser" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" -dependencies = [ - "ttf-parser 0.6.2", -] - -[[package]] -name = "owned_ttf_parser" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ee3f72636e6f164cc41c9f9057f4e58c4e13507699ea7f5e5242b64b8198ee" -dependencies = [ - "ttf-parser 0.13.2", -] - -[[package]] -name = "packed_struct" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c48e482b9a59ad6c2cdb06f7725e7bd33fe3525baaf4699fde7bfea6a5b77b1" -dependencies = [ - "bitvec 0.22.3", - "packed_struct_codegen", - "serde", -] - -[[package]] -name = "packed_struct_codegen" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e3692b867ec1d48ccb441e951637a2cc3130d0912c0059e48319e1c83e44bc" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "page_size" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "palette" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9735f7e1e51a3f740bacd5dc2724b61a7806f23597a8736e679f38ee3435d18" -dependencies = [ - "approx 0.5.0", - "num-traits", - "palette_derive", - "phf", -] - -[[package]] -name = "palette_derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7799c3053ea8a6d8a1193c7ba42f534e7863cf52e378a7f90406f4a645d33bad" -dependencies = [ - "find-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.5", -] +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" @@ -2073,21 +584,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ "lock_api", - "parking_lot_core 0.9.2", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2096,150 +593,18 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.34.0", -] - -[[package]] -name = "peg" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af728fe826811af3b38c37e93de6d104485953ea373d656eebae53d6987fcd2c" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4536be147b770b824895cbad934fccce8e49f14b4c4946eaa46a6e4a12fcdc16" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b0efd3ba03c3a409d44d60425f279ec442bcf0b9e63ff4e410da31c8b0f69f" - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" -dependencies = [ - "maplit", - "pest", - "sha-1", -] - -[[package]] -name = "phf" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ac8b67553a7ca9457ce0e526948cad581819238f4a9d1ea74545851fa24f37" -dependencies = [ - "phf_macros", - "phf_shared", - "proc-macro-hack", -] - -[[package]] -name = "phf_generator" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43f3220d96e0080cc9ea234978ccd80d904eafb17be31bb0f76daaea6493082" -dependencies = [ - "phf_shared", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b706f5936eb50ed880ae3009395b43ed19db5bff2ebd459c95e7bf013a89ab86" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68318426de33640f02be62b4ae8eb1261be2efbc337b60c54d845bf4484e0d9" -dependencies = [ - "siphasher", + "windows-sys", ] [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "plotters" @@ -2274,70 +639,13 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro-crate" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" -dependencies = [ - "thiserror", - "toml", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ - "unicode-xid", -] - -[[package]] -name = "profiling" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9926767b8b8244d7b6b64546585121d193c3d0b4856ccd656b7bfa9deb91ab6a" - -[[package]] -name = "pulldown-cmark" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" -dependencies = [ - "bitflags", - "memchr", - "unicase", -] - -[[package]] -name = "quick-xml" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" -dependencies = [ - "memchr", + "unicode-ident", ] [[package]] @@ -2349,28 +657,12 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" - [[package]] name = "radium" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - [[package]] name = "rand" version = "0.8.4" @@ -2426,21 +718,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "range-alloc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" - -[[package]] -name = "raw-window-handle" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" -dependencies = [ - "libc", -] - [[package]] name = "rayon" version = "1.5.1" @@ -2475,24 +752,12 @@ dependencies = [ "bitflags", ] -[[package]] -name = "redox_users" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" -dependencies = [ - "getrandom", - "redox_syscall", -] - [[package]] name = "regex" version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ - "aho-corasick", - "memchr", "regex-syntax", ] @@ -2501,6 +766,9 @@ name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] [[package]] name = "regex-syntax" @@ -2517,12 +785,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "renderdoc-sys" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" - [[package]] name = "rlimit" version = "0.6.2" @@ -2532,79 +794,9 @@ dependencies = [ "libc", ] -[[package]] -name = "roc_alias_analysis" -version = "0.1.0" -dependencies = [ - "morphic_lib", - "roc_collections", - "roc_debug_flags", - "roc_module", - "roc_mono", -] - -[[package]] -name = "roc_ast" -version = "0.1.0" -dependencies = [ - "arrayvec 0.7.2", - "bumpalo", - "libc", - "page_size", - "roc_builtins", - "roc_can", - "roc_collections", - "roc_error_macros", - "roc_load", - "roc_module", - "roc_parse", - "roc_problem", - "roc_region", - "roc_reporting", - "roc_target", - "roc_types", - "roc_unify", - "snafu", - "ven_graph", - "winapi", -] - -[[package]] -name = "roc_build" -version = "0.1.0" -dependencies = [ - "bumpalo", - "inkwell 0.1.0", - "libloading 0.7.1", - "roc_builtins", - "roc_can", - "roc_collections", - "roc_constrain", - "roc_error_macros", - "roc_gen_dev", - "roc_gen_llvm", - "roc_gen_wasm", - "roc_load", - "roc_module", - "roc_mono", - "roc_parse", - "roc_problem", - "roc_region", - "roc_reporting", - "roc_solve", - "roc_std", - "roc_target", - "roc_types", - "roc_unify", - "serde_json", - "target-lexicon", - "tempfile", - "wasi_libc_sys", -] - [[package]] name = "roc_builtins" -version = "0.1.0" +version = "0.0.1" dependencies = [ "dunce", "lazy_static", @@ -2612,14 +804,15 @@ dependencies = [ "roc_module", "roc_region", "roc_target", - "roc_types", + "roc_utils", + "tempfile", ] [[package]] name = "roc_can" -version = "0.1.0" +version = "0.0.1" dependencies = [ - "bitvec 1.0.0", + "bitvec", "bumpalo", "roc_collections", "roc_error_macros", @@ -2629,58 +822,17 @@ dependencies = [ "roc_problem", "roc_region", "roc_types", - "static_assertions 1.1.0", -] - -[[package]] -name = "roc_cli" -version = "0.1.0" -dependencies = [ - "bumpalo", - "clap 3.1.17", - "const_format", - "mimalloc", - "roc_build", - "roc_builtins", - "roc_can", - "roc_collections", - "roc_docs", - "roc_editor", - "roc_error_macros", - "roc_fmt", - "roc_linker", - "roc_load", - "roc_module", - "roc_mono", - "roc_parse", - "roc_region", - "roc_repl_cli", - "roc_reporting", - "roc_target", - "target-lexicon", - "tempfile", -] - -[[package]] -name = "roc_code_markup" -version = "0.1.0" -dependencies = [ - "bumpalo", - "itertools 0.10.1", - "palette", - "roc_ast", - "roc_module", - "roc_utils", - "serde", - "snafu", + "static_assertions", ] [[package]] name = "roc_collections" -version = "0.1.0" +version = "0.0.1" dependencies = [ + "bitvec", "bumpalo", - "hashbrown 0.11.2", + "fnv", + "hashbrown", "im", "im-rc", "wyhash", @@ -2688,10 +840,9 @@ dependencies = [ [[package]] name = "roc_constrain" -version = "0.1.0" +version = "0.0.1" dependencies = [ "arrayvec 0.7.2", - "roc_builtins", "roc_can", "roc_collections", "roc_error_macros", @@ -2703,93 +854,51 @@ dependencies = [ [[package]] name = "roc_debug_flags" -version = "0.1.0" +version = "0.0.1" [[package]] -name = "roc_docs" -version = "0.1.0" +name = "roc_derive" +version = "0.0.1" dependencies = [ "bumpalo", - "peg", - "pulldown-cmark", - "roc_ast", - "roc_builtins", "roc_can", - "roc_code_markup", "roc_collections", - "roc_highlight", - "roc_load", + "roc_derive_key", + "roc_error_macros", "roc_module", - "roc_parse", "roc_region", - "roc_reporting", - "roc_target", "roc_types", - "snafu", + "roc_unify", ] [[package]] -name = "roc_editor" -version = "0.1.0" +name = "roc_derive_key" +version = "0.0.1" dependencies = [ - "arrayvec 0.7.2", - "bumpalo", - "bytemuck", - "cgmath", - "colored", - "confy", - "copypasta", - "env_logger", - "fs_extra", - "futures", - "glyph_brush", - "libc", - "log", - "nonempty", - "page_size", - "palette", - "pest", - "pest_derive", - "roc_ast", - "roc_builtins", "roc_can", - "roc_code_markup", "roc_collections", - "roc_load", + "roc_error_macros", "roc_module", - "roc_parse", - "roc_problem", "roc_region", - "roc_reporting", - "roc_solve", "roc_types", - "roc_unify", - "serde", - "snafu", - "threadpool", - "ven_graph", - "wgpu", - "wgpu_glyph", - "winit", ] [[package]] name = "roc_error_macros" -version = "0.1.0" +version = "0.0.1" [[package]] name = "roc_exhaustive" -version = "0.1.0" +version = "0.0.1" dependencies = [ "roc_collections", "roc_module", "roc_region", - "roc_std", ] [[package]] name = "roc_fmt" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bumpalo", "roc_collections", @@ -2799,97 +908,40 @@ dependencies = [ ] [[package]] -name = "roc_gen_dev" -version = "0.1.0" +name = "roc_ident" +version = "0.0.1" + +[[package]] +name = "roc_intern" +version = "0.0.1" +dependencies = [ + "parking_lot", + "roc_collections", +] + +[[package]] +name = "roc_late_solve" +version = "0.0.1" dependencies = [ "bumpalo", - "object 0.26.2", - "packed_struct", - "roc_builtins", + "roc_can", "roc_collections", + "roc_derive", "roc_error_macros", "roc_module", - "roc_mono", - "roc_problem", - "roc_region", "roc_solve", - "roc_target", "roc_types", "roc_unify", - "target-lexicon", -] - -[[package]] -name = "roc_gen_llvm" -version = "0.1.0" -dependencies = [ - "bumpalo", - "inkwell 0.1.0", - "morphic_lib", - "roc_alias_analysis", - "roc_builtins", - "roc_collections", - "roc_debug_flags", - "roc_error_macros", - "roc_module", - "roc_mono", - "roc_std", - "roc_target", - "target-lexicon", -] - -[[package]] -name = "roc_gen_wasm" -version = "0.1.0" -dependencies = [ - "bumpalo", - "roc_builtins", - "roc_collections", - "roc_error_macros", - "roc_module", - "roc_mono", - "roc_std", - "roc_target", -] - -[[package]] -name = "roc_highlight" -version = "0.1.0" -dependencies = [ - "peg", - "roc_code_markup", -] - -[[package]] -name = "roc_ident" -version = "0.1.0" - -[[package]] -name = "roc_linker" -version = "0.1.0" -dependencies = [ - "bincode", - "bumpalo", - "clap 3.1.17", - "iced-x86", - "memmap2 0.5.3", - "object 0.26.2", - "roc_build", - "roc_collections", - "roc_mono", - "serde", - "target-lexicon", - "tempfile", ] [[package]] name = "roc_load" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bumpalo", "roc_builtins", + "roc_can", "roc_collections", - "roc_constrain", "roc_load_internal", "roc_module", "roc_reporting", @@ -2899,18 +951,21 @@ dependencies = [ [[package]] name = "roc_load_internal" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bumpalo", "crossbeam", - "num_cpus", - "parking_lot 0.12.0", + "parking_lot", "roc_builtins", "roc_can", "roc_collections", "roc_constrain", "roc_debug_flags", + "roc_derive", + "roc_derive_key", "roc_error_macros", + "roc_intern", + "roc_late_solve", "roc_module", "roc_mono", "roc_parse", @@ -2918,7 +973,9 @@ dependencies = [ "roc_region", "roc_reporting", "roc_solve", + "roc_solve_problem", "roc_target", + "roc_tracing", "roc_types", "roc_unify", "ven_pretty", @@ -2926,7 +983,7 @@ dependencies = [ [[package]] name = "roc_module" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bumpalo", "lazy_static", @@ -2935,37 +992,40 @@ dependencies = [ "roc_ident", "roc_region", "snafu", - "static_assertions 1.1.0", + "static_assertions", ] [[package]] name = "roc_mono" -version = "0.1.0" +version = "0.0.1" dependencies = [ + "bitvec", "bumpalo", - "hashbrown 0.11.2", + "hashbrown", "roc_builtins", "roc_can", "roc_collections", "roc_debug_flags", + "roc_derive", + "roc_derive_key", "roc_error_macros", "roc_exhaustive", + "roc_intern", + "roc_late_solve", "roc_module", "roc_problem", "roc_region", - "roc_solve", "roc_std", "roc_target", + "roc_tracing", "roc_types", - "roc_unify", - "static_assertions 1.1.0", - "ven_graph", + "static_assertions", "ven_pretty", ] [[package]] name = "roc_parse" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bumpalo", "encode_unicode", @@ -2976,7 +1036,7 @@ dependencies = [ [[package]] name = "roc_problem" -version = "0.1.0" +version = "0.0.1" dependencies = [ "roc_collections", "roc_module", @@ -2987,108 +1047,95 @@ dependencies = [ [[package]] name = "roc_region" -version = "0.1.0" +version = "0.0.1" dependencies = [ - "static_assertions 1.1.0", -] - -[[package]] -name = "roc_repl_cli" -version = "0.1.0" -dependencies = [ - "bumpalo", - "const_format", - "inkwell 0.1.0", - "libloading 0.7.1", - "roc_build", - "roc_builtins", - "roc_collections", - "roc_gen_llvm", - "roc_load", - "roc_mono", - "roc_parse", - "roc_repl_eval", - "roc_reporting", - "roc_std", - "roc_target", - "roc_types", - "rustyline", - "rustyline-derive", - "target-lexicon", -] - -[[package]] -name = "roc_repl_eval" -version = "0.1.0" -dependencies = [ - "bumpalo", - "roc_builtins", - "roc_can", - "roc_collections", - "roc_fmt", - "roc_load", - "roc_module", - "roc_mono", - "roc_parse", - "roc_region", - "roc_reporting", - "roc_std", - "roc_target", - "roc_types", + "static_assertions", ] [[package]] name = "roc_reporting" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bumpalo", "distance", "roc_can", "roc_collections", + "roc_error_macros", "roc_exhaustive", + "roc_fmt", "roc_module", "roc_parse", "roc_problem", "roc_region", - "roc_solve", + "roc_solve_problem", + "roc_std", "roc_types", "ven_pretty", ] [[package]] name = "roc_solve" -version = "0.1.0" +version = "0.0.1" dependencies = [ "arrayvec 0.7.2", "bumpalo", "roc_can", "roc_collections", "roc_debug_flags", + "roc_derive", + "roc_derive_key", "roc_error_macros", "roc_exhaustive", "roc_module", + "roc_problem", "roc_region", + "roc_solve_problem", "roc_types", "roc_unify", ] [[package]] -name = "roc_std" -version = "0.1.0" +name = "roc_solve_problem" +version = "0.0.1" dependencies = [ - "static_assertions 0.1.1", + "roc_can", + "roc_collections", + "roc_exhaustive", + "roc_module", + "roc_problem", + "roc_region", + "roc_types", +] + +[[package]] +name = "roc_std" +version = "0.0.1" +dependencies = [ + "arrayvec 0.7.2", + "static_assertions", ] [[package]] name = "roc_target" -version = "0.1.0" +version = "0.0.1" dependencies = [ + "strum", + "strum_macros", "target-lexicon", ] +[[package]] +name = "roc_tracing" +version = "0.0.1" +dependencies = [ + "tracing", + "tracing-appender", + "tracing-subscriber", +] + [[package]] name = "roc_types" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bumpalo", "roc_collections", @@ -3096,25 +1143,26 @@ dependencies = [ "roc_error_macros", "roc_module", "roc_region", - "static_assertions 1.1.0", - "ven_ena", + "static_assertions", ] [[package]] name = "roc_unify" -version = "0.1.0" +version = "0.0.1" dependencies = [ "bitflags", + "roc_can", "roc_collections", "roc_debug_flags", "roc_error_macros", "roc_module", + "roc_solve_problem", "roc_types", ] [[package]] name = "roc_utils" -version = "0.1.0" +version = "0.0.1" dependencies = [ "snafu", ] @@ -3125,62 +1173,20 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.4", + "semver", ] [[package]] -name = "rusttype" -version = "0.9.2" +name = "rustversion" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser 0.6.0", -] - -[[package]] -name = "rustyline" -version = "9.1.1" -source = "git+https://github.com/rtfeldman/rustyline?rev=e74333c#e74333c0d618896b88175bf06645108f996fe6d0" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "clipboard-win 4.2.2", - "dirs-next", - "fd-lock", - "libc", - "log", - "memchr", - "nix 0.23.1", - "radix_trie", - "scopeguard", - "smallvec", - "unicode-segmentation", - "unicode-width", - "utf8parse", - "winapi", -] - -[[package]] -name = "rustyline-derive" -version = "0.6.0" -source = "git+https://github.com/rtfeldman/rustyline?rev=e74333c#e74333c0d618896b88175bf06645108f996fe6d0" -dependencies = [ - "quote", - "syn", -] +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" [[package]] name = "ryu" @@ -3197,42 +1203,18 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.130" @@ -3281,54 +1263,20 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e277c495ac6cd1a01a58d0a0c574568b4d1ddf14f59965c6a58b8d96400b54f3" dependencies = [ - "itoa", + "itoa 0.4.8", "ryu", "serde", ] [[package]] -name = "serde_yaml" -version = "0.8.21" +name = "sharded-slab" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ - "dtoa", - "indexmap", - "serde", - "yaml-rust", + "lazy_static", ] -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - -[[package]] -name = "sha2" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "siphasher" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" - [[package]] name = "sized-chunks" version = "0.6.5" @@ -3339,79 +1287,17 @@ dependencies = [ "typenum", ] -[[package]] -name = "slab" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" - -[[package]] -name = "slotmap" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" -dependencies = [ - "version_check", -] - [[package]] name = "smallvec" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" - -[[package]] -name = "smithay-client-toolkit" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4750c76fd5d3ac95fa3ed80fe667d6a3d8590a960e5b575b98eea93339a80b80" -dependencies = [ - "andrew", - "bitflags", - "calloop", - "dlib 0.4.2", - "lazy_static", - "log", - "memmap2 0.1.0", - "nix 0.18.0", - "wayland-client 0.28.6", - "wayland-cursor 0.28.6", - "wayland-protocols 0.28.6", -] - -[[package]] -name = "smithay-client-toolkit" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210cf40de565aaaa085face1d860b17f6aee9f76f9d2816307ea2cc45eeb64f3" -dependencies = [ - "bitflags", - "dlib 0.5.0", - "lazy_static", - "log", - "memmap2 0.3.1", - "nix 0.22.0", - "pkg-config", - "wayland-client 0.29.1", - "wayland-cursor 0.29.1", - "wayland-protocols 0.29.1", -] - -[[package]] -name = "smithay-clipboard" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610b551bd25378bfd2b8e7a0fcbd83d427e8f2f6a40c47ae0f70688e9949dd55" -dependencies = [ - "smithay-client-toolkit 0.15.2", - "wayland-client 0.29.1", -] +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "snafu" -version = "0.6.10" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7" +checksum = "dd726aec4ebad65756394ff89a9b9598793d4e30121cd71690244c1e497b3aee" dependencies = [ "backtrace", "doc-comment", @@ -3420,43 +1306,22 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.6.10" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b" +checksum = "712529e9b0b014eabaa345b38e06032767e3dc393e8b017e853b1d7247094e74" dependencies = [ + "heck", "proc-macro2", "quote", "syn", ] -[[package]] -name = "spirv" -version = "0.2.0+1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" -dependencies = [ - "bitflags", - "num-traits", -] - -[[package]] -name = "static_assertions" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f406d6ee68db6796e11ffd7b4d171864c58b7451e79ef9460ea33c287a1f89a7" - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "str-buf" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a" - [[package]] name = "strip-ansi-escapes" version = "0.1.1" @@ -3467,26 +1332,33 @@ dependencies = [ ] [[package]] -name = "strsim" -version = "0.9.3" +name = "strum" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" [[package]] -name = "strsim" -version = "0.10.0" +name = "strum_macros" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] [[package]] name = "syn" -version = "1.0.81" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -3507,7 +1379,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "rand", "redox_syscall", @@ -3515,15 +1387,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - [[package]] name = "textwrap" version = "0.11.0" @@ -3533,12 +1396,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "thiserror" version = "1.0.30" @@ -3560,12 +1417,23 @@ dependencies = [ ] [[package]] -name = "threadpool" -version = "1.8.1" +name = "thread_local" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ - "num_cpus", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +dependencies = [ + "itoa 1.0.4", + "libc", + "num_threads", ] [[package]] @@ -3579,35 +1447,76 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.5.8" +name = "tracing" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "serde", + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", ] [[package]] -name = "ttf-parser" -version = "0.6.2" +name = "tracing-appender" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" - -[[package]] -name = "ttf-parser" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e835d06ed78a500d3d0e431a20c18ff5544b3f6e11376e834370cfd35e8948e" - -[[package]] -name = "twox-hash" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ - "cfg-if 1.0.0", - "rand", - "static_assertions 1.1.0", + "crossbeam-channel", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -3623,25 +1532,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] -name = "ucd-trie" -version = "0.1.3" +name = "unicode-ident" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-width" @@ -3649,12 +1543,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "utf8parse" version = "0.2.0" @@ -3662,18 +1550,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" [[package]] -name = "ven_ena" -version = "0.13.1" -dependencies = [ - "log", -] - -[[package]] -name = "ven_graph" -version = "2.0.5-pre" -dependencies = [ - "roc_collections", -] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "ven_pretty" @@ -3727,17 +1607,13 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" -[[package]] -name = "wasi_libc_sys" -version = "0.1.0" - [[package]] name = "wasm-bindgen" version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -3756,18 +1632,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.79" @@ -3797,152 +1661,6 @@ version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" -[[package]] -name = "wayland-client" -version = "0.28.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355" -dependencies = [ - "bitflags", - "downcast-rs", - "libc", - "nix 0.20.0", - "scoped-tls", - "wayland-commons 0.28.6", - "wayland-scanner 0.28.6", - "wayland-sys 0.28.6", -] - -[[package]] -name = "wayland-client" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9108ec1c37f4774d0c2937ba1a6c23d1786b2152c4a13bd9fdb20e42d16e8841" -dependencies = [ - "bitflags", - "downcast-rs", - "libc", - "nix 0.22.0", - "scoped-tls", - "wayland-commons 0.29.1", - "wayland-scanner 0.29.1", - "wayland-sys 0.29.1", -] - -[[package]] -name = "wayland-commons" -version = "0.28.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda" -dependencies = [ - "nix 0.20.0", - "once_cell", - "smallvec", - "wayland-sys 0.28.6", -] - -[[package]] -name = "wayland-commons" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "265ef51b3b3e5c9ef098f10425c39624663f459c3821dcaacc4748be975f1beb" -dependencies = [ - "nix 0.22.0", - "once_cell", - "smallvec", - "wayland-sys 0.29.1", -] - -[[package]] -name = "wayland-cursor" -version = "0.28.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a" -dependencies = [ - "nix 0.20.0", - "wayland-client 0.28.6", - "xcursor", -] - -[[package]] -name = "wayland-cursor" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c19bb6628daf4097e58b7911481e8371e13318d5a60894779901bd3267407a7" -dependencies = [ - "nix 0.22.0", - "wayland-client 0.29.1", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.28.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f" -dependencies = [ - "bitflags", - "wayland-client 0.28.6", - "wayland-commons 0.28.6", - "wayland-scanner 0.28.6", -] - -[[package]] -name = "wayland-protocols" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b3b6f1dc0193072ef4eadcb144da30d58c1f2895516c063804d213310703c8e" -dependencies = [ - "bitflags", - "wayland-client 0.29.1", - "wayland-commons 0.29.1", - "wayland-scanner 0.29.1", -] - -[[package]] -name = "wayland-scanner" -version = "0.28.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1" -dependencies = [ - "proc-macro2", - "quote", - "xml-rs", -] - -[[package]] -name = "wayland-scanner" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaaf2bc85e7b9143159af96bd23d954a5abe391c4376db712320643280fdc6f4" -dependencies = [ - "proc-macro2", - "quote", - "xml-rs", -] - -[[package]] -name = "wayland-sys" -version = "0.28.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8" -dependencies = [ - "dlib 0.5.0", - "lazy_static", - "pkg-config", -] - -[[package]] -name = "wayland-sys" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba9e06acb775b3007f8d3094438306979e572d1d3b844d7a71557a84b055d959" -dependencies = [ - "dlib 0.5.0", - "lazy_static", - "pkg-config", -] - [[package]] name = "web-sys" version = "0.3.55" @@ -3953,107 +1671,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "wgpu" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1577ecc4f6992b9e965878ac594efb24eed2bdf089c11f45b3d1c5f216e2e30" -dependencies = [ - "arrayvec 0.7.2", - "js-sys", - "log", - "parking_lot 0.11.2", - "raw-window-handle", - "smallvec", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-core" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdcbfa4885b32c2b1feb2faeb8b6a76065b752b8f08751b82f994e937687f46" -dependencies = [ - "arrayvec 0.7.2", - "bitflags", - "cfg_aliases", - "copyless", - "fxhash", - "log", - "naga", - "parking_lot 0.11.2", - "profiling", - "raw-window-handle", - "smallvec", - "thiserror", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-hal" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e493835d9edb153d5c8a9d8d016e1811dbe32ddb707a110be1453c7b051d3ec" -dependencies = [ - "arrayvec 0.7.2", - "ash", - "bit-set", - "bitflags", - "block", - "core-graphics-types", - "d3d12", - "foreign-types", - "fxhash", - "glow", - "gpu-alloc", - "gpu-descriptor", - "inplace_it", - "js-sys", - "khronos-egl", - "libloading 0.7.1", - "log", - "metal", - "naga", - "objc", - "parking_lot 0.11.2", - "profiling", - "range-alloc", - "raw-window-handle", - "renderdoc-sys", - "thiserror", - "wasm-bindgen", - "web-sys", - "wgpu-types", - "winapi", -] - -[[package]] -name = "wgpu-types" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e15e44ba88ec415466e18e91881319e7c9e96cb905dc623305168aea65b85ccc" -dependencies = [ - "bitflags", -] - -[[package]] -name = "wgpu_glyph" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c78d49f4d168b245882ce000ee94fc67e744b33760c0119b0dbf8cb3caf20de5" -dependencies = [ - "bytemuck", - "glyph_brush", - "log", - "wgpu", -] - [[package]] name = "winapi" version = "0.3.9" @@ -4085,124 +1702,49 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6" -dependencies = [ - "windows_aarch64_msvc 0.28.0", - "windows_i686_gnu 0.28.0", - "windows_i686_msvc 0.28.0", - "windows_x86_64_gnu 0.28.0", - "windows_x86_64_msvc 0.28.0", -] - [[package]] name = "windows-sys" version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" dependencies = [ - "windows_aarch64_msvc 0.34.0", - "windows_i686_gnu 0.34.0", - "windows_i686_msvc 0.34.0", - "windows_x86_64_gnu 0.34.0", - "windows_x86_64_msvc 0.34.0", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_msvc" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2" - [[package]] name = "windows_aarch64_msvc" version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" -[[package]] -name = "windows_i686_gnu" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a" - [[package]] name = "windows_i686_gnu" version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" -[[package]] -name = "windows_i686_msvc" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64" - [[package]] name = "windows_i686_msvc" version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" -[[package]] -name = "windows_x86_64_gnu" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954" - [[package]] name = "windows_x86_64_gnu" version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" -[[package]] -name = "windows_x86_64_msvc" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" - [[package]] name = "windows_x86_64_msvc" version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" -[[package]] -name = "winit" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79610794594d5e86be473ef7763f604f2159cbac8c94debd00df8fb41e86c2f8" -dependencies = [ - "bitflags", - "cocoa", - "core-foundation 0.9.2", - "core-graphics 0.22.3", - "core-video-sys", - "dispatch", - "instant", - "lazy_static", - "libc", - "log", - "mio", - "mio-misc", - "ndk", - "ndk-glue", - "ndk-sys", - "objc", - "parking_lot 0.11.2", - "percent-encoding", - "raw-window-handle", - "scopeguard", - "smithay-client-toolkit 0.12.3", - "wayland-client 0.28.6", - "winapi", - "x11-dl", -] - [[package]] name = "wyhash" version = "0.5.0" @@ -4212,15 +1754,6 @@ dependencies = [ "rand_core 0.6.3", ] -[[package]] -name = "wyz" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" -dependencies = [ - "tap", -] - [[package]] name = "wyz" version = "0.5.0" @@ -4230,72 +1763,8 @@ dependencies = [ "tap", ] -[[package]] -name = "x11-clipboard" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473068b7b80ac86a18328824f1054e5e007898c47b5bbc281bd7abe32bc3653c" -dependencies = [ - "xcb", -] - -[[package]] -name = "x11-dl" -version = "2.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" -dependencies = [ - "lazy_static", - "libc", - "pkg-config", -] - -[[package]] -name = "xcb" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771e2b996df720cd1c6dd9ff90f62d91698fd3610cc078388d0564bdd6622a9c" -dependencies = [ - "libc", - "log", - "quick-xml", -] - -[[package]] -name = "xcursor" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" -dependencies = [ - "nom", -] - -[[package]] -name = "xdg" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a23fe958c70412687039c86f578938b4a0bb50ec788e96bce4d6ab00ddd5803" -dependencies = [ - "dirs", -] - -[[package]] -name = "xi-unicode" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" - [[package]] name = "xml-rs" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 8789a4d968..e415143a39 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -813,10 +813,15 @@ fn redirect_dummy_dll_functions( // the array of addresses is null-terminated; make sure we haven't reached the end let current = u64::from_le_bytes(address_bytes.try_into().unwrap()); + crate::dbg_hex!(current); if current == 0 { internal_error!("invalid state: fewer thunks than function addresses"); } + // - 0x140000000 + let roc_app_target_va = roc_app_target_va; + crate::dbg_hex!(roc_app_target_va); + // update the address to a function VA address_bytes.copy_from_slice(&roc_app_target_va.to_le_bytes()); @@ -1105,33 +1110,67 @@ fn write_image_base_relocation( new_block_va: u32, relocations: &[u16], ) -> usize { + crate::dbg_hex!(new_block_va, relocations); + let mut next_block_start = reloc_section_start as u32; - let new_block_start = loop { + let mut blocks = vec![]; + + loop { let header = load_struct_inplace_mut::(mmap, next_block_start as usize); if header.virtual_address.get(LE) == 0 { - break next_block_start; + break; } + blocks.push((next_block_start, *header)); + next_block_start += header.size_of_block.get(LE); - }; + } - let size_of_block = 8 + 2 * relocations.len(); + // extra space that we'll use for the new relocations + let shift_amount = relocations.len() * 2; - let header = load_struct_inplace_mut::(mmap, new_block_start as usize); - *header = ImageBaseRelocation { - virtual_address: object::U32::new(LE, new_block_va), - size_of_block: object::U32::new(LE, size_of_block as u32), - }; + // now, in reverse, shift sections that need to be shifted + while let Some((block_start, header)) = blocks.pop() { + let header_va = header.virtual_address.get(LE); + let header_size = header.size_of_block.get(LE); - let destination = - load_structs_inplace_mut::(mmap, new_block_start as usize + 8, relocations.len()); + let block_start = block_start as usize; - destination.copy_from_slice(relocations); + match header_va.cmp(&new_block_va) { + std::cmp::Ordering::Greater => { + // shift this block + mmap.copy_within( + block_start..block_start + header_size as usize, + block_start + shift_amount, + ); + } + std::cmp::Ordering::Equal => { + // extend this block + let header = load_struct_inplace_mut::(mmap, block_start); - size_of_block + let new_size = header.size_of_block.get(LE) + 2; + header.size_of_block.set(LE, new_size); + + let number_of_entries = (new_size as usize - 8) / 2; + let entries = + load_structs_inplace_mut::(mmap, block_start + 8, number_of_entries); + + entries[number_of_entries - relocations.len()..].copy_from_slice(relocations); + + // sort by VA + entries.sort_unstable_by_key(|x| x & 0b0000_1111_1111_1111); + } + std::cmp::Ordering::Less => { + // done + break; + } + } + } + + shift_amount } #[cfg(test)] @@ -1513,7 +1552,7 @@ mod test { { let dir = tempfile::tempdir().unwrap(); let dir = dir.path(); - let dir = Path::new(r"C:\Users\folkert\Documents\GitHub\roc\linktest"); + // let dir = Path::new(r"C:\Users\folkert\Documents\GitHub\roc\linktest"); runner(dir); @@ -1541,7 +1580,7 @@ mod test { { let dir = tempfile::tempdir().unwrap(); let dir = dir.path(); - let dir = Path::new("/tmp/roc"); + // let dir = Path::new("/tmp/roc"); runner(dir); @@ -1658,6 +1697,7 @@ mod test { #[cfg(windows)] #[test] + #[ignore] fn app_internal_relocations_windows() { assert_eq!("Hello foo\n", windows_test(test_internal_relocations)) } @@ -1893,8 +1933,9 @@ mod test { // 0x3a08 let reloc_section_start = 0x4600; - let new_block_va = 0x3000; - let relocations = &[0xa03]; + let addr = 0x3a08 - 0x00002c00; + let new_block_va = 0x4000; + let relocations = &[(addr) as u16]; let added_reloc_bytes = write_image_base_relocation( executable, reloc_section_start, @@ -2044,9 +2085,6 @@ mod test { .map(|s| (s.name, s.offset_in_section as u64)) .collect(); - crate::dbg_hex!(&symbols); - symbols[0].1 = 0x140001000; - crate::dbg_hex!(md.thunks_start_offset); redirect_dummy_dll_functions( executable, From dbaa63e21005ce3dece2aea8751d240b18c5bc1b Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 15 Oct 2022 18:03:19 +0200 Subject: [PATCH 09/54] minor correction Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 6ab1cee498..82fa0aa3f5 100644 --- a/flake.nix +++ b/flake.nix @@ -129,7 +129,7 @@ formatter = pkgs.nixpkgs-fmt; - # You can build this package (the compiler) with the `nix build` command. + # You can build this package (the roc CLI) with the `nix build` command. packages.default = import ./. { inherit pkgs; }; }); } From fdd921aeeb4877a2b8dbcdeae0ffc6e554f1711d Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:09:56 +0200 Subject: [PATCH 10/54] add extra fields to metadata --- crates/linker/src/pe.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index e415143a39..fc637a53e8 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -49,7 +49,13 @@ struct PeMetadata { dynamic_relocations: DynamicRelocationsPe, /// File offset for the thunks of our dummy .dll - thunks_start_offset: usize, + thunks_start_offset_in_file: usize, + + /// Offset for the thunks of our dummy .dll within the .rdata section + thunks_start_offset_in_section: usize, + + /// Virtual address of the .rdata section + rdata_virtual_address: u32, /// Constants from the host .exe header image_base: u64, @@ -97,7 +103,18 @@ impl PeMetadata { .unwrap(); let dynamic_relocations = DynamicRelocationsPe::new(preprocessed_data); - let thunks_start_offset = find_thunks_start_offset(preprocessed_data, &dynamic_relocations); + let thunks_start_offset_in_file = + find_thunks_start_offset(preprocessed_data, &dynamic_relocations); + + let rdata_section = dynhost_obj + .sections() + .find(|s| s.name() == Ok(".rdata")) + .unwrap(); + + let thunks_start_offset_in_section = + thunks_start_offset_in_file - rdata_section.file_range().unwrap().0 as usize; + + let rdata_virtual_address = rdata_section.address() as u32; let optional_header = dynhost_obj.nt_headers().optional_header; let optional_header_offset = dynhost_obj.dos_header().nt_headers_offset() as usize @@ -143,7 +160,9 @@ impl PeMetadata { imports, exports, dynamic_relocations, - thunks_start_offset, + thunks_start_offset_in_file, + thunks_start_offset_in_section, + rdata_virtual_address, } } } @@ -375,7 +394,12 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b dbg!(&symbols); - redirect_dummy_dll_functions(executable, &symbols, &md.imports, md.thunks_start_offset); + redirect_dummy_dll_functions( + executable, + &symbols, + &md.imports, + md.thunks_start_offset_in_file, + ); } #[derive(Debug, Serialize, Deserialize)] @@ -2085,12 +2109,12 @@ mod test { .map(|s| (s.name, s.offset_in_section as u64)) .collect(); - crate::dbg_hex!(md.thunks_start_offset); + crate::dbg_hex!(md.thunks_start_offset_in_file); redirect_dummy_dll_functions( executable, &symbols, &md.imports, - md.thunks_start_offset, + md.thunks_start_offset_in_file, ); }; }; From 7ab46a144bbc4038e09d32e3e9fec6a2d46eef4f Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:12:06 +0200 Subject: [PATCH 11/54] cleanup --- crates/linker/src/pe.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index fc637a53e8..e5944b6dd1 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1134,10 +1134,7 @@ fn write_image_base_relocation( new_block_va: u32, relocations: &[u16], ) -> usize { - crate::dbg_hex!(new_block_va, relocations); - let mut next_block_start = reloc_section_start as u32; - let mut blocks = vec![]; loop { @@ -1156,6 +1153,9 @@ fn write_image_base_relocation( // extra space that we'll use for the new relocations let shift_amount = relocations.len() * 2; + // 8 in practice + const HEADER_WIDTH: usize = std::mem::size_of::(); + // now, in reverse, shift sections that need to be shifted while let Some((block_start, header)) = blocks.pop() { let header_va = header.virtual_address.get(LE); @@ -1175,16 +1175,19 @@ fn write_image_base_relocation( // extend this block let header = load_struct_inplace_mut::(mmap, block_start); - let new_size = header.size_of_block.get(LE) + 2; + let new_size = header.size_of_block.get(LE) + shift_amount as u32; header.size_of_block.set(LE, new_size); - let number_of_entries = (new_size as usize - 8) / 2; - let entries = - load_structs_inplace_mut::(mmap, block_start + 8, number_of_entries); + let number_of_entries = (new_size as usize - HEADER_WIDTH) / 2; + let entries = load_structs_inplace_mut::( + mmap, + block_start + HEADER_WIDTH, + number_of_entries, + ); entries[number_of_entries - relocations.len()..].copy_from_slice(relocations); - // sort by VA + // sort by VA. Upper 4 bits store the relocation type entries.sort_unstable_by_key(|x| x & 0b0000_1111_1111_1111); } std::cmp::Ordering::Less => { From 4c5189363230595172756b20bd5445cbe9693ee5 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:16:31 +0200 Subject: [PATCH 12/54] get rid of constants --- crates/linker/src/pe.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index e5944b6dd1..f749f6f3d9 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1958,11 +1958,18 @@ mod test { section_alignment, ); - // 0x3a08 - let reloc_section_start = 0x4600; - let addr = 0x3a08 - 0x00002c00; - let new_block_va = 0x4000; - let relocations = &[(addr) as u16]; + let reloc_section_header_start = + section_header_start - std::mem::size_of::(); + + let reloc_image_section = load_struct_inplace::( + executable, + reloc_section_header_start, + ); + + let reloc_section_start = reloc_image_section.pointer_to_raw_data.get(LE) as usize; + let offset_in_section = md.thunks_start_offset_in_section; + let relocations = &[(offset_in_section) as u16]; + let new_block_va = md.rdata_virtual_address - md.image_base as u32; let added_reloc_bytes = write_image_base_relocation( executable, reloc_section_start, From b3cf1c681279d38fe5b725af52cb6fd3712ac3d4 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:24:14 +0200 Subject: [PATCH 13/54] extract .dll relocation logic into function --- crates/linker/src/pe.rs | 72 ++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index f749f6f3d9..98a67d2d87 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -241,8 +241,7 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b let mut section_header_start = md.dynamic_relocations.section_headers_offset_in_file as usize + md.host_section_count * std::mem::size_of::(); - let reloc_section_header_start = - section_header_start - std::mem::size_of::(); + relocate_dummy_dll_entries(executable, &md); let mut code_bytes_added = 0; let mut data_bytes_added = 0; @@ -257,16 +256,6 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b section_alignment, ); - let reloc_section_start = 0x4600; - let new_block_va = 0xb000; - let relocations = &[0]; - let added_reloc_bytes = - write_image_base_relocation(executable, reloc_section_start, new_block_va, relocations); - - let ptr = load_struct_inplace_mut::(executable, reloc_section_header_start); - ptr.virtual_size - .set(LE, ptr.virtual_size.get(LE) + added_reloc_bytes as u32); - for kind in [SectionKind::Text, SectionKind::ReadOnlyData] { let length: usize = app_obj_sections .sections @@ -1200,6 +1189,34 @@ fn write_image_base_relocation( shift_amount } +fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { + // find the location to write the section headers for our new sections + let section_header_start = md.dynamic_relocations.section_headers_offset_in_file as usize + + md.host_section_count * std::mem::size_of::(); + + let reloc_section_header_start = + section_header_start - std::mem::size_of::(); + + let reloc_image_section = + load_struct_inplace::(executable, reloc_section_header_start); + + let relocations: Vec<_> = (0..md.dynamic_relocations.name_by_virtual_address.len()) + .map(|i| (md.thunks_start_offset_in_section + 2 * i) as u16) + .collect(); + + let reloc_section_start = reloc_image_section.pointer_to_raw_data.get(LE) as usize; + let added_reloc_bytes = write_image_base_relocation( + executable, + reloc_section_start, + md.rdata_virtual_address - md.image_base as u32, + &relocations, + ); + + let ptr = load_struct_inplace_mut::(executable, reloc_section_header_start); + ptr.virtual_size + .set(LE, ptr.virtual_size.get(LE) + added_reloc_bytes as u32); +} + #[cfg(test)] mod test { const PE_DYNHOST: &[u8] = include_bytes!("../dynhost_benchmarks_windows.exe") as &[_]; @@ -1945,6 +1962,8 @@ mod test { as usize + md.host_section_count * std::mem::size_of::(); + relocate_dummy_dll_entries(executable, &md); + let mut code_bytes_added = 0; let mut data_bytes_added = 0; let mut file_bytes_added = 0; @@ -1958,35 +1977,6 @@ mod test { section_alignment, ); - let reloc_section_header_start = - section_header_start - std::mem::size_of::(); - - let reloc_image_section = load_struct_inplace::( - executable, - reloc_section_header_start, - ); - - let reloc_section_start = reloc_image_section.pointer_to_raw_data.get(LE) as usize; - let offset_in_section = md.thunks_start_offset_in_section; - let relocations = &[(offset_in_section) as u16]; - let new_block_va = md.rdata_virtual_address - md.image_base as u32; - let added_reloc_bytes = write_image_base_relocation( - executable, - reloc_section_start, - new_block_va, - relocations, - ); - - let reloc_section_header_start = - section_header_start - std::mem::size_of::(); - - let ptr = load_struct_inplace_mut::( - executable, - reloc_section_header_start, - ); - ptr.virtual_size - .set(LE, ptr.virtual_size.get(LE) + added_reloc_bytes as u32); - for kind in [SectionKind::Text, SectionKind::ReadOnlyData] { let length: usize = app_obj_sections .sections From b5fb200a913be0126ad469936b2ff9ed72031cb1 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:29:50 +0200 Subject: [PATCH 14/54] ensure sections never have 0 virtual size --- crates/linker/src/pe.rs | 197 +--------------------------------------- 1 file changed, 3 insertions(+), 194 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 98a67d2d87..c167b6b614 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -271,7 +271,8 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b } } - let virtual_size = length as u32; + // NOTE: sections cannot be zero in size! + let virtual_size = u32::max(1, length as u32); let size_of_raw_data = next_multiple_of(length, file_alignment) as u32; match kind { @@ -1924,199 +1925,7 @@ mod test { std::fs::copy(&dir.join("preprocessedhost"), &dir.join("app.exe")).unwrap(); - { - let executable_path: &Path = &dir.join("app.exe"); - let metadata_path: &Path = &dir.join("metadata"); - let roc_app_bytes = &*roc_app; - let md = PeMetadata::read_from_file(metadata_path); - - let app_obj_sections = AppSections::from_data(roc_app_bytes); - let mut symbols = app_obj_sections.roc_symbols; - - let image_base: u64 = md.image_base; - let file_alignment = md.file_alignment as usize; - let section_alignment = md.section_alignment as usize; - - let app_sections_size: usize = app_obj_sections - .sections - .iter() - .map(|s| { - next_multiple_of(s.file_range.end - s.file_range.start, file_alignment) - }) - .sum(); - - let executable = - &mut open_mmap_mut(executable_path, md.dynhost_file_size + app_sections_size); - - let app_code_section_va = md.last_host_section_address - + next_multiple_of( - md.last_host_section_size as usize, - section_alignment as usize, - ) as u64; - - let mut section_file_offset = md.dynhost_file_size; - let mut virtual_address = (app_code_section_va - image_base) as u32; - - // find the location to write the section headers for our new sections - let mut section_header_start = md.dynamic_relocations.section_headers_offset_in_file - as usize - + md.host_section_count * std::mem::size_of::(); - - relocate_dummy_dll_entries(executable, &md); - - let mut code_bytes_added = 0; - let mut data_bytes_added = 0; - let mut file_bytes_added = 0; - - // relocations between the sections of the roc application - // (as opposed to relocations for symbols the app imports from the host) - let inter_app_relocations = process_internal_relocations( - &app_obj_sections.sections, - &app_obj_sections.other_symbols, - (app_code_section_va - image_base) as u32, - section_alignment, - ); - - for kind in [SectionKind::Text, SectionKind::ReadOnlyData] { - let length: usize = app_obj_sections - .sections - .iter() - .filter(|s| s.kind == kind) - .map(|s| s.file_range.end - s.file_range.start) - .sum(); - - // offset_in_section now becomes a proper virtual address - for symbol in symbols.iter_mut() { - if symbol.section_kind == kind { - symbol.offset_in_section += - image_base as usize + virtual_address as usize; - } - } - - let virtual_size = u32::max(1, length as u32); - let size_of_raw_data = next_multiple_of(length, file_alignment) as u32; - - match kind { - SectionKind::Text => { - code_bytes_added += size_of_raw_data; - - write_section_header( - executable, - *b".text1\0\0", - pe::IMAGE_SCN_MEM_READ - | pe::IMAGE_SCN_CNT_CODE - | pe::IMAGE_SCN_MEM_EXECUTE, - section_header_start, - section_file_offset, - virtual_size, - virtual_address, - size_of_raw_data, - ); - } - SectionKind::ReadOnlyData => { - data_bytes_added += size_of_raw_data; - - write_section_header( - executable, - *b".rdata1\0", - pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_CNT_INITIALIZED_DATA, - section_header_start, - section_file_offset, - virtual_size, - virtual_address, - size_of_raw_data, - ); - } - } - - let mut offset = section_file_offset; - let it = app_obj_sections.sections.iter().filter(|s| s.kind == kind); - for section in it { - let slice = - &roc_app_bytes[section.file_range.start..section.file_range.end]; - executable[offset..][..slice.len()].copy_from_slice(slice); - - for (name, app_relocation) in section.relocations.iter() { - let AppRelocation { - offset_in_section, - relocation, - address, - } = app_relocation; - - if let Some(destination) = md.exports.get(name) { - match relocation.kind() { - object::RelocationKind::Relative => { - // we implicitly only do 32-bit relocations - debug_assert_eq!(relocation.size(), 32); - - let delta = destination - - virtual_address as i64 - - *offset_in_section as i64 - + relocation.addend(); - - executable[offset + *offset_in_section as usize..][..4] - .copy_from_slice(&(delta as i32).to_le_bytes()); - } - _ => todo!(), - } - } else if let Some(destination) = inter_app_relocations.get(name) { - // we implicitly only do 32-bit relocations - debug_assert_eq!(relocation.size(), 32); - - let delta = destination - - virtual_address as i64 - - *offset_in_section as i64 - + relocation.addend(); - - executable[offset + *offset_in_section as usize..][..4] - .copy_from_slice(&(delta as i32).to_le_bytes()); - } else { - match relocation.kind() { - object::RelocationKind::Relative => { - // we implicitly only do 32-bit relocations - debug_assert_eq!(relocation.size(), 32); - - let delta = *address as i64 - *offset_in_section as i64 - + relocation.addend(); - - executable[offset + *offset_in_section as usize..][..4] - .copy_from_slice(&(delta as i32).to_le_bytes()); - } - _ => todo!(), - } - } - } - - offset += slice.len(); - } - - section_header_start += std::mem::size_of::(); - section_file_offset += size_of_raw_data as usize; - virtual_address += next_multiple_of(length, section_alignment) as u32; - file_bytes_added += next_multiple_of(length, section_alignment) as u32; - } - - update_optional_header( - executable, - md.optional_header_offset, - code_bytes_added as u32, - file_bytes_added as u32, - data_bytes_added as u32, - ); - - let mut symbols: Vec<_> = symbols - .into_iter() - .map(|s| (s.name, s.offset_in_section as u64)) - .collect(); - - crate::dbg_hex!(md.thunks_start_offset_in_file); - redirect_dummy_dll_functions( - executable, - &symbols, - &md.imports, - md.thunks_start_offset_in_file, - ); - }; + surgery_pe(&dir.join("app.exe"), &dir.join("metadata"), &*roc_app); }; } From e8dc02d578e2a2b08af29c48452a9a12a38e296c Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:30:59 +0200 Subject: [PATCH 15/54] remove unused import on windows --- crates/linker/src/elf.rs | 2 +- crates/linker/src/macho.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/linker/src/elf.rs b/crates/linker/src/elf.rs index 11db80e4da..5fda7a93bf 100644 --- a/crates/linker/src/elf.rs +++ b/crates/linker/src/elf.rs @@ -10,7 +10,6 @@ use roc_collections::all::MutMap; use roc_error_macros::{internal_error, user_error}; use std::convert::TryFrom; use std::ffi::CStr; -use std::fs; use std::mem; use std::os::raw::c_char; use std::path::Path; @@ -1016,6 +1015,7 @@ pub(crate) fn surgery_elf( // Make sure the final executable has permision to execute. #[cfg(target_family = "unix")] { + use std::fs; use std::os::unix::fs::PermissionsExt; let mut perms = fs::metadata(executable_path) diff --git a/crates/linker/src/macho.rs b/crates/linker/src/macho.rs index f713d51dca..33e304120f 100644 --- a/crates/linker/src/macho.rs +++ b/crates/linker/src/macho.rs @@ -10,7 +10,6 @@ use object::{ use roc_collections::all::MutMap; use roc_error_macros::internal_error; use std::ffi::CStr; -use std::fs; use std::mem; use std::path::Path; use std::time::{Duration, Instant}; @@ -1189,6 +1188,7 @@ pub(crate) fn surgery_macho( // Make sure the final executable has permision to execute. #[cfg(target_family = "unix")] { + use std::fs; use std::os::unix::fs::PermissionsExt; let mut perms = fs::metadata(executable_path) From a5935b262b9000bb11fef1ceaa7b5e43f4669599 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:31:36 +0200 Subject: [PATCH 16/54] cleanup --- crates/linker/src/pe.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index c167b6b614..0d24d36baa 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -382,8 +382,6 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b .map(|s| (s.name, s.offset_in_section as u64)) .collect(); - dbg!(&symbols); - redirect_dummy_dll_functions( executable, &symbols, @@ -827,15 +825,10 @@ fn redirect_dummy_dll_functions( // the array of addresses is null-terminated; make sure we haven't reached the end let current = u64::from_le_bytes(address_bytes.try_into().unwrap()); - crate::dbg_hex!(current); if current == 0 { internal_error!("invalid state: fewer thunks than function addresses"); } - // - 0x140000000 - let roc_app_target_va = roc_app_target_va; - crate::dbg_hex!(roc_app_target_va); - // update the address to a function VA address_bytes.copy_from_slice(&roc_app_target_va.to_le_bytes()); From ebc3e770de12f6ec1eef768ae3c5bd16ac28f949 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:33:01 +0200 Subject: [PATCH 17/54] more cleanup --- crates/linker/src/pe.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 0d24d36baa..df89f79491 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1590,7 +1590,6 @@ mod test { { let dir = tempfile::tempdir().unwrap(); let dir = dir.path(); - // let dir = Path::new(r"C:\Users\folkert\Documents\GitHub\roc\linktest"); runner(dir); @@ -1618,7 +1617,6 @@ mod test { { let dir = tempfile::tempdir().unwrap(); let dir = dir.path(); - // let dir = Path::new("/tmp/roc"); runner(dir); From 0e08ccdc0c1142d5f5d6470b8fd832242d822aca Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:34:24 +0200 Subject: [PATCH 18/54] enable test that works --- crates/linker/src/pe.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index df89f79491..436c7648e1 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1733,7 +1733,6 @@ mod test { #[cfg(windows)] #[test] - #[ignore] fn app_internal_relocations_windows() { assert_eq!("Hello foo\n", windows_test(test_internal_relocations)) } From b822c1c61726774b74343b8d551934e0d590f898 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 15 Oct 2022 20:45:20 +0200 Subject: [PATCH 19/54] basics test now works! --- crates/linker/src/pe.rs | 129 ---------------------------------------- 1 file changed, 129 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 436c7648e1..e9e72ea81f 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1690,7 +1690,6 @@ mod test { #[cfg(windows)] #[test] - #[ignore = "does not work yet"] fn basics_windows() { assert_eq!("Hello, 234567 32 1 3!\n", windows_test(test_basics)) } @@ -1802,132 +1801,4 @@ mod test { fn preprocessing_wine() { assert_eq!("Hello there\n", wine_test(preprocessing_help)) } - - #[allow(dead_code)] - fn stripped_basics(dir: &Path) { - { - let host_zig = indoc!( - r#" - const std = @import("std"); - - extern fn roc_magic() callconv(.C) u64; - - pub export fn roc_alloc() u64 { - return 123456; - } - - pub fn main() !void { - const stdout = std.io.getStdOut().writer(); - - var timer = std.time.Timer.start() catch unreachable; - - if (timer.read() == 1234) { - try stdout.print("Hello, {}!\n", .{32}); - } else { - try stdout.print("Hello, {}!\n", .{roc_magic()}); - } - } - "# - ); - let app_zig = indoc!( - r#" - export fn roc_magic() u64 { - return 32; - } - "# - ); - let zig = std::env::var("ROC_ZIG").unwrap_or_else(|_| "zig".into()); - - std::fs::write(dir.join("host.zig"), host_zig.as_bytes()).unwrap(); - std::fs::write(dir.join("app.zig"), app_zig.as_bytes()).unwrap(); - - // we need to compile the app first - let output = std::process::Command::new(&zig) - .current_dir(dir) - .args(&[ - "build-obj", - "app.zig", - "-target", - "x86_64-windows-gnu", - "--strip", - "-rdynamic", - "-OReleaseFast", - ]) - .output() - .unwrap(); - - if !output.status.success() { - use std::io::Write; - - std::io::stdout().write_all(&output.stdout).unwrap(); - std::io::stderr().write_all(&output.stderr).unwrap(); - - panic!("zig build-obj failed"); - } - - // open our app object; we'll copy sections from it later - let file = std::fs::File::open(dir.join("app.obj")).unwrap(); - let roc_app = unsafe { memmap2::Mmap::map(&file) }.unwrap(); - - let roc_app_sections = AppSections::from_data(&*roc_app); - let symbols = roc_app_sections.roc_symbols; - - // make the dummy dylib based on the app object - let names: Vec<_> = symbols.iter().map(|s| s.name.clone()).collect(); - let dylib_bytes = crate::generate_dylib::synthetic_dll(&names); - std::fs::write(dir.join("libapp.obj"), dylib_bytes).unwrap(); - - // now we can compile the host (it uses libapp.obj, hence the order here) - let output = std::process::Command::new(&zig) - .current_dir(dir) - .args(&[ - "build-exe", - "libapp.obj", - "host.zig", - "-lc", - "-target", - "x86_64-windows-gnu", - "-rdynamic", - "--strip", - "-rdynamic", - "-OReleaseFast", - ]) - .output() - .unwrap(); - - if !output.status.success() { - use std::io::Write; - - std::io::stdout().write_all(&output.stdout).unwrap(); - std::io::stderr().write_all(&output.stderr).unwrap(); - - panic!("zig build-exe failed"); - } - - preprocess_windows( - &dir.join("host.exe"), - &dir.join("metadata"), - &dir.join("preprocessedhost"), - false, - false, - ) - .unwrap(); - - std::fs::copy(&dir.join("preprocessedhost"), &dir.join("app.exe")).unwrap(); - - surgery_pe(&dir.join("app.exe"), &dir.join("metadata"), &*roc_app); - }; - } - - #[cfg(windows)] - #[test] - fn stripped_basics_windows() { - assert_eq!("Hello, 32!\n", windows_test(stripped_basics)) - } - - #[test] - #[ignore] - fn stripped_basics_wine() { - assert_eq!("Hello, 32!\n", wine_test(stripped_basics)) - } } From 73e48c9b7cc3027642dc4d9800c6d318ed957524 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 16 Oct 2022 01:03:03 +0200 Subject: [PATCH 20/54] add better comments --- crates/linker/src/pe.rs | 59 +++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index e9e72ea81f..007b328389 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -57,6 +57,11 @@ struct PeMetadata { /// Virtual address of the .rdata section rdata_virtual_address: u32, + /// The offset into the file of the .reloc section + reloc_offset_in_file: usize, + + reloc_section_index: usize, + /// Constants from the host .exe header image_base: u64, file_alignment: u32, @@ -116,6 +121,14 @@ impl PeMetadata { let rdata_virtual_address = rdata_section.address() as u32; + let (reloc_section_index, reloc_section) = dynhost_obj + .sections() + .enumerate() + .find(|(_, s)| s.name() == Ok(".reloc")) + .unwrap(); + + let reloc_offset_in_file = reloc_section.file_range().unwrap().0 as usize; + let optional_header = dynhost_obj.nt_headers().optional_header; let optional_header_offset = dynhost_obj.dos_header().nt_headers_offset() as usize + std::mem::size_of::() @@ -163,6 +176,8 @@ impl PeMetadata { thunks_start_offset_in_file, thunks_start_offset_in_section, rdata_virtual_address, + reloc_offset_in_file, + reloc_section_index, } } } @@ -1117,6 +1132,9 @@ fn write_image_base_relocation( new_block_va: u32, relocations: &[u16], ) -> usize { + // first, collect the blocks of relocations (each relocation block covers a 4K page) + // we will be moving stuff around, and have to work from the back to the front. However, the + // relocations are encoded in such a way that we can only decode them from front to back. let mut next_block_start = reloc_section_start as u32; let mut blocks = vec![]; @@ -1136,10 +1154,13 @@ fn write_image_base_relocation( // extra space that we'll use for the new relocations let shift_amount = relocations.len() * 2; - // 8 in practice + // this is 8 in practice const HEADER_WIDTH: usize = std::mem::size_of::(); - // now, in reverse, shift sections that need to be shifted + let mut found_block = false; + + // now, starting from the back, shift sections that need to be shifted and add the + // new relocations to the right block while let Some((block_start, header)) = blocks.pop() { let header_va = header.virtual_address.get(LE); let header_size = header.size_of_block.get(LE); @@ -1172,9 +1193,17 @@ fn write_image_base_relocation( // sort by VA. Upper 4 bits store the relocation type entries.sort_unstable_by_key(|x| x & 0b0000_1111_1111_1111); + + found_block = true; } std::cmp::Ordering::Less => { - // done + if !found_block { + // we don't currently implement adding a new block if the block does not + // already exist. Adding that logic is not hard, but let's see if we can get + // away with not having it. + internal_error!("the .rdata section with our dummy .dll info is not covered by a relocation block"); + } + break; } } @@ -1183,32 +1212,28 @@ fn write_image_base_relocation( shift_amount } +/// the roc app functions are called from the host with an indirect call: the code will look +/// in a table to find the actual address of the app function. This table must be relocated, +/// because it contains absolute addresses to jump to. fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { - // find the location to write the section headers for our new sections - let section_header_start = md.dynamic_relocations.section_headers_offset_in_file as usize - + md.host_section_count * std::mem::size_of::(); - - let reloc_section_header_start = - section_header_start - std::mem::size_of::(); - - let reloc_image_section = - load_struct_inplace::(executable, reloc_section_header_start); - let relocations: Vec<_> = (0..md.dynamic_relocations.name_by_virtual_address.len()) .map(|i| (md.thunks_start_offset_in_section + 2 * i) as u16) .collect(); - let reloc_section_start = reloc_image_section.pointer_to_raw_data.get(LE) as usize; let added_reloc_bytes = write_image_base_relocation( executable, - reloc_section_start, + md.reloc_offset_in_file, md.rdata_virtual_address - md.image_base as u32, &relocations, ); + // the reloc section got bigger, and we need to update the header with the new size + let reloc_section_header_start = md.dynamic_relocations.section_headers_offset_in_file as usize + + md.reloc_section_index * std::mem::size_of::(); + let ptr = load_struct_inplace_mut::(executable, reloc_section_header_start); - ptr.virtual_size - .set(LE, ptr.virtual_size.get(LE) + added_reloc_bytes as u32); + let new_virtual_size = ptr.virtual_size.get(LE) + added_reloc_bytes as u32; + ptr.virtual_size.set(LE, new_virtual_size); } #[cfg(test)] From a063bfcd308204e1821a501af5e3ad272323e3d2 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 16 Oct 2022 13:26:48 +0200 Subject: [PATCH 21/54] changes after review --- crates/linker/src/pe.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 007b328389..9ba708ea41 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1151,12 +1151,14 @@ fn write_image_base_relocation( next_block_start += header.size_of_block.get(LE); } - // extra space that we'll use for the new relocations - let shift_amount = relocations.len() * 2; - // this is 8 in practice const HEADER_WIDTH: usize = std::mem::size_of::(); + const ENTRY_WIDTH: usize = std::mem::size_of::(); + + // extra space that we'll use for the new relocations + let shift_amount = relocations.len() * ENTRY_WIDTH; + let mut found_block = false; // now, starting from the back, shift sections that need to be shifted and add the @@ -1182,7 +1184,7 @@ fn write_image_base_relocation( let new_size = header.size_of_block.get(LE) + shift_amount as u32; header.size_of_block.set(LE, new_size); - let number_of_entries = (new_size as usize - HEADER_WIDTH) / 2; + let number_of_entries = (new_size as usize - HEADER_WIDTH) / ENTRY_WIDTH; let entries = load_structs_inplace_mut::( mmap, block_start + HEADER_WIDTH, @@ -1197,14 +1199,14 @@ fn write_image_base_relocation( found_block = true; } std::cmp::Ordering::Less => { - if !found_block { + if found_block { + break; + } else { // we don't currently implement adding a new block if the block does not // already exist. Adding that logic is not hard, but let's see if we can get // away with not having it. internal_error!("the .rdata section with our dummy .dll info is not covered by a relocation block"); } - - break; } } } From 7131432e7c76aeb4bb615030312bff92f24f265a Mon Sep 17 00:00:00 2001 From: Christopher Duncan Date: Sat, 15 Oct 2022 19:45:31 -0400 Subject: [PATCH 22/54] Dynamically generate the documentation title --- crates/docs/src/lib.rs | 17 ++++++++++++++--- crates/docs/src/static/index.html | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/crates/docs/src/lib.rs b/crates/docs/src/lib.rs index 84f67e933e..54f76e904a 100644 --- a/crates/docs/src/lib.rs +++ b/crates/docs/src/lib.rs @@ -9,7 +9,7 @@ use roc_code_markup::slow_pool::SlowPool; use roc_highlight::highlight_parser::{highlight_defs, highlight_expr}; use roc_load::docs::DocEntry::DocDef; use roc_load::docs::{DocEntry, TypeAnnotation}; -use roc_load::docs::{ModuleDocumentation, RecordField}; +use roc_load::docs::{Documentation, ModuleDocumentation, RecordField}; use roc_load::{ExecutionMode, LoadConfig, LoadedModule, LoadingProblem, Threading}; use roc_module::symbol::{IdentIdsByModule, Interns, ModuleId}; use roc_parse::ident::{parse_ident, Ident}; @@ -28,7 +28,7 @@ pub fn generate_docs_html(filenames: Vec) { let loaded_modules = load_modules_for_files(filenames); // TODO: get info from a package module; this is all hardcoded for now. - let mut package = roc_load::docs::Documentation { + let package = Documentation { name: "documentation".to_string(), version: "".to_string(), docs: "Package introduction or README.".to_string(), @@ -104,7 +104,7 @@ pub fn generate_docs_html(filenames: Vec) { ); // Write each package's module docs html file - for loaded_module in package.modules.iter_mut() { + for loaded_module in package.modules.iter() { for (module_id, module_docs) in loaded_module.documentation.iter() { if *module_id == loaded_module.module_id { let module_dir = build_dir.join(module_docs.name.replace('.', "/").as_str()); @@ -113,6 +113,10 @@ pub fn generate_docs_html(filenames: Vec) { .expect("TODO gracefully handle not being able to create the module dir"); let rendered_module = template_html + .replace( + "", + page_title(&package, module_docs).as_str(), + ) .replace( "", render_name_and_version(package.name.as_str(), package.version.as_str()) @@ -138,6 +142,13 @@ fn sidebar_link_url(module: &ModuleDocumentation) -> String { url } +fn page_title(package: &Documentation, module: &ModuleDocumentation) -> String { + let package_name = &package.name; + let module_name = &module.name; + let title = format!("{module_name} - {package_name}"); + title +} + // converts plain-text code to highlighted html pub fn syntax_highlight_expr(code_str: &str) -> DocsResult { let trimmed_code_str = code_str.trim_end().trim(); diff --git a/crates/docs/src/static/index.html b/crates/docs/src/static/index.html index c759358f38..d36961ff87 100644 --- a/crates/docs/src/static/index.html +++ b/crates/docs/src/static/index.html @@ -3,7 +3,7 @@ - + From 13cf67dc133b92fe0603ae31bcc59c15123d472b Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:28:09 +0200 Subject: [PATCH 23/54] update and simplify examples README Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- examples/README.md | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/examples/README.md b/examples/README.md index 0358683fdc..573a612d5e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,20 +1,9 @@ # Examples -Run examples as follows: +To run examples: -1. Navigate to this `examples` folder +```bash +roc run examples/hello-world/main.roc +``` - ```bash - cd examples - ``` - -2. Run a particular example, such as Hello World: - - ```bash - roc run hello-world/main.roc - ``` - -`crates/cli_testing_examples/benchmarks/` contains some larger examples. - -Some examples like `crates/cli_testing_examples/benchmarks/NQueens.roc` require input after running. -For NQueens, input 10 in the terminal and press enter. +[crates/cli_testing_examples/](https://github.com/roc-lang/roc/tree/main/crates/cli_testing_examples) has even more examples. From 599fe513c002df7d2766ddd2c141d2ee39100e31 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 17 Oct 2022 13:48:15 +0200 Subject: [PATCH 24/54] cron link check Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/markdown_link_check.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/markdown_link_check.yml b/.github/workflows/markdown_link_check.yml index 70568ae433..1b60da4f8c 100644 --- a/.github/workflows/markdown_link_check.yml +++ b/.github/workflows/markdown_link_check.yml @@ -1,4 +1,7 @@ -on: [pull_request] +on: + pull_request: + schedule: + - cron: '0 9 * * *' # 9=9am utc+0 name: Check Markdown links @@ -16,3 +19,12 @@ jobs: use-quiet-mode: 'yes' use-verbose-mode: 'yes' base-branch: 'main' + check-modified-files-only: 'yes' + if: ${{ github.event_name == 'pull_request' }} + - uses: gaurav-nelson/github-action-markdown-link-check@v1 + with: + use-quiet-mode: 'yes' + use-verbose-mode: 'yes' + base-branch: 'main' + check-modified-files-only: 'no' + if: ${{ github.event_name == 'schedule' }} From 3492561bf84fbb925d1d4964d8429b1012da6b98 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:03:41 +0200 Subject: [PATCH 25/54] add web.eecs.umich.edu link check exception Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- mlc_config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mlc_config.json b/mlc_config.json index af7ab0794b..857e137852 100644 --- a/mlc_config.json +++ b/mlc_config.json @@ -17,6 +17,9 @@ }, { "pattern": "https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/deforestation-short-cut.pdf" + }, + { + "pattern": "https://web.eecs.umich.edu" } ] } From 1c3a098898ebb39e4c035617b1d47d35e2223dfe Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:17:41 +0200 Subject: [PATCH 26/54] generalize microsoft research exception Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- mlc_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlc_config.json b/mlc_config.json index 857e137852..1fdb957353 100644 --- a/mlc_config.json +++ b/mlc_config.json @@ -16,7 +16,7 @@ "pattern": "https://opensource.org" }, { - "pattern": "https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/deforestation-short-cut.pdf" + "pattern": "https://www.microsoft.com/en-us/research" }, { "pattern": "https://web.eecs.umich.edu" From 3dad6aba7c8cb31a0ea018b1830284a13b3fc46a Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:22:20 +0200 Subject: [PATCH 27/54] moved platform-switching --- ci/package_release.sh | 2 +- crates/cli/tests/cli_run.rs | 10 +++++----- .../platform-switching/.gitignore | 0 .../platform-switching/README.md | 0 .../platform-switching/c-platform/host.c | 0 .../platform-switching/c-platform/main.roc | 0 .../platform-switching/main.roc | 0 .../platform-switching/rocLovesC.roc | 0 .../platform-switching/rocLovesRust.roc | 0 .../platform-switching/rocLovesSwift.roc | 0 .../platform-switching/rocLovesWebAssembly.roc | 0 .../platform-switching/rocLovesZig.roc | 0 .../platform-switching/rust-platform/Cargo.lock | 0 .../platform-switching/rust-platform/Cargo.toml | 2 +- .../platform-switching/rust-platform/build.rs | 0 .../platform-switching/rust-platform/host.c | 0 .../platform-switching/rust-platform/main.roc | 0 .../platform-switching/rust-platform/src/lib.rs | 0 .../platform-switching/rust-platform/src/main.rs | 0 .../platform-switching/swift-platform/host.h | 0 .../platform-switching/swift-platform/host.swift | 0 .../platform-switching/swift-platform/main.roc | 0 .../web-assembly-platform/README.md | 12 ++++++------ .../platform-switching/web-assembly-platform/host.js | 0 .../web-assembly-platform/host.test.js | 0 .../web-assembly-platform/host.zig | 0 .../web-assembly-platform/index.html | 0 .../web-assembly-platform/main.roc | 0 .../platform-switching/zig-platform/host.zig | 0 .../platform-switching/zig-platform/main.roc | 0 getting_started/linux_x86_64.md | 6 +++--- getting_started/macos_apple_silicon.md | 6 +++--- getting_started/macos_x86_64.md | 6 +++--- getting_started/other.md | 6 +++--- 34 files changed, 25 insertions(+), 25 deletions(-) rename {crates/cli_testing_examples => examples}/platform-switching/.gitignore (100%) rename {crates/cli_testing_examples => examples}/platform-switching/README.md (100%) rename {crates/cli_testing_examples => examples}/platform-switching/c-platform/host.c (100%) rename {crates/cli_testing_examples => examples}/platform-switching/c-platform/main.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/main.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rocLovesC.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rocLovesRust.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rocLovesSwift.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rocLovesWebAssembly.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rocLovesZig.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rust-platform/Cargo.lock (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rust-platform/Cargo.toml (85%) rename {crates/cli_testing_examples => examples}/platform-switching/rust-platform/build.rs (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rust-platform/host.c (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rust-platform/main.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rust-platform/src/lib.rs (100%) rename {crates/cli_testing_examples => examples}/platform-switching/rust-platform/src/main.rs (100%) rename {crates/cli_testing_examples => examples}/platform-switching/swift-platform/host.h (100%) rename {crates/cli_testing_examples => examples}/platform-switching/swift-platform/host.swift (100%) rename {crates/cli_testing_examples => examples}/platform-switching/swift-platform/main.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/web-assembly-platform/README.md (77%) rename {crates/cli_testing_examples => examples}/platform-switching/web-assembly-platform/host.js (100%) rename {crates/cli_testing_examples => examples}/platform-switching/web-assembly-platform/host.test.js (100%) rename {crates/cli_testing_examples => examples}/platform-switching/web-assembly-platform/host.zig (100%) rename {crates/cli_testing_examples => examples}/platform-switching/web-assembly-platform/index.html (100%) rename {crates/cli_testing_examples => examples}/platform-switching/web-assembly-platform/main.roc (100%) rename {crates/cli_testing_examples => examples}/platform-switching/zig-platform/host.zig (100%) rename {crates/cli_testing_examples => examples}/platform-switching/zig-platform/main.roc (100%) diff --git a/ci/package_release.sh b/ci/package_release.sh index 4c03da969e..646c39e9bd 100755 --- a/ci/package_release.sh +++ b/ci/package_release.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash cp target/release/roc ./roc # to be able to exclude "target" later in the tar command cp -r target/release/lib ./lib -tar -czvf $1 --exclude="target" --exclude="zig-cache" roc lib LICENSE LEGAL_DETAILS examples/helloWorld.roc examples/cli crates/roc_std +tar -czvf $1 --exclude="target" --exclude="zig-cache" roc lib LICENSE LEGAL_DETAILS examples/helloWorld.roc examples/platform-switching examples/cli crates/roc_std diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index b84808f41f..538dd0cb5a 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -401,7 +401,7 @@ mod cli_run { // uses C platform fn platform_switching_main() { test_roc_app_slim( - "crates/cli_testing_examples/platform-switching", + "examples/platform-switching", "main.roc", "rocLovesPlatforms", "Which platform am I running on now?\n", @@ -416,7 +416,7 @@ mod cli_run { #[test] fn platform_switching_rust() { test_roc_app_slim( - "crates/cli_testing_examples/platform-switching", + "examples/platform-switching", "rocLovesRust.roc", "rocLovesRust", "Roc <3 Rust!\n", @@ -427,7 +427,7 @@ mod cli_run { #[test] fn platform_switching_zig() { test_roc_app_slim( - "crates/cli_testing_examples/platform-switching", + "examples/platform-switching", "rocLovesZig.roc", "rocLovesZig", "Roc <3 Zig!\n", @@ -438,7 +438,7 @@ mod cli_run { #[test] fn platform_switching_wasm() { test_roc_app_slim( - "crates/cli_testing_examples/platform-switching", + "examples/platform-switching", "rocLovesWebAssembly.roc", "rocLovesWebAssembly", "Roc <3 Web Assembly!\n", @@ -449,7 +449,7 @@ mod cli_run { #[test] fn platform_switching_swift() { test_roc_app_slim( - "crates/cli_testing_examples/platform-switching", + "examples/platform-switching", "rocLovesSwift.roc", "rocLovesSwift", "Roc <3 Swift!\n", diff --git a/crates/cli_testing_examples/platform-switching/.gitignore b/examples/platform-switching/.gitignore similarity index 100% rename from crates/cli_testing_examples/platform-switching/.gitignore rename to examples/platform-switching/.gitignore diff --git a/crates/cli_testing_examples/platform-switching/README.md b/examples/platform-switching/README.md similarity index 100% rename from crates/cli_testing_examples/platform-switching/README.md rename to examples/platform-switching/README.md diff --git a/crates/cli_testing_examples/platform-switching/c-platform/host.c b/examples/platform-switching/c-platform/host.c similarity index 100% rename from crates/cli_testing_examples/platform-switching/c-platform/host.c rename to examples/platform-switching/c-platform/host.c diff --git a/crates/cli_testing_examples/platform-switching/c-platform/main.roc b/examples/platform-switching/c-platform/main.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/c-platform/main.roc rename to examples/platform-switching/c-platform/main.roc diff --git a/crates/cli_testing_examples/platform-switching/main.roc b/examples/platform-switching/main.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/main.roc rename to examples/platform-switching/main.roc diff --git a/crates/cli_testing_examples/platform-switching/rocLovesC.roc b/examples/platform-switching/rocLovesC.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/rocLovesC.roc rename to examples/platform-switching/rocLovesC.roc diff --git a/crates/cli_testing_examples/platform-switching/rocLovesRust.roc b/examples/platform-switching/rocLovesRust.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/rocLovesRust.roc rename to examples/platform-switching/rocLovesRust.roc diff --git a/crates/cli_testing_examples/platform-switching/rocLovesSwift.roc b/examples/platform-switching/rocLovesSwift.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/rocLovesSwift.roc rename to examples/platform-switching/rocLovesSwift.roc diff --git a/crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc b/examples/platform-switching/rocLovesWebAssembly.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc rename to examples/platform-switching/rocLovesWebAssembly.roc diff --git a/crates/cli_testing_examples/platform-switching/rocLovesZig.roc b/examples/platform-switching/rocLovesZig.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/rocLovesZig.roc rename to examples/platform-switching/rocLovesZig.roc diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.lock b/examples/platform-switching/rust-platform/Cargo.lock similarity index 100% rename from crates/cli_testing_examples/platform-switching/rust-platform/Cargo.lock rename to examples/platform-switching/rust-platform/Cargo.lock diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml b/examples/platform-switching/rust-platform/Cargo.toml similarity index 85% rename from crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml rename to examples/platform-switching/rust-platform/Cargo.toml index 29083ca183..8d10ce6eea 100644 --- a/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml +++ b/examples/platform-switching/rust-platform/Cargo.toml @@ -16,7 +16,7 @@ name = "host" path = "src/main.rs" [dependencies] -roc_std = { path = "../../../../crates/roc_std" } +roc_std = { path = "../../../crates/roc_std" } libc = "0.2" [workspace] diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/build.rs b/examples/platform-switching/rust-platform/build.rs similarity index 100% rename from crates/cli_testing_examples/platform-switching/rust-platform/build.rs rename to examples/platform-switching/rust-platform/build.rs diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/host.c b/examples/platform-switching/rust-platform/host.c similarity index 100% rename from crates/cli_testing_examples/platform-switching/rust-platform/host.c rename to examples/platform-switching/rust-platform/host.c diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/main.roc b/examples/platform-switching/rust-platform/main.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/rust-platform/main.roc rename to examples/platform-switching/rust-platform/main.roc diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs b/examples/platform-switching/rust-platform/src/lib.rs similarity index 100% rename from crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs rename to examples/platform-switching/rust-platform/src/lib.rs diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/src/main.rs b/examples/platform-switching/rust-platform/src/main.rs similarity index 100% rename from crates/cli_testing_examples/platform-switching/rust-platform/src/main.rs rename to examples/platform-switching/rust-platform/src/main.rs diff --git a/crates/cli_testing_examples/platform-switching/swift-platform/host.h b/examples/platform-switching/swift-platform/host.h similarity index 100% rename from crates/cli_testing_examples/platform-switching/swift-platform/host.h rename to examples/platform-switching/swift-platform/host.h diff --git a/crates/cli_testing_examples/platform-switching/swift-platform/host.swift b/examples/platform-switching/swift-platform/host.swift similarity index 100% rename from crates/cli_testing_examples/platform-switching/swift-platform/host.swift rename to examples/platform-switching/swift-platform/host.swift diff --git a/crates/cli_testing_examples/platform-switching/swift-platform/main.roc b/examples/platform-switching/swift-platform/main.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/swift-platform/main.roc rename to examples/platform-switching/swift-platform/main.roc diff --git a/crates/cli_testing_examples/platform-switching/web-assembly-platform/README.md b/examples/platform-switching/web-assembly-platform/README.md similarity index 77% rename from crates/cli_testing_examples/platform-switching/web-assembly-platform/README.md rename to examples/platform-switching/web-assembly-platform/README.md index a1dba338dc..76f5720e29 100644 --- a/crates/cli_testing_examples/platform-switching/web-assembly-platform/README.md +++ b/examples/platform-switching/web-assembly-platform/README.md @@ -3,12 +3,12 @@ To run this website, first compile either of these identical apps: ```bash -# Option A: Compile crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc -cargo run -- build --target=wasm32 crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc +# Option A: Compile examples/platform-switching/rocLovesWebAssembly.roc +cargo run -- build --target=wasm32 examples/platform-switching/rocLovesWebAssembly.roc -# Option B: Compile crates/cli_testing_examples/platform-switching/main.roc with `pf: "web-assembly-platform/main.roc"` and move the result -cargo run -- build --target=wasm32 crates/cli_testing_examples/platform-switching/main.roc -(cd crates/cli_testing_examples/platform-switching && mv rocLovesPlatforms.wasm web-assembly-platform/rocLovesWebAssembly.wasm) +# Option B: Compile examples/platform-switching/main.roc with `pf: "web-assembly-platform/main.roc"` and move the result +cargo run -- build --target=wasm32 examples/platform-switching/main.roc +(cd examples/platform-switching && mv rocLovesPlatforms.wasm web-assembly-platform/rocLovesWebAssembly.wasm) ``` Then `cd` into the website directory @@ -16,7 +16,7 @@ and run any web server that can handle WebAssembly. For example, with `http-server`: ```bash -cd crates/cli_testing_examples/platform-switching/web-assembly-platform +cd examples/platform-switching/web-assembly-platform npm install -g http-server http-server ``` diff --git a/crates/cli_testing_examples/platform-switching/web-assembly-platform/host.js b/examples/platform-switching/web-assembly-platform/host.js similarity index 100% rename from crates/cli_testing_examples/platform-switching/web-assembly-platform/host.js rename to examples/platform-switching/web-assembly-platform/host.js diff --git a/crates/cli_testing_examples/platform-switching/web-assembly-platform/host.test.js b/examples/platform-switching/web-assembly-platform/host.test.js similarity index 100% rename from crates/cli_testing_examples/platform-switching/web-assembly-platform/host.test.js rename to examples/platform-switching/web-assembly-platform/host.test.js diff --git a/crates/cli_testing_examples/platform-switching/web-assembly-platform/host.zig b/examples/platform-switching/web-assembly-platform/host.zig similarity index 100% rename from crates/cli_testing_examples/platform-switching/web-assembly-platform/host.zig rename to examples/platform-switching/web-assembly-platform/host.zig diff --git a/crates/cli_testing_examples/platform-switching/web-assembly-platform/index.html b/examples/platform-switching/web-assembly-platform/index.html similarity index 100% rename from crates/cli_testing_examples/platform-switching/web-assembly-platform/index.html rename to examples/platform-switching/web-assembly-platform/index.html diff --git a/crates/cli_testing_examples/platform-switching/web-assembly-platform/main.roc b/examples/platform-switching/web-assembly-platform/main.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/web-assembly-platform/main.roc rename to examples/platform-switching/web-assembly-platform/main.roc diff --git a/crates/cli_testing_examples/platform-switching/zig-platform/host.zig b/examples/platform-switching/zig-platform/host.zig similarity index 100% rename from crates/cli_testing_examples/platform-switching/zig-platform/host.zig rename to examples/platform-switching/zig-platform/host.zig diff --git a/crates/cli_testing_examples/platform-switching/zig-platform/main.roc b/examples/platform-switching/zig-platform/main.roc similarity index 100% rename from crates/cli_testing_examples/platform-switching/zig-platform/main.roc rename to examples/platform-switching/zig-platform/main.roc diff --git a/getting_started/linux_x86_64.md b/getting_started/linux_x86_64.md index 3b390d5b23..35d12d8740 100644 --- a/getting_started/linux_x86_64.md +++ b/getting_started/linux_x86_64.md @@ -45,9 +45,9 @@ you need to install one or more of these platform language compilers, too. ```sh # Note: If you installed Rust in this terminal session, you'll need to open a new one first! - ./roc crates/cli_testing_examples/platform-switching/rocLovesRust.roc + ./roc examples/platform-switching/rocLovesRust.roc - ./roc crates/cli_testing_examples/platform-switching/rocLovesZig.roc + ./roc examples/platform-switching/rocLovesZig.roc - ./roc crates/cli_testing_examples/platform-switching/rocLovesC.roc + ./roc examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/macos_apple_silicon.md b/getting_started/macos_apple_silicon.md index ed54cded01..2101c22da0 100644 --- a/getting_started/macos_apple_silicon.md +++ b/getting_started/macos_apple_silicon.md @@ -48,9 +48,9 @@ you need to install one or more of these platform language compilers, too. ```sh # Note: If you installed rust in this terminal session, you'll need to open a new one first! - ./roc crates/cli_testing_examples/platform-switching/rocLovesRust.roc + ./roc examples/platform-switching/rocLovesRust.roc - ./roc crates/cli_testing_examples/platform-switching/rocLovesZig.roc + ./roc examples/platform-switching/rocLovesZig.roc - ./roc crates/cli_testing_examples/platform-switching/rocLovesC.roc + ./roc examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/macos_x86_64.md b/getting_started/macos_x86_64.md index 23aecdb905..7826aca997 100644 --- a/getting_started/macos_x86_64.md +++ b/getting_started/macos_x86_64.md @@ -42,9 +42,9 @@ you need to install one or more of these platform language compilers, too. ```sh # Note: If you installed rust in this terminal session, you'll need to open a new one first! - ./roc crates/cli_testing_examples/platform-switching/rocLovesRust.roc + ./roc examples/platform-switching/rocLovesRust.roc - ./roc crates/cli_testing_examples/platform-switching/rocLovesZig.roc + ./roc examples/platform-switching/rocLovesZig.roc - ./roc crates/cli_testing_examples/platform-switching/rocLovesC.roc + ./roc examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/other.md b/getting_started/other.md index 13c5c79db7..70f01dd2e5 100644 --- a/getting_started/other.md +++ b/getting_started/other.md @@ -7,11 +7,11 @@ 1. Run examples: ```sh - cargo run crates/cli_testing_examples/platform-switching/rocLovesRust.roc + cargo run examples/platform-switching/rocLovesRust.roc # This requires installing the Zig compiler, too. - cargo run crates/cli_testing_examples/platform-switching/rocLovesZig.roc + cargo run examples/platform-switching/rocLovesZig.roc # This requires installing the `clang` C compiler, too. - cargo run crates/cli_testing_examples/platform-switching/rocLovesC.roc + cargo run examples/platform-switching/rocLovesC.roc ``` From 07224e908636f6733ba3c39da38dba54970f14bb Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Mon, 17 Oct 2022 20:06:56 +0530 Subject: [PATCH 28/54] builtin(list): add List.walkFrom, List.walkFromUntil Signed-off-by: Prajwal S N --- crates/compiler/builtins/roc/List.roc | 18 ++++++++ crates/compiler/module/src/symbol.rs | 2 + crates/compiler/test_gen/src/gen_list.rs | 54 +++++++++++++++++++----- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index 19d6fc3ed5..22177f1458 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -29,6 +29,8 @@ interface List map3, product, walkUntil, + walkFrom, + walkFromUntil, range, sortWith, drop, @@ -443,6 +445,22 @@ walkBackwardsUntil = \list, initial, func -> Continue new -> new Break new -> new +## Walks to the end of the list from a specified starting index +walkFrom : List elem, Nat, state, (state, elem -> state) -> state +walkFrom = \list, index, state, func -> + walkHelp : _, _ -> [Continue _, Break []] + walkHelp = \currentState, element -> Continue (func currentState element) + + when List.iterHelp list state walkHelp index (List.len list) is + Continue new -> new + +## A combination of [List.walkFrom] and [List.walkUntil] +walkFromUntil : List elem, Nat, state, (state, elem -> [Continue state, Break state]) -> state +walkFromUntil = \list, index, state, func -> + when List.iterHelp list state func index (List.len list) is + Continue new -> new + Break new -> new + sum : List (Num a) -> Num a sum = \list -> List.walk list 0 Num.add diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index dcb32d8357..337b7af9db 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -1398,6 +1398,8 @@ define_builtins! { 75 LIST_WALK_TRY: "walkTry" 76 LIST_WALK_BACKWARDS_UNTIL: "walkBackwardsUntil" 77 LIST_COUNT_IF: "countIf" + 78 LIST_WALK_FROM: "walkFrom" + 79 LIST_WALK_FROM_UNTIL: "walkFromUntil" } 7 RESULT: "Result" => { 0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index e6deae9f97..d487bb479b 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -956,6 +956,12 @@ fn list_walk_until_even_prefix_sum() { ); } +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn list_walk_from_sum() { + assert_evals_to!(r#"List.walkFrom [1, 2, 3] 1 0 Num.add"#, 5, i64); +} + #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_keep_if_empty_list_of_int() { @@ -3482,16 +3488,6 @@ fn list_let_generalization() { ); } -#[test] -#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -fn list_walk_backwards_until_sum() { - assert_evals_to!( - r#"List.walkBackwardsUntil [1, 2] 0 \a,b -> Continue (a + b)"#, - 3, - i64 - ); -} - #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_walk_backwards_implements_position() { @@ -3520,6 +3516,16 @@ fn list_walk_backwards_implements_position() { ); } +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn list_walk_backwards_until_sum() { + assert_evals_to!( + r#"List.walkBackwardsUntil [1, 2] 0 \a,b -> Continue (a + b)"#, + 3, + i64 + ); +} + #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] fn list_walk_backwards_until_even_prefix_sum() { @@ -3537,3 +3543,31 @@ fn list_walk_backwards_until_even_prefix_sum() { i64 ); } + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn list_walk_from_until_sum() { + assert_evals_to!( + r#"List.walkFromUntil [1, 2, 3, 4] 2 0 \a,b -> Continue (a + b)"#, + 7, + i64 + ); +} + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn list_walk_from_even_prefix_sum() { + assert_evals_to!( + r#" + helper = \a, b -> + if Num.isEven b then + Continue (a + b) + + else + Break a + + List.walkFromUntil [2, 4, 8, 9] 1 0 helper"#, + 4 + 8, + i64 + ); +} From 58c7a21569fcab9a33ba4c3ff79e80cb3ef18c89 Mon Sep 17 00:00:00 2001 From: Folkert Date: Mon, 17 Oct 2022 21:21:27 +0200 Subject: [PATCH 29/54] make relocations work when the .rdata section is bigger than a 4kb page --- crates/linker/src/pe.rs | 127 ++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 43 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 9ba708ea41..950a4e520e 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1137,6 +1137,7 @@ fn write_image_base_relocation( // relocations are encoded in such a way that we can only decode them from front to back. let mut next_block_start = reloc_section_start as u32; let mut blocks = vec![]; + let mut block_has_relocation = false; loop { let header = @@ -1146,6 +1147,10 @@ fn write_image_base_relocation( break; } + if new_block_va == header.virtual_address.get(LE) { + block_has_relocation = true; + } + blocks.push((next_block_start, *header)); next_block_start += header.size_of_block.get(LE); @@ -1159,73 +1164,105 @@ fn write_image_base_relocation( // extra space that we'll use for the new relocations let shift_amount = relocations.len() * ENTRY_WIDTH; - let mut found_block = false; + crate::dbg_hex!(new_block_va, relocations); - // now, starting from the back, shift sections that need to be shifted and add the - // new relocations to the right block - while let Some((block_start, header)) = blocks.pop() { - let header_va = header.virtual_address.get(LE); - let header_size = header.size_of_block.get(LE); + if block_has_relocation { + // now, starting from the back, shift sections that need to be shifted and add the + // new relocations to the right block + while let Some((block_start, header)) = blocks.pop() { + let header_va = header.virtual_address.get(LE); + let header_size = header.size_of_block.get(LE); - let block_start = block_start as usize; + let block_start = block_start as usize; - match header_va.cmp(&new_block_va) { - std::cmp::Ordering::Greater => { - // shift this block - mmap.copy_within( - block_start..block_start + header_size as usize, - block_start + shift_amount, - ); - } - std::cmp::Ordering::Equal => { - // extend this block - let header = load_struct_inplace_mut::(mmap, block_start); + match header_va.cmp(&new_block_va) { + std::cmp::Ordering::Greater => { + // shift this block + mmap.copy_within( + block_start..block_start + header_size as usize, + block_start + shift_amount, + ); + } + std::cmp::Ordering::Equal => { + // extend this block + let header = load_struct_inplace_mut::(mmap, block_start); - let new_size = header.size_of_block.get(LE) + shift_amount as u32; - header.size_of_block.set(LE, new_size); + let new_size = header.size_of_block.get(LE) + shift_amount as u32; + header.size_of_block.set(LE, new_size); - let number_of_entries = (new_size as usize - HEADER_WIDTH) / ENTRY_WIDTH; - let entries = load_structs_inplace_mut::( - mmap, - block_start + HEADER_WIDTH, - number_of_entries, - ); + let number_of_entries = (new_size as usize - HEADER_WIDTH) / ENTRY_WIDTH; + let entries = load_structs_inplace_mut::( + mmap, + block_start + HEADER_WIDTH, + number_of_entries, + ); - entries[number_of_entries - relocations.len()..].copy_from_slice(relocations); + entries[number_of_entries - relocations.len()..].copy_from_slice(relocations); - // sort by VA. Upper 4 bits store the relocation type - entries.sort_unstable_by_key(|x| x & 0b0000_1111_1111_1111); - - found_block = true; - } - std::cmp::Ordering::Less => { - if found_block { + // sort by VA. Upper 4 bits store the relocation type + entries.sort_unstable_by_key(|x| x & 0b0000_1111_1111_1111); + } + std::cmp::Ordering::Less => { + // done break; - } else { - // we don't currently implement adding a new block if the block does not - // already exist. Adding that logic is not hard, but let's see if we can get - // away with not having it. - internal_error!("the .rdata section with our dummy .dll info is not covered by a relocation block"); } } } - } - shift_amount + shift_amount + } else { + let header = + load_struct_inplace_mut::(mmap, next_block_start as usize); + + let size_of_block = HEADER_WIDTH + relocations.len() * ENTRY_WIDTH; + + header.virtual_address.set(LE, new_block_va); + header.size_of_block.set(LE, size_of_block as u32); + + let number_of_entries = relocations.len(); + let entries = load_structs_inplace_mut::( + mmap, + next_block_start as usize + HEADER_WIDTH, + number_of_entries, + ); + + entries[number_of_entries - relocations.len()..].copy_from_slice(relocations); + + // sort by VA. Upper 4 bits store the relocation type + entries.sort_unstable_by_key(|x| x & 0b0000_1111_1111_1111); + + crate::dbg_hex!((next_block_start as usize + size_of_block) - reloc_section_start); + + size_of_block + } } /// the roc app functions are called from the host with an indirect call: the code will look /// in a table to find the actual address of the app function. This table must be relocated, /// because it contains absolute addresses to jump to. fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { + let thunks_start_va = (md.rdata_virtual_address - md.image_base as u32) + + md.thunks_start_offset_in_section as u32; + + // relocations are defined per 4kb page + const BLOCK_SIZE: u32 = 4096; + + let thunks_offset_in_block = thunks_start_va % BLOCK_SIZE; + let thunks_relocation_block_va = thunks_start_va - thunks_offset_in_block; + let relocations: Vec<_> = (0..md.dynamic_relocations.name_by_virtual_address.len()) - .map(|i| (md.thunks_start_offset_in_section + 2 * i) as u16) + .map(|i| (thunks_offset_in_block as usize + 2 * i) as u16) .collect(); + crate::dbg_hex!( + thunks_relocation_block_va, + md.rdata_virtual_address - md.image_base as u32, + ); + let added_reloc_bytes = write_image_base_relocation( executable, md.reloc_offset_in_file, - md.rdata_virtual_address - md.image_base as u32, + thunks_relocation_block_va, &relocations, ); @@ -1236,6 +1273,10 @@ fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { let ptr = load_struct_inplace_mut::(executable, reloc_section_header_start); let new_virtual_size = ptr.virtual_size.get(LE) + added_reloc_bytes as u32; ptr.virtual_size.set(LE, new_virtual_size); + + // TODO this is rounded up, so there is extra space and it does not need to change in our current examples + // let new_size_of_raw_data = ptr.size_of_raw_data.get(LE) + added_reloc_bytes as u32; + // ptr.size_of_raw_data.set(LE, new_size_of_raw_data); } #[cfg(test)] From d93902cd1815e0277b9e10fbe056f02468665570 Mon Sep 17 00:00:00 2001 From: Folkert Date: Mon, 17 Oct 2022 21:22:13 +0200 Subject: [PATCH 30/54] fix compilation on windows for windows --- crates/compiler/build/src/link.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/compiler/build/src/link.rs b/crates/compiler/build/src/link.rs index 601a21bd56..61d1fc5e22 100644 --- a/crates/compiler/build/src/link.rs +++ b/crates/compiler/build/src/link.rs @@ -203,7 +203,7 @@ pub fn build_zig_host_native( "build-exe", "-fPIE", shared_lib_path.to_str().unwrap(), - &bitcode::get_builtins_host_obj_path(), + &bitcode::get_builtins_windows_obj_path(), ]); } else { command.args(&["build-obj", "-fPIC"]); @@ -221,6 +221,7 @@ pub fn build_zig_host_native( // include libc "--library", "c", + "-dynamic", // cross-compile? "-target", target, From 27aaaf9c2692bc2f575f64998f82db71ada9810d Mon Sep 17 00:00:00 2001 From: Folkert Date: Mon, 17 Oct 2022 21:25:30 +0200 Subject: [PATCH 31/54] remove debug logs --- crates/linker/src/pe.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 950a4e520e..846457ef44 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1164,8 +1164,6 @@ fn write_image_base_relocation( // extra space that we'll use for the new relocations let shift_amount = relocations.len() * ENTRY_WIDTH; - crate::dbg_hex!(new_block_va, relocations); - if block_has_relocation { // now, starting from the back, shift sections that need to be shifted and add the // new relocations to the right block @@ -1231,8 +1229,6 @@ fn write_image_base_relocation( // sort by VA. Upper 4 bits store the relocation type entries.sort_unstable_by_key(|x| x & 0b0000_1111_1111_1111); - crate::dbg_hex!((next_block_start as usize + size_of_block) - reloc_section_start); - size_of_block } } @@ -1254,11 +1250,6 @@ fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { .map(|i| (thunks_offset_in_block as usize + 2 * i) as u16) .collect(); - crate::dbg_hex!( - thunks_relocation_block_va, - md.rdata_virtual_address - md.image_base as u32, - ); - let added_reloc_bytes = write_image_base_relocation( executable, md.reloc_offset_in_file, From 8aee32830ae3e3b2d677c8e6cb519e83cfcf0693 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 17 Oct 2022 17:28:54 -0500 Subject: [PATCH 32/54] Add symbols' localized type variable to the AST --- crates/compiler/can/src/builtins.rs | 38 ++--- crates/compiler/can/src/copy.rs | 4 +- crates/compiler/can/src/effect_module.rs | 86 ++++++---- crates/compiler/can/src/expr.rs | 154 ++++++++++-------- crates/compiler/can/src/module.rs | 2 +- crates/compiler/constrain/src/expr.rs | 12 +- crates/compiler/derive/src/decoding.rs | 36 ++-- crates/compiler/derive/src/encoding.rs | 18 +- crates/compiler/derive/src/hash.rs | 22 ++- crates/compiler/mono/src/ir.rs | 23 +-- .../compiler/test_derive/src/pretty_print.rs | 2 +- 11 files changed, 230 insertions(+), 167 deletions(-) diff --git a/crates/compiler/can/src/builtins.rs b/crates/compiler/can/src/builtins.rs index 81b222553c..d847eb1fe0 100644 --- a/crates/compiler/can/src/builtins.rs +++ b/crates/compiler/can/src/builtins.rs @@ -247,7 +247,7 @@ fn lowlevel_1(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def { let body = RunLowLevel { op, - args: vec![(arg1_var, Var(Symbol::ARG_1))], + args: vec![(arg1_var, Var(Symbol::ARG_1, arg1_var))], ret_var, }; @@ -268,8 +268,8 @@ fn lowlevel_2(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def { let body = RunLowLevel { op, args: vec![ - (arg1_var, Var(Symbol::ARG_1)), - (arg2_var, Var(Symbol::ARG_2)), + (arg1_var, Var(Symbol::ARG_1, arg1_var)), + (arg2_var, Var(Symbol::ARG_2, arg2_var)), ], ret_var, }; @@ -292,9 +292,9 @@ fn lowlevel_3(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def { let body = RunLowLevel { op, args: vec![ - (arg1_var, Var(Symbol::ARG_1)), - (arg2_var, Var(Symbol::ARG_2)), - (arg3_var, Var(Symbol::ARG_3)), + (arg1_var, Var(Symbol::ARG_1, arg1_var)), + (arg2_var, Var(Symbol::ARG_2, arg2_var)), + (arg3_var, Var(Symbol::ARG_3, arg3_var)), ], ret_var, }; @@ -322,10 +322,10 @@ fn lowlevel_4(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def { let body = RunLowLevel { op, args: vec![ - (arg1_var, Var(Symbol::ARG_1)), - (arg2_var, Var(Symbol::ARG_2)), - (arg3_var, Var(Symbol::ARG_3)), - (arg4_var, Var(Symbol::ARG_4)), + (arg1_var, Var(Symbol::ARG_1, arg1_var)), + (arg2_var, Var(Symbol::ARG_2, arg2_var)), + (arg3_var, Var(Symbol::ARG_3, arg3_var)), + (arg4_var, Var(Symbol::ARG_4, arg4_var)), ], ret_var, }; @@ -355,11 +355,11 @@ fn lowlevel_5(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def { let body = RunLowLevel { op, args: vec![ - (arg1_var, Var(Symbol::ARG_1)), - (arg2_var, Var(Symbol::ARG_2)), - (arg3_var, Var(Symbol::ARG_3)), - (arg4_var, Var(Symbol::ARG_4)), - (arg5_var, Var(Symbol::ARG_5)), + (arg1_var, Var(Symbol::ARG_1, arg1_var)), + (arg2_var, Var(Symbol::ARG_2, arg2_var)), + (arg3_var, Var(Symbol::ARG_3, arg3_var)), + (arg4_var, Var(Symbol::ARG_4, arg4_var)), + (arg5_var, Var(Symbol::ARG_5, arg5_var)), ], ret_var, }; @@ -486,7 +486,7 @@ fn to_num_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel) ext_var: var_store.fresh(), field: "b".into(), field_var: var_store.fresh(), - loc_expr: Box::new(no_region(Var(Symbol::ARG_2))), + loc_expr: Box::new(no_region(Var(Symbol::ARG_2, var_store.fresh()))), }, ), // out of bounds! @@ -509,7 +509,7 @@ fn to_num_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel) ext_var: var_store.fresh(), field: "a".into(), field_var: num_var_2, - loc_expr: Box::new(no_region(Var(Symbol::ARG_2))), + loc_expr: Box::new(no_region(Var(Symbol::ARG_2, var_store.fresh()))), }, ], var_store, @@ -523,7 +523,7 @@ fn to_num_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel) loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_2)), loc_expr: no_region(RunLowLevel { op: lowlevel, - args: vec![(num_var_1, Var(Symbol::ARG_1))], + args: vec![(num_var_1, Var(Symbol::ARG_1, var_store.fresh()))], ret_var: record_var, }), expr_var: record_var, @@ -549,7 +549,7 @@ fn to_num_is_zero(symbol: Symbol, var_store: &mut VarStore) -> Def { let body = Expr::RunLowLevel { op: LowLevel::Eq, args: vec![ - (num_var, Var(Symbol::ARG_1)), + (num_var, Var(Symbol::ARG_1, num_var)), ( num_var, Num( diff --git a/crates/compiler/can/src/copy.rs b/crates/compiler/can/src/copy.rs index 787e3a1741..3f5ed43b4c 100644 --- a/crates/compiler/can/src/copy.rs +++ b/crates/compiler/can/src/copy.rs @@ -255,9 +255,9 @@ fn deep_copy_expr_help(env: &mut C, copied: &mut Vec, expr elem_var: sub!(*elem_var), loc_elems: loc_elems.iter().map(|le| le.map(|e| go_help!(e))).collect(), }, - Var(sym) => Var(*sym), + Var(sym, var) => Var(*sym, sub!(*var)), &AbilityMember(sym, specialization, specialization_var) => { - AbilityMember(sym, specialization, specialization_var) + AbilityMember(sym, specialization, sub!(specialization_var)) } When { loc_cond, diff --git a/crates/compiler/can/src/effect_module.rs b/crates/compiler/can/src/effect_module.rs index b67fb03a21..dcc21b70fd 100644 --- a/crates/compiler/can/src/effect_module.rs +++ b/crates/compiler/can/src/effect_module.rs @@ -124,14 +124,15 @@ fn build_effect_always( Loc::at_zero(empty_record_pattern(var_store)), )]; - let body = Expr::Var(value_symbol); + let value_var = var_store.fresh(); + let body = Expr::Var(value_symbol, value_var); Expr::Closure(ClosureData { function_type: var_store.fresh(), closure_type: var_store.fresh(), return_type: var_store.fresh(), name: inner_closure_symbol, - captured_symbols: vec![(value_symbol, var_store.fresh())], + captured_symbols: vec![(value_symbol, value_var)], recursive: Recursive::NotRecursive, arguments, loc_body: Box::new(Loc::at_zero(body)), @@ -231,20 +232,22 @@ fn build_effect_map( .introduce("effect_map_thunk".into(), Region::zero()) .unwrap() }; + let thunk_var = var_store.fresh(); let mapper_symbol = { scope .introduce("effect_map_mapper".into(), Region::zero()) .unwrap() }; + let mapper_var = var_store.fresh(); let map_symbol = { scope.introduce("map".into(), Region::zero()).unwrap() }; // `thunk {}` let force_thunk_call = { let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(thunk_symbol)), + thunk_var, + Loc::at_zero(Expr::Var(thunk_symbol, thunk_var)), var_store.fresh(), var_store.fresh(), ); @@ -256,8 +259,8 @@ fn build_effect_map( // `toEffect (thunk {})` let mapper_call = { let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(mapper_symbol)), + mapper_var, + Loc::at_zero(Expr::Var(mapper_symbol, mapper_var)), var_store.fresh(), var_store.fresh(), ); @@ -411,9 +414,9 @@ fn build_effect_map( (map_symbol, def) } -fn force_thunk(expr: Expr, var_store: &mut VarStore) -> Expr { +fn force_thunk(expr: Expr, thunk_var: Variable, var_store: &mut VarStore) -> Expr { let boxed = ( - var_store.fresh(), + thunk_var, Loc::at_zero(expr), var_store.fresh(), var_store.fresh(), @@ -441,13 +444,19 @@ fn build_effect_after( let outer_closure_symbol = new_symbol!(scope, "effect_after_inner"); // `effect {}` - let force_effect_call = force_thunk(Expr::Var(effect_symbol), var_store); + let force_effect_var = var_store.fresh(); + let force_effect_call = force_thunk( + Expr::Var(effect_symbol, force_effect_var), + force_effect_var, + var_store, + ); // `toEffect (effect {})` + let to_effect_var = var_store.fresh(); let to_effect_call = { let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(to_effect_symbol)), + to_effect_var, + Loc::at_zero(Expr::Var(to_effect_symbol, to_effect_var)), var_store.fresh(), var_store.fresh(), ); @@ -459,7 +468,12 @@ fn build_effect_after( // let @Effect thunk = toEffect (effect {}) in thunk {} let let_effect_thunk = { // `thunk {}` - let force_inner_thunk_call = force_thunk(Expr::Var(thunk_symbol), var_store); + let force_inner_thunk_var = var_store.fresh(); + let force_inner_thunk_call = force_thunk( + Expr::Var(thunk_symbol, force_inner_thunk_var), + force_inner_thunk_var, + var_store, + ); let (specialized_def_type, type_arguments, lambda_set_variables) = build_fresh_opaque_variables(var_store); @@ -702,9 +716,10 @@ fn force_effect( let ret_var = var_store.fresh(); let force_thunk_call = { + let thunk_var = var_store.fresh(); let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(thunk_symbol)), + thunk_var, + Loc::at_zero(Expr::Var(thunk_symbol, thunk_var)), var_store.fresh(), ret_var, ); @@ -884,6 +899,7 @@ fn build_effect_forever_inner_body( effect: Symbol, var_store: &mut VarStore, ) -> Expr { + let thunk1_var = var_store.fresh(); let thunk1_symbol = { scope.introduce("thunk1".into(), Region::zero()).unwrap() }; let thunk2_symbol = { scope.introduce("thunk2".into(), Region::zero()).unwrap() }; @@ -909,7 +925,7 @@ fn build_effect_forever_inner_body( Def { loc_pattern: Loc::at_zero(pattern), - loc_expr: Loc::at_zero(Expr::Var(effect)), + loc_expr: Loc::at_zero(Expr::Var(effect, var_store.fresh())), expr_var: var_store.fresh(), pattern_vars, annotation: None, @@ -920,8 +936,8 @@ fn build_effect_forever_inner_body( let force_thunk_call = { let ret_var = var_store.fresh(); let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(thunk1_symbol)), + thunk1_var, + Loc::at_zero(Expr::Var(thunk1_symbol, thunk1_var)), var_store.fresh(), ret_var, ); @@ -945,12 +961,13 @@ fn build_effect_forever_inner_body( let forever_effect = { let boxed = ( var_store.fresh(), - Loc::at_zero(Expr::Var(forever_symbol)), + Loc::at_zero(Expr::Var(forever_symbol, var_store.fresh())), var_store.fresh(), var_store.fresh(), ); - let arguments = vec![(var_store.fresh(), Loc::at_zero(Expr::Var(effect)))]; + let effect_var = var_store.fresh(); + let arguments = vec![(effect_var, Loc::at_zero(Expr::Var(effect, effect_var)))]; Expr::Call(Box::new(boxed), arguments, CalledVia::Space) }; @@ -1198,14 +1215,16 @@ fn build_effect_loop_inner_body( // `step state` let rhs = { + let step_var = var_store.fresh(); let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(step_symbol)), + step_var, + Loc::at_zero(Expr::Var(step_symbol, step_var)), var_store.fresh(), var_store.fresh(), ); - let arguments = vec![(var_store.fresh(), Loc::at_zero(Expr::Var(state_symbol)))]; + let state_var = var_store.fresh(); + let arguments = vec![(state_var, Loc::at_zero(Expr::Var(state_symbol, state_var)))]; Expr::Call(Box::new(boxed), arguments, CalledVia::Space) }; @@ -1220,10 +1239,11 @@ fn build_effect_loop_inner_body( // thunk1 {} let force_thunk_call = { + let thunk1_var = var_store.fresh(); let ret_var = var_store.fresh(); let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(thunk1_symbol)), + thunk1_var, + Loc::at_zero(Expr::Var(thunk1_symbol, thunk1_var)), var_store.fresh(), ret_var, ); @@ -1236,16 +1256,22 @@ fn build_effect_loop_inner_body( // recursive call `loop newState step` let loop_new_state_step = { + let loop_var = var_store.fresh(); let boxed = ( - var_store.fresh(), - Loc::at_zero(Expr::Var(loop_symbol)), + loop_var, + Loc::at_zero(Expr::Var(loop_symbol, loop_var)), var_store.fresh(), var_store.fresh(), ); + let new_state_var = var_store.fresh(); + let step_var = var_store.fresh(); let arguments = vec![ - (var_store.fresh(), Loc::at_zero(Expr::Var(new_state_symbol))), - (var_store.fresh(), Loc::at_zero(Expr::Var(step_symbol))), + ( + new_state_var, + Loc::at_zero(Expr::Var(new_state_symbol, new_state_var)), + ), + (step_var, Loc::at_zero(Expr::Var(step_symbol, step_var))), ]; Expr::Call(Box::new(boxed), arguments, CalledVia::Space) }; @@ -1283,7 +1309,7 @@ fn build_effect_loop_inner_body( crate::expr::WhenBranch { patterns: vec![done_pattern], - value: Loc::at_zero(Expr::Var(done_symbol)), + value: Loc::at_zero(Expr::Var(done_symbol, var_store.fresh())), guard: None, redundant: RedundantMark::new(var_store), } @@ -1351,7 +1377,7 @@ pub fn build_host_exposed_def( )); captured_symbols.push((arg_symbol, arg_var)); - linked_symbol_arguments.push((arg_var, Expr::Var(arg_symbol))); + linked_symbol_arguments.push((arg_var, Expr::Var(arg_symbol, arg_var))); } let foreign_symbol_name = format!("roc_fx_{}", ident); diff --git a/crates/compiler/can/src/expr.rs b/crates/compiler/can/src/expr.rs index 1483e190db..c2befe9a1b 100644 --- a/crates/compiler/can/src/expr.rs +++ b/crates/compiler/can/src/expr.rs @@ -100,7 +100,7 @@ pub enum Expr { }, // Lookups - Var(Symbol), + Var(Symbol, Variable), AbilityMember( /// Actual member name Symbol, @@ -256,7 +256,7 @@ impl Expr { Self::Str(..) => Category::Str, Self::SingleQuote(..) => Category::Character, Self::List { .. } => Category::List, - &Self::Var(sym) => Category::Lookup(sym), + &Self::Var(sym, _) => Category::Lookup(sym), &Self::AbilityMember(sym, _, _) => Category::Lookup(sym), Self::When { .. } => Category::When, Self::If { .. } => Category::If, @@ -372,7 +372,7 @@ impl AccessorData { record_var, ext_var, field_var, - loc_expr: Box::new(Loc::at_zero(Expr::Var(record_symbol))), + loc_expr: Box::new(Loc::at_zero(Expr::Var(record_symbol, record_var))), field, }; @@ -440,7 +440,10 @@ impl OpaqueWrapFunctionData { let body = Expr::OpaqueRef { opaque_var, name: opaque_name, - argument: Box::new((argument_var, Loc::at_zero(Expr::Var(argument_symbol)))), + argument: Box::new(( + argument_var, + Loc::at_zero(Expr::Var(argument_symbol, argument_var)), + )), specialized_def_type: Box::new(specialized_def_type), type_arguments, lambda_set_variables, @@ -592,7 +595,7 @@ pub fn canonicalize_expr<'a>( } => { let (can_update, update_out) = canonicalize_expr(env, var_store, scope, loc_update.region, &loc_update.value); - if let Var(symbol) = &can_update.value { + if let Var(symbol, _) = &can_update.value { match canonicalize_fields(env, var_store, scope, region, fields.items) { Ok((can_fields, mut output)) => { output.references.union_mut(&update_out.references); @@ -765,7 +768,7 @@ pub fn canonicalize_expr<'a>( output.tail_call = None; let expr = match fn_expr.value { - Var(symbol) => { + Var(symbol, _) => { output.references.insert_call(symbol); // we're tail-calling a symbol by name, check if it's the tail-callable symbol @@ -994,7 +997,7 @@ pub fn canonicalize_expr<'a>( // Get all the lookups that were referenced in the condition, // so we can print their values later. - let lookups_in_cond = get_lookup_symbols(&loc_condition.value, var_store); + let lookups_in_cond = get_lookup_symbols(&loc_condition.value); let (loc_continuation, output2) = canonicalize_expr( env, @@ -1600,7 +1603,7 @@ fn canonicalize_var_lookup( var_store.fresh(), ) } else { - Var(symbol) + Var(symbol, var_store.fresh()) } } Err(problem) => { @@ -1623,7 +1626,7 @@ fn canonicalize_var_lookup( var_store.fresh(), ) } else { - Var(symbol) + Var(symbol, var_store.fresh()) } } Err(problem) => { @@ -1657,7 +1660,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) -> | other @ EmptyRecord | other @ Accessor { .. } | other @ Update { .. } - | other @ Var(_) + | other @ Var(..) | other @ AbilityMember(..) | other @ RunLowLevel { .. } | other @ TypedHole { .. } @@ -1960,67 +1963,71 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) -> let (fn_var, loc_expr, closure_var, expr_var) = *boxed_tuple; match loc_expr.value { - Var(symbol) if symbol.is_builtin() => match builtin_defs_map(symbol, var_store) { - Some(Def { - loc_expr: - Loc { - value: - Closure(ClosureData { - recursive, - arguments: params, - loc_body: boxed_body, - .. - }), - .. - }, - .. - }) => { - debug_assert_eq!(recursive, Recursive::NotRecursive); + Var(symbol, _) if symbol.is_builtin() => { + match builtin_defs_map(symbol, var_store) { + Some(Def { + loc_expr: + Loc { + value: + Closure(ClosureData { + recursive, + arguments: params, + loc_body: boxed_body, + .. + }), + .. + }, + .. + }) => { + debug_assert_eq!(recursive, Recursive::NotRecursive); - // Since this is a canonicalized Expr, we should have - // already detected any arity mismatches and replaced this - // with a RuntimeError if there was a mismatch. - debug_assert_eq!(params.len(), args.len()); + // Since this is a canonicalized Expr, we should have + // already detected any arity mismatches and replaced this + // with a RuntimeError if there was a mismatch. + debug_assert_eq!(params.len(), args.len()); - // Start with the function's body as the answer. - let mut loc_answer = *boxed_body; + // Start with the function's body as the answer. + let mut loc_answer = *boxed_body; - // Wrap the body in one LetNonRec for each argument, - // such that at the end we have all the arguments in - // scope with the values the caller provided. - for ((_param_var, _exhaustive_mark, loc_pattern), (expr_var, loc_expr)) in - params.iter().cloned().zip(args.into_iter()).rev() - { - // TODO get the correct vars into here. - // Not sure if param_var should be involved. - let pattern_vars = SendMap::default(); + // Wrap the body in one LetNonRec for each argument, + // such that at the end we have all the arguments in + // scope with the values the caller provided. + for ( + (_param_var, _exhaustive_mark, loc_pattern), + (expr_var, loc_expr), + ) in params.iter().cloned().zip(args.into_iter()).rev() + { + // TODO get the correct vars into here. + // Not sure if param_var should be involved. + let pattern_vars = SendMap::default(); - let def = Def { - loc_pattern, - loc_expr, - expr_var, - pattern_vars, - annotation: None, - }; + let def = Def { + loc_pattern, + loc_expr, + expr_var, + pattern_vars, + annotation: None, + }; - loc_answer = Loc { - region: Region::zero(), - value: LetNonRec(Box::new(def), Box::new(loc_answer)), - }; + loc_answer = Loc { + region: Region::zero(), + value: LetNonRec(Box::new(def), Box::new(loc_answer)), + }; + } + + loc_answer.value + } + Some(_) => { + unreachable!("Tried to inline a non-function"); + } + None => { + unreachable!( + "Tried to inline a builtin that wasn't registered: {:?}", + symbol + ); } - - loc_answer.value } - Some(_) => { - unreachable!("Tried to inline a non-function"); - } - None => { - unreachable!( - "Tried to inline a builtin that wasn't registered: {:?}", - symbol - ); - } - }, + } _ => { // For now, we only inline calls to builtins. Leave this alone! Call( @@ -2172,7 +2179,10 @@ fn desugar_str_segments(var_store: &mut VarStore, segments: Vec) -> Interpolation(loc_interpolated_expr) => loc_interpolated_expr, }; - let fn_expr = Loc::at(Region::zero(), Expr::Var(Symbol::STR_CONCAT)); + let fn_expr = Loc::at( + Region::zero(), + Expr::Var(Symbol::STR_CONCAT, var_store.fresh()), + ); let expr = Expr::Call( Box::new(( var_store.fresh(), @@ -2615,16 +2625,22 @@ pub struct DestructureDef { pub pattern_vars: VecMap, } -fn get_lookup_symbols(expr: &Expr, var_store: &mut VarStore) -> Vec<(Symbol, Variable)> { +fn get_lookup_symbols(expr: &Expr) -> Vec<(Symbol, Variable)> { let mut stack: Vec<&Expr> = vec![expr]; let mut symbols = Vec::new(); while let Some(expr) = stack.pop() { match expr { - Expr::Var(symbol) | Expr::Update { symbol, .. } | Expr::AbilityMember(symbol, _, _) => { + Expr::Var(symbol, var) + | Expr::Update { + symbol, + record_var: var, + .. + } + | Expr::AbilityMember(symbol, _, var) => { // Don't introduce duplicates, or make unused variables if !symbols.iter().any(|(sym, _)| sym == symbol) { - symbols.push((*symbol, var_store.fresh())); + symbols.push((*symbol, *var)); } } Expr::List { loc_elems, .. } => { @@ -2665,7 +2681,7 @@ fn get_lookup_symbols(expr: &Expr, var_store: &mut VarStore) -> Vec<(Symbol, Var stack.reserve(1 + args.len()); match &boxed_expr.1.value { - Expr::Var(_) => { + Expr::Var(_, _) => { // do nothing } function_expr => { diff --git a/crates/compiler/can/src/module.rs b/crates/compiler/can/src/module.rs index 6435fc65f2..07c5caa6df 100644 --- a/crates/compiler/can/src/module.rs +++ b/crates/compiler/can/src/module.rs @@ -1040,7 +1040,7 @@ fn fix_values_captured_in_closure_expr( | Float(..) | Str(_) | SingleQuote(..) - | Var(_) + | Var(..) | AbilityMember(..) | EmptyRecord | TypedHole { .. } diff --git a/crates/compiler/constrain/src/expr.rs b/crates/compiler/constrain/src/expr.rs index 12990f3d88..8f44b78562 100644 --- a/crates/compiler/constrain/src/expr.rs +++ b/crates/compiler/constrain/src/expr.rs @@ -351,7 +351,7 @@ pub fn constrain_expr( let (fn_var, loc_fn, closure_var, ret_var) = &**boxed; // The expression that evaluates to the function being called, e.g. `foo` in // (foo) bar baz - let opt_symbol = if let Var(symbol) | AbilityMember(symbol, _, _) = loc_fn.value { + let opt_symbol = if let Var(symbol, _) | AbilityMember(symbol, _, _) = loc_fn.value { Some(symbol) } else { None @@ -425,9 +425,13 @@ pub fn constrain_expr( let and_constraint = constraints.and_constraint(and_cons); constraints.exists(vars, and_constraint) } - Var(symbol) => { - // make lookup constraint to lookup this symbol's type in the environment - constraints.lookup(*symbol, expected, region) + Var(symbol, variable) => { + // Save the expectation in the variable, then lookup the symbol's type in the environment + let store_expected = + constraints.store(expected.get_type_ref().clone(), *variable, file!(), line!()); + let lookup_constr = + constraints.lookup(*symbol, expected.replace(Type::Variable(*variable)), region); + constraints.and_constraint([store_expected, lookup_constr]) } &AbilityMember(symbol, specialization_id, specialization_var) => { // Save the expectation in the `specialization_var` so we know what to specialize, then diff --git a/crates/compiler/derive/src/decoding.rs b/crates/compiler/derive/src/decoding.rs index 0671d7fdf3..8bd2b643d4 100644 --- a/crates/compiler/derive/src/decoding.rs +++ b/crates/compiler/derive/src/decoding.rs @@ -357,7 +357,7 @@ fn decoder_record_step_field( name: "Ok".into(), arguments: vec![( field_var, - Loc::at_zero(Expr::Var(ok_val_symbol)), + Loc::at_zero(Expr::Var(ok_val_symbol, field_var)), )], })), }, @@ -417,7 +417,7 @@ fn decoder_record_step_field( name: "Err".into(), arguments: vec![( decode_err_var, - Loc::at_zero(Expr::Var(err_val_symbol)), + Loc::at_zero(Expr::Var(err_val_symbol, decode_err_var)), )], }), guard: None, @@ -433,7 +433,7 @@ fn decoder_record_step_field( record_var: rec_var, ext_var: env.new_ext_var(ExtensionKind::Record), field_var: rec_dot_result, - loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol))), + loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol, rec_var))), field: "result".into(), })), cond_var: rec_dot_result, @@ -462,7 +462,7 @@ fn decoder_record_step_field( record_var: rec_var, ext_var: env.new_ext_var(ExtensionKind::Record), field_var: Variable::LIST_U8, - loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol))), + loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol, rec_var))), field: "rest".into(), })), }, @@ -499,12 +499,15 @@ fn decoder_record_step_field( let condition_expr = Expr::Call( Box::new(( this_decode_with_var, - Loc::at_zero(Expr::Var(Symbol::DECODE_DECODE_WITH)), + Loc::at_zero(Expr::Var(Symbol::DECODE_DECODE_WITH, this_decode_with_var)), lambda_set_var, rec_var, )), vec![ - (Variable::LIST_U8, Loc::at_zero(Expr::Var(bytes_arg_symbol))), + ( + Variable::LIST_U8, + Loc::at_zero(Expr::Var(bytes_arg_symbol, Variable::LIST_U8)), + ), ( decoder_var, Loc::at_zero(Expr::AbilityMember( @@ -513,7 +516,10 @@ fn decoder_record_step_field( decoder_var, )), ), - (fmt_arg_var, Loc::at_zero(Expr::Var(fmt_arg_symbol))), + ( + fmt_arg_var, + Loc::at_zero(Expr::Var(fmt_arg_symbol, fmt_arg_var)), + ), ], CalledVia::Space, ); @@ -600,7 +606,7 @@ fn decoder_record_step_field( Expr::Call( Box::new(( this_decode_custom_var, - Loc::at_zero(Expr::Var(Symbol::DECODE_CUSTOM)), + Loc::at_zero(Expr::Var(Symbol::DECODE_CUSTOM, this_decode_custom_var)), decode_custom_closure_var, decode_custom_ret_var, )), @@ -676,7 +682,7 @@ fn decoder_record_step_field( // when field is let body = Expr::When { - loc_cond: Box::new(Loc::at_zero(Expr::Var(field_arg_symbol))), + loc_cond: Box::new(Loc::at_zero(Expr::Var(field_arg_symbol, Variable::STR))), cond_var: Variable::STR, expr_var: keep_or_skip_var, region: Region::zero(), @@ -764,7 +770,7 @@ fn decoder_record_finalizer( pattern_symbols.push(symbol); - let field_expr = Expr::Var(symbol); + let field_expr = Expr::Var(symbol, field_var); let field = Field { var: field_var, region: Region::zero(), @@ -827,7 +833,7 @@ fn decoder_record_finalizer( record_var: state_record_var, ext_var: env.new_ext_var(ExtensionKind::Record), field_var: result_field_var, - loc_expr: Box::new(Loc::at_zero(Expr::Var(state_arg_symbol))), + loc_expr: Box::new(Loc::at_zero(Expr::Var(state_arg_symbol, state_record_var))), field: field_name.clone(), }; @@ -1126,7 +1132,7 @@ fn wrap_in_decode_custom_decode_with( // ~ bytes, Decoder (List elem) fmt, fmt -> DecoderResult (List val) env.unify(decode_with_type, this_decode_with_fn_var); - let decode_with_var = Var(Symbol::DECODE_DECODE_WITH); + let decode_with_var = Var(Symbol::DECODE_DECODE_WITH, this_decode_with_fn_var); let decode_with_fn = Box::new(( this_decode_with_fn_var, Loc::at_zero(decode_with_var), @@ -1137,9 +1143,9 @@ fn wrap_in_decode_custom_decode_with( decode_with_fn, vec![ // bytes inner_decoder fmt - (bytes_var, Loc::at_zero(Var(bytes_sym))), + (bytes_var, Loc::at_zero(Var(bytes_sym, bytes_var))), (inner_decoder_var, Loc::at_zero(inner_decoder)), - (fmt_var, Loc::at_zero(Var(fmt_sym))), + (fmt_var, Loc::at_zero(Var(fmt_sym, fmt_var))), ], CalledVia::Space, ); @@ -1231,7 +1237,7 @@ fn wrap_in_decode_custom_decode_with( // ~ (List U8, fmt -> DecodeResult (List elem)) -> Decoder (List elem) fmt env.unify(decode_custom_type, this_decode_custom_fn_var); - let decode_custom_var = Var(Symbol::DECODE_CUSTOM); + let decode_custom_var = Var(Symbol::DECODE_CUSTOM, this_decode_custom_fn_var); let decode_custom_fn = Box::new(( this_decode_custom_fn_var, Loc::at_zero(decode_custom_var), diff --git a/crates/compiler/derive/src/encoding.rs b/crates/compiler/derive/src/encoding.rs index 006b99e925..affd4d6acd 100644 --- a/crates/compiler/derive/src/encoding.rs +++ b/crates/compiler/derive/src/encoding.rs @@ -134,7 +134,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) { // toEncoder elem let to_encoder_call = Call( to_encoder_fn, - vec![(elem_var, Loc::at_zero(Var(elem_sym)))], + vec![(elem_var, Loc::at_zero(Var(elem_sym, elem_var)))], CalledVia::Space, ); @@ -217,7 +217,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) { let encode_list_call = Call( encode_list_fn, vec![ - (list_var, Loc::at_zero(Var(lst_sym))), + (list_var, Loc::at_zero(Var(lst_sym, list_var))), (to_elem_encoder_fn_var, Loc::at_zero(to_elem_encoder)), ], CalledVia::Space, @@ -314,7 +314,7 @@ fn to_encoder_record( record_var, ext_var: env.subs.fresh_unnamed_flex_var(), field_var, - loc_expr: Box::new(Loc::at_zero(Var(rcd_sym))), + loc_expr: Box::new(Loc::at_zero(Var(rcd_sym, record_var))), field: field_name, }; @@ -572,7 +572,7 @@ fn to_encoder_tag_union( // toEncoder rcd.a let to_encoder_call = Call( to_encoder_fn, - vec![(sym_var, Loc::at_zero(Var(sym)))], + vec![(sym_var, Loc::at_zero(Var(sym, sym_var)))], CalledVia::Space, ); @@ -662,7 +662,7 @@ fn to_encoder_tag_union( // A v1 v2 -> Encode.tag "A" [ Encode.toEncoder v1, Encode.toEncoder v2 ] // B v3 -> Encode.tag "B" [ Encode.toEncoder v3 ] let when_branches = When { - loc_cond: Box::new(Loc::at_zero(Var(tag_sym))), + loc_cond: Box::new(Loc::at_zero(Var(tag_sym, tag_union_var))), cond_var: tag_union_var, expr_var: whole_tag_encoders_var, region: Region::zero(), @@ -778,7 +778,7 @@ fn wrap_in_encode_custom( // Encode.appendWith : List U8, encoder_var, fmt -[appendWith]-> List U8 | fmt has EncoderFormatting let append_with_fn = Box::new(( this_append_with_fn_var, - Loc::at_zero(Var(Symbol::ENCODE_APPEND_WITH)), + Loc::at_zero(Var(Symbol::ENCODE_APPEND_WITH, this_append_with_fn_var)), this_append_with_clos_var, Variable::LIST_U8, )); @@ -788,11 +788,11 @@ fn wrap_in_encode_custom( append_with_fn, vec![ // (bytes_var, bytes) - (bytes_var, Loc::at_zero(Var(bytes_sym))), + (bytes_var, Loc::at_zero(Var(bytes_sym, bytes_var))), // (encoder_var, encoder) (encoder_var, Loc::at_zero(encoder)), // (fmt, fmt_var) - (fmt_var, Loc::at_zero(Var(fmt_sym))), + (fmt_var, Loc::at_zero(Var(fmt_sym, fmt_var))), ], CalledVia::Space, ); @@ -869,7 +869,7 @@ fn wrap_in_encode_custom( // Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt has EncoderFormatting let custom_fn = Box::new(( this_custom_fn_var, - Loc::at_zero(Var(Symbol::ENCODE_CUSTOM)), + Loc::at_zero(Var(Symbol::ENCODE_CUSTOM, this_custom_fn_var)), this_custom_clos_var, // -[clos]-> this_custom_encoder_var, // t' ~ Encoder fmt )); diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index d06084243a..678da5ee6c 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -90,7 +90,7 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (V let hasher_var = synth_var(env.subs, Content::FlexAbleVar(None, Symbol::HASH_HASHER)); let (body_var, body) = record_fields.iter_all().fold( - (hasher_var, Expr::Var(hasher_sym)), + (hasher_var, Expr::Var(hasher_sym, hasher_var)), |total_hasher, (field_name, field_var, _)| { let field_name = env.subs[field_name].clone(); let field_var = env.subs[field_var]; @@ -99,7 +99,7 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (V record_var, field_var, ext_var: env.subs.fresh_unnamed_flex_var(), - loc_expr: Box::new(Loc::at_zero(Expr::Var(rcd_sym))), + loc_expr: Box::new(Loc::at_zero(Expr::Var(rcd_sym, record_var))), field: field_name, }; @@ -215,7 +215,7 @@ fn hash_tag_union( let (discr_hasher_var, disc_hasher_expr) = call_hash_ability_member( env, hash_discr_member, - (hasher_var, Expr::Var(hasher_sym)), + (hasher_var, Expr::Var(hasher_sym, hasher_var)), ( discr_num_var, Expr::Int( @@ -232,7 +232,11 @@ fn hash_tag_union( let (body_var, body_expr) = (payload_vars.into_iter()).zip(payload_syms).fold( (discr_hasher_var, disc_hasher_expr), |total_hasher, (payload_var, payload_sym)| { - call_hash_hash(env, total_hasher, (payload_var, Expr::Var(payload_sym))) + call_hash_hash( + env, + total_hasher, + (payload_var, Expr::Var(payload_sym, payload_var)), + ) }, ); @@ -251,7 +255,7 @@ fn hash_tag_union( // ... let when_var = whole_hasher_var; let when_expr = Expr::When { - loc_cond: Box::new(Loc::at_zero(Expr::Var(union_sym))), + loc_cond: Box::new(Loc::at_zero(Expr::Var(union_sym, union_var))), cond_var: union_var, expr_var: when_var, region: Region::zero(), @@ -338,9 +342,13 @@ fn hash_newtype_tag_union( // Fold up `Hash.hash (... (Hash.hash discrHasher x11) ...) x1n` let (body_var, body_expr) = (payload_vars.into_iter()).zip(payload_syms).fold( - (hasher_var, Expr::Var(hasher_sym)), + (hasher_var, Expr::Var(hasher_sym, hasher_var)), |total_hasher, (payload_var, payload_sym)| { - call_hash_hash(env, total_hasher, (payload_var, Expr::Var(payload_sym))) + call_hash_hash( + env, + total_hasher, + (payload_var, Expr::Var(payload_sym, payload_var)), + ) }, ); diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index f2180db47b..6b27df1bbb 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -2376,7 +2376,7 @@ fn from_can_let<'a>( lower_rest!(variable, cont.value) } - Var(original) | AbilityMember(original, _, _) => { + Var(original, _) | AbilityMember(original, _, _) => { // a variable is aliased, e.g. // // foo = bar @@ -2605,7 +2605,7 @@ fn from_can_let<'a>( } match def.loc_expr.value { - roc_can::expr::Expr::Var(outer_symbol) if !procs.is_module_thunk(outer_symbol) => { + roc_can::expr::Expr::Var(outer_symbol, _) if !procs.is_module_thunk(outer_symbol) => { store_pattern(env, procs, layout_cache, &mono_pattern, outer_symbol, stmt) } _ => { @@ -2747,7 +2747,7 @@ fn pattern_to_when<'a>( cond_var: pattern_var, expr_var: body_var, region: Region::zero(), - loc_cond: Box::new(Loc::at_zero(Var(symbol))), + loc_cond: Box::new(Loc::at_zero(Var(symbol, pattern_var))), branches: vec![WhenBranch { patterns: vec![WhenBranchPattern { pattern, @@ -4074,11 +4074,14 @@ pub fn with_hole<'a>( hole, ) } - Var(mut symbol) => { + Var(mut symbol, _) => { // If this symbol is a raw value, find the real name we gave to its specialized usage. - if let ReuseSymbol::Value(_symbol) = - can_reuse_symbol(env, procs, &roc_can::expr::Expr::Var(symbol), variable) - { + if let ReuseSymbol::Value(_symbol) = can_reuse_symbol( + env, + procs, + &roc_can::expr::Expr::Var(symbol, variable), + variable, + ) { let real_symbol = procs .symbol_specializations @@ -5046,7 +5049,7 @@ pub fn with_hole<'a>( }; match loc_expr.value { - roc_can::expr::Expr::Var(proc_name) if is_known(proc_name) => { + roc_can::expr::Expr::Var(proc_name, _) if is_known(proc_name) => { // a call by a known name call_by_name( env, @@ -6010,7 +6013,7 @@ fn tag_union_to_function<'a>( let loc_pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(arg_symbol)); - let loc_expr = Loc::at_zero(roc_can::expr::Expr::Var(arg_symbol)); + let loc_expr = Loc::at_zero(roc_can::expr::Expr::Var(arg_symbol, arg_var)); loc_pattern_args.push((arg_var, AnnotatedMark::known_exhaustive(), loc_pattern)); loc_expr_args.push((arg_var, loc_expr)); @@ -7513,7 +7516,7 @@ fn can_reuse_symbol<'a>( AbilityMember(member, specialization_id, _) => { late_resolve_ability_specialization(env, *member, *specialization_id, expr_var) } - Var(symbol) => *symbol, + Var(symbol, _) => *symbol, _ => return NotASymbol, }; diff --git a/crates/compiler/test_derive/src/pretty_print.rs b/crates/compiler/test_derive/src/pretty_print.rs index ec3ce4f70e..0eaa70ce72 100644 --- a/crates/compiler/test_derive/src/pretty_print.rs +++ b/crates/compiler/test_derive/src/pretty_print.rs @@ -87,7 +87,7 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a, .append("]") .group(), ), - Var(sym) | AbilityMember(sym, _, _) => f.text(format!( + Var(sym, _) | AbilityMember(sym, _, _) => f.text(format!( "{}.{}", sym.module_string(c.interns), sym.as_str(c.interns), From d26e9c81e09ea36677c619b910b4ab06542919e5 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 17 Oct 2022 17:56:48 -0500 Subject: [PATCH 33/54] Resolve ability specializations looked up in expects --- Cargo.lock | 1 + crates/compiler/can/src/expr.rs | 53 +++++++++++++++++------ crates/compiler/can/src/module.rs | 6 +-- crates/compiler/constrain/src/expr.rs | 18 ++++++-- crates/compiler/load_internal/src/file.rs | 6 +-- crates/compiler/mono/src/ir.rs | 42 +++++++++++++++--- crates/repl_expect/Cargo.toml | 1 + crates/repl_expect/src/run.rs | 12 ++++- 8 files changed, 108 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f590cdd0bb..41058b0864 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3959,6 +3959,7 @@ dependencies = [ "pretty_assertions", "roc_build", "roc_builtins", + "roc_can", "roc_collections", "roc_gen_llvm", "roc_intern", diff --git a/crates/compiler/can/src/expr.rs b/crates/compiler/can/src/expr.rs index c2befe9a1b..4e7e9d13d4 100644 --- a/crates/compiler/can/src/expr.rs +++ b/crates/compiler/can/src/expr.rs @@ -230,14 +230,14 @@ pub enum Expr { Expect { loc_condition: Box>, loc_continuation: Box>, - lookups_in_cond: Vec<(Symbol, Variable)>, + lookups_in_cond: Vec, }, // not parsed, but is generated when lowering toplevel effectful expects ExpectFx { loc_condition: Box>, loc_continuation: Box>, - lookups_in_cond: Vec<(Symbol, Variable)>, + lookups_in_cond: Vec, }, /// Rendered as empty box in editor @@ -247,6 +247,13 @@ pub enum Expr { RuntimeError(RuntimeError), } +#[derive(Clone, Copy, Debug)] +pub struct ExpectLookup { + pub symbol: Symbol, + pub var: Variable, + pub ability_info: Option, +} + impl Expr { pub fn category(&self) -> Category { match self { @@ -2541,7 +2548,7 @@ impl Declarations { }) } - pub fn expects(&self) -> VecMap> { + pub fn expects(&self) -> VecMap> { let mut collector = ExpectCollector { expects: VecMap::default(), }; @@ -2625,9 +2632,9 @@ pub struct DestructureDef { pub pattern_vars: VecMap, } -fn get_lookup_symbols(expr: &Expr) -> Vec<(Symbol, Variable)> { +fn get_lookup_symbols(expr: &Expr) -> Vec { let mut stack: Vec<&Expr> = vec![expr]; - let mut symbols = Vec::new(); + let mut lookups: Vec = Vec::new(); while let Some(expr) = stack.pop() { match expr { @@ -2636,11 +2643,23 @@ fn get_lookup_symbols(expr: &Expr) -> Vec<(Symbol, Variable)> { symbol, record_var: var, .. - } - | Expr::AbilityMember(symbol, _, var) => { + } => { // Don't introduce duplicates, or make unused variables - if !symbols.iter().any(|(sym, _)| sym == symbol) { - symbols.push((*symbol, *var)); + if !lookups.iter().any(|l| l.symbol == *symbol) { + lookups.push(ExpectLookup { + symbol: *symbol, + var: *var, + ability_info: None, + }); + } + } + Expr::AbilityMember(symbol, spec_id, var) => { + if !lookups.iter().any(|l| l.symbol == *symbol) { + lookups.push(ExpectLookup { + symbol: *symbol, + var: *var, + ability_info: *spec_id, + }); } } Expr::List { loc_elems, .. } => { @@ -2737,7 +2756,7 @@ fn get_lookup_symbols(expr: &Expr) -> Vec<(Symbol, Variable)> { } } - symbols + lookups } /// Here we transform @@ -2784,14 +2803,22 @@ fn toplevel_expect_to_inline_expect_help(mut loc_expr: Loc, has_effects: b loop { match loc_expr.value { Expr::LetNonRec(boxed_def, remainder) => { - lookups_in_cond.extend(boxed_def.pattern_vars.iter().map(|(a, b)| (*a, *b))); + lookups_in_cond.extend(boxed_def.pattern_vars.iter().map(|(a, b)| ExpectLookup { + symbol: *a, + var: *b, + ability_info: None, + })); stack.push(StoredDef::NonRecursive(loc_expr.region, boxed_def)); loc_expr = *remainder; } Expr::LetRec(defs, remainder, mark) => { for def in &defs { - lookups_in_cond.extend(def.pattern_vars.iter().map(|(a, b)| (*a, *b))); + lookups_in_cond.extend(def.pattern_vars.iter().map(|(a, b)| ExpectLookup { + symbol: *a, + var: *b, + ability_info: None, + })); } stack.push(StoredDef::Recursive(loc_expr.region, defs, mark)); @@ -2834,7 +2861,7 @@ fn toplevel_expect_to_inline_expect_help(mut loc_expr: Loc, has_effects: b } struct ExpectCollector { - expects: VecMap>, + expects: VecMap>, } impl crate::traverse::Visitor for ExpectCollector { diff --git a/crates/compiler/can/src/module.rs b/crates/compiler/can/src/module.rs index 07c5caa6df..5a6381dd23 100644 --- a/crates/compiler/can/src/module.rs +++ b/crates/compiler/can/src/module.rs @@ -3,7 +3,7 @@ use crate::annotation::canonicalize_annotation; use crate::def::{canonicalize_defs, Def}; use crate::effect_module::HostedGeneratedFunctions; use crate::env::Env; -use crate::expr::{ClosureData, Declarations, Expr, Output, PendingDerives}; +use crate::expr::{ClosureData, Declarations, ExpectLookup, Expr, Output, PendingDerives}; use crate::pattern::{BindingsFromPattern, Pattern}; use crate::scope::Scope; use bumpalo::Bump; @@ -130,7 +130,7 @@ pub struct Module { pub aliases: MutMap, pub rigid_variables: RigidVariables, pub abilities_store: PendingAbilitiesStore, - pub loc_expects: VecMap>, + pub loc_expects: VecMap>, } #[derive(Debug, Default)] @@ -152,7 +152,7 @@ pub struct ModuleOutput { pub symbols_from_requires: Vec<(Loc, Loc)>, pub pending_derives: PendingDerives, pub scope: Scope, - pub loc_expects: VecMap>, + pub loc_expects: VecMap>, } fn validate_generate_with<'a>( diff --git a/crates/compiler/constrain/src/expr.rs b/crates/compiler/constrain/src/expr.rs index 8f44b78562..c1e8b1738a 100644 --- a/crates/compiler/constrain/src/expr.rs +++ b/crates/compiler/constrain/src/expr.rs @@ -13,8 +13,8 @@ use roc_can::expected::Expected::{self, *}; use roc_can::expected::PExpected; use roc_can::expr::Expr::{self, *}; use roc_can::expr::{ - AccessorData, AnnotatedMark, ClosureData, DeclarationTag, Declarations, DestructureDef, Field, - FunctionDef, OpaqueWrapFunctionData, WhenBranch, + AccessorData, AnnotatedMark, ClosureData, DeclarationTag, Declarations, DestructureDef, + ExpectLookup, Field, FunctionDef, OpaqueWrapFunctionData, WhenBranch, }; use roc_can::pattern::Pattern; use roc_can::traverse::symbols_introduced_from_pattern; @@ -519,7 +519,12 @@ pub fn constrain_expr( let mut vars = Vec::with_capacity(lookups_in_cond.len()); - for (symbol, var) in lookups_in_cond.iter() { + for ExpectLookup { + symbol, + var, + ability_info: _, + } in lookups_in_cond.iter() + { vars.push(*var); all_constraints.push(constraints.lookup( @@ -566,7 +571,12 @@ pub fn constrain_expr( let mut vars = Vec::with_capacity(lookups_in_cond.len()); - for (symbol, var) in lookups_in_cond.iter() { + for ExpectLookup { + symbol, + var, + ability_info: _, + } in lookups_in_cond.iter() + { vars.push(*var); all_constraints.push(constraints.lookup( diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index d35f496f70..54a14ee3f1 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -7,8 +7,8 @@ use parking_lot::Mutex; use roc_builtins::roc::module_source; use roc_can::abilities::{AbilitiesStore, PendingAbilitiesStore, ResolvedImpl}; use roc_can::constraint::{Constraint as ConstraintSoa, Constraints}; -use roc_can::expr::Declarations; use roc_can::expr::PendingDerives; +use roc_can::expr::{Declarations, ExpectLookup}; use roc_can::module::{ canonicalize_module_defs, ExposedByModule, ExposedForModule, ExposedModuleTypes, Module, ResolvedImplementations, TypeState, @@ -719,7 +719,7 @@ pub enum EntryPoint<'a> { pub struct Expectations { pub subs: roc_types::subs::Subs, pub path: PathBuf, - pub expectations: VecMap>, + pub expectations: VecMap>, pub ident_ids: IdentIds, } @@ -763,7 +763,7 @@ struct ParsedModule<'a> { header_for: HeaderFor<'a>, } -type LocExpects = VecMap>; +type LocExpects = VecMap>; /// A message sent out _from_ a worker thread, /// representing a result of work done, or a request for further work diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 6b27df1bbb..4f2dbfb2bf 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -9,7 +9,7 @@ use bumpalo::collections::{CollectIn, Vec}; use bumpalo::Bump; use roc_builtins::bitcode::{FloatWidth, IntWidth}; use roc_can::abilities::SpecializationId; -use roc_can::expr::{AnnotatedMark, ClosureData, IntValue}; +use roc_can::expr::{AnnotatedMark, ClosureData, ExpectLookup, IntValue}; use roc_can::module::ExposedByModule; use roc_collections::all::{default_hasher, BumpMap, BumpMapDefault, MutMap}; use roc_collections::VecMap; @@ -6350,11 +6350,25 @@ pub fn from_can<'a>( let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache); let cond_symbol = env.unique_symbol(); - let lookups = Vec::from_iter_in(lookups_in_cond.iter().map(|t| t.0), env.arena); - + let mut lookups = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); let mut layouts = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); - for (_, var) in lookups_in_cond { + for ExpectLookup { + symbol, + var, + ability_info, + } in lookups_in_cond + { + let symbol = match ability_info { + Some(specialization_id) => late_resolve_ability_specialization( + env, + symbol, + Some(specialization_id), + var, + ), + None => symbol, + }; + lookups.push(symbol); let res_layout = layout_cache.from_var(env.arena, var, env.subs); let layout = return_on_layout_error!(env, res_layout, "Expect"); layouts.push(layout); @@ -6389,11 +6403,25 @@ pub fn from_can<'a>( let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache); let cond_symbol = env.unique_symbol(); - let lookups = Vec::from_iter_in(lookups_in_cond.iter().map(|t| t.0), env.arena); - + let mut lookups = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); let mut layouts = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); - for (_, var) in lookups_in_cond { + for ExpectLookup { + symbol, + var, + ability_info, + } in lookups_in_cond + { + let symbol = match ability_info { + Some(specialization_id) => late_resolve_ability_specialization( + env, + symbol, + Some(specialization_id), + var, + ), + None => symbol, + }; + lookups.push(symbol); let res_layout = layout_cache.from_var(env.arena, var, env.subs); let layout = return_on_layout_error!(env, res_layout, "Expect"); layouts.push(layout); diff --git a/crates/repl_expect/Cargo.toml b/crates/repl_expect/Cargo.toml index e819722eab..935c44d3c0 100644 --- a/crates/repl_expect/Cargo.toml +++ b/crates/repl_expect/Cargo.toml @@ -10,6 +10,7 @@ bumpalo = {version = "3.11.0", features = ["collections"]} target-lexicon = "0.12.2" roc_builtins = {path = "../compiler/builtins"} +roc_can = {path = "../compiler/can"} roc_collections = {path = "../compiler/collections"} roc_intern = {path = "../compiler/intern"} roc_load = {path = "../compiler/load"} diff --git a/crates/repl_expect/src/run.rs b/crates/repl_expect/src/run.rs index c60869d478..44a54f8dcf 100644 --- a/crates/repl_expect/src/run.rs +++ b/crates/repl_expect/src/run.rs @@ -4,6 +4,7 @@ use bumpalo::collections::Vec as BumpVec; use bumpalo::Bump; use inkwell::context::Context; use roc_build::link::llvm_module_to_dylib; +use roc_can::expr::ExpectLookup; use roc_collections::{MutSet, VecMap}; use roc_gen_llvm::{ llvm::{build::LlvmBackendMode, externs::add_default_roc_externs}, @@ -389,7 +390,16 @@ fn render_expect_failure<'a>( }; let subs = arena.alloc(&mut data.subs); - let (symbols, variables): (Vec<_>, Vec<_>) = current.iter().map(|(a, b)| (*a, *b)).unzip(); + let (symbols, variables): (Vec<_>, Vec<_>) = current + .iter() + .map( + |ExpectLookup { + symbol, + var, + ability_info: _, + }| (*symbol, *var), + ) + .unzip(); let (offset, expressions) = crate::get_values( target_info, From 1225cb54fc7e4fba3be488576beeb4a21acdaa0d Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Mon, 17 Oct 2022 21:45:46 -0700 Subject: [PATCH 34/54] Fix memory leak in List.concat --- crates/compiler/builtins/bitcode/src/list.zig | 65 ++++++++++++------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/crates/compiler/builtins/bitcode/src/list.zig b/crates/compiler/builtins/bitcode/src/list.zig index df89083b43..fc7da7194d 100644 --- a/crates/compiler/builtins/bitcode/src/list.zig +++ b/crates/compiler/builtins/bitcode/src/list.zig @@ -745,37 +745,54 @@ pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_widt } else if (list_a.isUnique()) { const total_length: usize = list_a.len() + list_b.len(); - if (list_a.bytes) |source| { - const new_source = if (list_a.capacity >= total_length) - source - else - utils.unsafeReallocate( - source, - alignment, - list_a.len(), - total_length, - element_width, - ); + const resized_list_a = list_a.reallocate(alignment, total_length, element_width); - if (list_b.bytes) |source_b| { - @memcpy(new_source + list_a.len() * element_width, source_b, list_b.len() * element_width); - } + // These must exist, otherwise, the lists would have been empty. + const source_a = resized_list_a.bytes orelse unreachable; + const source_b = list_b.bytes orelse unreachable; + @memcpy(source_a + list_a.len() * element_width, source_b, list_b.len() * element_width); - return RocList{ .bytes = new_source, .length = total_length, .capacity = total_length }; - } + // decrement list b. + utils.decref(source_b, list_b.len(), alignment); + + return resized_list_a; + } else if (list_b.isUnique()) { + const total_length: usize = list_a.len() + list_b.len(); + + const resized_list_b = list_b.reallocate(alignment, total_length, element_width); + + // These must exist, otherwise, the lists would have been empty. + const source_a = list_a.bytes orelse unreachable; + const source_b = resized_list_b.bytes orelse unreachable; + + // This is a bit special, we need to first copy the elements of list_b to the end, + // then copy the elements of list_a to the beginning. + // This first call must use mem.copy because the slices might overlap. + const byte_count_a = list_a.len() * element_width; + const byte_count_b = list_b.len() * element_width; + mem.copy(u8, source_b[byte_count_a..byte_count_a + byte_count_b], source_b[0..byte_count_b]); + @memcpy(source_b, source_a, byte_count_a); + + // decrement list a. + utils.decref(source_a, list_a.len(), alignment); + + return resized_list_b; } const total_length: usize = list_a.len() + list_b.len(); const output = RocList.allocate(alignment, total_length, element_width); - if (output.bytes) |target| { - if (list_a.bytes) |source| { - @memcpy(target, source, list_a.len() * element_width); - } - if (list_b.bytes) |source| { - @memcpy(target + list_a.len() * element_width, source, list_b.len() * element_width); - } - } + // These must exist, otherwise, the lists would have been empty. + const target = output.bytes orelse unreachable; + const source_a = list_a.bytes orelse unreachable; + const source_b = list_b.bytes orelse unreachable; + + @memcpy(target, source_a, list_a.len() * element_width); + @memcpy(target + list_a.len() * element_width, source_b, list_b.len() * element_width); + + // decrement list a and b. + utils.decref(source_a, list_a.len(), alignment); + utils.decref(source_b, list_b.len(), alignment); return output; } From 9f09bebdca665c70e61665df47aa5c24ed05d605 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Mon, 17 Oct 2022 21:50:25 -0700 Subject: [PATCH 35/54] run --- crates/compiler/builtins/bitcode/src/list.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/builtins/bitcode/src/list.zig b/crates/compiler/builtins/bitcode/src/list.zig index fc7da7194d..155830dc17 100644 --- a/crates/compiler/builtins/bitcode/src/list.zig +++ b/crates/compiler/builtins/bitcode/src/list.zig @@ -770,7 +770,7 @@ pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_widt // This first call must use mem.copy because the slices might overlap. const byte_count_a = list_a.len() * element_width; const byte_count_b = list_b.len() * element_width; - mem.copy(u8, source_b[byte_count_a..byte_count_a + byte_count_b], source_b[0..byte_count_b]); + mem.copy(u8, source_b[byte_count_a .. byte_count_a + byte_count_b], source_b[0..byte_count_b]); @memcpy(source_b, source_a, byte_count_a); // decrement list a. From 14b3fbce7a8673488b6b254b26ef67c2c8d4661f Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Tue, 18 Oct 2022 20:21:15 +1100 Subject: [PATCH 36/54] added Comments section for tutorial.md --- TUTORIAL.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/TUTORIAL.md b/TUTORIAL.md index f9b3207325..eb3e2f0aca 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -1405,6 +1405,27 @@ imports [pf.Stdout, pf.Program, AdditionalModule, AnotherModule] provides main to pf ``` +## Comments + +Comments in `.roc` files begin with `##` and will be included in generated documentation with ```roc docs```. Comments require a single space after the `##`, and can include code blocks by adding five spaces after `##`. + +```coffee +## This is a comment for documentation, and includes a code block. +## +## x = 2 +## expect x == 2 +``` + +Like [Python](https://www.python.org), [Ruby](https://www.ruby-lang.org), [Perl](https://www.perl.org), and [Elixir](https://elixir-lang.org/), Roc also supports inline comments. They begin with `#` instead of `--`, and can also used to add information that won't be included in documentation. + +```coffee +# This is a line comment that won't appear in documentation. +myFunction : U8 -> U8 +myFunction = \bit -> bit % 2 # this is an inline comment +``` + +Roc does not have multiline comment syntax. + ## Tasks Tasks are technically not part of the Roc language, but they're very common in From a54fa05fe21499c4514d35d43b33602da8661766 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 18 Oct 2022 11:31:58 +0200 Subject: [PATCH 37/54] shorten text a bit Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- TUTORIAL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index eb3e2f0aca..7c6690a573 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -1407,7 +1407,7 @@ provides main to pf ## Comments -Comments in `.roc` files begin with `##` and will be included in generated documentation with ```roc docs```. Comments require a single space after the `##`, and can include code blocks by adding five spaces after `##`. +Comments that begin with `##` will be included in generated documentation (```roc docs```). They require a single space after the `##`, and can include code blocks by adding five spaces after `##`. ```coffee ## This is a comment for documentation, and includes a code block. @@ -1416,7 +1416,7 @@ Comments in `.roc` files begin with `##` and will be included in generated docum ## expect x == 2 ``` -Like [Python](https://www.python.org), [Ruby](https://www.ruby-lang.org), [Perl](https://www.perl.org), and [Elixir](https://elixir-lang.org/), Roc also supports inline comments. They begin with `#` instead of `--`, and can also used to add information that won't be included in documentation. +Like [Python](https://www.python.org), [Ruby](https://www.ruby-lang.org), [Perl](https://www.perl.org), and [Elixir](https://elixir-lang.org/), Roc also supports inline comments. They begin with `#`, and can be used to add information that won't be included in documentation. ```coffee # This is a line comment that won't appear in documentation. From 706d22a942172e9b79024d6579ced2315a104c44 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 18 Oct 2022 08:22:23 -0500 Subject: [PATCH 38/54] Fix encode/decode deriving --- crates/compiler/derive/src/encoding.rs | 2 +- crates/compiler/derive/src/hash.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/derive/src/encoding.rs b/crates/compiler/derive/src/encoding.rs index affd4d6acd..7c113e5862 100644 --- a/crates/compiler/derive/src/encoding.rs +++ b/crates/compiler/derive/src/encoding.rs @@ -314,7 +314,7 @@ fn to_encoder_record( record_var, ext_var: env.subs.fresh_unnamed_flex_var(), field_var, - loc_expr: Box::new(Loc::at_zero(Var(rcd_sym, record_var))), + loc_expr: Box::new(Loc::at_zero(Var(rcd_sym, env.subs.fresh_unnamed_flex_var()))), field: field_name, }; diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index 678da5ee6c..9edb04ce88 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -99,7 +99,7 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (V record_var, field_var, ext_var: env.subs.fresh_unnamed_flex_var(), - loc_expr: Box::new(Loc::at_zero(Expr::Var(rcd_sym, record_var))), + loc_expr: Box::new(Loc::at_zero(Expr::Var(rcd_sym, env.subs.fresh_unnamed_flex_var()))), field: field_name, }; From 5e10dddd6fcd8c6a8f5d12b8c09dd9d6c859c6c9 Mon Sep 17 00:00:00 2001 From: Folkert Date: Tue, 18 Oct 2022 18:43:40 +0200 Subject: [PATCH 39/54] support multiple app relocations per symbol --- crates/linker/src/pe.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 846457ef44..9b612d408b 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -327,7 +327,12 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b let slice = &roc_app_bytes[section.file_range.start..section.file_range.end]; executable[offset..][..slice.len()].copy_from_slice(slice); - for (name, app_relocation) in section.relocations.iter() { + let it = section + .relocations + .iter() + .flat_map(|(name, rs)| rs.iter().map(move |r| (name, r))); + + for (name, app_relocation) in it { let AppRelocation { offset_in_section, relocation, @@ -873,7 +878,7 @@ struct Section { /// File range of the section (in the app object) file_range: Range, kind: SectionKind, - relocations: MutMap, + relocations: MutMap>, app_section_index: SectionIndex, } @@ -949,7 +954,7 @@ impl AppSections { _ => continue, }; - let mut relocations = MutMap::default(); + let mut relocations: MutMap> = MutMap::default(); for (offset_in_section, relocation) in section.relocations() { match relocation.target() { @@ -961,14 +966,14 @@ impl AppSections { let address = symbol.as_ref().map(|s| s.address()).unwrap_or_default(); let name = symbol.and_then(|s| s.name()).unwrap_or_default(); - relocations.insert( - name.to_string(), - AppRelocation { + relocations + .entry(name.to_string()) + .or_default() + .push(AppRelocation { offset_in_section, address, relocation, - }, - ); + }); } _ => todo!(), } From b23b53aa6f8c9a22e8814ff772a8a1f29fe1f66e Mon Sep 17 00:00:00 2001 From: Folkert Date: Tue, 18 Oct 2022 18:45:38 +0200 Subject: [PATCH 40/54] disable -fPIE on windows --- crates/compiler/build/src/link.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/build/src/link.rs b/crates/compiler/build/src/link.rs index 61d1fc5e22..1b90815d22 100644 --- a/crates/compiler/build/src/link.rs +++ b/crates/compiler/build/src/link.rs @@ -201,7 +201,7 @@ pub fn build_zig_host_native( if let Some(shared_lib_path) = shared_lib_path { command.args(&[ "build-exe", - "-fPIE", + // "-fPIE", PIE seems to fail on windows shared_lib_path.to_str().unwrap(), &bitcode::get_builtins_windows_obj_path(), ]); From d7237dc9e9d7ce5607c879ee9519ded815dfb792 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 18 Oct 2022 12:09:18 -0500 Subject: [PATCH 41/54] Cargo format --- crates/compiler/derive/src/encoding.rs | 5 ++++- crates/compiler/derive/src/hash.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/compiler/derive/src/encoding.rs b/crates/compiler/derive/src/encoding.rs index 7c113e5862..e1e5a9cce5 100644 --- a/crates/compiler/derive/src/encoding.rs +++ b/crates/compiler/derive/src/encoding.rs @@ -314,7 +314,10 @@ fn to_encoder_record( record_var, ext_var: env.subs.fresh_unnamed_flex_var(), field_var, - loc_expr: Box::new(Loc::at_zero(Var(rcd_sym, env.subs.fresh_unnamed_flex_var()))), + loc_expr: Box::new(Loc::at_zero(Var( + rcd_sym, + env.subs.fresh_unnamed_flex_var(), + ))), field: field_name, }; diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index 9edb04ce88..62d681b409 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -99,7 +99,10 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (V record_var, field_var, ext_var: env.subs.fresh_unnamed_flex_var(), - loc_expr: Box::new(Loc::at_zero(Expr::Var(rcd_sym, env.subs.fresh_unnamed_flex_var()))), + loc_expr: Box::new(Loc::at_zero(Expr::Var( + rcd_sym, + env.subs.fresh_unnamed_flex_var(), + ))), field: field_name, }; From a68f69b8abcdd5c4bf94a2f1e19f0c03de93ea43 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Wed, 19 Oct 2022 08:11:26 +1100 Subject: [PATCH 42/54] removed references to other languages for Comments section for tutorial.md --- TUTORIAL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index 7c6690a573..85322e8a69 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -1416,7 +1416,7 @@ Comments that begin with `##` will be included in generated documentation (```ro ## expect x == 2 ``` -Like [Python](https://www.python.org), [Ruby](https://www.ruby-lang.org), [Perl](https://www.perl.org), and [Elixir](https://elixir-lang.org/), Roc also supports inline comments. They begin with `#`, and can be used to add information that won't be included in documentation. +Roc also supports inline comments and line comments with `#`. They can be used to add information that won't be included in documentation. ```coffee # This is a line comment that won't appear in documentation. From e39a385f5f7b63a339a2d7bfd7aa4bec76254818 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Sun, 16 Oct 2022 15:10:05 -0700 Subject: [PATCH 43/54] Allow parsing `when` cases with python-like indentation --- crates/compiler/fmt/tests/test_fmt.rs | 59 +++++++++++++++++ crates/compiler/parse/src/expr.rs | 2 +- ...nction_python_style_indent.expr.result-ast | 64 +++++++++++++++++++ ...n_in_function_python_style_indent.expr.roc | 3 + crates/compiler/parse/tests/test_parse.rs | 1 + 5 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast create mode 100644 crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.roc diff --git a/crates/compiler/fmt/tests/test_fmt.rs b/crates/compiler/fmt/tests/test_fmt.rs index 90d7ff65e0..0b99851e3d 100644 --- a/crates/compiler/fmt/tests/test_fmt.rs +++ b/crates/compiler/fmt/tests/test_fmt.rs @@ -3492,6 +3492,65 @@ mod test_fmt { )); } + #[test] + fn def_when() { + expr_formats_same(indoc!( + r#" + myLongFunctionName = \x -> + when b is + 1 | 2 -> + when c is + 6 | 7 -> + 8 + + 3 | 4 -> + 5 + + 123 + "# + )); + } + + #[test] + #[ignore] // TODO: reformat when-in-function-body with extra newline + fn def_when_with_python_indentation() { + expr_formats_to( + // vvv Currently this input formats to _itself_ :( vvv + // Instead, if the body of the `when` is multiline (the overwhelmingly common case) + // we want to make sure the `when` is at the beginning of the line, inserting + // a newline if necessary. + indoc!( + r#" + myLongFunctionName = \x -> when b is + 1 | 2 -> + when c is + 6 | 7 -> + 8 + + 3 | 4 -> + 5 + + 123 + "# + ), + indoc!( + r#" + myLongFunctionName = \x -> + when b is + 1 | 2 -> + when c is + 6 | 7 -> + 8 + + 3 | 4 -> + 5 + + 123 + "# + ), + ); + } + #[test] fn when_with_alternatives_1() { expr_formats_same(indoc!( diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index f51433e3da..431e58041e 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -2080,7 +2080,7 @@ mod when { /// Parsing when with indentation. fn when_with_indent<'a>() -> impl Parser<'a, u32, EWhen<'a>> { move |arena, state: State<'a>| { - let min_indent = state.column(); + let min_indent = state.line_indent() + 1; parser::keyword_e(keyword::WHEN, EWhen::When) .parse(arena, state) .map(|(progress, (), state)| (progress, min_indent, state)) diff --git a/crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast b/crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast new file mode 100644 index 0000000000..29d1fbc30a --- /dev/null +++ b/crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast @@ -0,0 +1,64 @@ +Defs( + Defs { + tags: [ + Index(2147483648), + ], + regions: [ + @0-33, + ], + space_before: [ + Slice(start = 0, length = 0), + ], + space_after: [ + Slice(start = 0, length = 0), + ], + spaces: [], + type_defs: [], + value_defs: [ + Body( + @0-4 Identifier( + "func", + ), + @7-33 Closure( + [ + @8-9 Identifier( + "x", + ), + ], + @13-33 When( + @18-19 Var { + module_name: "", + ident: "n", + }, + [ + WhenBranch { + patterns: [ + @27-28 SpaceBefore( + NumLiteral( + "0", + ), + [ + Newline, + ], + ), + ], + value: @32-33 Num( + "0", + ), + guard: None, + }, + ], + ), + ), + ), + ], + }, + @34-36 SpaceBefore( + Num( + "42", + ), + [ + Newline, + ], + ), +) diff --git a/crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.roc b/crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.roc new file mode 100644 index 0000000000..3e5e676b98 --- /dev/null +++ b/crates/compiler/parse/tests/snapshots/pass/when_in_function_python_style_indent.expr.roc @@ -0,0 +1,3 @@ +func = \x -> when n is + 0 -> 0 +42 \ No newline at end of file diff --git a/crates/compiler/parse/tests/test_parse.rs b/crates/compiler/parse/tests/test_parse.rs index c7816273ef..6506198015 100644 --- a/crates/compiler/parse/tests/test_parse.rs +++ b/crates/compiler/parse/tests/test_parse.rs @@ -284,6 +284,7 @@ mod test_parse { pass/when_if_guard.expr, pass/when_in_assignment.expr, pass/when_in_function.expr, + pass/when_in_function_python_style_indent.expr, pass/when_in_parens_indented.expr, pass/when_in_parens.expr, pass/when_with_alternative_patterns.expr, From 58f4afd9f0a7244e8fa3a7c04a88e1ce34f04242 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Tue, 18 Oct 2022 23:00:43 -0700 Subject: [PATCH 44/54] add a wrapper for RocStr and RocList that is Send safe --- crates/roc_std/src/roc_list.rs | 46 ++++++++++++++++++++++++++++++++++ crates/roc_std/src/roc_str.rs | 37 +++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/crates/roc_std/src/roc_list.rs b/crates/roc_std/src/roc_list.rs index d9ba93227d..050bdfe1bf 100644 --- a/crates/roc_std/src/roc_list.rs +++ b/crates/roc_std/src/roc_list.rs @@ -103,6 +103,24 @@ impl RocList { self.len() == 0 } + pub fn is_unique(&self) -> bool { + if let Some(storage) = self.storage() { + storage.is_unique() + } else { + // If there is no storage, this list is empty. + // An empty list is always unique. + true + } + } + + pub fn is_readonly(&self) -> bool { + if let Some(storage) = self.storage() { + storage.is_readonly() + } else { + false + } + } + /// Note that there is no way to convert directly to a Vec. /// /// This is because RocList values are not allocated using the system allocator, so @@ -586,6 +604,34 @@ where } } +// This is a RocList that is checked to ensure it is unique or readonly such that it can be sent between threads safely. +#[repr(transparent)] +pub struct SendSafeRocList(RocList); + +unsafe impl Send for SendSafeRocList where T: Send {} + +impl From> for SendSafeRocList +where + T: Clone, +{ + fn from(l: RocList) -> Self { + if l.is_unique() || l.is_readonly() { + SendSafeRocList(l) + } else { + // This is not unique, do a deep copy. + // TODO: look into proper into_iter that takes ownership. + // Then this won't need clone and will skip and refcount inc and dec for each element. + SendSafeRocList(RocList::from_slice(&l)) + } + } +} + +impl From> for RocList { + fn from(l: SendSafeRocList) -> Self { + l.0 + } +} + #[cfg(feature = "serde")] struct RocListVisitor { marker: PhantomData, diff --git a/crates/roc_std/src/roc_str.rs b/crates/roc_std/src/roc_str.rs index 7fbe68d12d..e8ce58771a 100644 --- a/crates/roc_std/src/roc_str.rs +++ b/crates/roc_std/src/roc_str.rs @@ -109,6 +109,20 @@ impl RocStr { self.len() == 0 } + pub fn is_unique(&self) -> bool { + match self.as_enum_ref() { + RocStrInnerRef::HeapAllocated(roc_list) => roc_list.is_unique(), + RocStrInnerRef::SmallString(_) => true, + } + } + + pub fn is_readonly(&self) -> bool { + match self.as_enum_ref() { + RocStrInnerRef::HeapAllocated(roc_list) => roc_list.is_readonly(), + RocStrInnerRef::SmallString(_) => false, + } + } + /// Note that there is no way to convert directly to a String. /// /// This is because RocStr values are not allocated using the system allocator, so @@ -627,6 +641,29 @@ impl Drop for RocStr { } } +// This is a RocStr that is checked to ensure it is unique or readonly such that it can be sent between threads safely. +#[repr(transparent)] +pub struct SendSafeRocStr(RocStr); + +unsafe impl Send for SendSafeRocStr {} + +impl From for SendSafeRocStr { + fn from(s: RocStr) -> Self { + if s.is_unique() || s.is_readonly() { + SendSafeRocStr(s) + } else { + // This is not unique, do a deep copy. + SendSafeRocStr(RocStr::from(s.as_str())) + } + } +} + +impl From for RocStr { + fn from(s: SendSafeRocStr) -> Self { + s.0 + } +} + #[repr(C)] union RocStrInner { heap_allocated: ManuallyDrop>, From 24cd78fe7ee16e6bf49e727cb25603a0dc9f20a2 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Tue, 18 Oct 2022 23:35:15 -0700 Subject: [PATCH 45/54] add tests and expose types --- crates/roc_std/src/lib.rs | 4 +- crates/roc_std/src/roc_list.rs | 9 ++++ crates/roc_std/src/roc_str.rs | 10 ++++ crates/roc_std/tests/test_roc_std.rs | 80 ++++++++++++++++++++++++++-- 4 files changed, 98 insertions(+), 5 deletions(-) diff --git a/crates/roc_std/src/lib.rs b/crates/roc_std/src/lib.rs index 47108e9c41..232b224baf 100644 --- a/crates/roc_std/src/lib.rs +++ b/crates/roc_std/src/lib.rs @@ -19,9 +19,9 @@ mod storage; pub use roc_box::RocBox; pub use roc_dict::RocDict; -pub use roc_list::RocList; +pub use roc_list::{RocList, SendSafeRocList}; pub use roc_set::RocSet; -pub use roc_str::{InteriorNulError, RocStr}; +pub use roc_str::{InteriorNulError, RocStr, SendSafeRocStr}; pub use storage::Storage; // A list of C functions that are being imported diff --git a/crates/roc_std/src/roc_list.rs b/crates/roc_std/src/roc_list.rs index 050bdfe1bf..64e7280144 100644 --- a/crates/roc_std/src/roc_list.rs +++ b/crates/roc_std/src/roc_list.rs @@ -121,6 +121,15 @@ impl RocList { } } + // Marks a list as readonly. This means that it will be leaked. + // For constants passed in from platform to application, this may be reasonable. + // Marked unsafe because it should not be used lightly. + pub unsafe fn set_readonly(&self) { + if let Some((_, storage)) = self.elements_and_storage() { + storage.set(Storage::Readonly); + } + } + /// Note that there is no way to convert directly to a Vec. /// /// This is because RocList values are not allocated using the system allocator, so diff --git a/crates/roc_std/src/roc_str.rs b/crates/roc_std/src/roc_str.rs index e8ce58771a..837ccb948e 100644 --- a/crates/roc_std/src/roc_str.rs +++ b/crates/roc_std/src/roc_str.rs @@ -123,6 +123,16 @@ impl RocStr { } } + // Marks a str as readonly. This means that it will be leaked. + // For constants passed in from platform to application, this may be reasonable. + // Marked unsafe because it should not be used lightly. + pub unsafe fn set_readonly(&self) { + match self.as_enum_ref() { + RocStrInnerRef::HeapAllocated(roc_list) => unsafe { roc_list.set_readonly() }, + RocStrInnerRef::SmallString(_) => {} + } + } + /// Note that there is no way to convert directly to a String. /// /// This is because RocStr values are not allocated using the system allocator, so diff --git a/crates/roc_std/tests/test_roc_std.rs b/crates/roc_std/tests/test_roc_std.rs index d81b93d896..4de4e543fe 100644 --- a/crates/roc_std/tests/test_roc_std.rs +++ b/crates/roc_std/tests/test_roc_std.rs @@ -59,7 +59,7 @@ pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut #[cfg(test)] mod test_roc_std { - use roc_std::{RocBox, RocDec, RocList, RocResult, RocStr}; + use roc_std::{RocBox, RocDec, RocList, RocResult, RocStr, SendSafeRocList, SendSafeRocStr}; fn roc_str_byte_representation(string: &RocStr) -> [u8; RocStr::SIZE] { unsafe { core::mem::transmute_copy(string) } @@ -126,7 +126,7 @@ mod test_roc_std { roc_str.reserve(42); - assert_gte!(roc_str.capacity(), 42); + assert_eq!(roc_str.capacity() >= 42, true); } #[test] @@ -135,7 +135,7 @@ mod test_roc_std { roc_str.reserve(5000); - assert_gte!(roc_str.capacity(), 5000); + assert_eq!(roc_str.capacity() >= 5000, true); } #[test] @@ -296,6 +296,80 @@ mod test_roc_std { let example = RocDec::from_str("1234.5678").unwrap(); assert_eq!(format!("{}", example), "1234.5678"); } + + #[test] + fn safe_send_no_copy() { + let x = RocStr::from("This is a long string but still unique. Yay!!!"); + assert_eq!(x.is_unique(), true); + + let safe_x = SendSafeRocStr::from(x); + let new_x = RocStr::from(safe_x); + assert_eq!(new_x.is_unique(), true); + assert_eq!( + new_x.as_str(), + "This is a long string but still unique. Yay!!!" + ); + } + + #[test] + fn safe_send_requires_copy() { + let x = RocStr::from("This is a long string but still unique. Yay!!!"); + let y = x.clone(); + let z = y.clone(); + assert_eq!(x.is_unique(), false); + assert_eq!(y.is_unique(), false); + assert_eq!(z.is_unique(), false); + + let safe_x = SendSafeRocStr::from(x); + let new_x = RocStr::from(safe_x); + assert_eq!(new_x.is_unique(), true); + assert_eq!(y.is_unique(), false); + assert_eq!(z.is_unique(), false); + assert_eq!( + new_x.as_str(), + "This is a long string but still unique. Yay!!!" + ); + } + + #[test] + fn safe_send_small_str() { + let x = RocStr::from("short"); + let y = x.clone(); + let z = y.clone(); + assert_eq!(x.is_unique(), true); + assert_eq!(y.is_unique(), true); + assert_eq!(z.is_unique(), true); + + let safe_x = SendSafeRocStr::from(x); + let new_x = RocStr::from(safe_x); + assert_eq!(new_x.is_unique(), true); + assert_eq!(y.is_unique(), true); + assert_eq!(z.is_unique(), true); + assert_eq!(new_x.as_str(), "short"); + } + + #[test] + fn empty_list_is_unique() { + let roc_list = RocList::::empty(); + assert_eq!(roc_list.is_unique(), true); + } + + #[test] + fn readonly_list_is_sendsafe() { + let x = RocList::from_slice(&[1, 2, 3, 4, 5]); + unsafe { x.set_readonly() }; + assert_eq!(x.is_readonly(), true); + + let y = x.clone(); + let z = y.clone(); + + let safe_x = SendSafeRocList::from(x); + let new_x = RocList::from(safe_x); + assert_eq!(new_x.is_readonly(), true); + assert_eq!(y.is_readonly(), true); + assert_eq!(z.is_readonly(), true); + assert_eq!(new_x.as_slice(), &[1, 2, 3, 4, 5]); + } } #[cfg(test)] From a572622ff7a0842229426e28033d11ea81f37a44 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 19 Oct 2022 14:12:41 +0200 Subject: [PATCH 46/54] update basereloc dir size --- crates/linker/src/pe.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 9b612d408b..482d89459e 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1267,12 +1267,26 @@ fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { + md.reloc_section_index * std::mem::size_of::(); let ptr = load_struct_inplace_mut::(executable, reloc_section_header_start); - let new_virtual_size = ptr.virtual_size.get(LE) + added_reloc_bytes as u32; + let old_section_size = ptr.virtual_size.get(LE); + let new_virtual_size = old_section_size + added_reloc_bytes as u32; ptr.virtual_size.set(LE, new_virtual_size); // TODO this is rounded up, so there is extra space and it does not need to change in our current examples // let new_size_of_raw_data = ptr.size_of_raw_data.get(LE) + added_reloc_bytes as u32; // ptr.size_of_raw_data.set(LE, new_size_of_raw_data); + assert!(new_virtual_size <= 0x200); + + // in the data directories, update the length of the base relocations + let dir = load_struct_inplace_mut::( + executable, + md.dynamic_relocations.data_directories_offset_in_file as usize + + object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC + * std::mem::size_of::(), + ); + + let old_dir_size = dir.size.get(LE); + debug_assert_eq!(old_section_size, old_dir_size); + dir.size.set(LE, new_virtual_size); } #[cfg(test)] From e2128a55f489d282d3b8dff3f8b37e72efa7de4a Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 19 Oct 2022 15:12:51 +0200 Subject: [PATCH 47/54] add assert to check we fit in the reloc section --- crates/linker/src/pe.rs | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 482d89459e..c533c6cd5b 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -653,6 +653,11 @@ impl Preprocessor { fn write_dummy_sections(&self, result: &mut MmapMut, extra_section_names: &[[u8; 8]]) { const W: usize = std::mem::size_of::(); + // only correct for the first section, but that is OK because it's overwritten later + // anyway. But, this value may be used to check whether a previous section overruns into + // the app sections. + let pointer_to_raw_data = result.len() - self.additional_length; + let previous_section_header = load_struct_inplace::(result, self.extra_sections_start - W); @@ -678,7 +683,7 @@ impl Preprocessor { // NOTE: this must be a valid virtual address, using 0 is invalid! virtual_address: object::U32::new(LE, next_virtual_address as u32), size_of_raw_data: Default::default(), - pointer_to_raw_data: Default::default(), + pointer_to_raw_data: object::U32::new(LE, pointer_to_raw_data as u32), pointer_to_relocations: Default::default(), pointer_to_linenumbers: Default::default(), number_of_relocations: Default::default(), @@ -1266,15 +1271,26 @@ fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { let reloc_section_header_start = md.dynamic_relocations.section_headers_offset_in_file as usize + md.reloc_section_index * std::mem::size_of::(); - let ptr = load_struct_inplace_mut::(executable, reloc_section_header_start); - let old_section_size = ptr.virtual_size.get(LE); - let new_virtual_size = old_section_size + added_reloc_bytes as u32; - ptr.virtual_size.set(LE, new_virtual_size); + let next_section = load_struct_inplace::( + executable, + reloc_section_header_start + std::mem::size_of::(), + ); - // TODO this is rounded up, so there is extra space and it does not need to change in our current examples - // let new_size_of_raw_data = ptr.size_of_raw_data.get(LE) + added_reloc_bytes as u32; - // ptr.size_of_raw_data.set(LE, new_size_of_raw_data); - assert!(new_virtual_size <= 0x200); + let next_section_pointer_to_raw_data = next_section.pointer_to_raw_data.get(LE); + + let reloc_section = + load_struct_inplace_mut::(executable, reloc_section_header_start); + let old_section_size = reloc_section.virtual_size.get(LE); + let new_virtual_size = old_section_size + added_reloc_bytes as u32; + reloc_section.virtual_size.set(LE, new_virtual_size); + + assert!( + reloc_section.pointer_to_raw_data.get(LE) + + reloc_section.virtual_size.get(LE) + + (added_reloc_bytes as u32) + < next_section_pointer_to_raw_data, + "new .reloc section is too big, and runs into the next section!", + ); // in the data directories, update the length of the base relocations let dir = load_struct_inplace_mut::( From 4de148456cd7183fc16b303796a1b80b35af9bd1 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 19 Oct 2022 15:32:34 +0200 Subject: [PATCH 48/54] stop updating reloc data directory --- crates/linker/src/pe.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index c533c6cd5b..171141c208 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1292,17 +1292,17 @@ fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { "new .reloc section is too big, and runs into the next section!", ); - // in the data directories, update the length of the base relocations - let dir = load_struct_inplace_mut::( - executable, - md.dynamic_relocations.data_directories_offset_in_file as usize - + object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC - * std::mem::size_of::(), - ); - - let old_dir_size = dir.size.get(LE); - debug_assert_eq!(old_section_size, old_dir_size); - dir.size.set(LE, new_virtual_size); + // // in the data directories, update the length of the base relocations + // let dir = load_struct_inplace_mut::( + // executable, + // md.dynamic_relocations.data_directories_offset_in_file as usize + // + object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC + // * std::mem::size_of::(), + // ); + // + // let old_dir_size = dir.size.get(LE); + // debug_assert_eq!(old_section_size, old_dir_size); + // dir.size.set(LE, new_virtual_size); } #[cfg(test)] From 644a12e7aa77115f48980556f03b042d14f51478 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 19 Oct 2022 16:52:51 +0200 Subject: [PATCH 49/54] re-enable --- crates/linker/src/pe.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 171141c208..c533c6cd5b 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1292,17 +1292,17 @@ fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { "new .reloc section is too big, and runs into the next section!", ); - // // in the data directories, update the length of the base relocations - // let dir = load_struct_inplace_mut::( - // executable, - // md.dynamic_relocations.data_directories_offset_in_file as usize - // + object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC - // * std::mem::size_of::(), - // ); - // - // let old_dir_size = dir.size.get(LE); - // debug_assert_eq!(old_section_size, old_dir_size); - // dir.size.set(LE, new_virtual_size); + // in the data directories, update the length of the base relocations + let dir = load_struct_inplace_mut::( + executable, + md.dynamic_relocations.data_directories_offset_in_file as usize + + object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC + * std::mem::size_of::(), + ); + + let old_dir_size = dir.size.get(LE); + debug_assert_eq!(old_section_size, old_dir_size); + dir.size.set(LE, new_virtual_size); } #[cfg(test)] From d0492327e86146e80b1d805e10797ed3700dbf6b Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 19 Oct 2022 17:41:46 +0200 Subject: [PATCH 50/54] Revert "re-enable" This reverts commit 644a12e7aa77115f48980556f03b042d14f51478. --- crates/linker/src/pe.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index c533c6cd5b..171141c208 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -1292,17 +1292,17 @@ fn relocate_dummy_dll_entries(executable: &mut [u8], md: &PeMetadata) { "new .reloc section is too big, and runs into the next section!", ); - // in the data directories, update the length of the base relocations - let dir = load_struct_inplace_mut::( - executable, - md.dynamic_relocations.data_directories_offset_in_file as usize - + object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC - * std::mem::size_of::(), - ); - - let old_dir_size = dir.size.get(LE); - debug_assert_eq!(old_section_size, old_dir_size); - dir.size.set(LE, new_virtual_size); + // // in the data directories, update the length of the base relocations + // let dir = load_struct_inplace_mut::( + // executable, + // md.dynamic_relocations.data_directories_offset_in_file as usize + // + object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC + // * std::mem::size_of::(), + // ); + // + // let old_dir_size = dir.size.get(LE); + // debug_assert_eq!(old_section_size, old_dir_size); + // dir.size.set(LE, new_virtual_size); } #[cfg(test)] From 6ebfcc8fa198449741703a90e4f78f046144271c Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Wed, 19 Oct 2022 11:54:17 -0700 Subject: [PATCH 51/54] add clone to SendSafe* types --- crates/roc_std/src/roc_list.rs | 14 ++++++++++++++ crates/roc_std/src/roc_str.rs | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/crates/roc_std/src/roc_list.rs b/crates/roc_std/src/roc_list.rs index 64e7280144..5dd8a4ad1c 100644 --- a/crates/roc_std/src/roc_list.rs +++ b/crates/roc_std/src/roc_list.rs @@ -619,6 +619,20 @@ pub struct SendSafeRocList(RocList); unsafe impl Send for SendSafeRocList where T: Send {} +impl Clone for SendSafeRocList +where + T: Clone, +{ + fn clone(&self) -> Self { + if self.0.is_readonly() { + SendSafeRocList(self.0.clone()) + } else { + // To keep self send safe, this must copy. + SendSafeRocList(RocList::from_slice(&self.0)) + } + } +} + impl From> for SendSafeRocList where T: Clone, diff --git a/crates/roc_std/src/roc_str.rs b/crates/roc_std/src/roc_str.rs index 837ccb948e..b760102c6a 100644 --- a/crates/roc_std/src/roc_str.rs +++ b/crates/roc_std/src/roc_str.rs @@ -657,6 +657,17 @@ pub struct SendSafeRocStr(RocStr); unsafe impl Send for SendSafeRocStr {} +impl Clone for SendSafeRocStr { + fn clone(&self) -> Self { + if self.0.is_readonly() { + SendSafeRocStr(self.0.clone()) + } else { + // To keep self send safe, this must copy. + SendSafeRocStr(RocStr::from(self.0.as_str())) + } + } +} + impl From for SendSafeRocStr { fn from(s: RocStr) -> Self { if s.is_unique() || s.is_readonly() { From 8804b28be0862cd4c80a2ddf71445f73379f5b44 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Wed, 19 Oct 2022 12:09:05 -0700 Subject: [PATCH 52/54] expand safety doc comment --- crates/roc_std/src/roc_list.rs | 17 ++++++++++++++--- crates/roc_std/src/roc_str.rs | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/crates/roc_std/src/roc_list.rs b/crates/roc_std/src/roc_list.rs index 5dd8a4ad1c..ff1f9eb4d6 100644 --- a/crates/roc_std/src/roc_list.rs +++ b/crates/roc_std/src/roc_list.rs @@ -121,9 +121,20 @@ impl RocList { } } - // Marks a list as readonly. This means that it will be leaked. - // For constants passed in from platform to application, this may be reasonable. - // Marked unsafe because it should not be used lightly. + /// Marks a list as readonly. This means that it will be leaked. + /// For constants passed in from platform to application, this may be reasonable. + /// + /// # Safety + /// + /// A value can be read-only in Roc for 3 reasons: + /// 1. The value is stored in read-only memory like a constant in the app. + /// 2. Our refcounting maxes out. When that happens, we saturate to read-only. + /// 3. This function is called + /// + /// Any value that is set to read-only will be leaked. + /// There is no way to tell how many references it has and if it is safe to free. + /// As such, only values that should have a static lifetime for the entire application run + /// should be considered for marking read-only. pub unsafe fn set_readonly(&self) { if let Some((_, storage)) = self.elements_and_storage() { storage.set(Storage::Readonly); diff --git a/crates/roc_std/src/roc_str.rs b/crates/roc_std/src/roc_str.rs index b760102c6a..0face1fe2c 100644 --- a/crates/roc_std/src/roc_str.rs +++ b/crates/roc_std/src/roc_str.rs @@ -123,9 +123,20 @@ impl RocStr { } } - // Marks a str as readonly. This means that it will be leaked. - // For constants passed in from platform to application, this may be reasonable. - // Marked unsafe because it should not be used lightly. + /// Marks a str as readonly. This means that it will be leaked. + /// For constants passed in from platform to application, this may be reasonable. + /// + /// # Safety + /// + /// A value can be read-only in Roc for 3 reasons: + /// 1. The value is stored in read-only memory like a constant in the app. + /// 2. Our refcounting maxes out. When that happens, we saturate to read-only. + /// 3. This function is called + /// + /// Any value that is set to read-only will be leaked. + /// There is no way to tell how many references it has and if it is safe to free. + /// As such, only values that should have a static lifetime for the entire application run + /// should be considered for marking read-only. pub unsafe fn set_readonly(&self) { match self.as_enum_ref() { RocStrInnerRef::HeapAllocated(roc_list) => unsafe { roc_list.set_readonly() }, From f826ff1a71b029f2df8ff77c62926cab02020811 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 19 Oct 2022 14:24:21 -0500 Subject: [PATCH 53/54] Remove addI* variants from Hash These are trivially fulfilled by converting a signed int to its unsigned repr and hashing that. --- crates/compiler/builtins/roc/Dict.roc | 16 ------- crates/compiler/builtins/roc/Hash.roc | 45 ++++++++++--------- crates/compiler/derive_key/src/hash.rs | 10 ++--- crates/compiler/module/src/symbol.rs | 10 ++--- crates/compiler/test_gen/src/gen_abilities.rs | 10 ----- 5 files changed, 35 insertions(+), 56 deletions(-) diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index 201a5c8ca7..7537cb507d 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -224,11 +224,6 @@ LowLevelHasher := { originalSeed : U64, state : U64 } has [ addU32, addU64, addU128, - addI8, - addI16, - addI32, - addI64, - addI128, complete, }, ] @@ -250,17 +245,6 @@ combineState = \@LowLevelHasher { originalSeed, state }, { a, b, seed, length } complete = \@LowLevelHasher { state } -> state -addI8 = \hasher, i8 -> - addU8 hasher (Num.toU8 i8) -addI16 = \hasher, i16 -> - addU16 hasher (Num.toU16 i16) -addI32 = \hasher, i32 -> - addU32 hasher (Num.toU32 i32) -addI64 = \hasher, i64 -> - addU64 hasher (Num.toU64 i64) -addI128 = \hasher, i128 -> - addU128 hasher (Num.toU128 i128) - # These implementations hash each value individually with the seed and then mix # the resulting hash with the state. There are other options that may be faster # like using the output of the last hash as the seed to the current hash. diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index ea323707b7..5f8081e8f6 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -9,11 +9,11 @@ interface Hash addU32, addU64, addU128, - addI8, - addI16, - addI32, - addI64, - addI128, + hashI8, + hashI16, + hashI32, + hashI64, + hashI128, complete, hashStrBytes, hashList, @@ -55,21 +55,6 @@ Hasher has ## Adds a single U128 to the hasher. addU128 : a, U128 -> a | a has Hasher - ## Adds a single I8 to the hasher. - addI8 : a, I8 -> a | a has Hasher - - ## Adds a single I16 to the hasher. - addI16 : a, I16 -> a | a has Hasher - - ## Adds a single I32 to the hasher. - addI32 : a, I32 -> a | a has Hasher - - ## Adds a single I64 to the hasher. - addI64 : a, I64 -> a | a has Hasher - - ## Adds a single I128 to the hasher. - addI128 : a, I128 -> a | a has Hasher - ## Completes the hasher, extracting a hash value from its ## accumulated hash state. complete : a -> U64 | a has Hasher @@ -83,6 +68,26 @@ hashList = \hasher, lst -> List.walk lst hasher \accumHasher, elem -> hash accumHasher elem +## Adds a single I8 to a hasher. +hashI8 : a, I8 -> a | a has Hasher +hashI8 = \hasher, n -> addU8 hasher (Num.toU8 n) + +## Adds a single I16 to a hasher. +hashI16 : a, I16 -> a | a has Hasher +hashI16 = \hasher, n -> addU16 hasher (Num.toU16 n) + +## Adds a single I32 to a hasher. +hashI32 : a, I32 -> a | a has Hasher +hashI32 = \hasher, n -> addU32 hasher (Num.toU32 n) + +## Adds a single I64 to a hasher. +hashI64 : a, I64 -> a | a has Hasher +hashI64 = \hasher, n -> addU64 hasher (Num.toU64 n) + +## Adds a single I128 to a hasher. +hashI128 : a, I128 -> a | a has Hasher +hashI128 = \hasher, n -> addU128 hasher (Num.toU128 n) + ## Adds a container of [Hash]able elements to a [Hasher] by hashing each element. ## The container is iterated using the walk method passed in. ## The order of the elements does not affect the final hash. diff --git a/crates/compiler/derive_key/src/hash.rs b/crates/compiler/derive_key/src/hash.rs index 0e8ad35f81..01d68c28e6 100644 --- a/crates/compiler/derive_key/src/hash.rs +++ b/crates/compiler/derive_key/src/hash.rs @@ -123,19 +123,19 @@ impl FlatHash { Ok(SingleLambdaSetImmediate(Symbol::HASH_ADD_U128)) } Symbol::NUM_I8 | Symbol::NUM_SIGNED8 => { - Ok(SingleLambdaSetImmediate(Symbol::HASH_ADD_I8)) + Ok(SingleLambdaSetImmediate(Symbol::HASH_HASH_I8)) } Symbol::NUM_I16 | Symbol::NUM_SIGNED16 => { - Ok(SingleLambdaSetImmediate(Symbol::HASH_ADD_I16)) + Ok(SingleLambdaSetImmediate(Symbol::HASH_HASH_I16)) } Symbol::NUM_I32 | Symbol::NUM_SIGNED32 => { - Ok(SingleLambdaSetImmediate(Symbol::HASH_ADD_I32)) + Ok(SingleLambdaSetImmediate(Symbol::HASH_HASH_I32)) } Symbol::NUM_I64 | Symbol::NUM_SIGNED64 => { - Ok(SingleLambdaSetImmediate(Symbol::HASH_ADD_I64)) + Ok(SingleLambdaSetImmediate(Symbol::HASH_HASH_I64)) } Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => { - Ok(SingleLambdaSetImmediate(Symbol::HASH_ADD_I128)) + Ok(SingleLambdaSetImmediate(Symbol::HASH_HASH_I128)) } // NB: I believe it is okay to unwrap opaques here because derivers are only used // by the backend, and the backend treats opaques like structural aliases. diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index 337b7af9db..24f16b855a 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -1528,11 +1528,11 @@ define_builtins! { 6 HASH_ADD_U32: "addU32" 7 HASH_ADD_U64: "addU64" 8 HASH_ADD_U128: "addU128" - 9 HASH_ADD_I8: "addI8" - 10 HASH_ADD_I16: "addI16" - 11 HASH_ADD_I32: "addI32" - 12 HASH_ADD_I64: "addI64" - 13 HASH_ADD_I128: "addI128" + 9 HASH_HASH_I8: "hashI8" + 10 HASH_HASH_I16: "hashI16" + 11 HASH_HASH_I32: "hashI32" + 12 HASH_HASH_I64: "hashI64" + 13 HASH_HASH_I128: "hashI128" 14 HASH_COMPLETE: "complete" 15 HASH_HASH_STR_BYTES: "hashStrBytes" 16 HASH_HASH_LIST: "hashList" diff --git a/crates/compiler/test_gen/src/gen_abilities.rs b/crates/compiler/test_gen/src/gen_abilities.rs index 509a232825..4370b19993 100644 --- a/crates/compiler/test_gen/src/gen_abilities.rs +++ b/crates/compiler/test_gen/src/gen_abilities.rs @@ -1122,11 +1122,6 @@ mod hash { addU32: tAddU32, addU64: tAddU64, addU128: tAddU128, - addI8: tAddI8, - addI16: tAddI16, - addI32: tAddI32, - addI64: tAddI64, - addI128: tAddI128, complete: tComplete, }] @@ -1165,11 +1160,6 @@ mod hash { tAddU32 = \@THasher total, n -> @THasher (do32 total n) tAddU64 = \@THasher total, n -> @THasher (do64 total n) tAddU128 = \@THasher total, n -> @THasher (do128 total n) - tAddI8 = \@THasher total, n -> @THasher (do8 total (Num.toU8 n)) - tAddI16 = \@THasher total, n -> @THasher (do16 total (Num.toU16 n)) - tAddI32 = \@THasher total, n -> @THasher (do32 total (Num.toU32 n)) - tAddI64 = \@THasher total, n -> @THasher (do64 total (Num.toU64 n)) - tAddI128 = \@THasher total, n -> @THasher (do128 total (Num.toU128 n)) tComplete = \@THasher _ -> Num.maxU64 tRead = \@THasher bytes -> bytes From e27b874331a9fc60c0381e4e007a2bcccd21378a Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Wed, 19 Oct 2022 18:22:44 -0700 Subject: [PATCH 54/54] update test to use HASH_HASH_I* instead of HASH_ADD_I* --- crates/compiler/test_derive/src/hash.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/compiler/test_derive/src/hash.rs b/crates/compiler/test_derive/src/hash.rs index 45a501e77e..c6a50040ba 100644 --- a/crates/compiler/test_derive/src/hash.rs +++ b/crates/compiler/test_derive/src/hash.rs @@ -66,11 +66,11 @@ fn immediates() { check_single_lset_immediate(Hash, v!(U32), Symbol::HASH_ADD_U32); check_single_lset_immediate(Hash, v!(U64), Symbol::HASH_ADD_U64); check_single_lset_immediate(Hash, v!(U128), Symbol::HASH_ADD_U128); - check_single_lset_immediate(Hash, v!(I8), Symbol::HASH_ADD_I8); - check_single_lset_immediate(Hash, v!(I16), Symbol::HASH_ADD_I16); - check_single_lset_immediate(Hash, v!(I32), Symbol::HASH_ADD_I32); - check_single_lset_immediate(Hash, v!(I64), Symbol::HASH_ADD_I64); - check_single_lset_immediate(Hash, v!(I128), Symbol::HASH_ADD_I128); + check_single_lset_immediate(Hash, v!(I8), Symbol::HASH_HASH_I8); + check_single_lset_immediate(Hash, v!(I16), Symbol::HASH_HASH_I16); + check_single_lset_immediate(Hash, v!(I32), Symbol::HASH_HASH_I32); + check_single_lset_immediate(Hash, v!(I64), Symbol::HASH_HASH_I64); + check_single_lset_immediate(Hash, v!(I128), Symbol::HASH_HASH_I128); check_single_lset_immediate(Hash, v!(STR), Symbol::HASH_HASH_STR_BYTES); check_single_lset_immediate(Hash, v!(Symbol::LIST_LIST v!(U8)), Symbol::HASH_HASH_LIST); check_single_lset_immediate(Hash, v!(Symbol::LIST_LIST v!(STR)), Symbol::HASH_HASH_LIST);