mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
Use roc_target over target_lexicon
Tailors a target class for our needs. Replaces tons of uses across the entire compiler. This is a base for later adding new targets like thumb.
This commit is contained in:
parent
185262510c
commit
6dc5bfb1b7
72 changed files with 1008 additions and 1371 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3168,6 +3168,7 @@ dependencies = [
|
|||
name = "roc_target"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"roc_error_macros",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"target-lexicon",
|
||||
|
|
|
@ -23,7 +23,7 @@ use roc_mono::ir::OptLevel;
|
|||
use roc_packaging::cache::RocCacheDir;
|
||||
use roc_packaging::tarball::Compression;
|
||||
use roc_reporting::report::ANSI_STYLE_CODES;
|
||||
use roc_target::Target;
|
||||
use roc_target::{Architecture, Target};
|
||||
use std::env;
|
||||
use std::ffi::{CString, OsStr, OsString};
|
||||
use std::io;
|
||||
|
@ -33,7 +33,6 @@ use std::path::{Path, PathBuf};
|
|||
use std::process;
|
||||
use std::time::{Duration, Instant};
|
||||
use strum::IntoEnumIterator;
|
||||
use target_lexicon::{Architecture, Triple};
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use tempfile::TempDir;
|
||||
|
||||
|
@ -442,7 +441,7 @@ fn opt_level_from_flags(matches: &ArgMatches) -> OptLevel {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn test(_matches: &ArgMatches, _triple: Triple) -> io::Result<i32> {
|
||||
pub fn test(_matches: &ArgMatches, _target: Target) -> io::Result<i32> {
|
||||
todo!("running tests does not work on windows right now")
|
||||
}
|
||||
|
||||
|
@ -454,11 +453,10 @@ struct ModuleTestResults {
|
|||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
||||
pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {
|
||||
use roc_build::program::report_problems_monomorphized;
|
||||
use roc_load::{ExecutionMode, FunctionKind, LoadConfig, LoadMonomorphizedError};
|
||||
use roc_packaging::cache;
|
||||
use roc_target::TargetInfo;
|
||||
|
||||
let start_time = Instant::now();
|
||||
let arena = Bump::new();
|
||||
|
@ -495,14 +493,12 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
|||
}
|
||||
|
||||
let arena = &arena;
|
||||
let target = &triple;
|
||||
let target_info = TargetInfo::from(target);
|
||||
// TODO may need to determine this dynamically based on dev builds.
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
|
||||
// Step 1: compile the app and generate the .o file
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
// TODO: expose this from CLI?
|
||||
render: roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
|
@ -536,7 +532,7 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
|||
let (dyn_lib, expects_by_module, layout_interner) =
|
||||
roc_repl_expect::run::expect_mono_module_to_dylib(
|
||||
arena,
|
||||
target.clone(),
|
||||
target,
|
||||
loaded,
|
||||
opt_level,
|
||||
LlvmBackendMode::CliTest,
|
||||
|
@ -673,7 +669,7 @@ pub fn build(
|
|||
matches: &ArgMatches,
|
||||
subcommands: &[String],
|
||||
config: BuildConfig,
|
||||
triple: Triple,
|
||||
target: Target,
|
||||
out_path: Option<&Path>,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
link_type: LinkType,
|
||||
|
@ -784,7 +780,7 @@ pub fn build(
|
|||
// Note: This allows using `--dev` with `--optimize`.
|
||||
// This means frontend optimizations and dev backend.
|
||||
let code_gen_backend = if matches.get_flag(FLAG_DEV) {
|
||||
if matches!(triple.architecture, Architecture::Wasm32) {
|
||||
if matches!(target.architecture(), Architecture::Wasm32) {
|
||||
CodeGenBackend::Wasm
|
||||
} else {
|
||||
CodeGenBackend::Assembly(AssemblyBackendMode::Binary)
|
||||
|
@ -818,7 +814,7 @@ pub fn build(
|
|||
|
||||
let linking_strategy = if wasm_dev_backend {
|
||||
LinkingStrategy::Additive
|
||||
} else if !roc_linker::supported(link_type, &triple)
|
||||
} else if !roc_linker::supported(link_type, target)
|
||||
|| matches.get_one::<String>(FLAG_LINKER).map(|s| s.as_str()) == Some("legacy")
|
||||
{
|
||||
LinkingStrategy::Legacy
|
||||
|
@ -827,8 +823,8 @@ pub fn build(
|
|||
};
|
||||
|
||||
let prebuilt = {
|
||||
let cross_compile = triple != Triple::host();
|
||||
let targeting_wasm = matches!(triple.architecture, Architecture::Wasm32);
|
||||
let cross_compile = target != Target::default();
|
||||
let targeting_wasm = matches!(target.architecture(), Architecture::Wasm32);
|
||||
|
||||
matches.get_flag(FLAG_PREBUILT) ||
|
||||
// When compiling for a different target, assume a prebuilt platform.
|
||||
|
@ -862,11 +858,11 @@ pub fn build(
|
|||
fuzz,
|
||||
};
|
||||
|
||||
let load_config = standard_load_config(&triple, build_ordering, threading);
|
||||
let load_config = standard_load_config(target, build_ordering, threading);
|
||||
|
||||
let res_binary_path = build_file(
|
||||
&arena,
|
||||
&triple,
|
||||
target,
|
||||
path.to_owned(),
|
||||
code_gen_options,
|
||||
emit_timings,
|
||||
|
@ -933,7 +929,7 @@ pub fn build(
|
|||
// ManuallyDrop will leak the bytes because we don't drop manually
|
||||
let bytes = &ManuallyDrop::new(std::fs::read(&binary_path).unwrap());
|
||||
|
||||
roc_run(&arena, opt_level, triple, args, bytes, expect_metadata)
|
||||
roc_run(&arena, opt_level, target, args, bytes, expect_metadata)
|
||||
}
|
||||
BuildAndRunIfNoErrors => {
|
||||
if problems.fatally_errored {
|
||||
|
@ -968,7 +964,7 @@ pub fn build(
|
|||
// ManuallyDrop will leak the bytes because we don't drop manually
|
||||
let bytes = &ManuallyDrop::new(std::fs::read(&binary_path).unwrap());
|
||||
|
||||
roc_run(&arena, opt_level, triple, args, bytes, expect_metadata)
|
||||
roc_run(&arena, opt_level, target, args, bytes, expect_metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -982,12 +978,12 @@ pub fn build(
|
|||
fn roc_run<'a, I: IntoIterator<Item = &'a OsStr>>(
|
||||
arena: &Bump,
|
||||
opt_level: OptLevel,
|
||||
triple: Triple,
|
||||
target: Target,
|
||||
args: I,
|
||||
binary_bytes: &[u8],
|
||||
expect_metadata: ExpectMetadata,
|
||||
) -> io::Result<i32> {
|
||||
match triple.architecture {
|
||||
match target.architecture() {
|
||||
Architecture::Wasm32 => {
|
||||
let executable = roc_run_executable_file_path(binary_bytes)?;
|
||||
let path = executable.as_path();
|
||||
|
|
|
@ -15,7 +15,7 @@ use roc_gen_dev::AssemblyBackendMode;
|
|||
use roc_gen_llvm::llvm::build::LlvmBackendMode;
|
||||
use roc_load::{FunctionKind, LoadingProblem, Threading};
|
||||
use roc_packaging::cache::{self, RocCacheDir};
|
||||
use roc_target::{get_target_triple_str, Target};
|
||||
use roc_target::Target;
|
||||
use std::fs::{self, FileType};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -49,7 +49,7 @@ fn main() -> io::Result<()> {
|
|||
&matches,
|
||||
&subcommands,
|
||||
BuildConfig::BuildAndRunIfNoErrors,
|
||||
Triple::host(),
|
||||
Triple::host().into(),
|
||||
None,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
LinkType::Executable,
|
||||
|
@ -64,7 +64,7 @@ fn main() -> io::Result<()> {
|
|||
matches,
|
||||
&subcommands,
|
||||
BuildConfig::BuildAndRun,
|
||||
Triple::host(),
|
||||
Triple::host().into(),
|
||||
None,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
LinkType::Executable,
|
||||
|
@ -77,7 +77,7 @@ fn main() -> io::Result<()> {
|
|||
}
|
||||
Some((CMD_TEST, matches)) => {
|
||||
if matches.contains_id(ROC_FILE) {
|
||||
test(matches, Triple::host())
|
||||
test(matches, Triple::host().into())
|
||||
} else {
|
||||
eprintln!("What .roc file do you want to test? Specify it at the end of the `roc test` command.");
|
||||
|
||||
|
@ -90,7 +90,7 @@ fn main() -> io::Result<()> {
|
|||
matches,
|
||||
&subcommands,
|
||||
BuildConfig::BuildAndRunIfNoErrors,
|
||||
Triple::host(),
|
||||
Triple::host().into(),
|
||||
None,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
LinkType::Executable,
|
||||
|
@ -130,7 +130,7 @@ fn main() -> io::Result<()> {
|
|||
roc_linker::generate_stub_lib(
|
||||
input_path,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
&target.to_triple(),
|
||||
target,
|
||||
function_kind,
|
||||
);
|
||||
Ok(0)
|
||||
|
@ -142,24 +142,22 @@ fn main() -> io::Result<()> {
|
|||
.and_then(|s| Target::from_str(s).ok())
|
||||
.unwrap_or_default();
|
||||
|
||||
let triple = target.to_triple();
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
let (platform_path, stub_lib, stub_dll_symbols) = roc_linker::generate_stub_lib(
|
||||
input_path,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
&triple,
|
||||
target,
|
||||
function_kind,
|
||||
);
|
||||
|
||||
// TODO: pipeline the executable location through here.
|
||||
// Currently it is essentally hardcoded as platform_path/dynhost.
|
||||
roc_linker::preprocess_host(
|
||||
&triple,
|
||||
target,
|
||||
&platform_path.with_file_name("main.roc"),
|
||||
// The target triple string must be derived from the triple to convert from the generic
|
||||
// `system` target to the exact specific target.
|
||||
&platform_path
|
||||
.with_file_name(format!("{}.rh", get_target_triple_str(&triple).unwrap())),
|
||||
&platform_path.with_file_name(format!("{}.rh", target)),
|
||||
&stub_lib,
|
||||
&stub_dll_symbols,
|
||||
);
|
||||
|
@ -184,7 +182,7 @@ fn main() -> io::Result<()> {
|
|||
matches,
|
||||
&subcommands,
|
||||
BuildConfig::BuildOnly,
|
||||
target.to_triple(),
|
||||
target,
|
||||
out_path,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
link_type,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::target::{arch_str, target_zig_str};
|
||||
use crate::target::arch_str;
|
||||
use libloading::{Error, Library};
|
||||
use roc_command_utils::{cargo, clang, rustup, zig};
|
||||
use roc_debug_flags;
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use roc_target::{Architecture, OperatingSystem, Target};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::DirEntry;
|
||||
|
@ -11,7 +12,6 @@ use std::io;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::{self, Child, Command};
|
||||
use std::{env, fs};
|
||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||
use wasi_libc_sys::{WASI_COMPILER_RT_PATH, WASI_LIBC_PATH};
|
||||
|
||||
pub use roc_linker::LinkType;
|
||||
|
@ -28,46 +28,33 @@ pub enum LinkingStrategy {
|
|||
|
||||
/// input_paths can include the host as well as the app. e.g. &["host.o", "roc_app.o"]
|
||||
pub fn link(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
output_path: PathBuf,
|
||||
input_paths: &[&str],
|
||||
link_type: LinkType,
|
||||
) -> io::Result<(Child, PathBuf)> {
|
||||
match target {
|
||||
Triple {
|
||||
architecture: Architecture::Wasm32,
|
||||
..
|
||||
} => link_wasm32(target, output_path, input_paths, link_type),
|
||||
Triple {
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => link_linux(target, output_path, input_paths, link_type),
|
||||
Triple {
|
||||
operating_system: OperatingSystem::Darwin,
|
||||
..
|
||||
} => link_macos(target, output_path, input_paths, link_type),
|
||||
Triple {
|
||||
operating_system: OperatingSystem::Windows,
|
||||
..
|
||||
} => link_windows(target, output_path, input_paths, link_type),
|
||||
match target.arch_os() {
|
||||
(Architecture::Wasm32, _) => link_wasm32(target, output_path, input_paths, link_type),
|
||||
(_, OperatingSystem::Linux) => link_linux(target, output_path, input_paths, link_type),
|
||||
(_, OperatingSystem::Mac) => link_macos(target, output_path, input_paths, link_type),
|
||||
(_, OperatingSystem::Windows) => link_windows(output_path, input_paths, link_type),
|
||||
_ => internal_error!("TODO gracefully handle unsupported target: {:?}", target),
|
||||
}
|
||||
}
|
||||
|
||||
/// Same format as the precompiled host filename, except with a file extension like ".o" or ".obj"
|
||||
pub fn legacy_host_file(target: &Triple, platform_main_roc: &Path) -> Option<PathBuf> {
|
||||
let os = roc_target::OperatingSystem::from(target.operating_system);
|
||||
let lib_ext = os.static_library_file_ext();
|
||||
pub fn legacy_host_file(target: Target, platform_main_roc: &Path) -> PathBuf {
|
||||
let lib_ext = target.static_library_file_ext();
|
||||
|
||||
let file_name = roc_linker::preprocessed_host_filename(target)?
|
||||
let file_name = roc_linker::preprocessed_host_filename(target)
|
||||
.replace(roc_linker::PRECOMPILED_HOST_EXT, lib_ext);
|
||||
|
||||
let lib_path = platform_main_roc.with_file_name(file_name);
|
||||
if lib_path.exists() {
|
||||
Some(lib_path)
|
||||
lib_path
|
||||
} else {
|
||||
let obj_ext = os.object_file_ext();
|
||||
Some(lib_path.with_extension(obj_ext))
|
||||
let obj_ext = target.object_file_ext();
|
||||
lib_path.with_extension(obj_ext)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,7 +303,7 @@ pub fn build_zig_host_wasm32(
|
|||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn build_c_host_native(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
env_path: &str,
|
||||
env_home: &str,
|
||||
env_cpath: &str,
|
||||
|
@ -335,7 +322,7 @@ pub fn build_c_host_native(
|
|||
.args(sources)
|
||||
.args(["-o", dest]);
|
||||
if let Some(shared_lib_path) = shared_lib_path {
|
||||
match target.operating_system {
|
||||
match target.operating_system() {
|
||||
OperatingSystem::Windows => {
|
||||
// just use zig as a C compiler
|
||||
|
||||
|
@ -347,7 +334,7 @@ pub fn build_c_host_native(
|
|||
env_home,
|
||||
dest,
|
||||
sources[0],
|
||||
get_target_str(target),
|
||||
"native",
|
||||
opt_level,
|
||||
Some(shared_lib_path),
|
||||
builtins_host_path,
|
||||
|
@ -406,7 +393,7 @@ pub fn build_swift_host_native(
|
|||
.env("HOME", env_home);
|
||||
|
||||
match arch {
|
||||
Architecture::Aarch64(_) => command.arg("-arm64"),
|
||||
Architecture::Aarch64 => command.arg("-arm64"),
|
||||
_ => command.arg(format!("-{arch}")),
|
||||
};
|
||||
|
||||
|
@ -437,7 +424,7 @@ pub fn build_swift_host_native(
|
|||
|
||||
pub fn rebuild_host(
|
||||
opt_level: OptLevel,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_main_roc: &Path,
|
||||
shared_lib_path: Option<&Path>,
|
||||
) -> PathBuf {
|
||||
|
@ -450,14 +437,12 @@ pub fn rebuild_host(
|
|||
let swift_host_src = platform_main_roc.with_file_name("host.swift");
|
||||
let swift_host_header_src = platform_main_roc.with_file_name("host.h");
|
||||
|
||||
let os = roc_target::OperatingSystem::from(target.operating_system);
|
||||
let executable_extension = match os {
|
||||
roc_target::OperatingSystem::Windows => "exe",
|
||||
roc_target::OperatingSystem::Unix => "",
|
||||
roc_target::OperatingSystem::Wasi => "",
|
||||
let executable_extension = match target.operating_system() {
|
||||
OperatingSystem::Windows => "exe",
|
||||
_ => "",
|
||||
};
|
||||
|
||||
let host_dest = if matches!(target.architecture, Architecture::Wasm32) {
|
||||
let host_dest = if matches!(target.architecture(), Architecture::Wasm32) {
|
||||
if matches!(opt_level, OptLevel::Development) {
|
||||
platform_main_roc.with_extension("o")
|
||||
} else {
|
||||
|
@ -468,7 +453,7 @@ pub fn rebuild_host(
|
|||
.with_file_name("dynhost")
|
||||
.with_extension(executable_extension)
|
||||
} else {
|
||||
legacy_host_file(target, platform_main_roc).unwrap()
|
||||
legacy_host_file(target, platform_main_roc)
|
||||
};
|
||||
|
||||
let env_path = env::var("PATH").unwrap_or_else(|_| "".to_string());
|
||||
|
@ -480,7 +465,7 @@ pub fn rebuild_host(
|
|||
|
||||
if zig_host_src.exists() {
|
||||
// Compile host.zig
|
||||
let zig_cmd = match target.architecture {
|
||||
let zig_cmd = match target.architecture() {
|
||||
Architecture::Wasm32 => {
|
||||
let emit_bin = if matches!(opt_level, OptLevel::Development) {
|
||||
format!("-femit-bin={}", host_dest.to_str().unwrap())
|
||||
|
@ -501,12 +486,12 @@ pub fn rebuild_host(
|
|||
&env_home,
|
||||
host_dest.to_str().unwrap(),
|
||||
zig_host_src.to_str().unwrap(),
|
||||
get_target_str(target),
|
||||
"native",
|
||||
opt_level,
|
||||
shared_lib_path,
|
||||
builtins_host_tempfile.path(),
|
||||
),
|
||||
Architecture::X86_32(_) => build_zig_host_native(
|
||||
Architecture::X86_32 => build_zig_host_native(
|
||||
&env_path,
|
||||
&env_home,
|
||||
host_dest.to_str().unwrap(),
|
||||
|
@ -516,17 +501,17 @@ pub fn rebuild_host(
|
|||
shared_lib_path,
|
||||
builtins_host_tempfile.path(),
|
||||
),
|
||||
Architecture::Aarch64(_) => build_zig_host_native(
|
||||
Architecture::Aarch64 => build_zig_host_native(
|
||||
&env_path,
|
||||
&env_home,
|
||||
host_dest.to_str().unwrap(),
|
||||
zig_host_src.to_str().unwrap(),
|
||||
target_zig_str(target),
|
||||
"native",
|
||||
opt_level,
|
||||
shared_lib_path,
|
||||
builtins_host_tempfile.path(),
|
||||
),
|
||||
_ => internal_error!("Unsupported architecture {:?}", target.architecture),
|
||||
_ => internal_error!("Unsupported architecture {:?}", target.architecture()),
|
||||
};
|
||||
|
||||
run_build_command(zig_cmd, "host.zig", 0);
|
||||
|
@ -714,7 +699,7 @@ pub fn rebuild_host(
|
|||
swift_host_header_src
|
||||
.exists()
|
||||
.then(|| swift_host_header_src.to_str().unwrap()),
|
||||
target.architecture,
|
||||
target.architecture(),
|
||||
);
|
||||
|
||||
run_build_command(swiftc_cmd, "host.swift", 0);
|
||||
|
@ -784,16 +769,6 @@ fn find_in_folder_or_subfolders(path: &PathBuf, folder_to_find: &str) -> Vec<Dir
|
|||
matching_dirs
|
||||
}
|
||||
|
||||
fn get_target_str(target: &Triple) -> &str {
|
||||
if target.operating_system == OperatingSystem::Windows
|
||||
&& target.environment == target_lexicon::Environment::Gnu
|
||||
{
|
||||
"x86_64-windows-gnu"
|
||||
} else {
|
||||
"native"
|
||||
}
|
||||
}
|
||||
|
||||
fn nix_paths() -> Vec<String> {
|
||||
let mut paths = vec![];
|
||||
|
||||
|
@ -862,12 +837,12 @@ fn extra_link_flags() -> Vec<String> {
|
|||
}
|
||||
|
||||
fn link_linux(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
output_path: PathBuf,
|
||||
input_paths: &[&str],
|
||||
link_type: LinkType,
|
||||
) -> io::Result<(Child, PathBuf)> {
|
||||
let architecture = format!("{}-linux-gnu", target.architecture);
|
||||
let architecture = format!("{}-linux-gnu", target.architecture());
|
||||
|
||||
// Command::new("cp")
|
||||
// .args(&[input_paths[0], "/home/folkertdev/roc/wasm/host.o"])
|
||||
|
@ -879,7 +854,7 @@ fn link_linux(
|
|||
// .output()
|
||||
// .unwrap();
|
||||
|
||||
if let Architecture::X86_32(_) = target.architecture {
|
||||
if let Architecture::X86_32 = target.architecture() {
|
||||
return Ok((
|
||||
zig()
|
||||
.args(["build-exe"])
|
||||
|
@ -971,7 +946,7 @@ fn link_linux(
|
|||
scrt1_path.to_string_lossy(),
|
||||
);
|
||||
|
||||
let ld_linux_path = match target.architecture {
|
||||
let ld_linux_path = match target.architecture() {
|
||||
Architecture::X86_64 => {
|
||||
// give preference to nix_path if it's defined, this prevents bugs
|
||||
if let Some(nix_glibc_path) = nix_glibc_path_opt() {
|
||||
|
@ -983,10 +958,10 @@ fn link_linux(
|
|||
build_path_or_panic(["/lib64", "ld-linux-x86-64.so.2"])
|
||||
}
|
||||
}
|
||||
Architecture::Aarch64(_) => build_path_or_panic(["/lib", "ld-linux-aarch64.so.1"]),
|
||||
Architecture::Aarch64 => build_path_or_panic(["/lib", "ld-linux-aarch64.so.1"]),
|
||||
_ => internal_error!(
|
||||
"TODO gracefully handle unsupported linux architecture: {:?}",
|
||||
target.architecture
|
||||
target.architecture()
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -1083,7 +1058,7 @@ fn link_linux(
|
|||
}
|
||||
|
||||
fn link_macos(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
output_path: PathBuf,
|
||||
input_paths: &[&str],
|
||||
link_type: LinkType,
|
||||
|
@ -1100,9 +1075,9 @@ fn link_macos(
|
|||
LinkType::None => internal_error!("link_macos should not be called with link type of none"),
|
||||
};
|
||||
|
||||
let arch = match target.architecture {
|
||||
Architecture::Aarch64(_) => "arm64".to_string(),
|
||||
_ => target.architecture.to_string(),
|
||||
let arch = match target.architecture() {
|
||||
Architecture::Aarch64 => "arm64".to_string(),
|
||||
_ => target.architecture().to_string(),
|
||||
};
|
||||
|
||||
let mut ld_command = Command::new("ld");
|
||||
|
@ -1177,8 +1152,8 @@ fn link_macos(
|
|||
|
||||
let mut ld_child = ld_command.spawn()?;
|
||||
|
||||
match target.architecture {
|
||||
Architecture::Aarch64(_) => {
|
||||
match target.architecture() {
|
||||
Architecture::Aarch64 => {
|
||||
ld_child.wait()?;
|
||||
|
||||
let mut codesign_cmd = Command::new("codesign");
|
||||
|
@ -1214,7 +1189,7 @@ fn get_macos_version() -> String {
|
|||
}
|
||||
|
||||
fn link_wasm32(
|
||||
_target: &Triple,
|
||||
_target: Target,
|
||||
output_path: PathBuf,
|
||||
input_paths: &[&str],
|
||||
_link_type: LinkType,
|
||||
|
@ -1249,7 +1224,6 @@ fn link_wasm32(
|
|||
}
|
||||
|
||||
fn link_windows(
|
||||
target: &Triple,
|
||||
output_path: PathBuf,
|
||||
input_paths: &[&str],
|
||||
link_type: LinkType,
|
||||
|
@ -1282,7 +1256,7 @@ fn link_windows(
|
|||
.args(input_paths)
|
||||
.args([
|
||||
"-target",
|
||||
get_target_str(target),
|
||||
"native",
|
||||
"--subsystem",
|
||||
"console",
|
||||
"-lc",
|
||||
|
@ -1298,7 +1272,7 @@ fn link_windows(
|
|||
|
||||
pub fn llvm_module_to_dylib(
|
||||
module: &inkwell::module::Module,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
opt_level: OptLevel,
|
||||
) -> Result<Library, Error> {
|
||||
use crate::target::{self, convert_opt_level};
|
||||
|
@ -1322,7 +1296,7 @@ pub fn llvm_module_to_dylib(
|
|||
|
||||
// Link app.o into a dylib - e.g. app.so or app.dylib
|
||||
let (mut child, dylib_path) = link(
|
||||
&Triple::host(),
|
||||
target,
|
||||
app_o_file.clone(),
|
||||
&[app_o_file.to_str().unwrap()],
|
||||
LinkType::Dylib,
|
||||
|
@ -1339,7 +1313,7 @@ pub fn llvm_module_to_dylib(
|
|||
// Load the dylib
|
||||
let path = dylib_path.as_path().to_str().unwrap();
|
||||
|
||||
if matches!(target.architecture, Architecture::Aarch64(_)) {
|
||||
if matches!(target.architecture(), Architecture::Aarch64) {
|
||||
// On AArch64 darwin machines, calling `ldopen` on Roc-generated libs from multiple threads
|
||||
// sometimes fails with
|
||||
// cannot dlopen until fork() handlers have completed
|
||||
|
|
|
@ -17,7 +17,7 @@ use roc_reporting::{
|
|||
cli::{report_problems, Problems},
|
||||
report::{RenderTarget, DEFAULT_PALETTE},
|
||||
};
|
||||
use roc_target::{OperatingSystem, TargetInfo};
|
||||
use roc_target::{Architecture, Target};
|
||||
use std::ffi::OsStr;
|
||||
use std::ops::Deref;
|
||||
use std::{
|
||||
|
@ -25,7 +25,6 @@ use std::{
|
|||
thread::JoinHandle,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
#[cfg(feature = "target-wasm32")]
|
||||
use roc_collections::all::MutSet;
|
||||
|
@ -96,7 +95,7 @@ pub fn gen_from_mono_module<'a>(
|
|||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
roc_file_path: &Path,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
code_gen_options: CodeGenOptions,
|
||||
preprocessed_host_path: &Path,
|
||||
wasm_dev_stack_bytes: Option<u32>,
|
||||
|
@ -146,7 +145,7 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
roc_file_path: &Path,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
opt_level: OptLevel,
|
||||
backend_mode: LlvmBackendMode,
|
||||
emit_debug_info: bool,
|
||||
|
@ -162,7 +161,6 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
let all_code_gen_start = Instant::now();
|
||||
|
||||
// Generate the binary
|
||||
let target_info = roc_target::TargetInfo::from(target);
|
||||
let context = Context::create();
|
||||
let module = arena.alloc(module_from_builtins(target, &context, "app"));
|
||||
|
||||
|
@ -210,7 +208,7 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
context: &context,
|
||||
interns: loaded.interns,
|
||||
module,
|
||||
target_info,
|
||||
target,
|
||||
mode: backend_mode,
|
||||
|
||||
exposed_to_host: loaded
|
||||
|
@ -387,9 +385,8 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
}
|
||||
|
||||
// Emit the .o file
|
||||
use target_lexicon::Architecture;
|
||||
match target.architecture {
|
||||
Architecture::X86_64 | Architecture::X86_32(_) | Architecture::Aarch64(_) => {
|
||||
match target.architecture() {
|
||||
Architecture::X86_64 | Architecture::X86_32 | Architecture::Aarch64 => {
|
||||
let reloc = RelocMode::PIC;
|
||||
let target_machine =
|
||||
target::target_machine(target, convert_opt_level(opt_level), reloc).unwrap();
|
||||
|
@ -405,7 +402,7 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
}
|
||||
_ => internal_error!(
|
||||
"TODO gracefully handle unsupported architecture: {:?}",
|
||||
target.architecture
|
||||
target.architecture()
|
||||
),
|
||||
}
|
||||
};
|
||||
|
@ -432,21 +429,19 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
fn gen_from_mono_module_dev<'a>(
|
||||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
preprocessed_host_path: &Path,
|
||||
wasm_dev_stack_bytes: Option<u32>,
|
||||
backend_mode: AssemblyBackendMode,
|
||||
) -> GenFromMono<'a> {
|
||||
use target_lexicon::Architecture;
|
||||
|
||||
match target.architecture {
|
||||
match target.architecture() {
|
||||
Architecture::Wasm32 => gen_from_mono_module_dev_wasm32(
|
||||
arena,
|
||||
loaded,
|
||||
preprocessed_host_path,
|
||||
wasm_dev_stack_bytes,
|
||||
),
|
||||
Architecture::X86_64 | Architecture::Aarch64(_) => {
|
||||
Architecture::X86_64 | Architecture::Aarch64 => {
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target, backend_mode)
|
||||
}
|
||||
_ => todo!(),
|
||||
|
@ -457,15 +452,13 @@ fn gen_from_mono_module_dev<'a>(
|
|||
pub fn gen_from_mono_module_dev<'a>(
|
||||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
_host_input_path: &Path,
|
||||
_wasm_dev_stack_bytes: Option<u32>,
|
||||
backend_mode: AssemblyBackendMode,
|
||||
) -> GenFromMono<'a> {
|
||||
use target_lexicon::Architecture;
|
||||
|
||||
match target.architecture {
|
||||
Architecture::X86_64 | Architecture::Aarch64(_) => {
|
||||
match target.architecture() {
|
||||
Architecture::X86_64 | Architecture::Aarch64 => {
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target, backend_mode)
|
||||
}
|
||||
_ => todo!(),
|
||||
|
@ -549,7 +542,7 @@ fn gen_from_mono_module_dev_wasm32<'a>(
|
|||
fn gen_from_mono_module_dev_assembly<'a>(
|
||||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
backend_mode: AssemblyBackendMode,
|
||||
) -> GenFromMono<'a> {
|
||||
let all_code_gen_start = Instant::now();
|
||||
|
@ -694,12 +687,10 @@ pub fn handle_loading_problem(problem: LoadingProblem) -> std::io::Result<i32> {
|
|||
}
|
||||
|
||||
pub fn standard_load_config(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
order: BuildOrdering,
|
||||
threading: Threading,
|
||||
) -> LoadConfig {
|
||||
let target_info = TargetInfo::from(target);
|
||||
|
||||
let exec_mode = match order {
|
||||
BuildOrdering::BuildIfChecks => ExecutionMode::ExecutableIfCheck,
|
||||
BuildOrdering::AlwaysBuild => ExecutionMode::Executable,
|
||||
|
@ -717,7 +708,7 @@ pub fn standard_load_config(
|
|||
};
|
||||
|
||||
LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render: RenderTarget::ColorTerminal,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
@ -729,7 +720,7 @@ pub fn standard_load_config(
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn build_file<'a>(
|
||||
arena: &'a Bump,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
app_module_path: PathBuf,
|
||||
code_gen_options: CodeGenOptions,
|
||||
emit_timings: bool,
|
||||
|
@ -767,7 +758,7 @@ pub fn build_file<'a>(
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
fn build_loaded_file<'a>(
|
||||
arena: &'a Bump,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
app_module_path: PathBuf,
|
||||
code_gen_options: CodeGenOptions,
|
||||
emit_timings: bool,
|
||||
|
@ -779,8 +770,6 @@ fn build_loaded_file<'a>(
|
|||
compilation_start: Instant,
|
||||
out_path: Option<&Path>,
|
||||
) -> Result<BuiltFile<'a>, BuildFileError<'a>> {
|
||||
let operating_system = roc_target::OperatingSystem::from(target.operating_system);
|
||||
|
||||
let platform_main_roc = match &loaded.entry_point {
|
||||
EntryPoint::Executable { platform_path, .. } => platform_path.to_path_buf(),
|
||||
_ => unreachable!(),
|
||||
|
@ -792,9 +781,9 @@ fn build_loaded_file<'a>(
|
|||
|
||||
if is_platform_prebuilt && linking_strategy == LinkingStrategy::Surgical {
|
||||
// Fallback to legacy linking if the preprocessed host file does not exist, but a legacy host does exist.
|
||||
let preprocessed_host_path = platform_main_roc
|
||||
.with_file_name(roc_linker::preprocessed_host_filename(target).unwrap());
|
||||
let legacy_host_path = legacy_host_file(target, &platform_main_roc).unwrap();
|
||||
let preprocessed_host_path =
|
||||
platform_main_roc.with_file_name(roc_linker::preprocessed_host_filename(target));
|
||||
let legacy_host_path = legacy_host_file(target, &platform_main_roc);
|
||||
if !preprocessed_host_path.exists() && legacy_host_path.exists() {
|
||||
linking_strategy = LinkingStrategy::Legacy;
|
||||
}
|
||||
|
@ -802,15 +791,15 @@ fn build_loaded_file<'a>(
|
|||
|
||||
// the preprocessed host is stored beside the platform's main.roc
|
||||
let preprocessed_host_path = if linking_strategy == LinkingStrategy::Legacy {
|
||||
if let roc_target::OperatingSystem::Wasi = operating_system {
|
||||
if target == Target::Wasm32 {
|
||||
// when compiling a wasm application, we implicitly assume here that the host is in zig
|
||||
// and has a file called "host.zig"
|
||||
platform_main_roc.with_file_name("host.zig")
|
||||
} else {
|
||||
legacy_host_file(target, &platform_main_roc).unwrap()
|
||||
legacy_host_file(target, &platform_main_roc)
|
||||
}
|
||||
} else {
|
||||
platform_main_roc.with_file_name(roc_linker::preprocessed_host_filename(target).unwrap())
|
||||
platform_main_roc.with_file_name(roc_linker::preprocessed_host_filename(target))
|
||||
};
|
||||
|
||||
let output_exe_path = match out_path {
|
||||
|
@ -841,22 +830,12 @@ fn build_loaded_file<'a>(
|
|||
if ends_with_sep {
|
||||
let filename = app_module_path.file_name().unwrap_or_default();
|
||||
|
||||
with_output_extension(
|
||||
&path.join(filename),
|
||||
operating_system,
|
||||
linking_strategy,
|
||||
link_type,
|
||||
)
|
||||
with_output_extension(&path.join(filename), target, linking_strategy, link_type)
|
||||
} else {
|
||||
path.to_path_buf()
|
||||
}
|
||||
}
|
||||
None => with_output_extension(
|
||||
&app_module_path,
|
||||
operating_system,
|
||||
linking_strategy,
|
||||
link_type,
|
||||
),
|
||||
None => with_output_extension(&app_module_path, target, linking_strategy, link_type),
|
||||
};
|
||||
|
||||
// We don't need to spawn a rebuild thread when using a prebuilt host.
|
||||
|
@ -1018,13 +997,13 @@ fn build_loaded_file<'a>(
|
|||
std::fs::write(&output_exe_path, &*roc_app_bytes).unwrap();
|
||||
}
|
||||
(LinkingStrategy::Legacy, _) => {
|
||||
let extension = if matches!(operating_system, roc_target::OperatingSystem::Wasi) {
|
||||
let extension = if target == Target::Wasm32 {
|
||||
// Legacy linker is only by used llvm wasm backend, not dev.
|
||||
// llvm wasm backend directly emits a bitcode file when targeting wasi, not a `.o` or `.wasm` file.
|
||||
// If we set the extension wrong, zig will print a ton of warnings when linking.
|
||||
"bc"
|
||||
} else {
|
||||
operating_system.object_file_ext()
|
||||
target.object_file_ext()
|
||||
};
|
||||
let app_o_file = tempfile::Builder::new()
|
||||
.prefix("roc_app")
|
||||
|
@ -1124,10 +1103,9 @@ fn spawn_rebuild_thread(
|
|||
platform_main_roc: PathBuf,
|
||||
preprocessed_host_path: PathBuf,
|
||||
output_exe_path: PathBuf,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
dll_stub_symbols: Vec<String>,
|
||||
) -> std::thread::JoinHandle<u128> {
|
||||
let thread_local_target = target.clone();
|
||||
std::thread::spawn(move || {
|
||||
// Printing to stderr because we want stdout to contain only the output of the roc program.
|
||||
// We are aware of the trade-offs.
|
||||
|
@ -1138,19 +1116,14 @@ fn spawn_rebuild_thread(
|
|||
|
||||
match linking_strategy {
|
||||
LinkingStrategy::Additive => {
|
||||
let host_dest = rebuild_host(
|
||||
opt_level,
|
||||
&thread_local_target,
|
||||
platform_main_roc.as_path(),
|
||||
None,
|
||||
);
|
||||
let host_dest = rebuild_host(opt_level, target, platform_main_roc.as_path(), None);
|
||||
|
||||
preprocess_host_wasm32(host_dest.as_path(), &preprocessed_host_path);
|
||||
}
|
||||
LinkingStrategy::Surgical => {
|
||||
build_and_preprocess_host_lowlevel(
|
||||
opt_level,
|
||||
&thread_local_target,
|
||||
target,
|
||||
platform_main_roc.as_path(),
|
||||
preprocessed_host_path.as_path(),
|
||||
&dll_stub_symbols,
|
||||
|
@ -1161,12 +1134,7 @@ fn spawn_rebuild_thread(
|
|||
std::fs::copy(&preprocessed_host_path, output_exe_path.as_path()).unwrap();
|
||||
}
|
||||
LinkingStrategy::Legacy => {
|
||||
rebuild_host(
|
||||
opt_level,
|
||||
&thread_local_target,
|
||||
platform_main_roc.as_path(),
|
||||
None,
|
||||
);
|
||||
rebuild_host(opt_level, target, platform_main_roc.as_path(), None);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1144,7 @@ fn spawn_rebuild_thread(
|
|||
|
||||
pub fn build_and_preprocess_host(
|
||||
opt_level: OptLevel,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_main_roc: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
exposed_symbols: roc_linker::ExposedSymbols,
|
||||
|
@ -1194,7 +1162,7 @@ pub fn build_and_preprocess_host(
|
|||
|
||||
fn build_and_preprocess_host_lowlevel(
|
||||
opt_level: OptLevel,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_main_roc: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
stub_dll_symbols: &[String],
|
||||
|
@ -1227,12 +1195,12 @@ pub fn check_file<'a>(
|
|||
|
||||
// only used for generating errors. We don't do code generation, so hardcoding should be fine
|
||||
// we need monomorphization for when exhaustiveness checking
|
||||
let target_info = TargetInfo::default_x86_64();
|
||||
let target = Target::LinuxX64;
|
||||
|
||||
// Step 1: compile the app and generate the .o file
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
// TODO: we may not want this for just checking.
|
||||
function_kind: FunctionKind::LambdaSet,
|
||||
// TODO: expose this from CLI?
|
||||
|
@ -1295,7 +1263,7 @@ pub fn build_str_test<'a>(
|
|||
app_module_source: &'a str,
|
||||
assume_prebuild: bool,
|
||||
) -> Result<BuiltFile<'a>, BuildFileError<'a>> {
|
||||
let triple = target_lexicon::Triple::host();
|
||||
let target = target_lexicon::Triple::host().into();
|
||||
|
||||
let code_gen_options = CodeGenOptions {
|
||||
backend: CodeGenBackend::Llvm(LlvmBackendMode::Binary),
|
||||
|
@ -1314,7 +1282,7 @@ pub fn build_str_test<'a>(
|
|||
let build_ordering = BuildOrdering::AlwaysBuild;
|
||||
let threading = Threading::AtMost(2);
|
||||
|
||||
let load_config = standard_load_config(&triple, build_ordering, threading);
|
||||
let load_config = standard_load_config(target, build_ordering, threading);
|
||||
|
||||
let compilation_start = std::time::Instant::now();
|
||||
|
||||
|
@ -1331,7 +1299,7 @@ pub fn build_str_test<'a>(
|
|||
|
||||
build_loaded_file(
|
||||
arena,
|
||||
&triple,
|
||||
target,
|
||||
app_module_path.to_path_buf(),
|
||||
code_gen_options,
|
||||
emit_timings,
|
||||
|
@ -1347,15 +1315,15 @@ pub fn build_str_test<'a>(
|
|||
|
||||
fn with_output_extension(
|
||||
path: &Path,
|
||||
os: OperatingSystem,
|
||||
target: Target,
|
||||
linking_strategy: LinkingStrategy,
|
||||
link_type: LinkType,
|
||||
) -> PathBuf {
|
||||
match (linking_strategy, link_type) {
|
||||
(LinkingStrategy::Additive, _) | (LinkingStrategy::Legacy, LinkType::None) => {
|
||||
// Additive linking and no linking both output the object file type.
|
||||
path.with_extension(os.object_file_ext())
|
||||
path.with_extension(target.object_file_ext())
|
||||
}
|
||||
_ => path.with_extension(os.executable_file_ext().unwrap_or_default()),
|
||||
_ => path.with_extension(target.executable_file_ext().unwrap_or_default()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,121 +1,65 @@
|
|||
use inkwell::{
|
||||
targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine, TargetTriple},
|
||||
targets::{
|
||||
CodeModel, InitializationConfig, RelocMode, Target as LlvmTarget, TargetMachine,
|
||||
TargetTriple,
|
||||
},
|
||||
OptimizationLevel,
|
||||
};
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use target_lexicon::{Architecture, Environment, OperatingSystem, Triple};
|
||||
use roc_target::{Architecture, Target};
|
||||
|
||||
pub fn target_triple_str(target: &Triple) -> &'static str {
|
||||
pub fn target_triple_str(target: Target) -> &'static str {
|
||||
// Best guide I've found on how to determine these magic strings:
|
||||
//
|
||||
// https://stackoverflow.com/questions/15036909/clang-how-to-list-supported-target-architectures
|
||||
match target {
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => "x86_64-unknown-linux-gnu",
|
||||
Triple {
|
||||
architecture: Architecture::X86_32(target_lexicon::X86_32Architecture::I386),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => "i386-unknown-linux-gnu",
|
||||
Triple {
|
||||
architecture: Architecture::Wasm32,
|
||||
..
|
||||
} => "wasm32-unknown-unknown",
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(_),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => "aarch64-unknown-linux-gnu",
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(_),
|
||||
operating_system: OperatingSystem::Darwin,
|
||||
..
|
||||
} => "aarch64-apple-darwin",
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Darwin,
|
||||
..
|
||||
} => "x86_64-unknown-darwin10",
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Windows,
|
||||
..
|
||||
} => "x86_64-pc-windows-gnu",
|
||||
Target::LinuxArm64 => "aarch64-unknown-linux-gnu",
|
||||
Target::LinuxX32 => "i386-unknown-linux-gnu",
|
||||
Target::LinuxX64 => "x86_64-unknown-linux-gnu",
|
||||
Target::MacArm64 => "aarch64-apple-darwin",
|
||||
Target::MacX64 => "x86_64-unknown-darwin10",
|
||||
Target::Wasm32 => "wasm32-unknown-unknown",
|
||||
Target::WinX64 => "x86_64-pc-windows-gnu",
|
||||
_ => internal_error!("TODO gracefully handle unsupported target: {:?}", target),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn target_zig_str(target: &Triple) -> &'static str {
|
||||
pub fn target_zig_str(target: Target) -> &'static str {
|
||||
// Zig has its own architecture mappings, defined here:
|
||||
// https://github.com/ziglang/zig/blob/master/tools/process_headers.zig
|
||||
//
|
||||
// and an open proposal to unify them with the more typical "target triples":
|
||||
// https://github.com/ziglang/zig/issues/4911
|
||||
match target {
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
environment: Environment::Musl,
|
||||
..
|
||||
} => "x86_64-linux-musl",
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => "x86_64-linux-gnu",
|
||||
Triple {
|
||||
architecture: Architecture::X86_32(target_lexicon::X86_32Architecture::I386),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
environment: Environment::Musl,
|
||||
..
|
||||
} => "i386-linux-musl",
|
||||
Triple {
|
||||
architecture: Architecture::X86_32(target_lexicon::X86_32Architecture::I386),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => "i386-linux-gnu",
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(_),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => "aarch64-linux-gnu",
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Darwin,
|
||||
..
|
||||
} => "x86_64-macos-none",
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(_),
|
||||
operating_system: OperatingSystem::Darwin,
|
||||
..
|
||||
} => "aarch64-macos-none",
|
||||
Target::LinuxArm64 => "aarch64-linux-gnu",
|
||||
Target::LinuxX32 => "i386-linux-gnu",
|
||||
Target::LinuxX64 => "x86_64-linux-gnu",
|
||||
Target::MacArm64 => "aarch64-macos-none",
|
||||
Target::MacX64 => "x86_64-macos-none",
|
||||
_ => internal_error!("TODO gracefully handle unsupported target: {:?}", target),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_arch(target: &Triple) {
|
||||
match target.architecture {
|
||||
Architecture::X86_64 | Architecture::X86_32(_)
|
||||
pub fn init_arch(target: Target) {
|
||||
match target.architecture() {
|
||||
Architecture::X86_64 | Architecture::X86_32
|
||||
if cfg!(any(feature = "target-x86", feature = "target-x86_64")) =>
|
||||
{
|
||||
Target::initialize_x86(&InitializationConfig::default());
|
||||
LlvmTarget::initialize_x86(&InitializationConfig::default());
|
||||
}
|
||||
Architecture::Aarch64(_) if cfg!(feature = "target-aarch64") => {
|
||||
Target::initialize_aarch64(&InitializationConfig::default());
|
||||
Architecture::Aarch64 if cfg!(feature = "target-aarch64") => {
|
||||
LlvmTarget::initialize_aarch64(&InitializationConfig::default());
|
||||
}
|
||||
Architecture::Arm(_) if cfg!(feature = "target-arm") => {
|
||||
Target::initialize_arm(&InitializationConfig::default());
|
||||
Architecture::Aarch32 if cfg!(feature = "target-arm") => {
|
||||
LlvmTarget::initialize_arm(&InitializationConfig::default());
|
||||
}
|
||||
Architecture::Wasm32 if cfg!(feature = "target-wasm32") => {
|
||||
Target::initialize_webassembly(&InitializationConfig::default());
|
||||
LlvmTarget::initialize_webassembly(&InitializationConfig::default());
|
||||
}
|
||||
_ => internal_error!(
|
||||
"TODO gracefully handle unsupported target architecture: {:?}",
|
||||
target.architecture
|
||||
target.architecture()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -123,25 +67,25 @@ pub fn init_arch(target: &Triple) {
|
|||
/// NOTE: arch_str is *not* the same as the beginning of the magic target triple
|
||||
/// string! For example, if it's "x86-64" here, the magic target triple string
|
||||
/// will begin with "x86_64" (with an underscore) instead.
|
||||
pub fn arch_str(target: &Triple) -> &'static str {
|
||||
pub fn arch_str(target: Target) -> &'static str {
|
||||
// Best guide I've found on how to determine these magic strings:
|
||||
//
|
||||
// https://stackoverflow.com/questions/15036909/clang-how-to-list-supported-target-architectures
|
||||
match target.architecture {
|
||||
Architecture::X86_64 if cfg!(feature = "target-x86_64") => "x86-64",
|
||||
Architecture::X86_32(_) if cfg!(feature = "target-x86") => "x86",
|
||||
Architecture::Aarch64(_) if cfg!(feature = "target-aarch64") => "aarch64",
|
||||
Architecture::Arm(_) if cfg!(feature = "target-arm") => "arm",
|
||||
Architecture::Wasm32 if cfg!(feature = "target-webassembly") => "wasm32",
|
||||
match target.architecture() {
|
||||
roc_target::Architecture::X86_64 if cfg!(feature = "target-x86_64") => "x86-64",
|
||||
roc_target::Architecture::X86_32 if cfg!(feature = "target-x86") => "x86",
|
||||
roc_target::Architecture::Aarch64 if cfg!(feature = "target-aarch64") => "aarch64",
|
||||
roc_target::Architecture::Aarch32 if cfg!(feature = "target-arm") => "arm",
|
||||
roc_target::Architecture::Wasm32 if cfg!(feature = "target-webassembly") => "wasm32",
|
||||
_ => internal_error!(
|
||||
"TODO gracefully handle unsupported target architecture: {:?}",
|
||||
target.architecture
|
||||
target.architecture()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn target_machine(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
opt: OptimizationLevel,
|
||||
reloc: RelocMode,
|
||||
) -> Option<TargetMachine> {
|
||||
|
@ -150,11 +94,7 @@ pub fn target_machine(
|
|||
init_arch(target);
|
||||
|
||||
let code_model = match target {
|
||||
Triple {
|
||||
operating_system: OperatingSystem::Darwin,
|
||||
architecture: Architecture::Aarch64(_),
|
||||
..
|
||||
} => {
|
||||
Target::MacArm64 => {
|
||||
// We used to have a problem that LLVM 12 would not compile our programs without a large code model.
|
||||
// The reason was not totally clear to us, but one guess is a few special-cases in
|
||||
// llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (instructions)
|
||||
|
@ -168,7 +108,7 @@ pub fn target_machine(
|
|||
_ => CodeModel::Default,
|
||||
};
|
||||
|
||||
Target::from_name(arch).unwrap().create_target_machine(
|
||||
LlvmTarget::from_name(arch).unwrap().create_target_machine(
|
||||
&TargetTriple::create(target_triple_str(target)),
|
||||
"generic",
|
||||
"",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use roc_module::symbol::Symbol;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use std::ops::Index;
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
|
@ -38,7 +38,7 @@ impl FloatWidth {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn alignment_bytes(&self, target_info: TargetInfo) -> u32 {
|
||||
pub const fn alignment_bytes(&self, target: Target) -> u32 {
|
||||
use roc_target::Architecture::*;
|
||||
use FloatWidth::*;
|
||||
|
||||
|
@ -47,7 +47,7 @@ impl FloatWidth {
|
|||
// the compiler is targeting (e.g. what the Roc code will be compiled to).
|
||||
match self {
|
||||
F32 => 4,
|
||||
F64 => match target_info.architecture {
|
||||
F64 => match target.architecture() {
|
||||
X86_64 | Aarch64 | Wasm32 => 8,
|
||||
X86_32 | Aarch32 => 4,
|
||||
},
|
||||
|
@ -107,7 +107,7 @@ impl IntWidth {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn alignment_bytes(&self, target_info: TargetInfo) -> u32 {
|
||||
pub const fn alignment_bytes(&self, target: Target) -> u32 {
|
||||
use roc_target::Architecture;
|
||||
use IntWidth::*;
|
||||
|
||||
|
@ -118,7 +118,7 @@ impl IntWidth {
|
|||
U8 | I8 => 1,
|
||||
U16 | I16 => 2,
|
||||
U32 | I32 => 4,
|
||||
U64 | I64 => match target_info.architecture {
|
||||
U64 | I64 => match target.architecture() {
|
||||
Architecture::X86_64
|
||||
| Architecture::Aarch64
|
||||
| Architecture::Aarch32
|
||||
|
@ -131,7 +131,7 @@ impl IntWidth {
|
|||
//
|
||||
// however, rust does not always think that this is true
|
||||
// Our alignmets here are correct, but they will not match rust/zig/llvm until they update to llvm version 18.
|
||||
match target_info.architecture {
|
||||
match target.architecture() {
|
||||
Architecture::X86_64 | Architecture::Aarch64 | Architecture::X86_32 => 16,
|
||||
Architecture::Aarch32 | Architecture::Wasm32 => 8,
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use roc_mono::layout::{
|
|||
TagIdIntType, UnionLayout,
|
||||
};
|
||||
use roc_mono::low_level::HigherOrder;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub(crate) mod aarch64;
|
||||
|
@ -790,7 +790,7 @@ pub fn new_backend_64bit<
|
|||
CC: CallConv<GeneralReg, FloatReg, ASM>,
|
||||
>(
|
||||
env: &'r Env<'a>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
interns: &'r mut Interns,
|
||||
layout_interner: &'r mut STLayoutInterner<'a>,
|
||||
) -> Backend64Bit<'a, 'r, GeneralReg, FloatReg, ASM, CC> {
|
||||
|
@ -800,7 +800,7 @@ pub fn new_backend_64bit<
|
|||
env,
|
||||
interns,
|
||||
layout_interner,
|
||||
helper_proc_gen: CodeGenHelp::new(env.arena, target_info, env.module_id),
|
||||
helper_proc_gen: CodeGenHelp::new(env.arena, target, env.module_id),
|
||||
helper_proc_symbols: bumpalo::vec![in env.arena],
|
||||
caller_procs: bumpalo::vec![in env.arena],
|
||||
proc_name: None,
|
||||
|
@ -812,7 +812,7 @@ pub fn new_backend_64bit<
|
|||
free_map: MutMap::default(),
|
||||
literal_map: MutMap::default(),
|
||||
join_map: MutMap::default(),
|
||||
storage_manager: storage::new_storage_manager(env, target_info),
|
||||
storage_manager: storage::new_storage_manager(env, target),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -853,8 +853,8 @@ impl<
|
|||
fn relocations_mut(&mut self) -> &mut Vec<'a, Relocation> {
|
||||
&mut self.relocs
|
||||
}
|
||||
fn target_info(&self) -> TargetInfo {
|
||||
self.storage_manager.target_info
|
||||
fn target(&self) -> Target {
|
||||
self.storage_manager.target
|
||||
}
|
||||
fn module_interns_helpers_mut(
|
||||
&mut self,
|
||||
|
@ -3627,7 +3627,7 @@ impl<
|
|||
|
||||
// mask out the tag id bits
|
||||
let (unmasked_symbol, unmasked_reg) =
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target_info) {
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target) {
|
||||
(None, ptr_reg)
|
||||
} else {
|
||||
let (mask_symbol, mask_reg) = self.clear_tag_id(ptr_reg);
|
||||
|
@ -3728,7 +3728,7 @@ impl<
|
|||
|
||||
// mask out the tag id bits
|
||||
let (unmasked_symbol, unmasked_reg) =
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target_info) {
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target) {
|
||||
(None, ptr_reg)
|
||||
} else {
|
||||
let (mask_symbol, mask_reg) = self.clear_tag_id(ptr_reg);
|
||||
|
@ -4007,8 +4007,8 @@ impl<
|
|||
UnionLayout::Recursive(_) => {
|
||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, sym);
|
||||
|
||||
let target_info = self.storage_manager.target_info;
|
||||
if union_layout.stores_tag_id_as_data(target_info) {
|
||||
let target = self.storage_manager.target;
|
||||
if union_layout.stores_tag_id_as_data(target) {
|
||||
let offset = union_layout.tag_id_offset(self.interner()).unwrap() as i32;
|
||||
|
||||
let ptr_reg = self
|
||||
|
@ -4173,7 +4173,7 @@ impl<
|
|||
.unwrap();
|
||||
|
||||
let largest_variant =
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target_info) {
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target) {
|
||||
self.layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Struct(
|
||||
self.env.arena.alloc([largest_variant_fields, Layout::U8]),
|
||||
|
@ -4214,7 +4214,7 @@ impl<
|
|||
};
|
||||
|
||||
// finally, we need to tag the pointer
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target_info) {
|
||||
if union_layout.stores_tag_id_as_data(self.storage_manager.target) {
|
||||
// allocate space on the stack for the whole tag payload
|
||||
let scratch_space = self.debug_symbol("scratch_space");
|
||||
let (data_size, data_alignment) =
|
||||
|
@ -4290,7 +4290,7 @@ impl<
|
|||
let other_fields = tags[tag_id as usize];
|
||||
|
||||
let stores_tag_id_as_data =
|
||||
union_layout.stores_tag_id_as_data(self.storage_manager.target_info);
|
||||
union_layout.stores_tag_id_as_data(self.storage_manager.target);
|
||||
|
||||
let (largest_variant_fields, _largest_variant_size) = tags
|
||||
.iter()
|
||||
|
|
|
@ -14,7 +14,7 @@ use roc_mono::{
|
|||
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
|
||||
},
|
||||
};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use std::cmp::max;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
|
@ -92,7 +92,7 @@ pub struct StorageManager<
|
|||
phantom_cc: PhantomData<CC>,
|
||||
phantom_asm: PhantomData<ASM>,
|
||||
pub(crate) env: &'r Env<'a>,
|
||||
pub(crate) target_info: TargetInfo,
|
||||
pub(crate) target: Target,
|
||||
// Data about where each symbol is stored.
|
||||
symbol_storage_map: MutMap<Symbol, Storage<GeneralReg, FloatReg>>,
|
||||
|
||||
|
@ -137,13 +137,13 @@ pub fn new_storage_manager<
|
|||
CC: CallConv<GeneralReg, FloatReg, ASM>,
|
||||
>(
|
||||
env: &'r Env<'a>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
) -> StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC> {
|
||||
StorageManager {
|
||||
phantom_asm: PhantomData,
|
||||
phantom_cc: PhantomData,
|
||||
env,
|
||||
target_info,
|
||||
target,
|
||||
symbol_storage_map: MutMap::default(),
|
||||
allocation_map: MutMap::default(),
|
||||
join_param_map: MutMap::default(),
|
||||
|
|
|
@ -28,7 +28,7 @@ use roc_mono::list_element_layout;
|
|||
mod generic64;
|
||||
mod object_builder;
|
||||
pub use object_builder::build_module;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
mod run_roc;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -312,7 +312,7 @@ trait Backend<'a> {
|
|||
fn interns_mut(&mut self) -> &mut Interns;
|
||||
fn interner(&self) -> &STLayoutInterner<'a>;
|
||||
fn relocations_mut(&mut self) -> &mut Vec<'a, Relocation>;
|
||||
fn target_info(&self) -> TargetInfo;
|
||||
fn target(&self) -> Target;
|
||||
|
||||
fn interner_mut(&mut self) -> &mut STLayoutInterner<'a> {
|
||||
self.module_interns_helpers_mut().1
|
||||
|
|
|
@ -14,8 +14,7 @@ use roc_module::symbol::Interns;
|
|||
use roc_mono::ir::{Call, CallSpecId, Expr, UpdateModeId};
|
||||
use roc_mono::ir::{Proc, ProcLayout, Stmt};
|
||||
use roc_mono::layout::{LambdaName, Layout, LayoutIds, LayoutInterner, STLayoutInterner};
|
||||
use roc_target::TargetInfo;
|
||||
use target_lexicon::{Architecture as TargetArch, BinaryFormat as TargetBF, Triple};
|
||||
use roc_target::Target;
|
||||
|
||||
// This is used by some code below which is currently commented out.
|
||||
// See that code for more details!
|
||||
|
@ -27,7 +26,7 @@ pub fn build_module<'a, 'r>(
|
|||
env: &'r Env<'a>,
|
||||
interns: &'r mut Interns,
|
||||
layout_interner: &'r mut STLayoutInterner<'a>,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
procedures: MutMap<(symbol::Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) -> Object<'a> {
|
||||
let module_object = build_module_help(env, interns, layout_interner, target, procedures);
|
||||
|
@ -49,21 +48,17 @@ fn build_module_help<'a, 'r>(
|
|||
env: &'r Env<'a>,
|
||||
interns: &'r mut Interns,
|
||||
layout_interner: &'r mut STLayoutInterner<'a>,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
procedures: MutMap<(symbol::Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) -> Object<'a> {
|
||||
match target {
|
||||
Triple {
|
||||
architecture: TargetArch::X86_64,
|
||||
binary_format: TargetBF::Elf,
|
||||
..
|
||||
} if cfg!(feature = "target-x86_64") => {
|
||||
Target::LinuxX64 if cfg!(feature = "target-x86_64") => {
|
||||
let backend = new_backend_64bit::<
|
||||
x86_64::X86_64GeneralReg,
|
||||
x86_64::X86_64FloatReg,
|
||||
x86_64::X86_64Assembler,
|
||||
x86_64::X86_64SystemV,
|
||||
>(env, TargetInfo::default_x86_64(), interns, layout_interner);
|
||||
>(env, target, interns, layout_interner);
|
||||
// Newer version of `ld` require `.note.GNU-stack` for security reasons.
|
||||
// It specifies that we will not execute code stored on the stack.
|
||||
let mut object =
|
||||
|
@ -75,17 +70,13 @@ fn build_module_help<'a, 'r>(
|
|||
);
|
||||
build_object(procedures, backend, object)
|
||||
}
|
||||
Triple {
|
||||
architecture: TargetArch::X86_64,
|
||||
binary_format: TargetBF::Macho,
|
||||
..
|
||||
} if cfg!(feature = "target-x86_64") => {
|
||||
Target::MacX64 if cfg!(feature = "target-x86_64") => {
|
||||
let backend = new_backend_64bit::<
|
||||
x86_64::X86_64GeneralReg,
|
||||
x86_64::X86_64FloatReg,
|
||||
x86_64::X86_64Assembler,
|
||||
x86_64::X86_64SystemV,
|
||||
>(env, TargetInfo::default_x86_64(), interns, layout_interner);
|
||||
>(env, target, interns, layout_interner);
|
||||
build_object(
|
||||
procedures,
|
||||
backend,
|
||||
|
@ -96,53 +87,39 @@ fn build_module_help<'a, 'r>(
|
|||
),
|
||||
)
|
||||
}
|
||||
Triple {
|
||||
architecture: TargetArch::X86_64,
|
||||
binary_format: TargetBF::Coff,
|
||||
..
|
||||
} if cfg!(feature = "target-x86_64") => {
|
||||
Target::WinX64 if cfg!(feature = "target-x86_64") => {
|
||||
let backend = new_backend_64bit::<
|
||||
x86_64::X86_64GeneralReg,
|
||||
x86_64::X86_64FloatReg,
|
||||
x86_64::X86_64Assembler,
|
||||
x86_64::X86_64WindowsFastcall,
|
||||
>(env, TargetInfo::default_x86_64(), interns, layout_interner);
|
||||
>(env, target, interns, layout_interner);
|
||||
build_object(
|
||||
procedures,
|
||||
backend,
|
||||
Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little),
|
||||
)
|
||||
}
|
||||
Triple {
|
||||
architecture: TargetArch::Aarch64(_),
|
||||
binary_format: TargetBF::Elf,
|
||||
..
|
||||
} if cfg!(feature = "target-aarch64") => {
|
||||
let backend =
|
||||
new_backend_64bit::<
|
||||
Target::LinuxArm64 if cfg!(feature = "target-aarch64") => {
|
||||
let backend = new_backend_64bit::<
|
||||
aarch64::AArch64GeneralReg,
|
||||
aarch64::AArch64FloatReg,
|
||||
aarch64::AArch64Assembler,
|
||||
aarch64::AArch64Call,
|
||||
>(env, TargetInfo::default_aarch64(), interns, layout_interner);
|
||||
>(env, target, interns, layout_interner);
|
||||
build_object(
|
||||
procedures,
|
||||
backend,
|
||||
Object::new(BinaryFormat::Elf, Architecture::Aarch64, Endianness::Little),
|
||||
)
|
||||
}
|
||||
Triple {
|
||||
architecture: TargetArch::Aarch64(_),
|
||||
binary_format: TargetBF::Macho,
|
||||
..
|
||||
} if cfg!(feature = "target-aarch64") => {
|
||||
let backend =
|
||||
new_backend_64bit::<
|
||||
Target::MacArm64 if cfg!(feature = "target-aarch64") => {
|
||||
let backend = new_backend_64bit::<
|
||||
aarch64::AArch64GeneralReg,
|
||||
aarch64::AArch64FloatReg,
|
||||
aarch64::AArch64Assembler,
|
||||
aarch64::AArch64Call,
|
||||
>(env, TargetInfo::default_aarch64(), interns, layout_interner);
|
||||
>(env, target, interns, layout_interner);
|
||||
build_object(
|
||||
procedures,
|
||||
backend,
|
||||
|
@ -394,7 +371,7 @@ fn generate_wrapper<'a, B: Backend<'a>>(
|
|||
};
|
||||
output.add_symbol(symbol);
|
||||
if let Some(sym_id) = output.symbol_id(name) {
|
||||
let reloc = create_relocation(backend.target_info(), sym_id, offset + proc_offset);
|
||||
let reloc = create_relocation(backend.target(), sym_id, offset + proc_offset);
|
||||
|
||||
match output.add_relocation(text_section, reloc) {
|
||||
Ok(obj) => obj,
|
||||
|
@ -405,8 +382,8 @@ fn generate_wrapper<'a, B: Backend<'a>>(
|
|||
}
|
||||
}
|
||||
|
||||
fn create_relocation(target_info: TargetInfo, symbol: SymbolId, offset: u64) -> write::Relocation {
|
||||
let (encoding, size, addend, kind) = match target_info.architecture {
|
||||
fn create_relocation(target: Target, symbol: SymbolId, offset: u64) -> write::Relocation {
|
||||
let (encoding, size, addend, kind) = match target.architecture() {
|
||||
roc_target::Architecture::Aarch32 => todo!(),
|
||||
roc_target::Architecture::Aarch64 => {
|
||||
if cfg!(target_os = "macos") {
|
||||
|
@ -957,7 +934,7 @@ fn build_proc<'a, B: Backend<'a>>(
|
|||
proc: Proc<'a>,
|
||||
) {
|
||||
let mut local_data_index = 0;
|
||||
let target_info = backend.target_info();
|
||||
let target = backend.target();
|
||||
let (proc_data, relocs, rc_proc_names) = backend.build_proc(proc, layout_ids);
|
||||
let proc_offset = output.add_symbol_data(proc_id, section_id, &proc_data, 16);
|
||||
for reloc in relocs.iter() {
|
||||
|
@ -1078,7 +1055,7 @@ fn build_proc<'a, B: Backend<'a>>(
|
|||
add_undefined_rc_proc(output, name, &rc_proc_names);
|
||||
|
||||
if let Some(sym_id) = output.symbol_id(name.as_bytes()) {
|
||||
create_relocation(target_info, sym_id, offset + proc_offset)
|
||||
create_relocation(target, sym_id, offset + proc_offset)
|
||||
} else {
|
||||
internal_error!("failed to find fn symbol for {:?}", name);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ impl LlvmAlignment<'_> for IntWidth {
|
|||
// 128-bit integers are not consistently represented by LLVM.
|
||||
// - AArch64 uses 16-byte alignment (https://godbolt.org/z/dYrfG5o4b)
|
||||
// - x86-64 uses 8-byte alignment (https://godbolt.org/z/qj5Mann6b)
|
||||
let arch = interner.target_info().architecture;
|
||||
let arch = interner.target().architecture();
|
||||
match arch {
|
||||
Architecture::X86_64 => 8,
|
||||
_ => 16,
|
||||
|
@ -33,7 +33,7 @@ impl LlvmAlignment<'_> for IntWidth {
|
|||
|
||||
impl<'a> LlvmAlignment<'a> for FloatWidth {
|
||||
fn llvm_alignment_bytes(&self, interner: &STLayoutInterner<'a>) -> u32 {
|
||||
self.alignment_bytes(interner.target_info())
|
||||
self.alignment_bytes(interner.target())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ impl<'a> LlvmAlignment<'a> for Builtin<'a> {
|
|||
use std::mem::align_of;
|
||||
use Builtin::*;
|
||||
|
||||
let ptr_width = interner.target_info().ptr_width() as u32;
|
||||
let ptr_width = interner.target().ptr_width() as u32;
|
||||
|
||||
// for our data structures, what counts is the alignment of the `( ptr, len )` tuple, and
|
||||
// since both of those are one pointer size, the alignment of that structure is a pointer
|
||||
|
@ -99,7 +99,7 @@ impl<'a> LlvmAlignment<'a> for UnionLayout<'a> {
|
|||
Recursive(_)
|
||||
| NullableWrapped { .. }
|
||||
| NullableUnwrapped { .. }
|
||||
| NonNullableUnwrapped(_) => interner.target_info().ptr_width() as u32,
|
||||
| NonNullableUnwrapped(_) => interner.target().ptr_width() as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ impl<'a> LlvmAlignment<'a> for LayoutRepr<'a> {
|
|||
.llvm_alignment_bytes(interner),
|
||||
Builtin(builtin) => builtin.llvm_alignment_bytes(interner),
|
||||
RecursivePointer(_) | Ptr(_) | FunctionPointer(_) | Erased(_) => {
|
||||
interner.target_info().ptr_width() as u32
|
||||
interner.target().ptr_width() as u32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ pub fn call_bitcode_fn<'ctx>(
|
|||
panic!("LLVM error: Did not get return value from bitcode function {fn_name:?}")
|
||||
});
|
||||
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
if env.target.operating_system() == roc_target::OperatingSystem::Windows {
|
||||
// On windows zig uses a vector type <2xi64> instead of a i128 value
|
||||
let vec_type = env.context.i64_type().vec_type(2);
|
||||
if ret.get_type() == vec_type.into() {
|
||||
|
@ -70,7 +70,7 @@ fn call_bitcode_fn_help<'ctx>(
|
|||
let it = args
|
||||
.iter()
|
||||
.map(|x| {
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
if env.target.operating_system() == roc_target::OperatingSystem::Windows {
|
||||
if x.get_type() == env.context.i128_type().into() {
|
||||
let parent = env
|
||||
.builder
|
||||
|
@ -1067,7 +1067,7 @@ pub(crate) fn call_str_bitcode_fn<'ctx>(
|
|||
use bumpalo::collections::Vec;
|
||||
use roc_target::Architecture::*;
|
||||
|
||||
match env.target_info.architecture {
|
||||
match env.target.architecture() {
|
||||
Aarch32 | X86_32 => {
|
||||
let mut arguments: Vec<BasicValueEnum> =
|
||||
Vec::with_capacity_in(other_arguments.len() + 2 * strings.len(), env.arena);
|
||||
|
@ -1123,7 +1123,7 @@ pub(crate) fn call_list_bitcode_fn<'ctx>(
|
|||
use bumpalo::collections::Vec;
|
||||
use roc_target::Architecture::*;
|
||||
|
||||
match env.target_info.architecture {
|
||||
match env.target.architecture() {
|
||||
Aarch32 | X86_32 => {
|
||||
let mut arguments: Vec<BasicValueEnum> =
|
||||
Vec::with_capacity_in(other_arguments.len() + 2 * lists.len(), env.arena);
|
||||
|
|
|
@ -52,10 +52,9 @@ use roc_mono::layout::{
|
|||
RawFunctionLayout, STLayoutInterner, TagIdIntType, UnionLayout,
|
||||
};
|
||||
use roc_std::RocDec;
|
||||
use roc_target::{PtrWidth, TargetInfo};
|
||||
use roc_target::{PtrWidth, Target};
|
||||
use std::convert::TryInto;
|
||||
use std::path::Path;
|
||||
use target_lexicon::{Aarch64Architecture, Architecture, OperatingSystem, Triple};
|
||||
|
||||
use super::convert::{struct_type_from_union_layout, RocUnion};
|
||||
use super::intrinsics::{
|
||||
|
@ -737,7 +736,7 @@ pub struct Env<'a, 'ctx, 'env> {
|
|||
pub compile_unit: &'env DICompileUnit<'ctx>,
|
||||
pub module: &'ctx Module<'ctx>,
|
||||
pub interns: Interns,
|
||||
pub target_info: TargetInfo,
|
||||
pub target: Target,
|
||||
pub mode: LlvmBackendMode,
|
||||
pub exposed_to_host: MutSet<Symbol>,
|
||||
}
|
||||
|
@ -750,7 +749,7 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
pub fn ptr_int(&self) -> IntType<'ctx> {
|
||||
let ctx = self.context;
|
||||
|
||||
match self.target_info.ptr_width() {
|
||||
match self.target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => ctx.i32_type(),
|
||||
roc_target::PtrWidth::Bytes8 => ctx.i64_type(),
|
||||
}
|
||||
|
@ -763,14 +762,14 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
pub fn twice_ptr_int(&self) -> IntType<'ctx> {
|
||||
let ctx = self.context;
|
||||
|
||||
match self.target_info.ptr_width() {
|
||||
match self.target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => ctx.i64_type(),
|
||||
roc_target::PtrWidth::Bytes8 => ctx.i128_type(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn small_str_bytes(&self) -> u32 {
|
||||
self.target_info.ptr_width() as u32 * 3
|
||||
self.target.ptr_width() as u32 * 3
|
||||
}
|
||||
|
||||
pub fn build_intrinsic_call(
|
||||
|
@ -872,7 +871,7 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
) -> CallSiteValue<'ctx> {
|
||||
let false_val = self.context.bool_type().const_int(0, false);
|
||||
|
||||
let intrinsic_name = match self.target_info.ptr_width() {
|
||||
let intrinsic_name = match self.target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes8 => LLVM_MEMSET_I64,
|
||||
roc_target::PtrWidth::Bytes4 => LLVM_MEMSET_I32,
|
||||
};
|
||||
|
@ -932,7 +931,7 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
env: &Env<'a, 'ctx, 'env>,
|
||||
string: BasicValueEnum<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
match env.target_info.ptr_width() {
|
||||
match env.target.ptr_width() {
|
||||
PtrWidth::Bytes4 => {
|
||||
// we need to pass the string by reference, but we currently hold the value.
|
||||
let alloca = env
|
||||
|
@ -1011,48 +1010,29 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
}
|
||||
|
||||
pub fn module_from_builtins<'ctx>(
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
ctx: &'ctx Context,
|
||||
module_name: &str,
|
||||
) -> Module<'ctx> {
|
||||
// In the build script for the builtins module, we compile the builtins into LLVM bitcode
|
||||
|
||||
let bitcode_bytes: &[u8] = if target == &target_lexicon::Triple::host() {
|
||||
let bitcode_bytes: &[u8] = if target == target_lexicon::Triple::host().into() {
|
||||
include_bytes!("../../../builtins/bitcode/zig-out/builtins-host.bc")
|
||||
} else {
|
||||
match target {
|
||||
Triple {
|
||||
architecture: Architecture::Wasm32,
|
||||
..
|
||||
} => {
|
||||
Target::Wasm32 => {
|
||||
include_bytes!("../../../builtins/bitcode/zig-out/builtins-wasm32.bc")
|
||||
}
|
||||
Triple {
|
||||
architecture: Architecture::X86_32(_),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => {
|
||||
Target::LinuxX32 => {
|
||||
include_bytes!("../../../builtins/bitcode/zig-out/builtins-x86.bc")
|
||||
}
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => {
|
||||
Target::LinuxX64 => {
|
||||
include_bytes!("../../../builtins/bitcode/zig-out/builtins-x86_64.bc")
|
||||
}
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => {
|
||||
Target::LinuxArm64 => {
|
||||
include_bytes!("../../../builtins/bitcode/zig-out/builtins-aarch64.bc")
|
||||
}
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Windows,
|
||||
..
|
||||
} => {
|
||||
Target::WinX64 => {
|
||||
include_bytes!("../../../builtins/bitcode/zig-out/builtins-windows-x86_64.bc")
|
||||
}
|
||||
_ => panic!("The zig builtins are not currently built for this target: {target:?}"),
|
||||
|
@ -1416,7 +1396,7 @@ fn build_string_literal<'ctx>(
|
|||
|
||||
let alloca = const_str_alloca_ptr(env, parent, ptr, number_of_elements, number_of_elements);
|
||||
|
||||
match env.target_info.ptr_width() {
|
||||
match env.target.ptr_width() {
|
||||
PtrWidth::Bytes4 => {
|
||||
env.builder
|
||||
.new_build_load(zig_str_type(env), alloca, "load_const_str")
|
||||
|
@ -1449,7 +1429,7 @@ fn small_str_ptr_width_8<'ctx>(
|
|||
parent: FunctionValue<'ctx>,
|
||||
str_literal: &str,
|
||||
) -> PointerValue<'ctx> {
|
||||
debug_assert_eq!(env.target_info.ptr_width() as u8, 8);
|
||||
debug_assert_eq!(env.target.ptr_width() as u8, 8);
|
||||
|
||||
let mut array = [0u8; 24];
|
||||
|
||||
|
@ -1473,7 +1453,7 @@ fn small_str_ptr_width_8<'ctx>(
|
|||
}
|
||||
|
||||
fn small_str_ptr_width_4<'ctx>(env: &Env<'_, 'ctx, '_>, str_literal: &str) -> StructValue<'ctx> {
|
||||
debug_assert_eq!(env.target_info.ptr_width() as u8, 4);
|
||||
debug_assert_eq!(env.target.ptr_width() as u8, 4);
|
||||
|
||||
let mut array = [0u8; 12];
|
||||
|
||||
|
@ -1779,7 +1759,7 @@ pub(crate) fn build_exp_expr<'a, 'ctx>(
|
|||
|
||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(
|
||||
env,
|
||||
if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||
if union_layout.stores_tag_id_in_pointer(env.target) {
|
||||
tag_pointer_clear_tag_id(env, tag_ptr)
|
||||
} else {
|
||||
tag_ptr
|
||||
|
@ -1876,7 +1856,7 @@ pub(crate) fn build_exp_expr<'a, 'ctx>(
|
|||
|
||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(
|
||||
env,
|
||||
if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||
if union_layout.stores_tag_id_in_pointer(env.target) {
|
||||
tag_pointer_clear_tag_id(env, tag_ptr)
|
||||
} else {
|
||||
tag_ptr
|
||||
|
@ -2261,7 +2241,7 @@ fn build_wrapped_tag<'a, 'ctx>(
|
|||
);
|
||||
let struct_type = env.context.struct_type(&field_types, false);
|
||||
|
||||
if union_layout.stores_tag_id_as_data(env.target_info) {
|
||||
if union_layout.stores_tag_id_as_data(env.target) {
|
||||
let tag_id_ptr = builder.new_build_struct_gep(
|
||||
union_struct_type,
|
||||
raw_data_ptr,
|
||||
|
@ -2556,7 +2536,7 @@ fn tag_pointer_set_tag_id<'ctx>(
|
|||
pointer: PointerValue<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
// we only have 3 bits, so can encode only 0..7 (or on 32-bit targets, 2 bits to encode 0..3)
|
||||
debug_assert!((tag_id as u32) < env.target_info.ptr_width() as u32);
|
||||
debug_assert!((tag_id as u32) < env.target.ptr_width() as u32);
|
||||
|
||||
let tag_id_intval = env.ptr_int().const_int(tag_id as u64, false);
|
||||
|
||||
|
@ -2580,8 +2560,8 @@ fn tag_pointer_set_tag_id<'ctx>(
|
|||
.new_build_pointer_cast(indexed_pointer, pointer.get_type(), "cast_from_i8_ptr")
|
||||
}
|
||||
|
||||
pub fn tag_pointer_tag_id_bits_and_mask(target_info: TargetInfo) -> (u64, u64) {
|
||||
match target_info.ptr_width() {
|
||||
pub fn tag_pointer_tag_id_bits_and_mask(target: Target) -> (u64, u64) {
|
||||
match target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes8 => (3, 0b0000_0111),
|
||||
roc_target::PtrWidth::Bytes4 => (2, 0b0000_0011),
|
||||
}
|
||||
|
@ -2591,7 +2571,7 @@ pub fn tag_pointer_read_tag_id<'ctx>(
|
|||
env: &Env<'_, 'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let (_, mask) = tag_pointer_tag_id_bits_and_mask(env.target_info);
|
||||
let (_, mask) = tag_pointer_tag_id_bits_and_mask(env.target);
|
||||
let ptr_int = env.ptr_int();
|
||||
|
||||
let as_int = env.builder.new_build_ptr_to_int(pointer, ptr_int, "to_int");
|
||||
|
@ -2607,7 +2587,7 @@ pub fn tag_pointer_clear_tag_id<'ctx>(
|
|||
env: &Env<'_, 'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
let (_, tag_id_bits_mask) = tag_pointer_tag_id_bits_and_mask(env.target_info);
|
||||
let (_, tag_id_bits_mask) = tag_pointer_tag_id_bits_and_mask(env.target);
|
||||
|
||||
let as_int = env
|
||||
.builder
|
||||
|
@ -2725,7 +2705,7 @@ pub fn get_tag_id<'a, 'ctx>(
|
|||
UnionLayout::Recursive(_) => {
|
||||
let argument_ptr = argument.into_pointer_value();
|
||||
|
||||
if union_layout.stores_tag_id_as_data(env.target_info) {
|
||||
if union_layout.stores_tag_id_as_data(env.target) {
|
||||
get_tag_id_wrapped(env, layout_interner, *union_layout, argument_ptr)
|
||||
} else {
|
||||
tag_pointer_read_tag_id(env, argument_ptr)
|
||||
|
@ -2756,7 +2736,7 @@ pub fn get_tag_id<'a, 'ctx>(
|
|||
{
|
||||
env.builder.position_at_end(else_block);
|
||||
|
||||
let tag_id = if union_layout.stores_tag_id_as_data(env.target_info) {
|
||||
let tag_id = if union_layout.stores_tag_id_as_data(env.target) {
|
||||
get_tag_id_wrapped(env, layout_interner, *union_layout, argument_ptr)
|
||||
} else {
|
||||
tag_pointer_read_tag_id(env, argument_ptr)
|
||||
|
@ -2894,7 +2874,7 @@ fn reserve_with_refcount_union_as_block_of_memory<'a, 'ctx>(
|
|||
union_layout: UnionLayout<'a>,
|
||||
fields: &[&[InLayout<'a>]],
|
||||
) -> PointerValue<'ctx> {
|
||||
let ptr_bytes = env.target_info;
|
||||
let ptr_bytes = env.target;
|
||||
|
||||
let roc_union = if union_layout.stores_tag_id_as_data(ptr_bytes) {
|
||||
RocUnion::tagged_from_slices(layout_interner, env.context, fields)
|
||||
|
@ -2988,11 +2968,11 @@ fn list_literal<'a, 'ctx>(
|
|||
let size = list_length * element_width as usize;
|
||||
let alignment = layout_interner
|
||||
.alignment_bytes(element_layout)
|
||||
.max(env.target_info.ptr_width() as u32);
|
||||
.max(env.target.ptr_width() as u32);
|
||||
|
||||
let mut is_all_constant = true;
|
||||
let zero_elements =
|
||||
(env.target_info.ptr_width() as u8 as f64 / element_width as f64).ceil() as usize;
|
||||
(env.target.ptr_width() as u8 as f64 / element_width as f64).ceil() as usize;
|
||||
|
||||
// runtime-evaluated elements
|
||||
let mut runtime_evaluated_elements = Vec::with_capacity_in(list_length, env.arena);
|
||||
|
@ -3498,7 +3478,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
if value.is_pointer_value() {
|
||||
let clear_tag_id = match other_layout {
|
||||
LayoutRepr::Union(union_layout) => {
|
||||
union_layout.stores_tag_id_in_pointer(env.target_info)
|
||||
union_layout.stores_tag_id_in_pointer(env.target)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
@ -3562,7 +3542,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
let value = value.into_pointer_value();
|
||||
|
||||
let clear_tag_id = match layout_interner.runtime_representation(layout) {
|
||||
LayoutRepr::Union(union) => union.stores_tag_id_in_pointer(env.target_info),
|
||||
LayoutRepr::Union(union) => union.stores_tag_id_in_pointer(env.target),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -3640,7 +3620,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
if env.mode.runs_expects() {
|
||||
bd.position_at_end(throw_block);
|
||||
|
||||
match env.target_info.ptr_width() {
|
||||
match env.target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes8 => {
|
||||
let shared_memory = SharedMemoryPointer::get(env);
|
||||
|
||||
|
@ -3712,7 +3692,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
if env.mode.runs_expects() {
|
||||
bd.position_at_end(throw_block);
|
||||
|
||||
match env.target_info.ptr_width() {
|
||||
match env.target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes8 => {
|
||||
let shared_memory = SharedMemoryPointer::get(env);
|
||||
|
||||
|
@ -4891,7 +4871,7 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx>(
|
|||
// On x86_*, Modify the argument to specify it is passed by value and nonnull
|
||||
// Aarch*, just passes in the pointer directly.
|
||||
if matches!(
|
||||
env.target_info.architecture,
|
||||
env.target.architecture(),
|
||||
roc_target::Architecture::X86_32 | roc_target::Architecture::X86_64
|
||||
) {
|
||||
let c_abi_type = match layout_interner.get_repr(*layout) {
|
||||
|
@ -5072,7 +5052,7 @@ fn expose_function_to_host_help_c_abi<'a, 'ctx>(
|
|||
}
|
||||
|
||||
pub fn get_sjlj_buffer<'ctx>(env: &Env<'_, 'ctx, '_>) -> PointerValue<'ctx> {
|
||||
let word_type = match env.target_info.ptr_width() {
|
||||
let word_type = match env.target.ptr_width() {
|
||||
PtrWidth::Bytes4 => env.context.i32_type(),
|
||||
PtrWidth::Bytes8 => env.context.i64_type(),
|
||||
};
|
||||
|
@ -5088,7 +5068,7 @@ pub fn get_sjlj_buffer<'ctx>(env: &Env<'_, 'ctx, '_>) -> PointerValue<'ctx> {
|
|||
// The following three words are available for use in a target-specific manner.
|
||||
//
|
||||
// So, let's create a 5-word buffer.
|
||||
let size = if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
let size = if env.target.operating_system() == roc_target::OperatingSystem::Windows {
|
||||
// Due to https://github.com/llvm/llvm-project/issues/72908
|
||||
// on windows, we store the register contents into this buffer directly!
|
||||
30
|
||||
|
@ -5114,10 +5094,10 @@ pub fn get_sjlj_buffer<'ctx>(env: &Env<'_, 'ctx, '_>) -> PointerValue<'ctx> {
|
|||
|
||||
pub fn build_setjmp_call<'ctx>(env: &Env<'_, 'ctx, '_>) -> BasicValueEnum<'ctx> {
|
||||
let jmp_buf = get_sjlj_buffer(env);
|
||||
if env.target_info.architecture == roc_target::Architecture::Aarch64 {
|
||||
if env.target.architecture() == roc_target::Architecture::Aarch64 {
|
||||
// Due to https://github.com/roc-lang/roc/issues/2965, we use a setjmp we linked in from Zig
|
||||
call_bitcode_fn(env, &[jmp_buf.into()], bitcode::UTILS_SETJMP)
|
||||
} else if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
} else if env.target.operating_system() == roc_target::OperatingSystem::Windows {
|
||||
// Due to https://github.com/llvm/llvm-project/issues/72908, we use a setjmp defined as asm in Zig
|
||||
call_bitcode_fn(env, &[jmp_buf.into()], bitcode::UTILS_WINDOWS_SETJMP)
|
||||
} else {
|
||||
|
@ -6770,10 +6750,14 @@ pub fn to_cc_return<'a>(
|
|||
layout: InLayout<'a>,
|
||||
) -> CCReturn {
|
||||
let return_size = layout_interner.stack_size(layout);
|
||||
let pass_result_by_pointer = match env.target_info.operating_system {
|
||||
roc_target::OperatingSystem::Windows => return_size > env.target_info.ptr_width() as u32,
|
||||
roc_target::OperatingSystem::Unix => return_size > 2 * env.target_info.ptr_width() as u32,
|
||||
roc_target::OperatingSystem::Wasi => return_size > 2 * env.target_info.ptr_width() as u32,
|
||||
// TODO: loop back and update this. It actually cares about the full abi (arch + os)
|
||||
let pass_result_by_pointer = match env.target.operating_system() {
|
||||
roc_target::OperatingSystem::Windows => return_size > env.target.ptr_width() as u32,
|
||||
roc_target::OperatingSystem::Linux
|
||||
| roc_target::OperatingSystem::Mac
|
||||
| roc_target::OperatingSystem::Freestanding => {
|
||||
return_size > 2 * env.target.ptr_width() as u32
|
||||
}
|
||||
};
|
||||
|
||||
if return_size == 0 {
|
||||
|
@ -6996,7 +6980,7 @@ fn define_global_str_literal_ptr<'ctx>(
|
|||
ptr,
|
||||
&[env
|
||||
.ptr_int()
|
||||
.const_int(env.target_info.ptr_width() as u64, false)],
|
||||
.const_int(env.target.ptr_width() as u64, false)],
|
||||
"get_rc_ptr",
|
||||
)
|
||||
};
|
||||
|
@ -7026,11 +7010,11 @@ fn define_global_str_literal<'ctx>(
|
|||
Some(current) => current,
|
||||
|
||||
None => {
|
||||
let size = message.bytes().len() + env.target_info.ptr_width() as usize;
|
||||
let size = message.bytes().len() + env.target.ptr_width() as usize;
|
||||
let mut bytes = Vec::with_capacity_in(size, env.arena);
|
||||
|
||||
// insert NULL bytes for the refcount
|
||||
for _ in 0..env.target_info.ptr_width() as usize {
|
||||
for _ in 0..env.target.ptr_width() as usize {
|
||||
bytes.push(env.context.i8_type().const_zero());
|
||||
}
|
||||
|
||||
|
@ -7049,7 +7033,7 @@ fn define_global_str_literal<'ctx>(
|
|||
// strings are NULL-terminated, which means we can't store the refcount (which is 8
|
||||
// NULL bytes)
|
||||
global.set_constant(true);
|
||||
global.set_alignment(env.target_info.ptr_width() as u32);
|
||||
global.set_alignment(env.target.ptr_width() as u32);
|
||||
global.set_unnamed_addr(true);
|
||||
global.set_linkage(inkwell::module::Linkage::Private);
|
||||
|
||||
|
|
|
@ -378,7 +378,7 @@ pub(crate) fn list_replace_unsafe<'a, 'ctx>(
|
|||
// the list has the same alignment as a usize / ptr. The element comes first in the struct if
|
||||
// its alignment is bigger than that of a list.
|
||||
let element_align = layout_interner.alignment_bytes(element_layout);
|
||||
let element_first = element_align > env.target_info.ptr_width() as u32;
|
||||
let element_first = element_align > env.target.ptr_width() as u32;
|
||||
|
||||
let fields = if element_first {
|
||||
[element_layout, Layout::LIST_U8 /* any list works */]
|
||||
|
|
|
@ -11,7 +11,7 @@ use roc_mono::layout::{
|
|||
round_up_to_alignment, Builtin, FunctionPointer, InLayout, Layout, LayoutInterner, LayoutRepr,
|
||||
STLayoutInterner, UnionLayout,
|
||||
};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
use super::struct_::RocStruct;
|
||||
|
||||
|
@ -106,7 +106,7 @@ pub fn struct_type_from_union_layout<'a, 'ctx>(
|
|||
| NullableWrapped {
|
||||
other_tags: tags, ..
|
||||
} => {
|
||||
if union_layout.stores_tag_id_as_data(env.target_info) {
|
||||
if union_layout.stores_tag_id_as_data(env.target) {
|
||||
RocUnion::tagged_from_slices(layout_interner, env.context, tags).struct_type()
|
||||
} else {
|
||||
RocUnion::untagged_from_slices(layout_interner, env.context, tags).struct_type()
|
||||
|
@ -489,8 +489,8 @@ impl<'ctx> RocUnion<'ctx> {
|
|||
}
|
||||
|
||||
/// The int type that the C ABI turns our RocList/RocStr into
|
||||
pub fn str_list_int(ctx: &Context, target_info: TargetInfo) -> IntType<'_> {
|
||||
match target_info.ptr_width() {
|
||||
pub fn str_list_int(ctx: &Context, target: Target) -> IntType<'_> {
|
||||
match target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => ctx.i64_type(),
|
||||
roc_target::PtrWidth::Bytes8 => ctx.i128_type(),
|
||||
}
|
||||
|
|
|
@ -184,8 +184,7 @@ pub(crate) fn clone_to_shared_memory<'a, 'ctx>(
|
|||
let after_header = offset;
|
||||
|
||||
let space_for_offsets = env.ptr_int().const_int(
|
||||
(lookups.len() * env.target_info.ptr_size() + lookups.len() * std::mem::size_of::<u32>())
|
||||
as _,
|
||||
(lookups.len() * env.target.ptr_size() + lookups.len() * std::mem::size_of::<u32>()) as _,
|
||||
false,
|
||||
);
|
||||
|
||||
|
@ -232,9 +231,7 @@ pub(crate) fn clone_to_shared_memory<'a, 'ctx>(
|
|||
{
|
||||
build_copy(env, original_ptr, offset, lookup_start.into());
|
||||
|
||||
let ptr_width = env
|
||||
.ptr_int()
|
||||
.const_int(env.target_info.ptr_size() as _, false);
|
||||
let ptr_width = env.ptr_int().const_int(env.target.ptr_size() as _, false);
|
||||
|
||||
offset = env.builder.new_build_int_add(offset, ptr_width, "offset");
|
||||
}
|
||||
|
@ -698,7 +695,7 @@ fn build_clone_tag_help<'a, 'ctx>(
|
|||
let tag_value = tag_pointer_clear_tag_id(env, tag_value.into_pointer_value());
|
||||
|
||||
let layout = LayoutRepr::struct_(field_layouts);
|
||||
let layout = if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||
let layout = if union_layout.stores_tag_id_in_pointer(env.target) {
|
||||
layout
|
||||
} else {
|
||||
// [...fields, tag ID]
|
||||
|
@ -914,7 +911,7 @@ fn write_pointer_with_tag_id<'a, 'ctx>(
|
|||
union_layout: UnionLayout<'a>,
|
||||
tag_id: usize,
|
||||
) {
|
||||
if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||
if union_layout.stores_tag_id_in_pointer(env.target) {
|
||||
// first, store tag id as u32
|
||||
let tag_id_intval = env.context.i32_type().const_int(tag_id as _, false);
|
||||
build_copy(env, ptr, offset, tag_id_intval.into());
|
||||
|
|
|
@ -195,7 +195,7 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
|
|||
}
|
||||
}
|
||||
|
||||
match env.target_info.operating_system {
|
||||
match env.target.operating_system() {
|
||||
roc_target::OperatingSystem::Windows => {
|
||||
// We don't need these functions on Windows
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ pub fn add_sjlj_roc_panic(env: &Env<'_, '_, '_>) {
|
|||
|
||||
// write our error message to the RocStr pointer
|
||||
{
|
||||
let loaded_roc_str = match env.target_info.ptr_width() {
|
||||
let loaded_roc_str = match env.target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => roc_str_arg,
|
||||
// On 64-bit we pass RocStrs by reference internally
|
||||
roc_target::PtrWidth::Bytes8 => {
|
||||
|
@ -315,12 +315,12 @@ pub fn add_sjlj_roc_panic(env: &Env<'_, '_, '_>) {
|
|||
|
||||
pub fn build_longjmp_call(env: &Env) {
|
||||
let jmp_buf = get_sjlj_buffer(env);
|
||||
if env.target_info.architecture == roc_target::Architecture::Aarch64 {
|
||||
if env.target.architecture() == roc_target::Architecture::Aarch64 {
|
||||
// Due to https://github.com/roc-lang/roc/issues/2965, we use a setjmp we linked in from Zig
|
||||
let tag = env.context.i32_type().const_int(1, false);
|
||||
let _call =
|
||||
call_void_bitcode_fn(env, &[jmp_buf.into(), tag.into()], bitcode::UTILS_LONGJMP);
|
||||
} else if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
} else if env.target.operating_system() == roc_target::OperatingSystem::Windows {
|
||||
let tag = env.context.i32_type().const_int(1, false);
|
||||
let _call = call_void_bitcode_fn(
|
||||
env,
|
||||
|
|
|
@ -20,7 +20,7 @@ use roc_mono::{
|
|||
},
|
||||
list_element_layout,
|
||||
};
|
||||
use roc_target::{PtrWidth, TargetInfo};
|
||||
use roc_target::{PtrWidth, Target};
|
||||
|
||||
use crate::llvm::{
|
||||
bitcode::{
|
||||
|
@ -129,7 +129,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
// Str.joinWith : List Str, Str -> Str
|
||||
arguments!(list, string);
|
||||
|
||||
match env.target_info.ptr_width() {
|
||||
match env.target.ptr_width() {
|
||||
PtrWidth::Bytes4 => {
|
||||
// list and string are both stored as structs on the stack on 32-bit targets
|
||||
call_str_bitcode_fn(
|
||||
|
@ -197,7 +197,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
};
|
||||
|
||||
use roc_target::Architecture::*;
|
||||
let result = match env.target_info.architecture {
|
||||
let result = match env.target.architecture() {
|
||||
Aarch32 | X86_32 => {
|
||||
let zig_function = env.module.get_function(intrinsic).unwrap();
|
||||
let zig_function_type = zig_function.get_type();
|
||||
|
@ -283,14 +283,14 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
};
|
||||
|
||||
use roc_target::OperatingSystem::*;
|
||||
let cc_return_by_pointer = match env.target_info.operating_system {
|
||||
let cc_return_by_pointer = match env.target.operating_system() {
|
||||
Windows => {
|
||||
// there is just one return register on Windows
|
||||
(width + 1) as usize > env.target_info.ptr_size()
|
||||
(width + 1) as usize > env.target.ptr_size()
|
||||
}
|
||||
_ => {
|
||||
// on other systems we have two return registers
|
||||
(width + 1) as usize > 2 * env.target_info.ptr_size()
|
||||
(width + 1) as usize > 2 * env.target.ptr_size()
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -415,7 +415,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
.new_build_alloca(result_type, "alloca_utf8_validate_bytes_result");
|
||||
|
||||
use roc_target::Architecture::*;
|
||||
match env.target_info.architecture {
|
||||
match env.target.architecture() {
|
||||
Aarch32 | X86_32 => {
|
||||
arguments!(list);
|
||||
let (a, b) = pass_list_or_string_to_zig_32bit(env, list.into_struct_value());
|
||||
|
@ -1299,7 +1299,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
|
||||
let value_ptr = match layout_interner.runtime_representation(data_layout) {
|
||||
LayoutRepr::Union(union_layout)
|
||||
if union_layout.stores_tag_id_in_pointer(env.target_info) =>
|
||||
if union_layout.stores_tag_id_in_pointer(env.target) =>
|
||||
{
|
||||
tag_pointer_clear_tag_id(env, ptr)
|
||||
}
|
||||
|
@ -1898,7 +1898,7 @@ fn dec_split_into_words<'ctx>(
|
|||
fn dec_alloca<'ctx>(env: &Env<'_, 'ctx, '_>, value: IntValue<'ctx>) -> BasicValueEnum<'ctx> {
|
||||
use roc_target::Architecture::*;
|
||||
use roc_target::OperatingSystem::*;
|
||||
match env.target_info.operating_system {
|
||||
match env.target.operating_system() {
|
||||
Windows => {
|
||||
let dec_type = zig_dec_type(env);
|
||||
|
||||
|
@ -1917,8 +1917,8 @@ fn dec_alloca<'ctx>(env: &Env<'_, 'ctx, '_>, value: IntValue<'ctx>) -> BasicValu
|
|||
|
||||
alloca.into()
|
||||
}
|
||||
Unix => {
|
||||
if matches!(env.target_info.architecture, X86_32 | X86_64) {
|
||||
Linux | Mac => {
|
||||
if matches!(env.target.architecture(), X86_32 | X86_64) {
|
||||
internal_error!("X86 unix does not pass with a dec alloc instead it splits into high and low halves");
|
||||
}
|
||||
let i64_type = env.context.i64_type();
|
||||
|
@ -1937,21 +1937,15 @@ fn dec_alloca<'ctx>(env: &Env<'_, 'ctx, '_>, value: IntValue<'ctx>) -> BasicValu
|
|||
env.builder
|
||||
.new_build_load(i64_type.array_type(2), alloca, "load as array")
|
||||
}
|
||||
Wasi => unimplemented!(),
|
||||
Freestanding => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn dec_to_str<'ctx>(env: &Env<'_, 'ctx, '_>, dec: BasicValueEnum<'ctx>) -> BasicValueEnum<'ctx> {
|
||||
use roc_target::Architecture::*;
|
||||
use roc_target::OperatingSystem::*;
|
||||
|
||||
let dec = dec.into_int_value();
|
||||
|
||||
match env.target_info {
|
||||
TargetInfo {
|
||||
architecture: X86_64 | X86_32,
|
||||
operating_system: Unix,
|
||||
} => {
|
||||
match env.target {
|
||||
Target::LinuxX32 | Target::LinuxX64 | Target::MacX64 => {
|
||||
let (low, high) = dec_split_into_words(env, dec);
|
||||
|
||||
call_str_bitcode_fn(
|
||||
|
@ -1962,10 +1956,7 @@ fn dec_to_str<'ctx>(env: &Env<'_, 'ctx, '_>, dec: BasicValueEnum<'ctx>) -> Basic
|
|||
bitcode::DEC_TO_STR,
|
||||
)
|
||||
}
|
||||
TargetInfo {
|
||||
architecture: Wasm32,
|
||||
operating_system: Unix,
|
||||
} => call_str_bitcode_fn(
|
||||
Target::Wasm32 => call_str_bitcode_fn(
|
||||
env,
|
||||
&[],
|
||||
&[dec.into()],
|
||||
|
@ -1987,22 +1978,13 @@ fn dec_unary_op<'ctx>(
|
|||
fn_name: &str,
|
||||
dec: BasicValueEnum<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
use roc_target::Architecture::*;
|
||||
use roc_target::OperatingSystem::*;
|
||||
|
||||
let dec = dec.into_int_value();
|
||||
match env.target_info {
|
||||
TargetInfo {
|
||||
architecture: X86_64 | X86_32,
|
||||
operating_system: Unix,
|
||||
} => {
|
||||
match env.target {
|
||||
Target::LinuxX32 | Target::LinuxX64 | Target::MacX64 => {
|
||||
let (low, high) = dec_split_into_words(env, dec);
|
||||
call_bitcode_fn(env, &[low.into(), high.into()], fn_name)
|
||||
}
|
||||
TargetInfo {
|
||||
architecture: Wasm32,
|
||||
operating_system: Unix,
|
||||
} => call_bitcode_fn(env, &[dec.into()], fn_name),
|
||||
Target::Wasm32 => call_bitcode_fn(env, &[dec.into()], fn_name),
|
||||
_ => call_bitcode_fn(env, &[dec_alloca(env, dec)], fn_name),
|
||||
}
|
||||
}
|
||||
|
@ -2013,17 +1995,11 @@ fn dec_binary_op<'ctx>(
|
|||
dec1: BasicValueEnum<'ctx>,
|
||||
dec2: BasicValueEnum<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
use roc_target::Architecture::*;
|
||||
use roc_target::OperatingSystem::*;
|
||||
|
||||
let dec1 = dec1.into_int_value();
|
||||
let dec2 = dec2.into_int_value();
|
||||
|
||||
match env.target_info {
|
||||
TargetInfo {
|
||||
architecture: X86_64 | X86_32,
|
||||
operating_system: Unix,
|
||||
} => {
|
||||
match env.target {
|
||||
Target::LinuxX32 | Target::LinuxX64 | Target::MacX64 => {
|
||||
let (low1, high1) = dec_split_into_words(env, dec1);
|
||||
let (low2, high2) = dec_split_into_words(env, dec2);
|
||||
let lowr_highr = call_bitcode_fn(
|
||||
|
@ -2043,10 +2019,7 @@ fn dec_binary_op<'ctx>(
|
|||
.build_load(env.context.i128_type(), ptr, "to_i128")
|
||||
.unwrap()
|
||||
}
|
||||
TargetInfo {
|
||||
architecture: Wasm32,
|
||||
operating_system: Unix,
|
||||
} => call_bitcode_fn(env, &[dec1.into(), dec2.into()], fn_name),
|
||||
Target::Wasm32 => call_bitcode_fn(env, &[dec1.into(), dec2.into()], fn_name),
|
||||
_ => call_bitcode_fn(
|
||||
env,
|
||||
&[dec_alloca(env, dec1), dec_alloca(env, dec2)],
|
||||
|
@ -2061,20 +2034,14 @@ fn dec_binop_with_overflow<'ctx>(
|
|||
lhs: BasicValueEnum<'ctx>,
|
||||
rhs: BasicValueEnum<'ctx>,
|
||||
) -> StructValue<'ctx> {
|
||||
use roc_target::Architecture::*;
|
||||
use roc_target::OperatingSystem::*;
|
||||
|
||||
let lhs = lhs.into_int_value();
|
||||
let rhs = rhs.into_int_value();
|
||||
|
||||
let return_type = zig_with_overflow_roc_dec(env);
|
||||
let return_alloca = env.builder.new_build_alloca(return_type, "return_alloca");
|
||||
|
||||
match env.target_info {
|
||||
TargetInfo {
|
||||
architecture: X86_64 | X86_32,
|
||||
operating_system: Unix,
|
||||
} => {
|
||||
match env.target {
|
||||
Target::LinuxX32 | Target::LinuxX64 | Target::MacX64 => {
|
||||
let (lhs_low, lhs_high) = dec_split_into_words(env, lhs);
|
||||
let (rhs_low, rhs_high) = dec_split_into_words(env, rhs);
|
||||
call_void_bitcode_fn(
|
||||
|
@ -2089,10 +2056,7 @@ fn dec_binop_with_overflow<'ctx>(
|
|||
fn_name,
|
||||
);
|
||||
}
|
||||
TargetInfo {
|
||||
architecture: Wasm32,
|
||||
operating_system: Unix,
|
||||
} => {
|
||||
Target::Wasm32 => {
|
||||
call_void_bitcode_fn(
|
||||
env,
|
||||
&[return_alloca.into(), lhs.into(), rhs.into()],
|
||||
|
@ -2123,17 +2087,11 @@ pub(crate) fn dec_binop_with_unchecked<'ctx>(
|
|||
lhs: BasicValueEnum<'ctx>,
|
||||
rhs: BasicValueEnum<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
use roc_target::Architecture::*;
|
||||
use roc_target::OperatingSystem::*;
|
||||
|
||||
let lhs = lhs.into_int_value();
|
||||
let rhs = rhs.into_int_value();
|
||||
|
||||
match env.target_info {
|
||||
TargetInfo {
|
||||
architecture: X86_64 | X86_32,
|
||||
operating_system: Unix,
|
||||
} => {
|
||||
match env.target {
|
||||
Target::LinuxX32 | Target::LinuxX64 | Target::MacX64 => {
|
||||
let (lhs_low, lhs_high) = dec_split_into_words(env, lhs);
|
||||
let (rhs_low, rhs_high) = dec_split_into_words(env, rhs);
|
||||
call_bitcode_fn(
|
||||
|
@ -2147,10 +2105,7 @@ pub(crate) fn dec_binop_with_unchecked<'ctx>(
|
|||
fn_name,
|
||||
)
|
||||
}
|
||||
TargetInfo {
|
||||
architecture: Wasm32,
|
||||
operating_system: Unix,
|
||||
} => call_bitcode_fn(env, &[lhs.into(), rhs.into()], fn_name),
|
||||
Target::Wasm32 => call_bitcode_fn(env, &[lhs.into(), rhs.into()], fn_name),
|
||||
_ => call_bitcode_fn(env, &[dec_alloca(env, lhs), dec_alloca(env, rhs)], fn_name),
|
||||
}
|
||||
}
|
||||
|
@ -2432,7 +2387,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
&bitcode::NUM_INT_TO_INT_CHECKING_MAX_AND_MIN[target_int_width][arg_width]
|
||||
};
|
||||
|
||||
let result = match env.target_info.ptr_width() {
|
||||
let result = match env.target.ptr_width() {
|
||||
PtrWidth::Bytes4 => {
|
||||
let zig_function = env.module.get_function(intrinsic).unwrap();
|
||||
let zig_function_type = zig_function.get_type();
|
||||
|
@ -2489,12 +2444,11 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
let return_by_pointer = {
|
||||
if env.target_info.operating_system
|
||||
== roc_target::OperatingSystem::Windows
|
||||
if env.target.operating_system() == roc_target::OperatingSystem::Windows
|
||||
{
|
||||
target_int_width.stack_size() as usize >= env.target_info.ptr_size()
|
||||
target_int_width.stack_size() as usize >= env.target.ptr_size()
|
||||
} else {
|
||||
target_int_width.stack_size() as usize > env.target_info.ptr_size()
|
||||
target_int_width.stack_size() as usize > env.target.ptr_size()
|
||||
}
|
||||
};
|
||||
if return_by_pointer {
|
||||
|
|
|
@ -80,7 +80,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
|||
|
||||
pub fn is_1<'a, 'env>(&self, env: &Env<'a, 'ctx, 'env>) -> IntValue<'ctx> {
|
||||
let current = self.get_refcount(env);
|
||||
let one = match env.target_info.ptr_width() {
|
||||
let one = match env.target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => {
|
||||
env.context.i32_type().const_int(i32::MIN as u64, false)
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
|||
) {
|
||||
let alignment = layout
|
||||
.allocation_alignment_bytes(layout_interner)
|
||||
.max(env.target_info.ptr_width() as u32);
|
||||
.max(env.target.ptr_width() as u32);
|
||||
|
||||
let context = env.context;
|
||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
|
@ -1034,7 +1034,7 @@ pub fn build_header_help<'ctx>(
|
|||
|
||||
// this should be `Linkage::Private`, but that will remove all of the code for the inc/dec
|
||||
// functions on windows. LLVM just does not emit the assembly for them. Investigate why this is
|
||||
let linkage = if let roc_target::OperatingSystem::Windows = env.target_info.operating_system {
|
||||
let linkage = if let roc_target::OperatingSystem::Windows = env.target.operating_system() {
|
||||
Linkage::External
|
||||
} else {
|
||||
Linkage::Private
|
||||
|
@ -1162,7 +1162,7 @@ fn build_rec_union_help<'a, 'ctx>(
|
|||
|
||||
debug_assert!(arg_val.is_pointer_value());
|
||||
let current_tag_id = get_tag_id(env, layout_interner, fn_val, &union_layout, arg_val);
|
||||
let value_ptr = if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||
let value_ptr = if union_layout.stores_tag_id_in_pointer(env.target) {
|
||||
tag_pointer_clear_tag_id(env, arg_val.into_pointer_value())
|
||||
} else {
|
||||
arg_val.into_pointer_value()
|
||||
|
|
|
@ -31,8 +31,7 @@ use crate::layout::{ReturnMethod, WasmLayout};
|
|||
use crate::low_level::{call_higher_order_lowlevel, LowLevelCall};
|
||||
use crate::storage::{AddressValue, Storage, StoredValue, StoredVarKind};
|
||||
use crate::{
|
||||
copy_memory, CopyMemoryConfig, Env, DEBUG_SETTINGS, MEMORY_NAME, PTR_SIZE, PTR_TYPE,
|
||||
TARGET_INFO,
|
||||
copy_memory, CopyMemoryConfig, Env, DEBUG_SETTINGS, MEMORY_NAME, PTR_SIZE, PTR_TYPE, TARGET,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -1651,8 +1650,8 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
return;
|
||||
}
|
||||
|
||||
let stores_tag_id_as_data = union_layout.stores_tag_id_as_data(TARGET_INFO);
|
||||
let stores_tag_id_in_pointer = union_layout.stores_tag_id_in_pointer(TARGET_INFO);
|
||||
let stores_tag_id_as_data = union_layout.stores_tag_id_as_data(TARGET);
|
||||
let stores_tag_id_in_pointer = union_layout.stores_tag_id_in_pointer(TARGET);
|
||||
let (data_size, data_alignment) =
|
||||
union_layout.data_size_and_alignment(self.layout_interner);
|
||||
|
||||
|
@ -1774,7 +1773,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
}
|
||||
};
|
||||
|
||||
if union_layout.stores_tag_id_as_data(TARGET_INFO) {
|
||||
if union_layout.stores_tag_id_as_data(TARGET) {
|
||||
let id_offset = union_layout.tag_id_offset(self.layout_interner).unwrap();
|
||||
|
||||
let id_align = union_layout.discriminant().alignment_bytes();
|
||||
|
@ -1788,7 +1787,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
U0 | U1 | U8 => self.code_builder.i32_load8_u(id_align, id_offset),
|
||||
U16 => self.code_builder.i32_load16_u(id_align, id_offset),
|
||||
}
|
||||
} else if union_layout.stores_tag_id_in_pointer(TARGET_INFO) {
|
||||
} else if union_layout.stores_tag_id_in_pointer(TARGET) {
|
||||
self.storage
|
||||
.load_symbols(&mut self.code_builder, &[structure]);
|
||||
self.code_builder.i32_const(3);
|
||||
|
@ -1847,7 +1846,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
StoredValue::Local { local_id, .. } => (local_id, 0),
|
||||
};
|
||||
|
||||
let stores_tag_id_in_pointer = union_layout.stores_tag_id_in_pointer(TARGET_INFO);
|
||||
let stores_tag_id_in_pointer = union_layout.stores_tag_id_in_pointer(TARGET);
|
||||
|
||||
let from_addr_val = if stores_tag_id_in_pointer {
|
||||
self.code_builder.get_local(tag_local_id);
|
||||
|
@ -1912,7 +1911,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
StoredValue::Local { local_id, .. } => (*local_id, 0),
|
||||
};
|
||||
|
||||
let stores_tag_id_in_pointer = union_layout.stores_tag_id_in_pointer(TARGET_INFO);
|
||||
let stores_tag_id_in_pointer = union_layout.stores_tag_id_in_pointer(TARGET);
|
||||
|
||||
let from_offset = tag_offset + field_offset;
|
||||
|
||||
|
|
|
@ -18,16 +18,16 @@ use roc_module::symbol::{Interns, ModuleId, Symbol};
|
|||
use roc_mono::code_gen_help::CodeGenHelp;
|
||||
use roc_mono::ir::{Proc, ProcLayout};
|
||||
use roc_mono::layout::{LayoutIds, STLayoutInterner};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_wasm_module::parse::ParseError;
|
||||
use roc_wasm_module::{Align, LocalId, ValueType, WasmModule};
|
||||
|
||||
use crate::backend::{ProcLookupData, ProcSource, WasmBackend};
|
||||
use crate::code_builder::CodeBuilder;
|
||||
|
||||
const TARGET_INFO: TargetInfo = TargetInfo::default_wasm32();
|
||||
const TARGET: Target = Target::Wasm32;
|
||||
const PTR_SIZE: u32 = {
|
||||
let value = TARGET_INFO.ptr_width() as u32;
|
||||
let value = TARGET.ptr_width() as u32;
|
||||
|
||||
// const assert that our pointer width is actually 4
|
||||
// the code relies on the pointer width being exactly 4
|
||||
|
@ -135,7 +135,7 @@ pub fn build_app_module<'a, 'r>(
|
|||
host_to_app_map,
|
||||
host_module,
|
||||
fn_index_offset,
|
||||
CodeGenHelp::new(env.arena, TargetInfo::default_wasm32(), env.module_id),
|
||||
CodeGenHelp::new(env.arena, Target::Wasm32, env.module_id),
|
||||
);
|
||||
|
||||
if DEBUG_SETTINGS.user_procs_ir {
|
||||
|
|
|
@ -67,7 +67,8 @@ fn write_types_for_module_real(module_id: ModuleId, filename: &str, output_path:
|
|||
let arena = Bump::new();
|
||||
let cwd = std::env::current_dir().unwrap();
|
||||
let source = roc_builtins::roc::module_source(module_id);
|
||||
let target_info = roc_target::TargetInfo::default_x86_64();
|
||||
// This is just for typechecking. Target shouldn't matter.
|
||||
let target = roc_target::Target::LinuxX64;
|
||||
let function_kind = roc_solve::FunctionKind::LambdaSet;
|
||||
|
||||
let res_module = roc_load_internal::file::load_and_typecheck_str(
|
||||
|
@ -76,7 +77,7 @@ fn write_types_for_module_real(module_id: ModuleId, filename: &str, output_path:
|
|||
source,
|
||||
cwd,
|
||||
Default::default(),
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
roc_reporting::report::DEFAULT_PALETTE,
|
||||
|
|
|
@ -6,7 +6,7 @@ use roc_collections::all::MutMap;
|
|||
use roc_module::symbol::ModuleId;
|
||||
use roc_packaging::cache::RocCacheDir;
|
||||
use roc_reporting::report::{Palette, RenderTarget};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use std::path::PathBuf;
|
||||
|
||||
const SKIP_SUBS_CACHE: bool = {
|
||||
|
@ -51,7 +51,7 @@ fn load<'a>(
|
|||
pub fn load_single_threaded<'a>(
|
||||
arena: &'a Bump,
|
||||
load_start: LoadStart<'a>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
render: RenderTarget,
|
||||
palette: Palette,
|
||||
|
@ -65,7 +65,7 @@ pub fn load_single_threaded<'a>(
|
|||
arena,
|
||||
load_start,
|
||||
exposed_types,
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
cached_subs,
|
||||
render,
|
||||
|
@ -172,7 +172,7 @@ pub fn load_and_typecheck_str<'a>(
|
|||
filename: PathBuf,
|
||||
source: &'a str,
|
||||
src_dir: PathBuf,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
render: RenderTarget,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
|
@ -188,7 +188,7 @@ pub fn load_and_typecheck_str<'a>(
|
|||
match load_single_threaded(
|
||||
arena,
|
||||
load_start,
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render,
|
||||
palette,
|
||||
|
|
|
@ -123,7 +123,7 @@ mod test_reporting {
|
|||
let mut file = File::create(file_path).unwrap();
|
||||
writeln!(file, "{module_src}").unwrap();
|
||||
let load_config = LoadConfig {
|
||||
target_info: roc_target::TargetInfo::default_x86_64(),
|
||||
target: roc_target::Target::LinuxX64,
|
||||
render: RenderTarget::Generic,
|
||||
palette: DEFAULT_PALETTE,
|
||||
threading: Threading::Single,
|
||||
|
|
|
@ -64,7 +64,7 @@ use roc_reporting::report::{to_file_problem_report_string, Palette, RenderTarget
|
|||
use roc_solve::module::{extract_module_owned_implementations, SolveConfig, Solved, SolvedModule};
|
||||
use roc_solve::FunctionKind;
|
||||
use roc_solve_problem::TypeError;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_types::subs::{CopiedImport, ExposedTypesStorageSubs, Subs, VarStore, Variable};
|
||||
use roc_types::types::{Alias, Types};
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
|
@ -104,7 +104,7 @@ macro_rules! log {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct LoadConfig {
|
||||
pub target_info: TargetInfo,
|
||||
pub target: Target,
|
||||
pub render: RenderTarget,
|
||||
pub palette: Palette,
|
||||
pub threading: Threading,
|
||||
|
@ -453,7 +453,7 @@ fn start_phase<'a>(
|
|||
Subs::default(),
|
||||
None, // no expectations for derived module
|
||||
ProcsBase::default(),
|
||||
LayoutCache::new(state.layout_interner.fork(), state.target_info),
|
||||
LayoutCache::new(state.layout_interner.fork(), state.target),
|
||||
ModuleTiming::new(Instant::now()),
|
||||
)
|
||||
} else if state.make_specializations_pass.current_pass() == 1 {
|
||||
|
@ -512,7 +512,7 @@ fn start_phase<'a>(
|
|||
&mut ident_ids,
|
||||
&state.derived_module,
|
||||
&mut module_timing,
|
||||
state.target_info,
|
||||
state.target,
|
||||
&state.exposed_types,
|
||||
&mut procs_base,
|
||||
&mut state.world_abilities,
|
||||
|
@ -691,7 +691,7 @@ struct State<'a> {
|
|||
pub platform_data: Option<PlatformData<'a>>,
|
||||
pub exposed_types: ExposedByModule,
|
||||
pub platform_path: PlatformPath<'a>,
|
||||
pub target_info: TargetInfo,
|
||||
pub target: Target,
|
||||
pub(self) function_kind: FunctionKind,
|
||||
|
||||
/// Note: only packages and platforms actually expose any modules;
|
||||
|
@ -755,7 +755,7 @@ impl<'a> State<'a> {
|
|||
root_id: ModuleId,
|
||||
root_path: PathBuf,
|
||||
opt_platform_shorthand: Option<&'a str>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
exposed_types: ExposedByModule,
|
||||
arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
|
||||
|
@ -776,7 +776,7 @@ impl<'a> State<'a> {
|
|||
root_subs: None,
|
||||
opt_platform_shorthand,
|
||||
cache_dir,
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
platform_data: None,
|
||||
platform_path: PlatformPath::NotSpecified,
|
||||
|
@ -803,7 +803,7 @@ impl<'a> State<'a> {
|
|||
exec_mode,
|
||||
make_specializations_pass: MakeSpecializationsPass::Pass(1),
|
||||
world_abilities: Default::default(),
|
||||
layout_interner: GlobalLayoutInterner::with_capacity(128, target_info),
|
||||
layout_interner: GlobalLayoutInterner::with_capacity(128, target),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1033,7 +1033,7 @@ pub fn load_and_typecheck_str<'a>(
|
|||
source: &'a str,
|
||||
src_dir: PathBuf,
|
||||
exposed_types: ExposedByModule,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
render: RenderTarget,
|
||||
palette: Palette,
|
||||
|
@ -1049,7 +1049,7 @@ pub fn load_and_typecheck_str<'a>(
|
|||
let cached_subs = MutMap::default();
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
render,
|
||||
palette,
|
||||
threading,
|
||||
|
@ -1317,7 +1317,7 @@ pub fn load<'a>(
|
|||
arena,
|
||||
load_start,
|
||||
exposed_types,
|
||||
load_config.target_info,
|
||||
load_config.target,
|
||||
load_config.function_kind,
|
||||
cached_types,
|
||||
load_config.render,
|
||||
|
@ -1329,7 +1329,7 @@ pub fn load<'a>(
|
|||
arena,
|
||||
load_start,
|
||||
exposed_types,
|
||||
load_config.target_info,
|
||||
load_config.target,
|
||||
load_config.function_kind,
|
||||
cached_types,
|
||||
load_config.render,
|
||||
|
@ -1346,7 +1346,7 @@ pub fn load_single_threaded<'a>(
|
|||
arena: &'a Bump,
|
||||
load_start: LoadStart<'a>,
|
||||
exposed_types: ExposedByModule,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
cached_types: MutMap<ModuleId, TypeState>,
|
||||
render: RenderTarget,
|
||||
|
@ -1376,7 +1376,7 @@ pub fn load_single_threaded<'a>(
|
|||
root_id,
|
||||
root_path,
|
||||
opt_platform_shorthand,
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
exposed_types,
|
||||
arc_modules,
|
||||
|
@ -1427,7 +1427,7 @@ pub fn load_single_threaded<'a>(
|
|||
&msg_tx,
|
||||
&src_dir,
|
||||
roc_cache_dir,
|
||||
target_info,
|
||||
target,
|
||||
);
|
||||
|
||||
match control_flow {
|
||||
|
@ -1672,7 +1672,7 @@ fn load_multi_threaded<'a>(
|
|||
arena: &'a Bump,
|
||||
load_start: LoadStart<'a>,
|
||||
exposed_types: ExposedByModule,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
cached_types: MutMap<ModuleId, TypeState>,
|
||||
render: RenderTarget,
|
||||
|
@ -1718,7 +1718,7 @@ fn load_multi_threaded<'a>(
|
|||
root_id,
|
||||
root_path,
|
||||
opt_platform_shorthand,
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
exposed_types,
|
||||
arc_modules,
|
||||
|
@ -1794,7 +1794,7 @@ fn load_multi_threaded<'a>(
|
|||
msg_tx,
|
||||
src_dir,
|
||||
roc_cache_dir,
|
||||
target_info,
|
||||
target,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -1923,7 +1923,7 @@ fn worker_task_step<'a>(
|
|||
msg_tx: &MsgSender<'a>,
|
||||
src_dir: &Path,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
) -> Result<ControlFlow<(), ()>, LoadingProblem<'a>> {
|
||||
match worker_msg_rx.try_recv() {
|
||||
Ok(msg) => {
|
||||
|
@ -1952,7 +1952,7 @@ fn worker_task_step<'a>(
|
|||
src_dir,
|
||||
msg_tx.clone(),
|
||||
roc_cache_dir,
|
||||
target_info,
|
||||
target,
|
||||
);
|
||||
|
||||
match result {
|
||||
|
@ -1997,7 +1997,7 @@ fn worker_task<'a>(
|
|||
msg_tx: MsgSender<'a>,
|
||||
src_dir: &Path,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
) -> Result<(), LoadingProblem<'a>> {
|
||||
// Keep listening until we receive a Shutdown msg
|
||||
for msg in worker_msg_rx.iter() {
|
||||
|
@ -2051,7 +2051,7 @@ fn worker_task<'a>(
|
|||
src_dir,
|
||||
msg_tx.clone(),
|
||||
roc_cache_dir,
|
||||
target_info,
|
||||
target,
|
||||
);
|
||||
|
||||
match result {
|
||||
|
@ -2720,7 +2720,7 @@ fn update<'a>(
|
|||
|
||||
if state.goal_phase() > Phase::SolveTypes || state.exec_mode.build_if_checks() {
|
||||
let layout_cache = state.layout_caches.pop().unwrap_or_else(|| {
|
||||
LayoutCache::new(state.layout_interner.fork(), state.target_info)
|
||||
LayoutCache::new(state.layout_interner.fork(), state.target)
|
||||
});
|
||||
|
||||
let typechecked = TypeCheckedModule {
|
||||
|
@ -2948,7 +2948,7 @@ fn update<'a>(
|
|||
}
|
||||
|
||||
let layout_interner = {
|
||||
let mut taken = GlobalLayoutInterner::with_capacity(0, state.target_info);
|
||||
let mut taken = GlobalLayoutInterner::with_capacity(0, state.target);
|
||||
std::mem::swap(&mut state.layout_interner, &mut taken);
|
||||
taken
|
||||
};
|
||||
|
@ -3001,7 +3001,7 @@ fn update<'a>(
|
|||
arena,
|
||||
&layout_interner,
|
||||
module_id,
|
||||
state.target_info,
|
||||
state.target,
|
||||
ident_ids,
|
||||
&mut update_mode_ids,
|
||||
&mut state.procedures,
|
||||
|
@ -5676,7 +5676,7 @@ fn make_specializations<'a>(
|
|||
mut layout_cache: LayoutCache<'a>,
|
||||
specializations_we_must_make: Vec<ExternalSpecializations<'a>>,
|
||||
mut module_timing: ModuleTiming,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
world_abilities: WorldAbilities,
|
||||
exposed_by_module: &ExposedByModule,
|
||||
derived_module: SharedDerivedModule,
|
||||
|
@ -5691,7 +5691,7 @@ fn make_specializations<'a>(
|
|||
expectation_subs: expectations.as_mut().map(|e| &mut e.subs),
|
||||
home,
|
||||
ident_ids: &mut ident_ids,
|
||||
target_info,
|
||||
target,
|
||||
update_mode_ids: &mut update_mode_ids,
|
||||
// call_specialization_counter=0 is reserved
|
||||
call_specialization_counter: 1,
|
||||
|
@ -5762,7 +5762,7 @@ fn build_pending_specializations<'a>(
|
|||
declarations: Declarations,
|
||||
mut module_timing: ModuleTiming,
|
||||
mut layout_cache: LayoutCache<'a>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
exposed_to_host: ExposedToHost,
|
||||
exposed_by_module: &ExposedByModule,
|
||||
world_abilities: WorldAbilities,
|
||||
|
@ -5791,7 +5791,7 @@ fn build_pending_specializations<'a>(
|
|||
expectation_subs: expectations.as_mut().map(|e| &mut e.subs),
|
||||
home,
|
||||
ident_ids: &mut ident_ids,
|
||||
target_info,
|
||||
target,
|
||||
update_mode_ids: &mut update_mode_ids,
|
||||
// call_specialization_counter=0 is reserved
|
||||
call_specialization_counter: 1,
|
||||
|
@ -6241,7 +6241,7 @@ fn load_derived_partial_procs<'a>(
|
|||
ident_ids: &mut IdentIds,
|
||||
derived_module: &SharedDerivedModule,
|
||||
module_timing: &mut ModuleTiming,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
exposed_by_module: &ExposedByModule,
|
||||
procs_base: &mut ProcsBase<'a>,
|
||||
world_abilities: &mut WorldAbilities,
|
||||
|
@ -6272,7 +6272,7 @@ fn load_derived_partial_procs<'a>(
|
|||
expectation_subs: None,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
target,
|
||||
update_mode_ids: &mut update_mode_ids,
|
||||
// call_specialization_counter=0 is reserved
|
||||
call_specialization_counter: 1,
|
||||
|
@ -6346,7 +6346,7 @@ fn run_task<'a>(
|
|||
src_dir: &Path,
|
||||
msg_tx: MsgSender<'a>,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
) -> Result<(), LoadingProblem<'a>> {
|
||||
use BuildTask::*;
|
||||
|
||||
|
@ -6451,7 +6451,7 @@ fn run_task<'a>(
|
|||
decls,
|
||||
module_timing,
|
||||
layout_cache,
|
||||
target_info,
|
||||
target,
|
||||
exposed_to_host,
|
||||
&exposed_by_module,
|
||||
world_abilities,
|
||||
|
@ -6480,7 +6480,7 @@ fn run_task<'a>(
|
|||
layout_cache,
|
||||
specializations_we_must_make,
|
||||
module_timing,
|
||||
target_info,
|
||||
target,
|
||||
world_abilities,
|
||||
&exposed_by_module,
|
||||
derived_module,
|
||||
|
|
|
@ -31,7 +31,7 @@ use roc_reporting::report::RocDocAllocator;
|
|||
use roc_reporting::report::{can_problem, DEFAULT_PALETTE};
|
||||
use roc_reporting::report::{strip_colors, RenderTarget};
|
||||
use roc_solve::FunctionKind;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_types::pretty_print::name_and_print_var;
|
||||
use roc_types::pretty_print::DebugPrint;
|
||||
use std::collections::HashMap;
|
||||
|
@ -41,7 +41,7 @@ fn load_and_typecheck(
|
|||
arena: &Bump,
|
||||
filename: PathBuf,
|
||||
exposed_types: ExposedByModule,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
) -> Result<LoadedModule, LoadingProblem> {
|
||||
use LoadResult::*;
|
||||
|
@ -54,7 +54,7 @@ fn load_and_typecheck(
|
|||
DEFAULT_PALETTE,
|
||||
)?;
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render: RenderTarget::Generic,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
@ -75,7 +75,7 @@ fn load_and_typecheck(
|
|||
}
|
||||
}
|
||||
|
||||
const TARGET_INFO: roc_target::TargetInfo = roc_target::TargetInfo::default_x86_64();
|
||||
const TARGET: Target = Target::LinuxX64;
|
||||
|
||||
// HELPERS
|
||||
|
||||
|
@ -184,7 +184,7 @@ fn multiple_modules_help<'a>(
|
|||
arena,
|
||||
full_file_path,
|
||||
Default::default(),
|
||||
TARGET_INFO,
|
||||
TARGET,
|
||||
FunctionKind::LambdaSet,
|
||||
)
|
||||
};
|
||||
|
@ -204,7 +204,7 @@ fn load_fixture(
|
|||
&arena,
|
||||
filename,
|
||||
subs_by_module,
|
||||
TARGET_INFO,
|
||||
TARGET,
|
||||
FunctionKind::LambdaSet,
|
||||
);
|
||||
let mut loaded_module = match loaded {
|
||||
|
@ -367,7 +367,7 @@ fn interface_with_deps() {
|
|||
&arena,
|
||||
filename,
|
||||
subs_by_module,
|
||||
TARGET_INFO,
|
||||
TARGET,
|
||||
FunctionKind::LambdaSet,
|
||||
);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use bumpalo::collections::CollectIn;
|
|||
use bumpalo::Bump;
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
use crate::ir::{
|
||||
BranchInfo, Call, CallSpecId, CallType, Expr, JoinPointId, Literal, ModifyRc, PassedFunction,
|
||||
|
@ -93,20 +93,20 @@ pub struct Context<'a> {
|
|||
pub struct CodeGenHelp<'a> {
|
||||
arena: &'a Bump,
|
||||
home: ModuleId,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
layout_isize: InLayout<'a>,
|
||||
specializations: Vec<'a, Specialization<'a>>,
|
||||
debug_recursion_depth: usize,
|
||||
}
|
||||
|
||||
impl<'a> CodeGenHelp<'a> {
|
||||
pub fn new(arena: &'a Bump, target_info: TargetInfo, home: ModuleId) -> Self {
|
||||
let layout_isize = Layout::isize(target_info);
|
||||
pub fn new(arena: &'a Bump, target: Target, home: ModuleId) -> Self {
|
||||
let layout_isize = Layout::isize(target);
|
||||
|
||||
CodeGenHelp {
|
||||
arena,
|
||||
home,
|
||||
target_info,
|
||||
target,
|
||||
layout_isize,
|
||||
specializations: Vec::with_capacity_in(16, arena),
|
||||
debug_recursion_depth: 0,
|
||||
|
|
|
@ -383,7 +383,7 @@ pub fn refcount_reset_proc_body<'a>(
|
|||
};
|
||||
|
||||
// Constant for unique refcount
|
||||
let refcount_1_encoded = match root.target_info.ptr_width() {
|
||||
let refcount_1_encoded = match root.target.ptr_width() {
|
||||
PtrWidth::Bytes4 => i32::MIN as i128,
|
||||
PtrWidth::Bytes8 => i64::MIN as i128,
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ pub fn refcount_reset_proc_body<'a>(
|
|||
);
|
||||
|
||||
let mask_lower_bits = match layout_interner.get_repr(layout) {
|
||||
LayoutRepr::Union(ul) => ul.stores_tag_id_in_pointer(root.target_info),
|
||||
LayoutRepr::Union(ul) => ul.stores_tag_id_in_pointer(root.target),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -508,7 +508,7 @@ pub fn refcount_resetref_proc_body<'a>(
|
|||
};
|
||||
|
||||
// Constant for unique refcount
|
||||
let refcount_1_encoded = match root.target_info.ptr_width() {
|
||||
let refcount_1_encoded = match root.target.ptr_width() {
|
||||
PtrWidth::Bytes4 => i32::MIN as i128,
|
||||
PtrWidth::Bytes8 => i64::MIN as i128,
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ pub fn refcount_resetref_proc_body<'a>(
|
|||
);
|
||||
|
||||
let mask_lower_bits = match layout_interner.get_repr(layout) {
|
||||
LayoutRepr::Union(ul) => ul.stores_tag_id_in_pointer(root.target_info),
|
||||
LayoutRepr::Union(ul) => ul.stores_tag_id_in_pointer(root.target),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -617,7 +617,7 @@ fn rc_ptr_from_data_ptr_help<'a>(
|
|||
// Pointer size constant
|
||||
let ptr_size_sym = root.create_symbol(ident_ids, "ptr_size");
|
||||
let ptr_size_expr = Expr::Literal(Literal::Int(
|
||||
(root.target_info.ptr_width() as i128).to_ne_bytes(),
|
||||
(root.target.ptr_width() as i128).to_ne_bytes(),
|
||||
));
|
||||
let ptr_size_stmt = |next| Stmt::Let(ptr_size_sym, ptr_size_expr, root.layout_isize, next);
|
||||
|
||||
|
@ -630,7 +630,7 @@ fn rc_ptr_from_data_ptr_help<'a>(
|
|||
},
|
||||
arguments: root.arena.alloc([addr_sym, ptr_size_sym]),
|
||||
});
|
||||
let sub_stmt = |next| Stmt::Let(rc_addr_sym, sub_expr, Layout::usize(root.target_info), next);
|
||||
let sub_stmt = |next| Stmt::Let(rc_addr_sym, sub_expr, Layout::usize(root.target), next);
|
||||
|
||||
// Typecast the refcount address from integer to pointer
|
||||
let cast_expr = Expr::Call(Call {
|
||||
|
@ -697,7 +697,7 @@ fn modify_refcount<'a>(
|
|||
}
|
||||
|
||||
HelperOp::Dec | HelperOp::DecRef(_) => {
|
||||
debug_assert!(alignment >= root.target_info.ptr_width() as u32);
|
||||
debug_assert!(alignment >= root.target.ptr_width() as u32);
|
||||
|
||||
let (op, ptr) = match ptr {
|
||||
Pointer::ToData(s) => (LowLevel::RefCountDecDataPtr, s),
|
||||
|
@ -780,7 +780,7 @@ fn refcount_str<'a>(
|
|||
};
|
||||
let length_stmt = |next| Stmt::Let(length, length_expr, layout_isize, next);
|
||||
|
||||
let alignment = root.target_info.ptr_width() as u32;
|
||||
let alignment = root.target.ptr_width() as u32;
|
||||
|
||||
// let is_slice = lowlevel NumLt length zero
|
||||
let is_slice = root.create_symbol(ident_ids, "is_slice");
|
||||
|
@ -1032,7 +1032,7 @@ fn refcount_list<'a>(
|
|||
//
|
||||
|
||||
let alignment = Ord::max(
|
||||
root.target_info.ptr_width() as u32,
|
||||
root.target.ptr_width() as u32,
|
||||
layout_interner.alignment_bytes(elem_layout),
|
||||
);
|
||||
|
||||
|
|
|
@ -1181,7 +1181,7 @@ fn specialize_list<'a, 'i>(
|
|||
newer_continuation = arena.alloc(Stmt::Let(
|
||||
index_symbol,
|
||||
Expr::Literal(Literal::Int(i128::to_ne_bytes(i as i128))),
|
||||
Layout::isize(layout_interner.target_info()),
|
||||
Layout::isize(layout_interner.target()),
|
||||
index,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
|||
use roc_problem::can::{RuntimeError, ShadowKind};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use roc_std::RocDec;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_types::subs::{
|
||||
instantiate_rigids, storage_copy_var_to, Content, ExhaustiveMark, FlatType, RedundantMark,
|
||||
StorageSubs, Subs, Variable, VariableSubsSlice,
|
||||
|
@ -1354,7 +1354,7 @@ pub struct Env<'a, 'i> {
|
|||
pub expectation_subs: Option<&'i mut Subs>,
|
||||
pub home: ModuleId,
|
||||
pub ident_ids: &'i mut IdentIds,
|
||||
pub target_info: TargetInfo,
|
||||
pub target: Target,
|
||||
pub update_mode_ids: &'i mut UpdateModeIds,
|
||||
pub call_specialization_counter: u32,
|
||||
// TODO: WorldAbilities and exposed_by_module share things, think about how to combine them
|
||||
|
|
|
@ -1779,7 +1779,7 @@ fn test_to_comparison<'a>(
|
|||
let real_len = env.unique_symbol();
|
||||
let test_len = env.unique_symbol();
|
||||
|
||||
let usize_layout = Layout::usize(env.target_info);
|
||||
let usize_layout = Layout::usize(env.target);
|
||||
|
||||
stores.push((real_len, usize_layout, real_len_expr));
|
||||
stores.push((test_len, usize_layout, test_len_expr));
|
||||
|
@ -2337,7 +2337,7 @@ fn decide_to_branching<'a>(
|
|||
let len_symbol = env.unique_symbol();
|
||||
|
||||
let switch = Stmt::Switch {
|
||||
cond_layout: Layout::usize(env.target_info),
|
||||
cond_layout: Layout::usize(env.target),
|
||||
cond_symbol: len_symbol,
|
||||
branches: branches.into_bump_slice(),
|
||||
default_branch: (default_branch_info, env.arena.alloc(default_branch)),
|
||||
|
@ -2355,7 +2355,7 @@ fn decide_to_branching<'a>(
|
|||
Stmt::Let(
|
||||
len_symbol,
|
||||
len_expr,
|
||||
Layout::usize(env.target_info),
|
||||
Layout::usize(env.target),
|
||||
env.arena.alloc(switch),
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -10,7 +10,7 @@ use roc_error_macros::{internal_error, todo_abilities};
|
|||
use roc_module::ident::{Lowercase, TagName};
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_problem::can::RuntimeError;
|
||||
use roc_target::{PtrWidth, TargetInfo};
|
||||
use roc_target::{PtrWidth, Target};
|
||||
use roc_types::num::NumericRange;
|
||||
use roc_types::subs::{
|
||||
self, Content, FlatType, GetSubsSlice, OptVariable, RecordFields, Subs, TagExt, TupleElems,
|
||||
|
@ -114,7 +114,7 @@ macro_rules! inc_stat {
|
|||
/// Layout cache to avoid recomputing [Layout] from a [Variable] multiple times.
|
||||
#[derive(Debug)]
|
||||
pub struct LayoutCache<'a> {
|
||||
pub target_info: TargetInfo,
|
||||
pub target: Target,
|
||||
cache: std::vec::Vec<CacheLayer<LayoutResult<'a>>>,
|
||||
raw_function_cache: std::vec::Vec<CacheLayer<RawFunctionLayoutResult<'a>>>,
|
||||
|
||||
|
@ -128,13 +128,13 @@ pub struct LayoutCache<'a> {
|
|||
}
|
||||
|
||||
impl<'a> LayoutCache<'a> {
|
||||
pub fn new(interner: TLLayoutInterner<'a>, target_info: TargetInfo) -> Self {
|
||||
pub fn new(interner: TLLayoutInterner<'a>, target: Target) -> Self {
|
||||
let mut cache = std::vec::Vec::with_capacity(4);
|
||||
cache.push(Default::default());
|
||||
let mut raw_cache = std::vec::Vec::with_capacity(4);
|
||||
raw_cache.push(Default::default());
|
||||
Self {
|
||||
target_info,
|
||||
target,
|
||||
cache,
|
||||
raw_function_cache: raw_cache,
|
||||
|
||||
|
@ -964,39 +964,39 @@ impl<'a> UnionLayout<'a> {
|
|||
self.discriminant().layout()
|
||||
}
|
||||
|
||||
fn stores_tag_id_in_pointer_bits(tags: &[&[InLayout<'a>]], target_info: TargetInfo) -> bool {
|
||||
tags.len() < target_info.ptr_width() as usize
|
||||
fn stores_tag_id_in_pointer_bits(tags: &[&[InLayout<'a>]], target: Target) -> bool {
|
||||
tags.len() < target.ptr_width() as usize
|
||||
}
|
||||
|
||||
pub const POINTER_MASK_32BIT: usize = 0b0000_0111;
|
||||
pub const POINTER_MASK_64BIT: usize = 0b0000_0011;
|
||||
|
||||
pub fn tag_id_pointer_bits_and_mask(target_info: TargetInfo) -> (usize, usize) {
|
||||
match target_info.ptr_width() {
|
||||
pub fn tag_id_pointer_bits_and_mask(target: Target) -> (usize, usize) {
|
||||
match target.ptr_width() {
|
||||
PtrWidth::Bytes8 => (3, Self::POINTER_MASK_64BIT),
|
||||
PtrWidth::Bytes4 => (2, Self::POINTER_MASK_32BIT),
|
||||
}
|
||||
}
|
||||
|
||||
// i.e. it is not implicit and not stored in the pointer bits
|
||||
pub fn stores_tag_id_as_data(&self, target_info: TargetInfo) -> bool {
|
||||
pub fn stores_tag_id_as_data(&self, target: Target) -> bool {
|
||||
match self {
|
||||
UnionLayout::NonRecursive(_) => true,
|
||||
UnionLayout::Recursive(tags)
|
||||
| UnionLayout::NullableWrapped {
|
||||
other_tags: tags, ..
|
||||
} => !Self::stores_tag_id_in_pointer_bits(tags, target_info),
|
||||
} => !Self::stores_tag_id_in_pointer_bits(tags, target),
|
||||
UnionLayout::NonNullableUnwrapped(_) | UnionLayout::NullableUnwrapped { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stores_tag_id_in_pointer(&self, target_info: TargetInfo) -> bool {
|
||||
pub fn stores_tag_id_in_pointer(&self, target: Target) -> bool {
|
||||
match self {
|
||||
UnionLayout::NonRecursive(_) => false,
|
||||
UnionLayout::Recursive(tags)
|
||||
| UnionLayout::NullableWrapped {
|
||||
other_tags: tags, ..
|
||||
} => Self::stores_tag_id_in_pointer_bits(tags, target_info),
|
||||
} => Self::stores_tag_id_in_pointer_bits(tags, target),
|
||||
UnionLayout::NonNullableUnwrapped(_) | UnionLayout::NullableUnwrapped { .. } => false,
|
||||
}
|
||||
}
|
||||
|
@ -1049,7 +1049,7 @@ impl<'a> UnionLayout<'a> {
|
|||
};
|
||||
|
||||
// because we store a refcount, the alignment must be at least the size of a pointer
|
||||
allocation.max(interner.target_info().ptr_width() as u32)
|
||||
allocation.max(interner.target().ptr_width() as u32)
|
||||
}
|
||||
|
||||
/// Size of the data in memory, whether it's stack or heap (for non-null tag ids)
|
||||
|
@ -1059,7 +1059,7 @@ impl<'a> UnionLayout<'a> {
|
|||
{
|
||||
let (data_width, data_align) = self.data_size_and_alignment_help_match(interner);
|
||||
|
||||
if self.stores_tag_id_as_data(interner.target_info()) {
|
||||
if self.stores_tag_id_as_data(interner.target()) {
|
||||
use Discriminant::*;
|
||||
match self.discriminant() {
|
||||
U0 => (round_up_to_alignment(data_width, data_align), data_align),
|
||||
|
@ -1089,7 +1089,7 @@ impl<'a> UnionLayout<'a> {
|
|||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
if !self.stores_tag_id_as_data(interner.target_info()) {
|
||||
if !self.stores_tag_id_as_data(interner.target()) {
|
||||
return None;
|
||||
};
|
||||
|
||||
|
@ -1151,7 +1151,7 @@ impl<'a> UnionLayout<'a> {
|
|||
UnionLayout::Recursive(_)
|
||||
| UnionLayout::NonNullableUnwrapped(_)
|
||||
| UnionLayout::NullableWrapped { .. }
|
||||
| UnionLayout::NullableUnwrapped { .. } => interner.target_info().ptr_width() as u32,
|
||||
| UnionLayout::NullableUnwrapped { .. } => interner.target().ptr_width() as u32,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2686,7 +2686,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
LayoutRepr::Builtin(builtin) => {
|
||||
use Builtin::*;
|
||||
|
||||
match interner.target_info().ptr_width() {
|
||||
match interner.target().ptr_width() {
|
||||
PtrWidth::Bytes4 => {
|
||||
// more things fit into a register
|
||||
false
|
||||
|
@ -2700,7 +2700,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => true,
|
||||
LayoutRepr::Struct(_) => {
|
||||
// TODO: write tests for this!
|
||||
self.stack_size(interner) as usize > interner.target_info().max_by_value_size()
|
||||
self.stack_size(interner) as usize > interner.target().max_by_value_size()
|
||||
}
|
||||
|
||||
LayoutRepr::LambdaSet(lambda_set) => interner
|
||||
|
@ -2739,7 +2739,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
use LayoutRepr::*;
|
||||
|
||||
match self {
|
||||
Builtin(builtin) => builtin.stack_size(interner.target_info()),
|
||||
Builtin(builtin) => builtin.stack_size(interner.target()),
|
||||
Struct(field_layouts) => {
|
||||
let mut sum = 0;
|
||||
|
||||
|
@ -2754,9 +2754,9 @@ impl<'a> LayoutRepr<'a> {
|
|||
.get_repr(lambda_set.runtime_representation())
|
||||
.stack_size_without_alignment(interner),
|
||||
RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => {
|
||||
interner.target_info().ptr_width() as u32
|
||||
interner.target().ptr_width() as u32
|
||||
}
|
||||
Erased(e) => e.stack_size_without_alignment(interner.target_info()),
|
||||
Erased(e) => e.stack_size_without_alignment(interner.target()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2801,17 +2801,17 @@ impl<'a> LayoutRepr<'a> {
|
|||
Recursive(_)
|
||||
| NullableWrapped { .. }
|
||||
| NullableUnwrapped { .. }
|
||||
| NonNullableUnwrapped(_) => interner.target_info().ptr_width() as u32,
|
||||
| NonNullableUnwrapped(_) => interner.target().ptr_width() as u32,
|
||||
}
|
||||
}
|
||||
LambdaSet(lambda_set) => interner
|
||||
.get_repr(lambda_set.runtime_representation())
|
||||
.alignment_bytes(interner),
|
||||
Builtin(builtin) => builtin.alignment_bytes(interner.target_info()),
|
||||
Builtin(builtin) => builtin.alignment_bytes(interner.target()),
|
||||
RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => {
|
||||
interner.target_info().ptr_width() as u32
|
||||
interner.target().ptr_width() as u32
|
||||
}
|
||||
Erased(e) => e.alignment_bytes(interner.target_info()),
|
||||
Erased(e) => e.alignment_bytes(interner.target()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2819,7 +2819,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
let ptr_width = interner.target_info().ptr_width() as u32;
|
||||
let ptr_width = interner.target().ptr_width() as u32;
|
||||
|
||||
use LayoutRepr::*;
|
||||
match self {
|
||||
|
@ -2834,7 +2834,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
}
|
||||
Ptr(inner) => interner.get_repr(*inner).alignment_bytes(interner),
|
||||
FunctionPointer(_) => ptr_width,
|
||||
Erased(e) => e.allocation_alignment_bytes(interner.target_info()),
|
||||
Erased(e) => e.allocation_alignment_bytes(interner.target()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2994,15 +2994,15 @@ impl<'a> LayoutRepr<'a> {
|
|||
pub type SeenRecPtrs<'a> = VecSet<InLayout<'a>>;
|
||||
|
||||
impl<'a> Layout<'a> {
|
||||
pub fn usize(target_info: TargetInfo) -> InLayout<'a> {
|
||||
match target_info.ptr_width() {
|
||||
pub fn usize(target: Target) -> InLayout<'a> {
|
||||
match target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => Layout::U32,
|
||||
roc_target::PtrWidth::Bytes8 => Layout::U64,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isize(target_info: TargetInfo) -> InLayout<'a> {
|
||||
match target_info.ptr_width() {
|
||||
pub fn isize(target: Target) -> InLayout<'a> {
|
||||
match target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => Layout::I32,
|
||||
roc_target::PtrWidth::Bytes8 => Layout::I64,
|
||||
}
|
||||
|
@ -3067,10 +3067,10 @@ impl<'a> Builtin<'a> {
|
|||
pub const WRAPPER_LEN: u32 = 1;
|
||||
pub const WRAPPER_CAPACITY: u32 = 2;
|
||||
|
||||
pub fn stack_size(&self, target_info: TargetInfo) -> u32 {
|
||||
pub fn stack_size(&self, target: Target) -> u32 {
|
||||
use Builtin::*;
|
||||
|
||||
let ptr_width = target_info.ptr_width() as u32;
|
||||
let ptr_width = target.ptr_width() as u32;
|
||||
|
||||
match self {
|
||||
Int(int) => int.stack_size(),
|
||||
|
@ -3082,20 +3082,20 @@ impl<'a> Builtin<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn alignment_bytes(&self, target_info: TargetInfo) -> u32 {
|
||||
pub fn alignment_bytes(&self, target: Target) -> u32 {
|
||||
use std::mem::align_of;
|
||||
use Builtin::*;
|
||||
|
||||
let ptr_width = target_info.ptr_width() as u32;
|
||||
let ptr_width = target.ptr_width() as u32;
|
||||
|
||||
// for our data structures, what counts is the alignment of the `( ptr, len )` tuple, and
|
||||
// since both of those are one pointer size, the alignment of that structure is a pointer
|
||||
// size
|
||||
match self {
|
||||
Int(int_width) => int_width.alignment_bytes(target_info),
|
||||
Float(float_width) => float_width.alignment_bytes(target_info),
|
||||
Int(int_width) => int_width.alignment_bytes(target),
|
||||
Float(float_width) => float_width.alignment_bytes(target),
|
||||
Bool => align_of::<bool>() as u32,
|
||||
Decimal => IntWidth::I128.alignment_bytes(target_info),
|
||||
Decimal => IntWidth::I128.alignment_bytes(target),
|
||||
// we often treat these as i128 (64-bit systems)
|
||||
// or i64 (32-bit systems).
|
||||
//
|
||||
|
@ -3186,8 +3186,8 @@ impl<'a> Builtin<'a> {
|
|||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
let target_info = interner.target_info();
|
||||
let ptr_width = target_info.ptr_width() as u32;
|
||||
let target = interner.target();
|
||||
let ptr_width = target.ptr_width() as u32;
|
||||
|
||||
let allocation = match self {
|
||||
Builtin::Str => ptr_width,
|
||||
|
@ -3196,10 +3196,10 @@ impl<'a> Builtin<'a> {
|
|||
e.alignment_bytes(interner).max(ptr_width)
|
||||
}
|
||||
// The following are usually not heap-allocated, but they might be when inside a Box.
|
||||
Builtin::Int(int_width) => int_width.alignment_bytes(target_info).max(ptr_width),
|
||||
Builtin::Float(float_width) => float_width.alignment_bytes(target_info).max(ptr_width),
|
||||
Builtin::Int(int_width) => int_width.alignment_bytes(target).max(ptr_width),
|
||||
Builtin::Float(float_width) => float_width.alignment_bytes(target).max(ptr_width),
|
||||
Builtin::Bool => (core::mem::align_of::<bool>() as u32).max(ptr_width),
|
||||
Builtin::Decimal => IntWidth::I128.alignment_bytes(target_info).max(ptr_width),
|
||||
Builtin::Decimal => IntWidth::I128.alignment_bytes(target).max(ptr_width),
|
||||
};
|
||||
|
||||
allocation.max(ptr_width)
|
||||
|
@ -4788,7 +4788,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn width_and_alignment_union_empty_struct() {
|
||||
let mut interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||
let mut interner = STLayoutInterner::with_capacity(4, Target::LinuxX64);
|
||||
|
||||
let lambda_set = LambdaSet {
|
||||
args: &(&[] as &[InLayout]),
|
||||
|
@ -4813,7 +4813,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn memcpy_size_result_u32_unit() {
|
||||
let mut interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||
let mut interner = STLayoutInterner::with_capacity(4, Target::LinuxX64);
|
||||
|
||||
let ok_tag = &[interner.insert(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)).direct(),
|
||||
|
@ -4829,13 +4829,13 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn void_stack_size() {
|
||||
let interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||
let interner = STLayoutInterner::with_capacity(4, Target::LinuxX64);
|
||||
assert_eq!(Layout::VOID_NAKED.repr(&interner).stack_size(&interner), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn align_u128_in_tag_union() {
|
||||
let interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||
let interner = STLayoutInterner::with_capacity(4, Target::LinuxX64);
|
||||
assert_eq!(interner.alignment_bytes(Layout::U128), 16);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
use super::{InLayout, LayoutRepr, UnionLayout};
|
||||
|
||||
|
@ -27,16 +27,16 @@ impl Erased {
|
|||
false
|
||||
}
|
||||
|
||||
pub fn stack_size_without_alignment(&self, target_info: TargetInfo) -> u32 {
|
||||
(target_info.ptr_width() as u32) * 3
|
||||
pub fn stack_size_without_alignment(&self, target: Target) -> u32 {
|
||||
(target.ptr_width() as u32) * 3
|
||||
}
|
||||
|
||||
pub fn alignment_bytes(&self, target_info: TargetInfo) -> u32 {
|
||||
target_info.ptr_width() as u32
|
||||
pub fn alignment_bytes(&self, target: Target) -> u32 {
|
||||
target.ptr_width() as u32
|
||||
}
|
||||
|
||||
pub fn allocation_alignment_bytes(&self, target_info: TargetInfo) -> u32 {
|
||||
target_info.ptr_width() as u32
|
||||
pub fn allocation_alignment_bytes(&self, target: Target) -> u32 {
|
||||
target.ptr_width() as u32
|
||||
}
|
||||
|
||||
pub fn is_refcounted(&self) -> bool {
|
||||
|
|
|
@ -10,7 +10,7 @@ use parking_lot::{Mutex, RwLock};
|
|||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_collections::{default_hasher, BumpMap};
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
use crate::layout::LayoutRepr;
|
||||
|
||||
|
@ -208,7 +208,7 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
self.get_repr(a) == self.get_repr(b)
|
||||
}
|
||||
|
||||
fn target_info(&self) -> TargetInfo;
|
||||
fn target(&self) -> Target;
|
||||
|
||||
fn alignment_bytes(&self, layout: InLayout<'a>) -> u32 {
|
||||
self.get_repr(layout).alignment_bytes(self)
|
||||
|
@ -545,7 +545,7 @@ struct GlobalLayoutInternerInner<'a> {
|
|||
map: Mutex<BumpMap<Layout<'a>, InLayout<'a>>>,
|
||||
normalized_lambda_set_map: Mutex<BumpMap<LambdaSet<'a>, LambdaSet<'a>>>,
|
||||
vec: RwLock<Vec<Layout<'a>>>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
}
|
||||
|
||||
/// A derivative of a [GlobalLayoutInterner] interner that provides caching desirable for
|
||||
|
@ -564,7 +564,7 @@ pub struct TLLayoutInterner<'a> {
|
|||
normalized_lambda_set_map: BumpMap<LambdaSet<'a>, LambdaSet<'a>>,
|
||||
/// Cache of interned values from the parent for local access.
|
||||
vec: RefCell<Vec<Option<Layout<'a>>>>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
}
|
||||
|
||||
/// A single-threaded interner, with no concurrency properties.
|
||||
|
@ -576,7 +576,7 @@ pub struct STLayoutInterner<'a> {
|
|||
map: BumpMap<Layout<'a>, InLayout<'a>>,
|
||||
normalized_lambda_set_map: BumpMap<LambdaSet<'a>, LambdaSet<'a>>,
|
||||
vec: Vec<Layout<'a>>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
}
|
||||
|
||||
/// Interner constructed with an exclusive lock over [GlobalLayoutInterner]
|
||||
|
@ -584,7 +584,7 @@ struct LockedGlobalInterner<'a, 'r> {
|
|||
map: &'r mut BumpMap<Layout<'a>, InLayout<'a>>,
|
||||
normalized_lambda_set_map: &'r mut BumpMap<LambdaSet<'a>, LambdaSet<'a>>,
|
||||
vec: &'r mut Vec<Layout<'a>>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
}
|
||||
|
||||
/// Generic hasher for a value, to be used by all interners.
|
||||
|
@ -614,8 +614,8 @@ fn make_normalized_lamdba_set<'a>(
|
|||
|
||||
impl<'a> GlobalLayoutInterner<'a> {
|
||||
/// Creates a new global interner with the given capacity.
|
||||
pub fn with_capacity(cap: usize, target_info: TargetInfo) -> Self {
|
||||
STLayoutInterner::with_capacity(cap, target_info).into_global()
|
||||
pub fn with_capacity(cap: usize, target: Target) -> Self {
|
||||
STLayoutInterner::with_capacity(cap, target).into_global()
|
||||
}
|
||||
|
||||
/// Creates a derivative [TLLayoutInterner] pointing back to this global interner.
|
||||
|
@ -625,7 +625,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
|||
map: Default::default(),
|
||||
normalized_lambda_set_map: Default::default(),
|
||||
vec: Default::default(),
|
||||
target_info: self.0.target_info,
|
||||
target: self.0.target,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,7 +637,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
|||
map,
|
||||
normalized_lambda_set_map,
|
||||
vec,
|
||||
target_info,
|
||||
target,
|
||||
} = match Arc::try_unwrap(self.0) {
|
||||
Ok(inner) => inner,
|
||||
Err(li) => return Err(Self(li)),
|
||||
|
@ -649,7 +649,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
|||
map,
|
||||
normalized_lambda_set_map,
|
||||
vec,
|
||||
target_info,
|
||||
target,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -703,7 +703,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
|||
map: &mut map,
|
||||
normalized_lambda_set_map: &mut normalized_lambda_set_map,
|
||||
vec: &mut vec,
|
||||
target_info: self.0.target_info,
|
||||
target: self.0.target,
|
||||
};
|
||||
reify::reify_lambda_set_captures(arena, &mut interner, slot, normalized.set)
|
||||
} else {
|
||||
|
@ -765,7 +765,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
|||
map: &mut map,
|
||||
normalized_lambda_set_map: &mut normalized_lambda_set_map,
|
||||
vec: &mut vec,
|
||||
target_info: self.0.target_info,
|
||||
target: self.0.target,
|
||||
};
|
||||
let full_layout = reify::reify_recursive_layout(arena, &mut interner, slot, normalized);
|
||||
|
||||
|
@ -927,19 +927,19 @@ impl<'a> LayoutInterner<'a> for TLLayoutInterner<'a> {
|
|||
value
|
||||
}
|
||||
|
||||
fn target_info(&self) -> TargetInfo {
|
||||
self.target_info
|
||||
fn target(&self) -> Target {
|
||||
self.target
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> STLayoutInterner<'a> {
|
||||
/// Creates a new single threaded interner with the given capacity.
|
||||
pub fn with_capacity(cap: usize, target_info: TargetInfo) -> Self {
|
||||
pub fn with_capacity(cap: usize, target: Target) -> Self {
|
||||
let mut interner = Self {
|
||||
map: BumpMap::with_capacity_and_hasher(cap, default_hasher()),
|
||||
normalized_lambda_set_map: BumpMap::with_capacity_and_hasher(cap, default_hasher()),
|
||||
vec: Vec::with_capacity(cap),
|
||||
target_info,
|
||||
target,
|
||||
};
|
||||
fill_reserved_layouts(&mut interner);
|
||||
interner
|
||||
|
@ -954,13 +954,13 @@ impl<'a> STLayoutInterner<'a> {
|
|||
map,
|
||||
normalized_lambda_set_map,
|
||||
vec,
|
||||
target_info,
|
||||
target,
|
||||
} = self;
|
||||
GlobalLayoutInterner(Arc::new(GlobalLayoutInternerInner {
|
||||
map: Mutex::new(map),
|
||||
normalized_lambda_set_map: Mutex::new(normalized_lambda_set_map),
|
||||
vec: RwLock::new(vec),
|
||||
target_info,
|
||||
target,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -1072,8 +1072,8 @@ macro_rules! st_impl {
|
|||
self.vec[index]
|
||||
}
|
||||
|
||||
fn target_info(&self) -> TargetInfo {
|
||||
self.target_info
|
||||
fn target(&self) -> Target{
|
||||
self.target
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1758,13 +1758,13 @@ pub mod dbg_stable {
|
|||
mod insert_lambda_set {
|
||||
use bumpalo::Bump;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
use crate::layout::{LambdaSet, Layout, LayoutRepr, SemanticRepr};
|
||||
|
||||
use super::{GlobalLayoutInterner, InLayout, LayoutInterner, NeedsRecursionPointerFixup};
|
||||
|
||||
const TARGET_INFO: TargetInfo = TargetInfo::default_x86_64();
|
||||
const TARGET: Target = Target::LinuxX64;
|
||||
const TEST_SET: &&[(Symbol, &[InLayout])] =
|
||||
&(&[(Symbol::ATTR_ATTR, &[Layout::UNIT] as &[_])] as &[_]);
|
||||
const TEST_ARGS: &&[InLayout] = &(&[Layout::UNIT] as &[_]);
|
||||
|
@ -1776,7 +1776,7 @@ mod insert_lambda_set {
|
|||
fn two_threads_write() {
|
||||
for _ in 0..100 {
|
||||
let mut arenas: Vec<_> = std::iter::repeat_with(Bump::new).take(10).collect();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let set = TEST_SET;
|
||||
let repr = Layout::UNIT;
|
||||
std::thread::scope(|s| {
|
||||
|
@ -1797,7 +1797,7 @@ mod insert_lambda_set {
|
|||
#[test]
|
||||
fn insert_then_reintern() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let mut interner = global.fork();
|
||||
|
||||
let lambda_set =
|
||||
|
@ -1812,7 +1812,7 @@ mod insert_lambda_set {
|
|||
#[test]
|
||||
fn write_global_then_single_threaded() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let set = TEST_SET;
|
||||
let repr = Layout::UNIT;
|
||||
|
||||
|
@ -1832,7 +1832,7 @@ mod insert_lambda_set {
|
|||
#[test]
|
||||
fn write_single_threaded_then_global() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let mut st_interner = global.unwrap().unwrap();
|
||||
|
||||
let set = TEST_SET;
|
||||
|
@ -1852,13 +1852,13 @@ mod insert_lambda_set {
|
|||
#[cfg(test)]
|
||||
mod insert_recursive_layout {
|
||||
use bumpalo::Bump;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
use crate::layout::{Builtin, InLayout, Layout, LayoutRepr, SemanticRepr, UnionLayout};
|
||||
|
||||
use super::{GlobalLayoutInterner, LayoutInterner};
|
||||
|
||||
const TARGET_INFO: TargetInfo = TargetInfo::default_x86_64();
|
||||
const TARGET: Target = Target::LinuxX64;
|
||||
|
||||
fn make_layout<'a>(arena: &'a Bump, interner: &mut impl LayoutInterner<'a>) -> Layout<'a> {
|
||||
let list_rec = Layout {
|
||||
|
@ -1905,7 +1905,7 @@ mod insert_recursive_layout {
|
|||
#[test]
|
||||
fn write_two_threads() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let layout = {
|
||||
let mut interner = global.fork();
|
||||
make_layout(arena, &mut interner)
|
||||
|
@ -1927,7 +1927,7 @@ mod insert_recursive_layout {
|
|||
#[test]
|
||||
fn write_twice_thread_local_single_thread() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let mut interner = global.fork();
|
||||
let layout = make_layout(arena, &mut interner);
|
||||
|
||||
|
@ -1943,7 +1943,7 @@ mod insert_recursive_layout {
|
|||
#[test]
|
||||
fn write_twice_single_thread() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let mut interner = GlobalLayoutInterner::unwrap(global).unwrap();
|
||||
let layout = make_layout(arena, &mut interner);
|
||||
|
||||
|
@ -1960,7 +1960,7 @@ mod insert_recursive_layout {
|
|||
fn many_threads_read_write() {
|
||||
for _ in 0..100 {
|
||||
let mut arenas: Vec<_> = std::iter::repeat_with(Bump::new).take(10).collect();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
std::thread::scope(|s| {
|
||||
let mut handles = Vec::with_capacity(10);
|
||||
for arena in arenas.iter_mut() {
|
||||
|
@ -1983,7 +1983,7 @@ mod insert_recursive_layout {
|
|||
#[test]
|
||||
fn insert_then_reintern() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let mut interner = global.fork();
|
||||
|
||||
let layout = make_layout(arena, &mut interner);
|
||||
|
@ -1996,7 +1996,7 @@ mod insert_recursive_layout {
|
|||
#[test]
|
||||
fn write_global_then_single_threaded() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let layout = {
|
||||
let mut interner = global.fork();
|
||||
make_layout(arena, &mut interner)
|
||||
|
@ -2018,7 +2018,7 @@ mod insert_recursive_layout {
|
|||
#[test]
|
||||
fn write_single_threaded_then_global() {
|
||||
let arena = &Bump::new();
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET_INFO);
|
||||
let global = GlobalLayoutInterner::with_capacity(2, TARGET);
|
||||
let mut st_interner = global.unwrap().unwrap();
|
||||
|
||||
let layout = make_layout(arena, &mut st_interner);
|
||||
|
|
|
@ -20,7 +20,7 @@ use bumpalo::collections::CollectIn;
|
|||
use roc_collections::{MutMap, MutSet};
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
/**
|
||||
Insert reset and reuse operations into the IR.
|
||||
|
@ -30,7 +30,7 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
|||
arena: &'a Bump,
|
||||
layout_interner: &'i STLayoutInterner<'a>,
|
||||
home: ModuleId,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
ident_ids: &'i mut IdentIds,
|
||||
update_mode_ids: &'i mut UpdateModeIds,
|
||||
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
|
@ -44,7 +44,7 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
|||
let new_proc = insert_reset_reuse_operations_proc(
|
||||
arena,
|
||||
layout_interner,
|
||||
target_info,
|
||||
target,
|
||||
home,
|
||||
ident_ids,
|
||||
update_mode_ids,
|
||||
|
@ -58,7 +58,7 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
|||
fn insert_reset_reuse_operations_proc<'a, 'i>(
|
||||
arena: &'a Bump,
|
||||
layout_interner: &'i STLayoutInterner<'a>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
home: ModuleId,
|
||||
ident_ids: &'i mut IdentIds,
|
||||
update_mode_ids: &'i mut UpdateModeIds,
|
||||
|
@ -70,7 +70,7 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
|
|||
}
|
||||
|
||||
let mut env = ReuseEnvironment {
|
||||
target_info,
|
||||
target,
|
||||
symbol_tags: MutMap::default(),
|
||||
non_unique_symbols: MutSet::default(),
|
||||
reuse_tokens: MutMap::default(),
|
||||
|
@ -464,7 +464,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
),
|
||||
ModifyRc::Free(_) => {
|
||||
if union_layout
|
||||
.stores_tag_id_in_pointer(environment.target_info)
|
||||
.stores_tag_id_in_pointer(environment.target)
|
||||
{
|
||||
(
|
||||
Symbol::new(home, ident_ids.gen_unique()),
|
||||
|
@ -761,7 +761,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
|
||||
// Create a new environment for the body. With everything but the jump reuse tokens. As those should be given by the jump.
|
||||
let mut first_pass_body_environment = ReuseEnvironment {
|
||||
target_info: environment.target_info,
|
||||
target: environment.target,
|
||||
symbol_tags: environment.symbol_tags.clone(),
|
||||
non_unique_symbols: environment.non_unique_symbols.clone(),
|
||||
reuse_tokens: max_reuse_token_symbols.clone(),
|
||||
|
@ -924,7 +924,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
let (second_pass_body_environment, second_pass_body) = {
|
||||
// Create a new environment for the body. With everything but the jump reuse tokens. As those should be given by the jump.
|
||||
let mut body_environment = ReuseEnvironment {
|
||||
target_info: environment.target_info,
|
||||
target: environment.target,
|
||||
symbol_tags: environment.symbol_tags.clone(),
|
||||
non_unique_symbols: environment.non_unique_symbols.clone(),
|
||||
reuse_tokens: used_reuse_tokens.clone(),
|
||||
|
@ -1182,7 +1182,7 @@ enum JoinPointReuseTokens<'a> {
|
|||
|
||||
#[derive(Clone)]
|
||||
struct ReuseEnvironment<'a> {
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
symbol_tags: MutMap<Symbol, Tag>,
|
||||
non_unique_symbols: MutSet<Symbol>,
|
||||
reuse_tokens: ReuseTokens<'a>,
|
||||
|
|
|
@ -8,6 +8,8 @@ license.workspace = true
|
|||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
roc_error_macros = { path = "../../error_macros" }
|
||||
|
||||
strum.workspace = true
|
||||
strum_macros.workspace = true
|
||||
target-lexicon.workspace = true
|
||||
|
|
|
@ -3,70 +3,104 @@
|
|||
// See github.com/roc-lang/roc/issues/800 for discussion of the large_enum_variant check.
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
|
||||
use strum_macros::{EnumCount, EnumIter, EnumString, IntoStaticStr};
|
||||
use std::str::FromStr;
|
||||
|
||||
use roc_error_macros::user_error;
|
||||
use strum_macros::{EnumCount, EnumIter};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum OperatingSystem {
|
||||
Freestanding,
|
||||
Linux,
|
||||
Mac,
|
||||
Windows,
|
||||
Unix,
|
||||
Wasi,
|
||||
}
|
||||
|
||||
impl OperatingSystem {
|
||||
pub const fn new(target: target_lexicon::OperatingSystem) -> Option<Self> {
|
||||
match target {
|
||||
target_lexicon::OperatingSystem::Windows => Some(OperatingSystem::Windows),
|
||||
target_lexicon::OperatingSystem::Wasi => Some(OperatingSystem::Wasi),
|
||||
target_lexicon::OperatingSystem::Linux => Some(OperatingSystem::Unix),
|
||||
target_lexicon::OperatingSystem::MacOSX { .. } => Some(OperatingSystem::Unix),
|
||||
target_lexicon::OperatingSystem::Darwin => Some(OperatingSystem::Unix),
|
||||
target_lexicon::OperatingSystem::Unknown => Some(OperatingSystem::Unix),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PtrWidth {
|
||||
Bytes4 = 4,
|
||||
Bytes8 = 8,
|
||||
}
|
||||
|
||||
pub const fn object_file_ext(&self) -> &str {
|
||||
match self {
|
||||
OperatingSystem::Windows => "obj",
|
||||
OperatingSystem::Unix => "o",
|
||||
OperatingSystem::Wasi => "wasm",
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumIter, EnumCount)]
|
||||
pub enum Architecture {
|
||||
Aarch32,
|
||||
Aarch64,
|
||||
Wasm32,
|
||||
X86_32,
|
||||
X86_64,
|
||||
}
|
||||
|
||||
pub const fn static_library_file_ext(&self) -> &str {
|
||||
match self {
|
||||
OperatingSystem::Windows => "lib",
|
||||
OperatingSystem::Unix => "a",
|
||||
OperatingSystem::Wasi => "wasm",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn executable_file_ext(&self) -> Option<&str> {
|
||||
match self {
|
||||
OperatingSystem::Windows => Some("exe"),
|
||||
OperatingSystem::Unix => None,
|
||||
OperatingSystem::Wasi => Some("wasm"),
|
||||
}
|
||||
impl std::fmt::Display for Architecture {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let arch_str = match self {
|
||||
Architecture::Aarch32 => "aarch32",
|
||||
Architecture::Aarch64 => "aarch64",
|
||||
Architecture::Wasm32 => "wasm32",
|
||||
Architecture::X86_32 => "x86_32",
|
||||
Architecture::X86_64 => "x86_64",
|
||||
};
|
||||
write!(f, "{}", arch_str)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<target_lexicon::OperatingSystem> for OperatingSystem {
|
||||
fn from(target: target_lexicon::OperatingSystem) -> Self {
|
||||
Self::new(target)
|
||||
.unwrap_or_else(|| unreachable!("unsupported operating system {:?}", target))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct TargetInfo {
|
||||
pub architecture: Architecture,
|
||||
pub operating_system: OperatingSystem,
|
||||
}
|
||||
|
||||
impl TargetInfo {
|
||||
impl Architecture {
|
||||
pub const fn ptr_width(&self) -> PtrWidth {
|
||||
self.architecture.ptr_width()
|
||||
use Architecture::*;
|
||||
|
||||
match self {
|
||||
X86_64 | Aarch64 => PtrWidth::Bytes8,
|
||||
X86_32 | Aarch32 | Wasm32 => PtrWidth::Bytes4,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn ptr_alignment_bytes(&self) -> usize {
|
||||
self.ptr_width() as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, EnumIter, PartialEq, Eq)]
|
||||
pub enum Target {
|
||||
LinuxX32,
|
||||
LinuxX64,
|
||||
LinuxArm64,
|
||||
MacX64,
|
||||
MacArm64,
|
||||
WinX32,
|
||||
WinX64,
|
||||
WinArm64,
|
||||
Wasm32,
|
||||
}
|
||||
|
||||
impl Target {
|
||||
pub const fn architecture(&self) -> Architecture {
|
||||
use Target::*;
|
||||
match self {
|
||||
LinuxX32 | WinX32 => Architecture::X86_32,
|
||||
LinuxX64 | WinX64 | MacX64 => Architecture::X86_64,
|
||||
LinuxArm64 | WinArm64 | MacArm64 => Architecture::Aarch64,
|
||||
Wasm32 => Architecture::Wasm32,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn operating_system(&self) -> OperatingSystem {
|
||||
use Target::*;
|
||||
match self {
|
||||
LinuxX32 | LinuxX64 | LinuxArm64 => OperatingSystem::Linux,
|
||||
MacX64 | MacArm64 => OperatingSystem::Mac,
|
||||
WinX32 | WinX64 | WinArm64 => OperatingSystem::Windows,
|
||||
Wasm32 => OperatingSystem::Freestanding,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn arch_os(&self) -> (Architecture, OperatingSystem) {
|
||||
(self.architecture(), self.operating_system())
|
||||
}
|
||||
|
||||
pub const fn ptr_width(&self) -> PtrWidth {
|
||||
self.architecture().ptr_width()
|
||||
}
|
||||
|
||||
pub const fn ptr_size(&self) -> usize {
|
||||
|
@ -85,196 +119,177 @@ impl TargetInfo {
|
|||
}
|
||||
|
||||
pub const fn ptr_alignment_bytes(&self) -> usize {
|
||||
self.architecture.ptr_alignment_bytes()
|
||||
self.architecture().ptr_alignment_bytes()
|
||||
}
|
||||
|
||||
pub const fn default_aarch64() -> Self {
|
||||
TargetInfo {
|
||||
architecture: Architecture::Aarch64,
|
||||
operating_system: OperatingSystem::Unix,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn default_x86_64() -> Self {
|
||||
TargetInfo {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Unix,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn default_wasm32() -> Self {
|
||||
TargetInfo {
|
||||
architecture: Architecture::Wasm32,
|
||||
operating_system: OperatingSystem::Wasi,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&target_lexicon::Triple> for TargetInfo {
|
||||
fn from(triple: &target_lexicon::Triple) -> Self {
|
||||
let architecture = Architecture::from(triple.architecture);
|
||||
let operating_system = OperatingSystem::from(triple.operating_system);
|
||||
|
||||
Self {
|
||||
architecture,
|
||||
operating_system,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PtrWidth {
|
||||
Bytes4 = 4,
|
||||
Bytes8 = 8,
|
||||
}
|
||||
|
||||
/// These should be sorted alphabetically!
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumIter, EnumCount)]
|
||||
#[repr(u8)]
|
||||
pub enum Architecture {
|
||||
Aarch32,
|
||||
Aarch64,
|
||||
Wasm32,
|
||||
X86_32,
|
||||
X86_64,
|
||||
}
|
||||
|
||||
impl Architecture {
|
||||
pub const fn ptr_width(&self) -> PtrWidth {
|
||||
use Architecture::*;
|
||||
|
||||
pub const fn object_file_ext(&self) -> &str {
|
||||
use Target::*;
|
||||
match self {
|
||||
X86_64 | Aarch64 => PtrWidth::Bytes8,
|
||||
X86_32 | Aarch32 | Wasm32 => PtrWidth::Bytes4,
|
||||
LinuxX32 | LinuxX64 | LinuxArm64 | MacX64 | MacArm64 => "o",
|
||||
WinX32 | WinX64 | WinArm64 => "obj",
|
||||
Wasm32 => "wasm",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn ptr_alignment_bytes(&self) -> usize {
|
||||
self.ptr_width() as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl From<target_lexicon::Architecture> for Architecture {
|
||||
fn from(target: target_lexicon::Architecture) -> Self {
|
||||
match target {
|
||||
target_lexicon::Architecture::X86_64 => Architecture::X86_64,
|
||||
target_lexicon::Architecture::X86_32(_) => Architecture::X86_32,
|
||||
target_lexicon::Architecture::Aarch64(_) => Architecture::Aarch64,
|
||||
target_lexicon::Architecture::Arm(_) => Architecture::Aarch32,
|
||||
target_lexicon::Architecture::Wasm32 => Architecture::Wasm32,
|
||||
_ => unreachable!("unsupported architecture"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, EnumIter, EnumString, IntoStaticStr, PartialEq, Eq, Default)]
|
||||
pub enum Target {
|
||||
#[strum(serialize = "system")]
|
||||
#[default]
|
||||
System,
|
||||
#[strum(serialize = "linux-x32")]
|
||||
LinuxX32,
|
||||
#[strum(serialize = "linux-x64")]
|
||||
LinuxX64,
|
||||
#[strum(serialize = "linux-arm64")]
|
||||
LinuxArm64,
|
||||
#[strum(serialize = "macos-x64")]
|
||||
MacX64,
|
||||
#[strum(serialize = "macos-arm64")]
|
||||
MacArm64,
|
||||
#[strum(serialize = "windows-x32")]
|
||||
WinX32,
|
||||
#[strum(serialize = "windows-x64")]
|
||||
WinX64,
|
||||
#[strum(serialize = "windows-arm64")]
|
||||
WinArm64,
|
||||
#[strum(serialize = "wasm32")]
|
||||
Wasm32,
|
||||
}
|
||||
|
||||
const MACOS: target_lexicon::OperatingSystem = target_lexicon::OperatingSystem::MacOSX {
|
||||
major: 12,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
};
|
||||
|
||||
impl Target {
|
||||
pub fn to_triple(self) -> Triple {
|
||||
use target_lexicon::*;
|
||||
|
||||
pub const fn static_library_file_ext(&self) -> &str {
|
||||
use Target::*;
|
||||
match self {
|
||||
Target::System => Triple::host(),
|
||||
Target::LinuxX32 => Triple {
|
||||
architecture: Architecture::X86_32(X86_32Architecture::I386),
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Elf,
|
||||
},
|
||||
Target::LinuxX64 => Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Elf,
|
||||
},
|
||||
Target::LinuxArm64 => Triple {
|
||||
architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64),
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Elf,
|
||||
},
|
||||
Target::WinX32 => Triple {
|
||||
architecture: Architecture::X86_32(X86_32Architecture::I386),
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Windows,
|
||||
environment: Environment::Gnu,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
},
|
||||
Target::WinX64 => Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Windows,
|
||||
environment: Environment::Gnu,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
},
|
||||
Target::WinArm64 => Triple {
|
||||
architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64),
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Windows,
|
||||
environment: Environment::Gnu,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
},
|
||||
Target::MacX64 => Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
vendor: Vendor::Apple,
|
||||
operating_system: MACOS,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Macho,
|
||||
},
|
||||
Target::MacArm64 => Triple {
|
||||
architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64),
|
||||
vendor: Vendor::Apple,
|
||||
operating_system: MACOS,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Macho,
|
||||
},
|
||||
Target::Wasm32 => Triple {
|
||||
architecture: Architecture::Wasm32,
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Wasi,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Wasm,
|
||||
},
|
||||
LinuxX32 | LinuxX64 | LinuxArm64 | MacX64 | MacArm64 => "a",
|
||||
WinX32 | WinX64 | WinArm64 => "lib",
|
||||
Wasm32 => "wasm",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn executable_file_ext(&self) -> Option<&str> {
|
||||
use Target::*;
|
||||
match self {
|
||||
LinuxX32 | LinuxX64 | LinuxArm64 | MacX64 | MacArm64 => None,
|
||||
WinX32 | WinX64 | WinArm64 => Some("exe"),
|
||||
Wasm32 => Some("wasm"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Target> for Triple {
|
||||
pub enum ParseError {
|
||||
InvalidTargetString,
|
||||
}
|
||||
|
||||
impl FromStr for Target {
|
||||
type Err = ParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
use Target::*;
|
||||
match s {
|
||||
"system" => Ok(Self::default()),
|
||||
"linux-x32" => Ok(LinuxX32),
|
||||
"linux-x64" => Ok(LinuxX64),
|
||||
"linux-arm64" => Ok(LinuxArm64),
|
||||
// TODO: Can we change these to just `mac`.
|
||||
// Currently, we need to keep it as `macos` to match platform naming.
|
||||
"macos-x64" => Ok(MacX64),
|
||||
"macos-arm64" => Ok(MacArm64),
|
||||
"windows-x32" => Ok(WinX32),
|
||||
"windows-x64" => Ok(WinX64),
|
||||
"windows-arm64" => Ok(WinArm64),
|
||||
"wasm32" => Ok(Wasm32),
|
||||
_ => Err(ParseError::InvalidTargetString),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Target> for &'static str {
|
||||
fn from(target: Target) -> Self {
|
||||
Self::from(&target)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Target> for &'static str {
|
||||
fn from(target: &Target) -> Self {
|
||||
target.to_triple()
|
||||
use Target::*;
|
||||
match target {
|
||||
LinuxX32 => "linux-x32",
|
||||
LinuxX64 => "linux-x64",
|
||||
LinuxArm64 => "linux-arm64",
|
||||
// TODO: Can we change these to just `mac`.
|
||||
// Currently, we need to keep it as `macos` to match platform naming.
|
||||
MacX64 => "macos-x64",
|
||||
MacArm64 => "macos-arm64",
|
||||
WinX32 => "windows-x32",
|
||||
WinX64 => "windows-x64",
|
||||
WinArm64 => "windows-arm64",
|
||||
Wasm32 => "wasm32",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Target {
|
||||
fn default() -> Self {
|
||||
Triple::host().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Triple> for Target {
|
||||
fn from(triple: &Triple) -> Self {
|
||||
use target_lexicon::*;
|
||||
match triple {
|
||||
Triple {
|
||||
architecture: Architecture::X86_32(_),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => Target::LinuxX32,
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => Target::LinuxX64,
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(_),
|
||||
operating_system: OperatingSystem::Linux,
|
||||
..
|
||||
} => Target::LinuxArm64,
|
||||
Triple {
|
||||
architecture: Architecture::X86_32(_),
|
||||
operating_system: OperatingSystem::Windows,
|
||||
..
|
||||
} => Target::WinX32,
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::Windows,
|
||||
..
|
||||
} => Target::WinX64,
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(_),
|
||||
operating_system: OperatingSystem::Windows,
|
||||
..
|
||||
} => Target::WinArm64,
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
operating_system: OperatingSystem::MacOSX { .. } | OperatingSystem::Darwin,
|
||||
..
|
||||
} => Target::MacX64,
|
||||
Triple {
|
||||
architecture: Architecture::Aarch64(_),
|
||||
operating_system: OperatingSystem::MacOSX { .. } | OperatingSystem::Darwin,
|
||||
..
|
||||
} => Target::MacArm64,
|
||||
Triple {
|
||||
architecture: Architecture::Wasm32,
|
||||
..
|
||||
} => Target::Wasm32,
|
||||
_ => {
|
||||
user_error!("Target triple ({}) is not currently supported by the roc compiler. Feel free to file an issue to request support", triple);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Triple> for Target {
|
||||
fn from(triple: Triple) -> Self {
|
||||
Target::from(&triple)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum TargetFromTripleError {
|
||||
TripleUnsupported,
|
||||
}
|
||||
|
||||
impl TryFrom<(Architecture, OperatingSystem)> for Target {
|
||||
type Error = TargetFromTripleError;
|
||||
|
||||
fn try_from(arch_os: (Architecture, OperatingSystem)) -> Result<Self, Self::Error> {
|
||||
match arch_os {
|
||||
(Architecture::X86_32, OperatingSystem::Linux) => Ok(Target::LinuxX32),
|
||||
(Architecture::X86_64, OperatingSystem::Linux) => Ok(Target::LinuxX64),
|
||||
(Architecture::Aarch64, OperatingSystem::Linux) => Ok(Target::LinuxArm64),
|
||||
(Architecture::X86_32, OperatingSystem::Windows) => Ok(Target::WinX32),
|
||||
(Architecture::X86_64, OperatingSystem::Windows) => Ok(Target::WinX64),
|
||||
(Architecture::Aarch64, OperatingSystem::Windows) => Ok(Target::WinArm64),
|
||||
(Architecture::X86_64, OperatingSystem::Mac) => Ok(Target::MacX64),
|
||||
(Architecture::Aarch64, OperatingSystem::Mac) => Ok(Target::MacArm64),
|
||||
(Architecture::Wasm32, _) => Ok(Target::Wasm32),
|
||||
_ => Err(TargetFromTripleError::TripleUnsupported),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,48 +298,3 @@ impl std::fmt::Display for Target {
|
|||
write!(f, "{}", Into::<&'static str>::into(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_target_triple_str(target: &target_lexicon::Triple) -> Option<&'static str> {
|
||||
match target {
|
||||
target_lexicon::Triple {
|
||||
architecture: target_lexicon::Architecture::Wasm32,
|
||||
..
|
||||
} => Some(Target::Wasm32.into()),
|
||||
target_lexicon::Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Linux,
|
||||
architecture: target_lexicon::Architecture::X86_64,
|
||||
..
|
||||
} => Some(Target::LinuxX64.into()),
|
||||
target_lexicon::Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Linux,
|
||||
architecture: target_lexicon::Architecture::Aarch64(_),
|
||||
..
|
||||
} => Some(Target::LinuxArm64.into()),
|
||||
target_lexicon::Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Darwin,
|
||||
architecture: target_lexicon::Architecture::Aarch64(_),
|
||||
..
|
||||
} => Some(Target::MacArm64.into()),
|
||||
target_lexicon::Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Darwin,
|
||||
architecture: target_lexicon::Architecture::X86_64,
|
||||
..
|
||||
} => Some(Target::MacX64.into()),
|
||||
target_lexicon::Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Windows,
|
||||
architecture: target_lexicon::Architecture::X86_64,
|
||||
..
|
||||
} => Some(Target::WinX64.into()),
|
||||
target_lexicon::Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Windows,
|
||||
architecture: target_lexicon::Architecture::X86_32(_),
|
||||
..
|
||||
} => Some(Target::WinX32.into()),
|
||||
target_lexicon::Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Windows,
|
||||
architecture: target_lexicon::Architecture::Aarch64(_),
|
||||
..
|
||||
} => Some(Target::WinArm64.into()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -517,7 +517,7 @@ where
|
|||
{
|
||||
let arena = Bump::new();
|
||||
let (builtin_module, source, path) = module_source_and_path(builtin);
|
||||
let target_info = roc_target::TargetInfo::default_x86_64();
|
||||
let target = roc_target::Target::LinuxX64;
|
||||
|
||||
let LoadedModule {
|
||||
mut interns,
|
||||
|
@ -531,7 +531,7 @@ where
|
|||
source,
|
||||
path.parent().unwrap().to_path_buf(),
|
||||
Default::default(),
|
||||
target_info,
|
||||
target,
|
||||
FunctionKind::LambdaSet,
|
||||
roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
roc_reporting::report::DEFAULT_PALETTE,
|
||||
|
|
|
@ -22,8 +22,8 @@ fn width_and_alignment_u8_u8() {
|
|||
use roc_mono::layout::Layout;
|
||||
use roc_mono::layout::UnionLayout;
|
||||
|
||||
let target_info = roc_target::TargetInfo::default_x86_64();
|
||||
let interner = STLayoutInterner::with_capacity(4, target_info);
|
||||
let target = roc_target::Target::LinuxX64;
|
||||
let interner = STLayoutInterner::with_capacity(4, target);
|
||||
|
||||
let t = &[Layout::U8] as &[_];
|
||||
let tt = [t, t];
|
||||
|
|
|
@ -56,7 +56,7 @@ pub fn helper(
|
|||
}
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info: roc_target::TargetInfo::default_x86_64(),
|
||||
target: roc_target::Target::LinuxX64,
|
||||
render: roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
palette: roc_reporting::report::DEFAULT_PALETTE,
|
||||
threading: Threading::Single,
|
||||
|
@ -197,14 +197,9 @@ pub fn helper(
|
|||
mode: roc_gen_dev::AssemblyBackendMode::Test,
|
||||
};
|
||||
|
||||
let target = target_lexicon::Triple::host();
|
||||
let module_object = roc_gen_dev::build_module(
|
||||
&env,
|
||||
&mut interns,
|
||||
&mut layout_interner,
|
||||
&target,
|
||||
procedures,
|
||||
);
|
||||
let target = target_lexicon::Triple::host().into();
|
||||
let module_object =
|
||||
roc_gen_dev::build_module(&env, &mut interns, &mut layout_interner, target, procedures);
|
||||
|
||||
let module_out = module_object
|
||||
.write()
|
||||
|
@ -215,7 +210,7 @@ pub fn helper(
|
|||
roc_bitcode::host_tempfile().expect("failed to write host builtins object to tempfile");
|
||||
|
||||
let (mut child, dylib_path) = link(
|
||||
&target,
|
||||
target,
|
||||
app_o_file.clone(),
|
||||
// Long term we probably want a smarter way to link in zig builtins.
|
||||
// With the current method all methods are kept and it adds about 100k to all outputs.
|
||||
|
|
|
@ -16,7 +16,7 @@ use roc_mono::ir::{CrashTag, OptLevel, SingleEntryPoint};
|
|||
use roc_packaging::cache::RocCacheDir;
|
||||
use roc_region::all::LineInfo;
|
||||
use roc_reporting::report::{RenderTarget, DEFAULT_PALETTE};
|
||||
use target_lexicon::Triple;
|
||||
use roc_target::Target;
|
||||
|
||||
#[cfg(feature = "gen-llvm-wasm")]
|
||||
use crate::helpers::from_wasm32_memory::FromWasm32Memory;
|
||||
|
@ -52,11 +52,9 @@ fn create_llvm_module<'a>(
|
|||
src: &str,
|
||||
config: HelperConfig,
|
||||
context: &'a inkwell::context::Context,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
) -> (&'static str, String, &'a Module<'a>) {
|
||||
let target_info = roc_target::TargetInfo::from(target);
|
||||
|
||||
let filename = PathBuf::from("Test.roc");
|
||||
let src_dir = PathBuf::from("fake/test/path");
|
||||
|
||||
|
@ -72,7 +70,7 @@ fn create_llvm_module<'a>(
|
|||
}
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render: RenderTarget::ColorTerminal,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
@ -227,7 +225,7 @@ fn create_llvm_module<'a>(
|
|||
context,
|
||||
interns,
|
||||
module,
|
||||
target_info,
|
||||
target,
|
||||
mode: config.mode,
|
||||
// important! we don't want any procedures to get the C calling convention
|
||||
exposed_to_host: MutSet::default(),
|
||||
|
@ -332,33 +330,21 @@ pub fn helper<'a>(
|
|||
context: &'a inkwell::context::Context,
|
||||
function_kind: FunctionKind,
|
||||
) -> (&'static str, String, Library) {
|
||||
let target = target_lexicon::Triple::host();
|
||||
let target = target_lexicon::Triple::host().into();
|
||||
|
||||
let (main_fn_name, delayed_errors, module) =
|
||||
create_llvm_module(arena, src, config, context, &target, function_kind);
|
||||
create_llvm_module(arena, src, config, context, target, function_kind);
|
||||
|
||||
if !config.emit_debug_info {
|
||||
module.strip_debug_info();
|
||||
}
|
||||
let res_lib = llvm_module_to_dylib(module, &target, config.opt_level);
|
||||
let res_lib = llvm_module_to_dylib(module, target, config.opt_level);
|
||||
|
||||
let lib = res_lib.expect("Error loading compiled dylib for test");
|
||||
|
||||
(main_fn_name, delayed_errors, lib)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn wasm32_target_tripple() -> Triple {
|
||||
use target_lexicon::{Architecture, BinaryFormat};
|
||||
|
||||
let mut triple = Triple::unknown();
|
||||
|
||||
triple.architecture = Architecture::Wasm32;
|
||||
triple.binary_format = BinaryFormat::Wasm;
|
||||
|
||||
triple
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn write_final_wasm() -> bool {
|
||||
#[allow(unused_imports)]
|
||||
|
@ -383,10 +369,10 @@ fn compile_to_wasm_bytes<'a>(
|
|||
static TEMP_DIR: OnceLock<tempfile::TempDir> = OnceLock::new();
|
||||
let temp_dir = TEMP_DIR.get_or_init(|| tempfile::tempdir().unwrap());
|
||||
|
||||
let target = wasm32_target_tripple();
|
||||
let target = Target::Wasm32;
|
||||
|
||||
let (_main_fn_name, _delayed_errors, llvm_module) =
|
||||
create_llvm_module(arena, src, config, context, &target, function_kind);
|
||||
create_llvm_module(arena, src, config, context, target, function_kind);
|
||||
|
||||
let content_hash = crate::helpers::src_hash(src);
|
||||
let wasm_file = llvm_module_to_wasm_file(temp_dir, content_hash, llvm_module);
|
||||
|
|
|
@ -88,7 +88,7 @@ fn compile_roc_to_wasm_bytes<'a, T: Wasm32Result>(
|
|||
}
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info: roc_target::TargetInfo::default_wasm32(),
|
||||
target: roc_target::Target::Wasm32,
|
||||
render: roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
palette: DEFAULT_PALETTE_HTML,
|
||||
threading: Threading::Single,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use bumpalo::Bump;
|
||||
use roc_gen_wasm::Env;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
|
@ -259,7 +259,7 @@ fn test_help(
|
|||
dump_filename: &str,
|
||||
) {
|
||||
let arena = Bump::new();
|
||||
let mut layout_interner = STLayoutInterner::with_capacity(4, TargetInfo::default_wasm32());
|
||||
let mut layout_interner = STLayoutInterner::with_capacity(4, Target::Wasm32);
|
||||
|
||||
let BackendInputs {
|
||||
env,
|
||||
|
|
|
@ -27,7 +27,7 @@ use roc_mono::ir::ProcLayout;
|
|||
use roc_mono::layout::STLayoutInterner;
|
||||
use test_mono_macros::*;
|
||||
|
||||
const TARGET_INFO: roc_target::TargetInfo = roc_target::TargetInfo::default_x86_64();
|
||||
const TARGET: roc_target::Target = roc_target::Target::LinuxX64;
|
||||
|
||||
/// Without this, some tests pass in `cargo test --release` but fail without
|
||||
/// the --release flag because they run out of stack space. This increases
|
||||
|
@ -104,7 +104,7 @@ fn compiles_to_ir(test_name: &str, src: &str, mode: &str, allow_type_errors: boo
|
|||
}
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info: TARGET_INFO,
|
||||
target: TARGET,
|
||||
// TODO parameterize
|
||||
function_kind: FunctionKind::LambdaSet,
|
||||
threading: Threading::Single,
|
||||
|
|
|
@ -79,7 +79,7 @@ pub fn run_load_and_infer<'a>(
|
|||
file_path,
|
||||
module_src,
|
||||
dir.path().to_path_buf(),
|
||||
roc_target::TargetInfo::default_x86_64(),
|
||||
roc_target::Target::LinuxX64,
|
||||
function_kind,
|
||||
roc_reporting::report::RenderTarget::Generic,
|
||||
RocCacheDir::Disallowed,
|
||||
|
|
|
@ -43,7 +43,7 @@ pub(crate) fn write_compiled_ir<'a>(
|
|||
let file_path = dir.path().join(filename);
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info: roc_target::TargetInfo::default_x86_64(),
|
||||
target: roc_target::Target::LinuxX64,
|
||||
function_kind: compiler_settings.function_kind,
|
||||
threading: Threading::Single,
|
||||
render: roc_reporting::report::RenderTarget::Generic,
|
||||
|
|
|
@ -462,7 +462,7 @@ fn render_sidebar<'a, I: Iterator<Item = &'a ModuleDocumentation>>(modules: I) -
|
|||
pub fn load_module_for_docs(filename: PathBuf) -> LoadedModule {
|
||||
let arena = Bump::new();
|
||||
let load_config = LoadConfig {
|
||||
target_info: roc_target::TargetInfo::default_x86_64(), // This is just type-checking for docs, so "target" doesn't matter
|
||||
target: roc_target::Target::LinuxX64, // This is just type-checking for docs, so "target" doesn't matter
|
||||
function_kind: roc_solve::FunctionKind::LambdaSet,
|
||||
render: roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
palette: roc_reporting::report::DEFAULT_PALETTE,
|
||||
|
|
|
@ -16,7 +16,8 @@ Architecture : [
|
|||
]
|
||||
|
||||
OperatingSystem : [
|
||||
Freestanding,
|
||||
Linux,
|
||||
Mac,
|
||||
Windows,
|
||||
Unix,
|
||||
Wasi,
|
||||
]
|
||||
|
|
|
@ -176,16 +176,18 @@ pub struct Target {
|
|||
#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)]
|
||||
#[repr(u8)]
|
||||
pub enum OperatingSystem {
|
||||
Unix = 0,
|
||||
Wasi = 1,
|
||||
Windows = 2,
|
||||
Freestanding = 0,
|
||||
Linux = 1,
|
||||
Mac = 2,
|
||||
Windows = 3,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for OperatingSystem {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Self::Unix => f.write_str("OperatingSystem::Unix"),
|
||||
Self::Wasi => f.write_str("OperatingSystem::Wasi"),
|
||||
Self::Freestanding => f.write_str("OperatingSystem::Freestanding"),
|
||||
Self::Linux => f.write_str("OperatingSystem::Linux"),
|
||||
Self::Mac => f.write_str("OperatingSystem::Mac"),
|
||||
Self::Windows => f.write_str("OperatingSystem::Windows"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use roc_mono::ir::{generate_glue_procs, CrashTag, GlueProc, OptLevel};
|
|||
use roc_mono::layout::{GlobalLayoutInterner, LayoutCache, LayoutInterner};
|
||||
use roc_packaging::cache::{self, RocCacheDir};
|
||||
use roc_reporting::report::{RenderTarget, DEFAULT_PALETTE};
|
||||
use roc_target::{Architecture, TargetInfo};
|
||||
use roc_target::{Architecture, Target, TargetFromTripleError::TripleUnsupported};
|
||||
use roc_types::subs::{Subs, Variable};
|
||||
use std::fs::File;
|
||||
use std::io::{self, ErrorKind, Write};
|
||||
|
@ -41,16 +41,17 @@ pub fn generate(
|
|||
spec_path: &Path,
|
||||
backend: CodeGenBackend,
|
||||
) -> io::Result<i32> {
|
||||
let target = Triple::host().into();
|
||||
// TODO: Add verification around the paths. Make sure they heav the correct file extension and what not.
|
||||
match load_types(
|
||||
input_path.to_path_buf(),
|
||||
Threading::AllAvailable,
|
||||
IgnoreErrors::NONE,
|
||||
target,
|
||||
) {
|
||||
Ok(types) => {
|
||||
// TODO: we should to modify the app file first before loading it.
|
||||
// Somehow it has to point to the correct platform file which may not exist on the target machine.
|
||||
let triple = Triple::host();
|
||||
|
||||
let code_gen_options = CodeGenOptions {
|
||||
backend,
|
||||
|
@ -61,14 +62,14 @@ pub fn generate(
|
|||
};
|
||||
|
||||
let load_config = standard_load_config(
|
||||
&triple,
|
||||
target,
|
||||
BuildOrdering::BuildIfChecks,
|
||||
Threading::AllAvailable,
|
||||
);
|
||||
|
||||
let arena = ManuallyDrop::new(Bump::new());
|
||||
let link_type = LinkType::Dylib;
|
||||
let linking_strategy = if roc_linker::supported(link_type, &triple) {
|
||||
let linking_strategy = if roc_linker::supported(link_type, target) {
|
||||
LinkingStrategy::Surgical
|
||||
} else {
|
||||
LinkingStrategy::Legacy
|
||||
|
@ -79,7 +80,7 @@ pub fn generate(
|
|||
let res_binary_path = match tempdir_res {
|
||||
Ok(dylib_dir) => build_file(
|
||||
&arena,
|
||||
&triple,
|
||||
target,
|
||||
spec_path.to_path_buf(),
|
||||
code_gen_options,
|
||||
false,
|
||||
|
@ -105,12 +106,10 @@ pub fn generate(
|
|||
expect_metadata: _,
|
||||
}) => {
|
||||
// TODO: Should binary_path be update to deal with extensions?
|
||||
use target_lexicon::OperatingSystem;
|
||||
let lib_path = match triple.operating_system {
|
||||
use roc_target::OperatingSystem;
|
||||
let lib_path = match target.operating_system() {
|
||||
OperatingSystem::Windows => binary_path.with_extension("dll"),
|
||||
OperatingSystem::Darwin | OperatingSystem::MacOSX { .. } => {
|
||||
binary_path.with_extension("dylib")
|
||||
}
|
||||
OperatingSystem::Mac => binary_path.with_extension("dylib"),
|
||||
|
||||
_ => binary_path.with_extension("so.1.0"),
|
||||
};
|
||||
|
@ -398,8 +397,8 @@ pub fn load_types(
|
|||
full_file_path: PathBuf,
|
||||
threading: Threading,
|
||||
ignore_errors: IgnoreErrors,
|
||||
target: Target,
|
||||
) -> Result<Vec<Types>, io::Error> {
|
||||
let target_info = (&Triple::host()).into();
|
||||
// TODO the function kind may need to be parameterizable.
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
let arena = &Bump::new();
|
||||
|
@ -417,7 +416,7 @@ pub fn load_types(
|
|||
full_file_path,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render: RenderTarget::Generic,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
@ -456,18 +455,19 @@ pub fn load_types(
|
|||
exposed_to_host.get(&symbol).copied()
|
||||
});
|
||||
|
||||
let operating_system = target_info.operating_system;
|
||||
let operating_system = target.operating_system();
|
||||
let architectures = Architecture::iter();
|
||||
let mut arch_types = Vec::with_capacity(architectures.len());
|
||||
|
||||
for architecture in architectures {
|
||||
let mut interns = interns.clone(); // TODO there may be a way to avoid this.
|
||||
let target_info = TargetInfo {
|
||||
architecture,
|
||||
operating_system,
|
||||
let target = match Target::try_from((architecture, operating_system)) {
|
||||
Ok(t) => t,
|
||||
Err(TripleUnsupported) => continue,
|
||||
};
|
||||
let layout_interner = GlobalLayoutInterner::with_capacity(128, target_info);
|
||||
let mut layout_cache = LayoutCache::new(layout_interner.fork(), target_info);
|
||||
|
||||
let layout_interner = GlobalLayoutInterner::with_capacity(128, target);
|
||||
let mut layout_cache = LayoutCache::new(layout_interner.fork(), target);
|
||||
let mut glue_procs_by_layout = MutMap::default();
|
||||
|
||||
let mut extern_names = MutMap::default();
|
||||
|
@ -528,7 +528,7 @@ pub fn load_types(
|
|||
arena.alloc(interns),
|
||||
glue_procs_by_layout,
|
||||
layout_cache,
|
||||
target_info,
|
||||
target,
|
||||
exposed_to_host.clone(),
|
||||
);
|
||||
|
||||
|
|
|
@ -195,16 +195,18 @@ pub struct Target {
|
|||
#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)]
|
||||
#[repr(u8)]
|
||||
pub enum OperatingSystem {
|
||||
Unix = 0,
|
||||
Wasi = 1,
|
||||
Windows = 2,
|
||||
Freestanding = 0,
|
||||
Linux = 1,
|
||||
Mac = 2,
|
||||
Windows = 3,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for OperatingSystem {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Self::Unix => f.write_str("OperatingSystem::Unix"),
|
||||
Self::Wasi => f.write_str("OperatingSystem::Wasi"),
|
||||
Self::Freestanding => f.write_str("OperatingSystem::Freestanding"),
|
||||
Self::Linux => f.write_str("OperatingSystem::Linux"),
|
||||
Self::Mac => f.write_str("OperatingSystem::Mac"),
|
||||
Self::Windows => f.write_str("OperatingSystem::Windows"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use roc_mono::{
|
|||
InLayout, Layout, LayoutCache, LayoutInterner, LayoutRepr, TLLayoutInterner, UnionLayout,
|
||||
},
|
||||
};
|
||||
use roc_target::{Architecture, OperatingSystem, TargetInfo};
|
||||
use roc_target::{Architecture, OperatingSystem, Target};
|
||||
use roc_types::{
|
||||
subs::{Content, FlatType, GetSubsSlice, Label, Subs, SubsSlice, UnionLabels, Variable},
|
||||
types::{AliasKind, RecordField},
|
||||
|
@ -65,13 +65,13 @@ pub struct Types {
|
|||
/// This is important for declaration order in C; we need to output a
|
||||
/// type declaration earlier in the file than where it gets referenced by another type.
|
||||
deps: VecMap<TypeId, Vec<TypeId>>,
|
||||
target: TargetInfo,
|
||||
target: Target,
|
||||
}
|
||||
|
||||
impl Types {
|
||||
const UNIT: TypeId = TypeId(0);
|
||||
|
||||
pub fn with_capacity(cap: usize, target_info: TargetInfo) -> Self {
|
||||
pub fn with_capacity(cap: usize, target: Target) -> Self {
|
||||
let mut types = Vec::with_capacity(cap);
|
||||
let mut sizes = Vec::with_capacity(cap);
|
||||
let mut aligns = Vec::with_capacity(cap);
|
||||
|
@ -81,7 +81,7 @@ impl Types {
|
|||
aligns.push(1);
|
||||
|
||||
Self {
|
||||
target: target_info,
|
||||
target,
|
||||
types,
|
||||
sizes,
|
||||
aligns,
|
||||
|
@ -98,7 +98,7 @@ impl Types {
|
|||
interns: &'a Interns,
|
||||
glue_procs_by_layout: MutMap<Layout<'a>, &'a [String]>,
|
||||
layout_cache: LayoutCache<'a>,
|
||||
target: TargetInfo,
|
||||
target: Target,
|
||||
mut entry_points: MutMap<Symbol, Variable>,
|
||||
) -> Self {
|
||||
let mut types = Self::with_capacity(entry_points.len(), target);
|
||||
|
@ -639,7 +639,7 @@ impl Types {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn target(&self) -> TargetInfo {
|
||||
pub fn target(&self) -> Target {
|
||||
self.target
|
||||
}
|
||||
}
|
||||
|
@ -905,11 +905,11 @@ impl From<&Option<TypeId>> for roc_type::U1 {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<TargetInfo> for roc_type::Target {
|
||||
fn from(target: TargetInfo) -> Self {
|
||||
impl From<Target> for roc_type::Target {
|
||||
fn from(target: Target) -> Self {
|
||||
roc_type::Target {
|
||||
architecture: target.architecture.into(),
|
||||
operatingSystem: target.operating_system.into(),
|
||||
architecture: target.architecture().into(),
|
||||
operatingSystem: target.operating_system().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -928,10 +928,12 @@ impl From<Architecture> for roc_type::Architecture {
|
|||
|
||||
impl From<OperatingSystem> for roc_type::OperatingSystem {
|
||||
fn from(os: OperatingSystem) -> Self {
|
||||
// TODO: Update Glue to new OS Tags.
|
||||
match os {
|
||||
OperatingSystem::Windows => roc_type::OperatingSystem::Windows,
|
||||
OperatingSystem::Unix => roc_type::OperatingSystem::Unix,
|
||||
OperatingSystem::Wasi => roc_type::OperatingSystem::Wasi,
|
||||
OperatingSystem::Linux => roc_type::OperatingSystem::Linux,
|
||||
OperatingSystem::Mac => roc_type::OperatingSystem::Mac,
|
||||
OperatingSystem::Freestanding => roc_type::OperatingSystem::Freestanding,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1179,7 +1181,7 @@ impl<'a> Env<'a> {
|
|||
interns: &'a Interns,
|
||||
layout_interner: TLLayoutInterner<'a>,
|
||||
glue_procs_by_layout: MutMap<Layout<'a>, &'a [String]>,
|
||||
target: TargetInfo,
|
||||
target: Target,
|
||||
) -> Self {
|
||||
Env {
|
||||
arena,
|
||||
|
|
|
@ -112,7 +112,7 @@ pub(crate) fn global_analysis(doc_info: DocInfo) -> Vec<AnalyzedDocument> {
|
|||
fi,
|
||||
&doc_info.source,
|
||||
src_dir,
|
||||
roc_target::TargetInfo::default_x86_64(),
|
||||
roc_target::Target::LinuxX64,
|
||||
roc_load::FunctionKind::LambdaSet,
|
||||
roc_reporting::report::RenderTarget::Generic,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
|
|
|
@ -332,8 +332,7 @@ impl<'a> Surgeries<'a> {
|
|||
}
|
||||
|
||||
/// Constructs a `Metadata` from a host executable binary, and writes it to disk
|
||||
pub(crate) fn preprocess_elf(
|
||||
endianness: target_lexicon::Endianness,
|
||||
pub(crate) fn preprocess_elf_le(
|
||||
host_exe_path: &Path,
|
||||
metadata_path: &Path,
|
||||
preprocessed_path: &Path,
|
||||
|
@ -479,11 +478,6 @@ pub(crate) fn preprocess_elf(
|
|||
|
||||
let text_disassembly_duration = text_disassembly_start.elapsed();
|
||||
|
||||
let scanning_dynamic_deps_duration;
|
||||
let platform_gen_start;
|
||||
|
||||
let out_mmap = match endianness {
|
||||
target_lexicon::Endianness::Little => {
|
||||
let scanning_dynamic_deps_start = Instant::now();
|
||||
|
||||
let ElfDynamicDeps {
|
||||
|
@ -496,12 +490,11 @@ pub(crate) fn preprocess_elf(
|
|||
&exec_obj, &mut md, &app_syms, shared_lib, exec_data, verbose,
|
||||
);
|
||||
|
||||
scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed();
|
||||
let scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed();
|
||||
|
||||
platform_gen_start = Instant::now();
|
||||
let platform_gen_start = Instant::now();
|
||||
|
||||
// TODO little endian
|
||||
gen_elf_le(
|
||||
let out_mmap = gen_elf_le(
|
||||
exec_data,
|
||||
&mut md,
|
||||
preprocessed_path,
|
||||
|
@ -511,15 +504,7 @@ pub(crate) fn preprocess_elf(
|
|||
dynamic_lib_count,
|
||||
shared_lib_index,
|
||||
verbose,
|
||||
)
|
||||
}
|
||||
target_lexicon::Endianness::Big => {
|
||||
// TODO probably need to make gen_elf a macro to get this
|
||||
// to work, which is annoying. A parameterized function
|
||||
// does *not* work.
|
||||
todo!("Roc does not yet support big-endian ELF hosts!");
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
let platform_gen_duration = platform_gen_start.elapsed();
|
||||
|
||||
|
@ -1743,7 +1728,7 @@ mod tests {
|
|||
|
||||
use crate::preprocessed_host_filename;
|
||||
use indoc::indoc;
|
||||
use target_lexicon::Triple;
|
||||
use roc_target::Target;
|
||||
|
||||
const ELF64_DYNHOST: &[u8] = include_bytes!("../dynhost_benchmarks_elf64") as &[_];
|
||||
|
||||
|
@ -1778,9 +1763,6 @@ mod tests {
|
|||
fn collect_undefined_symbols_elf() {
|
||||
let object = object::File::parse(ELF64_DYNHOST).unwrap();
|
||||
|
||||
let mut triple = Triple::host();
|
||||
triple.binary_format = target_lexicon::BinaryFormat::Elf;
|
||||
|
||||
let mut keys: Vec<_> = object
|
||||
.dynamic_symbols()
|
||||
.filter(is_roc_undefined)
|
||||
|
@ -1800,7 +1782,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn zig_host_app_help(dir: &Path, target: &Triple) {
|
||||
fn zig_host_app_help(dir: &Path, target: Target) {
|
||||
let host_zig = indoc!(
|
||||
r#"
|
||||
const std = @import("std");
|
||||
|
@ -1885,10 +1867,9 @@ mod tests {
|
|||
panic!("zig build-exe failed");
|
||||
}
|
||||
|
||||
let preprocessed_host_filename = dir.join(preprocessed_host_filename(target).unwrap());
|
||||
let preprocessed_host_filename = dir.join(preprocessed_host_filename(target));
|
||||
|
||||
preprocess_elf(
|
||||
target_lexicon::Endianness::Little,
|
||||
preprocess_elf_le(
|
||||
&dir.join("host"),
|
||||
&dir.join("metadata"),
|
||||
&preprocessed_host_filename,
|
||||
|
@ -1911,12 +1892,10 @@ mod tests {
|
|||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn zig_host_app() {
|
||||
use std::str::FromStr;
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let dir = dir.path();
|
||||
|
||||
zig_host_app_help(dir, &Triple::from_str("x86_64-unknown-linux-musl").unwrap());
|
||||
zig_host_app_help(dir, Target::LinuxX64);
|
||||
|
||||
let output = std::process::Command::new(dir.join("final"))
|
||||
.current_dir(dir)
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use object::write;
|
||||
use object::{Architecture, BinaryFormat, Endianness, SymbolFlags, SymbolKind, SymbolScope};
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_target::Target;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
// TODO: Eventually do this from scratch and in memory instead of with ld.
|
||||
pub fn create_dylib_macho(
|
||||
custom_names: &[String],
|
||||
triple: &Triple,
|
||||
target: Target,
|
||||
) -> object::read::Result<Vec<u8>> {
|
||||
let dummy_obj_file = tempfile::Builder::new()
|
||||
.prefix("roc_lib")
|
||||
|
@ -19,9 +19,9 @@ pub fn create_dylib_macho(
|
|||
let dummy_lib_file = tmp.path().to_path_buf().with_file_name("libapp.so");
|
||||
|
||||
let obj_target = BinaryFormat::MachO;
|
||||
let obj_arch = match triple.architecture {
|
||||
target_lexicon::Architecture::X86_64 => Architecture::X86_64,
|
||||
target_lexicon::Architecture::Aarch64(_) => Architecture::Aarch64,
|
||||
let obj_arch = match target.architecture() {
|
||||
roc_target::Architecture::X86_64 => Architecture::X86_64,
|
||||
roc_target::Architecture::Aarch64 => Architecture::Aarch64,
|
||||
_ => {
|
||||
// We should have verified this via supported() before calling this function
|
||||
unreachable!()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use target_lexicon::Triple;
|
||||
use roc_target::{OperatingSystem, Target};
|
||||
|
||||
mod elf64;
|
||||
mod macho;
|
||||
|
@ -12,11 +12,11 @@ pub(crate) use elf64::create_dylib_elf64;
|
|||
|
||||
pub(crate) use pe::APP_DLL;
|
||||
|
||||
pub fn generate(target: &Triple, custom_names: &[String]) -> object::read::Result<Vec<u8>> {
|
||||
match target.binary_format {
|
||||
target_lexicon::BinaryFormat::Elf => elf64::create_dylib_elf64(custom_names),
|
||||
target_lexicon::BinaryFormat::Macho => macho::create_dylib_macho(custom_names, target),
|
||||
target_lexicon::BinaryFormat::Coff => Ok(pe::synthetic_dll(custom_names)),
|
||||
pub fn generate(target: Target, custom_names: &[String]) -> object::read::Result<Vec<u8>> {
|
||||
match target.operating_system() {
|
||||
OperatingSystem::Linux => elf64::create_dylib_elf64(custom_names),
|
||||
OperatingSystem::Mac => macho::create_dylib_macho(custom_names, target),
|
||||
OperatingSystem::Windows => Ok(pe::synthetic_dll(custom_names)),
|
||||
other => unimplemented!("dylib creation for {:?}", other),
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,10 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
use object::Object;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
fn check_exports(target: &Triple) {
|
||||
fn check_exports(triple: &Triple) {
|
||||
let target = triple.into();
|
||||
let custom_names = ["foo".to_string(), "bar".to_string()];
|
||||
|
||||
let bytes = generate(target, &custom_names).unwrap();
|
||||
|
@ -75,16 +77,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_exports_coff_manual() {
|
||||
let target = target_lexicon::Triple {
|
||||
architecture: target_lexicon::Architecture::X86_64,
|
||||
operating_system: target_lexicon::OperatingSystem::Windows,
|
||||
binary_format: target_lexicon::BinaryFormat::Coff,
|
||||
..target_lexicon::Triple::host()
|
||||
};
|
||||
|
||||
let custom_names = ["foo".to_string(), "bar".to_string()];
|
||||
|
||||
let bytes = generate(&target, &custom_names).unwrap();
|
||||
let bytes = generate(Target::WinX64, &custom_names).unwrap();
|
||||
let object = object::read::pe::PeFile64::parse(bytes.as_slice()).unwrap();
|
||||
|
||||
let exports = {
|
||||
|
|
|
@ -11,11 +11,10 @@ use roc_module::symbol::Interns;
|
|||
use roc_packaging::cache::RocCacheDir;
|
||||
use roc_reporting::report::{RenderTarget, DEFAULT_PALETTE};
|
||||
use roc_solve::FunctionKind;
|
||||
use roc_target::get_target_triple_str;
|
||||
use roc_target::{Architecture, OperatingSystem, Target};
|
||||
use std::cmp::Ordering;
|
||||
use std::mem;
|
||||
use std::path::{Path, PathBuf};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
mod elf;
|
||||
mod macho;
|
||||
|
@ -31,30 +30,13 @@ pub enum LinkType {
|
|||
None = 2,
|
||||
}
|
||||
|
||||
pub fn supported(link_type: LinkType, target: &Triple) -> bool {
|
||||
pub fn supported(link_type: LinkType, target: Target) -> bool {
|
||||
if let LinkType::Executable = link_type {
|
||||
match target {
|
||||
Triple {
|
||||
architecture: target_lexicon::Architecture::X86_64,
|
||||
operating_system: target_lexicon::OperatingSystem::Linux,
|
||||
binary_format: target_lexicon::BinaryFormat::Elf,
|
||||
..
|
||||
} => true,
|
||||
|
||||
Target::LinuxX64 => true,
|
||||
Target::WinX64 => true,
|
||||
// macho support is incomplete
|
||||
Triple {
|
||||
operating_system: target_lexicon::OperatingSystem::Darwin,
|
||||
binary_format: target_lexicon::BinaryFormat::Macho,
|
||||
..
|
||||
} => false,
|
||||
|
||||
Triple {
|
||||
architecture: target_lexicon::Architecture::X86_64,
|
||||
operating_system: target_lexicon::OperatingSystem::Windows,
|
||||
binary_format: target_lexicon::BinaryFormat::Coff,
|
||||
..
|
||||
} => true,
|
||||
|
||||
Target::MacX64 => false,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
|
@ -64,18 +46,16 @@ pub fn supported(link_type: LinkType, target: &Triple) -> bool {
|
|||
|
||||
pub const PRECOMPILED_HOST_EXT: &str = "rh"; // Short for "roc host"
|
||||
|
||||
pub fn preprocessed_host_filename(target: &Triple) -> Option<String> {
|
||||
roc_target::get_target_triple_str(target).map(|x| format!("{x}.{PRECOMPILED_HOST_EXT}"))
|
||||
pub fn preprocessed_host_filename(target: Target) -> String {
|
||||
format!("{target}.{PRECOMPILED_HOST_EXT}")
|
||||
}
|
||||
|
||||
fn metadata_file_name(target: &Triple) -> String {
|
||||
let target_triple_str = get_target_triple_str(target);
|
||||
|
||||
format!("metadata_{}.rm", target_triple_str.unwrap_or("unknown"))
|
||||
fn metadata_file_name(target: Target) -> String {
|
||||
format!("metadata_{}.rm", target)
|
||||
}
|
||||
|
||||
pub fn link_preprocessed_host(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_path: &Path,
|
||||
roc_app_bytes: &[u8],
|
||||
binary_path: &Path,
|
||||
|
@ -88,21 +68,20 @@ pub fn link_preprocessed_host(
|
|||
pub fn generate_stub_lib(
|
||||
input_path: &Path,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
triple: &Triple,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
) -> (PathBuf, PathBuf, Vec<String>) {
|
||||
// Note: this should theoretically just be able to load the host, I think.
|
||||
// Instead, I am loading an entire app because that was simpler and had example code.
|
||||
// If this was expected to stay around for the the long term, we should change it.
|
||||
// But hopefully it will be removable once we have surgical linking on all platforms.
|
||||
let target_info = triple.into();
|
||||
let arena = &bumpalo::Bump::new();
|
||||
let loaded = roc_load::load_and_monomorphize(
|
||||
arena,
|
||||
input_path.to_path_buf(),
|
||||
roc_cache_dir,
|
||||
LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render: RenderTarget::Generic,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
@ -138,14 +117,14 @@ pub fn generate_stub_lib(
|
|||
};
|
||||
|
||||
if let EntryPoint::Executable { platform_path, .. } = &loaded.entry_point {
|
||||
let stub_lib = if let target_lexicon::OperatingSystem::Windows = triple.operating_system {
|
||||
let stub_lib = if target.operating_system() == OperatingSystem::Windows {
|
||||
platform_path.with_file_name("libapp.obj")
|
||||
} else {
|
||||
platform_path.with_file_name("libapp.so")
|
||||
};
|
||||
|
||||
let stub_dll_symbols = exposed_symbols.stub_dll_symbols();
|
||||
generate_dynamic_lib(triple, &stub_dll_symbols, &stub_lib);
|
||||
generate_dynamic_lib(target, &stub_dll_symbols, &stub_lib);
|
||||
(platform_path.into(), stub_lib, stub_dll_symbols)
|
||||
} else {
|
||||
unreachable!();
|
||||
|
@ -153,11 +132,11 @@ pub fn generate_stub_lib(
|
|||
}
|
||||
|
||||
pub fn generate_stub_lib_from_loaded(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_main_roc: &Path,
|
||||
stub_dll_symbols: &[String],
|
||||
) -> PathBuf {
|
||||
let stub_lib_path = if let target_lexicon::OperatingSystem::Windows = target.operating_system {
|
||||
let stub_lib_path = if target.operating_system() == OperatingSystem::Windows {
|
||||
platform_main_roc.with_file_name("libapp.dll")
|
||||
} else {
|
||||
platform_main_roc.with_file_name("libapp.so")
|
||||
|
@ -252,7 +231,7 @@ impl ExposedSymbols {
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_dynamic_lib(target: &Triple, stub_dll_symbols: &[String], stub_lib_path: &Path) {
|
||||
fn generate_dynamic_lib(target: Target, stub_dll_symbols: &[String], stub_lib_path: &Path) {
|
||||
if !stub_lib_is_up_to_date(target, stub_lib_path, stub_dll_symbols) {
|
||||
let bytes = crate::generate_dylib::generate(target, stub_dll_symbols)
|
||||
.unwrap_or_else(|e| internal_error!("{e}"));
|
||||
|
@ -261,7 +240,7 @@ fn generate_dynamic_lib(target: &Triple, stub_dll_symbols: &[String], stub_lib_p
|
|||
internal_error!("failed to write stub lib to {:?}: {e}", stub_lib_path)
|
||||
}
|
||||
|
||||
if let target_lexicon::OperatingSystem::Windows = target.operating_system {
|
||||
if target.operating_system() == OperatingSystem::Windows {
|
||||
generate_import_library(stub_lib_path, stub_dll_symbols);
|
||||
}
|
||||
}
|
||||
|
@ -336,24 +315,22 @@ fn generate_def_file(custom_names: &[String]) -> Result<String, std::fmt::Error>
|
|||
Ok(def_file)
|
||||
}
|
||||
|
||||
fn object_matches_target<'a>(target: &Triple, object: &object::File<'a, &'a [u8]>) -> bool {
|
||||
use target_lexicon::{Architecture as TLA, OperatingSystem as TLO};
|
||||
|
||||
match target.architecture {
|
||||
TLA::X86_64 => {
|
||||
fn object_matches_target<'a>(target: Target, object: &object::File<'a, &'a [u8]>) -> bool {
|
||||
match target.architecture() {
|
||||
Architecture::X86_64 => {
|
||||
if object.architecture() != object::Architecture::X86_64 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let target_format = match target.operating_system {
|
||||
TLO::Linux => object::BinaryFormat::Elf,
|
||||
TLO::Windows => object::BinaryFormat::Pe,
|
||||
let target_format = match target.operating_system() {
|
||||
OperatingSystem::Linux => object::BinaryFormat::Elf,
|
||||
OperatingSystem::Windows => object::BinaryFormat::Pe,
|
||||
_ => todo!("surgical linker does not support target {:?}", target),
|
||||
};
|
||||
|
||||
object.format() == target_format
|
||||
}
|
||||
TLA::Aarch64(_) => object.architecture() == object::Architecture::Aarch64,
|
||||
Architecture::Aarch64 => object.architecture() == object::Architecture::Aarch64,
|
||||
_ => todo!("surgical linker does not support target {:?}", target),
|
||||
}
|
||||
}
|
||||
|
@ -361,7 +338,7 @@ fn object_matches_target<'a>(target: &Triple, object: &object::File<'a, &'a [u8]
|
|||
/// Checks whether the stub `.dll/.so` is up to date, in other words that it exports exactly the
|
||||
/// symbols that it is supposed to export, and is built for the right target. If this is the case,
|
||||
/// we can skip rebuildingthe stub lib.
|
||||
fn stub_lib_is_up_to_date(target: &Triple, stub_lib_path: &Path, custom_names: &[String]) -> bool {
|
||||
fn stub_lib_is_up_to_date(target: Target, stub_lib_path: &Path, custom_names: &[String]) -> bool {
|
||||
if !std::path::Path::exists(stub_lib_path) {
|
||||
return false;
|
||||
}
|
||||
|
@ -386,14 +363,14 @@ fn stub_lib_is_up_to_date(target: &Triple, stub_lib_path: &Path, custom_names: &
|
|||
}
|
||||
|
||||
pub fn preprocess_host(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_main_roc: &Path,
|
||||
preprocessed_path: &Path,
|
||||
shared_lib: &Path,
|
||||
stub_dll_symbols: &[String],
|
||||
) {
|
||||
let metadata_path = platform_main_roc.with_file_name(metadata_file_name(target));
|
||||
let host_exe_path = if let target_lexicon::OperatingSystem::Windows = target.operating_system {
|
||||
let host_exe_path = if target.operating_system() == OperatingSystem::Windows {
|
||||
platform_main_roc.with_file_name("dynhost.exe")
|
||||
} else {
|
||||
platform_main_roc.with_file_name("dynhost")
|
||||
|
@ -414,7 +391,7 @@ pub fn preprocess_host(
|
|||
/// Constructs a `Metadata` from a host executable binary, and writes it to disk
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn preprocess(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
host_exe_path: &Path,
|
||||
metadata_path: &Path,
|
||||
preprocessed_path: &Path,
|
||||
|
@ -427,14 +404,9 @@ fn preprocess(
|
|||
println!("Targeting: {target}");
|
||||
}
|
||||
|
||||
let endianness = target
|
||||
.endianness()
|
||||
.unwrap_or(target_lexicon::Endianness::Little);
|
||||
|
||||
match target.binary_format {
|
||||
target_lexicon::BinaryFormat::Elf => {
|
||||
crate::elf::preprocess_elf(
|
||||
endianness,
|
||||
match target.arch_os() {
|
||||
(_, OperatingSystem::Linux) => {
|
||||
crate::elf::preprocess_elf_le(
|
||||
host_exe_path,
|
||||
metadata_path,
|
||||
preprocessed_path,
|
||||
|
@ -444,9 +416,8 @@ fn preprocess(
|
|||
);
|
||||
}
|
||||
|
||||
target_lexicon::BinaryFormat::Macho => {
|
||||
crate::macho::preprocess_macho(
|
||||
target,
|
||||
(_, OperatingSystem::Mac) => {
|
||||
crate::macho::preprocess_macho_le(
|
||||
host_exe_path,
|
||||
metadata_path,
|
||||
preprocessed_path,
|
||||
|
@ -456,7 +427,7 @@ fn preprocess(
|
|||
);
|
||||
}
|
||||
|
||||
target_lexicon::BinaryFormat::Coff => {
|
||||
(_, OperatingSystem::Windows) => {
|
||||
crate::pe::preprocess_windows(
|
||||
host_exe_path,
|
||||
metadata_path,
|
||||
|
@ -468,12 +439,9 @@ fn preprocess(
|
|||
.unwrap_or_else(|e| internal_error!("{}", e));
|
||||
}
|
||||
|
||||
target_lexicon::BinaryFormat::Wasm => {
|
||||
(Architecture::Wasm32, _) => {
|
||||
todo!("Roc does not yet support web assembly hosts!");
|
||||
}
|
||||
target_lexicon::BinaryFormat::Unknown => {
|
||||
internal_error!("Roc does not support unknown host binary formats!");
|
||||
}
|
||||
other => {
|
||||
internal_error!(
|
||||
concat!(
|
||||
|
@ -492,14 +460,14 @@ fn surgery(
|
|||
executable_path: &Path,
|
||||
verbose: bool,
|
||||
time: bool,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
) {
|
||||
match target.binary_format {
|
||||
target_lexicon::BinaryFormat::Elf => {
|
||||
match target.arch_os() {
|
||||
(_, OperatingSystem::Linux) => {
|
||||
crate::elf::surgery_elf(roc_app_bytes, metadata_path, executable_path, verbose, time);
|
||||
}
|
||||
|
||||
target_lexicon::BinaryFormat::Macho => {
|
||||
(_, OperatingSystem::Mac) => {
|
||||
crate::macho::surgery_macho(
|
||||
roc_app_bytes,
|
||||
metadata_path,
|
||||
|
@ -509,16 +477,13 @@ fn surgery(
|
|||
);
|
||||
}
|
||||
|
||||
target_lexicon::BinaryFormat::Coff => {
|
||||
(_, OperatingSystem::Windows) => {
|
||||
crate::pe::surgery_pe(executable_path, metadata_path, roc_app_bytes);
|
||||
}
|
||||
|
||||
target_lexicon::BinaryFormat::Wasm => {
|
||||
(Architecture::Wasm32, _) => {
|
||||
todo!("Roc does not yet support web assembly hosts!");
|
||||
}
|
||||
target_lexicon::BinaryFormat::Unknown => {
|
||||
internal_error!("Roc does not support unknown host binary formats!");
|
||||
}
|
||||
other => {
|
||||
internal_error!(
|
||||
concat!(
|
||||
|
|
|
@ -17,7 +17,6 @@ use std::{
|
|||
path::Path,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
use crate::{
|
||||
align_by_constraint, align_to_offset_by_constraint, load_struct_inplace,
|
||||
|
@ -322,8 +321,7 @@ impl<'a> Surgeries<'a> {
|
|||
}
|
||||
|
||||
/// Constructs a `Metadata` from a host executable binary, and writes it to disk
|
||||
pub(crate) fn preprocess_macho(
|
||||
target: &Triple,
|
||||
pub(crate) fn preprocess_macho_le(
|
||||
host_exe_path: &Path,
|
||||
metadata_path: &Path,
|
||||
preprocessed_path: &Path,
|
||||
|
@ -544,15 +542,6 @@ pub(crate) fn preprocess_macho(
|
|||
|
||||
let text_disassembly_duration = text_disassembly_start.elapsed();
|
||||
|
||||
let scanning_dynamic_deps_duration;
|
||||
let platform_gen_start;
|
||||
|
||||
let out_mmap = {
|
||||
match target
|
||||
.endianness()
|
||||
.unwrap_or(target_lexicon::Endianness::Little)
|
||||
{
|
||||
target_lexicon::Endianness::Little => {
|
||||
let scanning_dynamic_deps_start = Instant::now();
|
||||
|
||||
// let ElfDynamicDeps {
|
||||
|
@ -564,9 +553,9 @@ pub(crate) fn preprocess_macho(
|
|||
// &exec_obj, &mut md, &app_syms, shared_lib, exec_data, verbose,
|
||||
// );
|
||||
|
||||
scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed();
|
||||
let scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed();
|
||||
|
||||
platform_gen_start = Instant::now();
|
||||
let platform_gen_start = Instant::now();
|
||||
|
||||
// TODO little endian
|
||||
let macho_load_so_offset = match macho_load_so_offset {
|
||||
|
@ -581,22 +570,13 @@ pub(crate) fn preprocess_macho(
|
|||
// future this could change? Is there some way to make this more future-proof?
|
||||
md.load_align_constraint = 4096;
|
||||
|
||||
gen_macho_le(
|
||||
let out_mmap = gen_macho_le(
|
||||
exec_data,
|
||||
&mut md,
|
||||
preprocessed_path,
|
||||
macho_load_so_offset,
|
||||
target,
|
||||
verbose,
|
||||
)
|
||||
}
|
||||
target_lexicon::Endianness::Big => {
|
||||
// TODO Is big-endian macOS even a thing that exists anymore?
|
||||
// Just ancient PowerPC machines maybe?
|
||||
todo!("Roc does not yet support big-endian macOS hosts!");
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
let platform_gen_duration = platform_gen_start.elapsed();
|
||||
|
||||
|
@ -652,7 +632,6 @@ fn gen_macho_le(
|
|||
md: &mut Metadata,
|
||||
out_filename: &Path,
|
||||
macho_load_so_offset: usize,
|
||||
_target: &Triple,
|
||||
_verbose: bool,
|
||||
) -> MmapMut {
|
||||
// Just adding some extra context/useful info here.
|
||||
|
|
|
@ -1795,7 +1795,7 @@ mod test {
|
|||
}
|
||||
|
||||
let preprocessed_host_filename =
|
||||
dir.join(preprocessed_host_filename(&Triple::host()).unwrap());
|
||||
dir.join(preprocessed_host_filename(Triple::host().into()));
|
||||
|
||||
preprocess_windows(
|
||||
&dir.join("host.exe"),
|
||||
|
|
|
@ -15,18 +15,16 @@ use roc_repl_eval::eval::jit_to_ast;
|
|||
use roc_repl_eval::gen::{format_answer, ReplOutput};
|
||||
use roc_repl_eval::{ReplApp, ReplAppMemory};
|
||||
use roc_std::RocStr;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_types::pretty_print::{name_and_print_var, DebugPrint};
|
||||
use roc_types::subs::Subs;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
pub fn eval_llvm(
|
||||
mut loaded: MonomorphizedModule<'_>,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
opt_level: OptLevel,
|
||||
) -> Option<ReplOutput> {
|
||||
let arena = Bump::new();
|
||||
let target_info = TargetInfo::from(target);
|
||||
|
||||
debug_assert_eq!(loaded.exposed_to_host.top_level_values.len(), 1);
|
||||
let (main_fn_symbol, main_fn_var) = loaded
|
||||
|
@ -81,7 +79,7 @@ pub fn eval_llvm(
|
|||
&subs,
|
||||
&interns,
|
||||
layout_interner.into_global().fork(),
|
||||
target_info,
|
||||
target,
|
||||
);
|
||||
|
||||
let expr_str = format_answer(&arena, expr).to_string();
|
||||
|
@ -180,12 +178,10 @@ impl ReplAppMemory for CliMemory {
|
|||
)]
|
||||
fn mono_module_to_dylib_llvm<'a>(
|
||||
arena: &'a Bump,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
opt_level: OptLevel,
|
||||
) -> Result<(libloading::Library, &'a str, Subs, STLayoutInterner<'a>), libloading::Error> {
|
||||
let target_info = TargetInfo::from(target);
|
||||
|
||||
let MonomorphizedModule {
|
||||
procedures,
|
||||
host_exposed_lambda_sets,
|
||||
|
@ -217,7 +213,7 @@ fn mono_module_to_dylib_llvm<'a>(
|
|||
context: &context,
|
||||
interns,
|
||||
module,
|
||||
target_info,
|
||||
target,
|
||||
mode: LlvmBackendMode::GenTest, // so roc_panic is generated
|
||||
// important! we don't want any procedures to get the C calling convention
|
||||
exposed_to_host: MutSet::default(),
|
||||
|
@ -286,7 +282,7 @@ fn mono_module_to_dylib_llvm<'a>(
|
|||
)]
|
||||
fn mono_module_to_dylib_asm<'a>(
|
||||
arena: &'a Bump,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
_opt_level: OptLevel,
|
||||
) -> Result<(libloading::Library, &'a str, Subs, STLayoutInterner<'a>), libloading::Error> {
|
||||
|
@ -295,8 +291,6 @@ fn mono_module_to_dylib_asm<'a>(
|
|||
|
||||
let app_o_file = dir.path().join("app.o");
|
||||
|
||||
let _target_info = TargetInfo::from(target);
|
||||
|
||||
let MonomorphizedModule {
|
||||
module_id,
|
||||
procedures,
|
||||
|
@ -317,14 +311,8 @@ fn mono_module_to_dylib_asm<'a>(
|
|||
mode: roc_gen_dev::AssemblyBackendMode::Repl,
|
||||
};
|
||||
|
||||
let target = target_lexicon::Triple::host();
|
||||
let module_object = roc_gen_dev::build_module(
|
||||
&env,
|
||||
&mut interns,
|
||||
&mut layout_interner,
|
||||
&target,
|
||||
procedures,
|
||||
);
|
||||
let module_object =
|
||||
roc_gen_dev::build_module(&env, &mut interns, &mut layout_interner, target, procedures);
|
||||
|
||||
let module_out = module_object
|
||||
.write()
|
||||
|
@ -342,7 +330,7 @@ fn mono_module_to_dylib_asm<'a>(
|
|||
roc_bitcode::host_tempfile().expect("failed to write host builtins object to tempfile");
|
||||
|
||||
let (mut child, dylib_path) = roc_build::link::link(
|
||||
&target,
|
||||
target,
|
||||
app_o_file.clone(),
|
||||
// Long term we probably want a smarter way to link in zig builtins.
|
||||
// With the current method all methods are kept and it adds about 100k to all outputs.
|
||||
|
|
|
@ -10,7 +10,7 @@ use roc_repl_ui::colors::{CYAN, END_COL};
|
|||
use roc_repl_ui::repl_state::{ReplAction, ReplState};
|
||||
use roc_repl_ui::{format_output, is_incomplete, CONT_PROMPT, PROMPT, SHORT_INSTRUCTIONS, TIPS};
|
||||
use roc_reporting::report::{ANSI_STYLE_CODES, DEFAULT_PALETTE};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use rustyline::highlight::{Highlighter, PromptInfo};
|
||||
use rustyline::validate::{self, ValidationContext, ValidationResult, Validator};
|
||||
use rustyline_derive::{Completer, Helper, Hinter};
|
||||
|
@ -46,8 +46,7 @@ pub fn main() -> i32 {
|
|||
let mut editor = Editor::<ReplHelper>::new();
|
||||
let repl_helper = ReplHelper::default();
|
||||
editor.set_helper(Some(repl_helper));
|
||||
let target = Triple::host();
|
||||
let target_info = TargetInfo::from(&target);
|
||||
let target = Triple::host().into();
|
||||
let mut arena = Bump::new();
|
||||
|
||||
loop {
|
||||
|
@ -63,9 +62,9 @@ pub fn main() -> i32 {
|
|||
.state;
|
||||
|
||||
arena.reset();
|
||||
match repl_state.step(&arena, line, target_info, DEFAULT_PALETTE) {
|
||||
match repl_state.step(&arena, line, target, DEFAULT_PALETTE) {
|
||||
ReplAction::Eval { opt_mono, problems } => {
|
||||
let output = evaluate(opt_mono, problems, &target);
|
||||
let output = evaluate(opt_mono, problems, target);
|
||||
// If there was no output, don't print a blank line!
|
||||
// (This happens for something like a type annotation.)
|
||||
if !output.is_empty() {
|
||||
|
@ -104,7 +103,7 @@ pub fn main() -> i32 {
|
|||
pub fn evaluate(
|
||||
opt_mono: Option<MonomorphizedModule<'_>>,
|
||||
problems: Problems,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
) -> String {
|
||||
let opt_output = opt_mono.and_then(|mono| eval_llvm(mono, target, OptLevel::Normal));
|
||||
format_output(ANSI_STYLE_CODES, opt_output, problems)
|
||||
|
|
|
@ -16,7 +16,7 @@ use roc_mono::layout::{
|
|||
use roc_parse::ast::{AssignedField, Collection, Expr, Pattern, StrLiteral};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use roc_std::RocDec;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_types::subs::{
|
||||
Content, FlatType, GetSubsSlice, RecordFields, Subs, TagExt, TupleElems, UnionTags, Variable,
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ use crate::{ReplApp, ReplAppMemory};
|
|||
struct Env<'a, 'env> {
|
||||
arena: &'a Bump,
|
||||
subs: &'env Subs,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
interns: &'a Interns,
|
||||
layout_cache: LayoutCache<'a>,
|
||||
}
|
||||
|
@ -49,14 +49,14 @@ pub fn jit_to_ast<'a, A: ReplApp<'a>>(
|
|||
subs: &Subs,
|
||||
interns: &'a Interns,
|
||||
layout_interner: TLLayoutInterner<'a>,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
) -> Expr<'a> {
|
||||
let mut env = Env {
|
||||
arena,
|
||||
subs,
|
||||
target_info,
|
||||
target,
|
||||
interns,
|
||||
layout_cache: LayoutCache::new(layout_interner, target_info),
|
||||
layout_cache: LayoutCache::new(layout_interner, target),
|
||||
};
|
||||
|
||||
match layout {
|
||||
|
@ -338,7 +338,7 @@ fn tag_id_from_recursive_ptr<'a, M: ReplAppMemory>(
|
|||
union_layout: UnionLayout<'a>,
|
||||
rec_addr: usize,
|
||||
) -> (i64, usize) {
|
||||
let tag_in_ptr = union_layout.stores_tag_id_in_pointer(env.target_info);
|
||||
let tag_in_ptr = union_layout.stores_tag_id_in_pointer(env.target);
|
||||
|
||||
if tag_in_ptr {
|
||||
let (tag_id, data_addr) = mem.deref_pointer_with_tag_id(rec_addr);
|
||||
|
@ -416,7 +416,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
Expr::Str(StrLiteral::PlainLine(arena_str))
|
||||
};
|
||||
|
||||
match app.call_function_returns_roc_str(env.target_info, main_fn_name, body) {
|
||||
match app.call_function_returns_roc_str(env.target, main_fn_name, body) {
|
||||
Some(string) => string,
|
||||
None => Expr::REPL_RUNTIME_CRASH,
|
||||
}
|
||||
|
@ -628,8 +628,8 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
}
|
||||
(_, LayoutRepr::Builtin(Builtin::List(elem_layout))) => {
|
||||
let elem_addr = mem.deref_usize(addr);
|
||||
let len = mem.deref_usize(addr + env.target_info.ptr_width() as usize);
|
||||
let _cap = mem.deref_usize(addr + 2 * env.target_info.ptr_width() as usize);
|
||||
let len = mem.deref_usize(addr + env.target.ptr_width() as usize);
|
||||
let _cap = mem.deref_usize(addr + 2 * env.target.ptr_width() as usize);
|
||||
|
||||
list_to_ast(env, mem, elem_addr, len, elem_layout, raw_content)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use roc_parse::ast::Expr;
|
|||
use roc_region::all::LineInfo;
|
||||
use roc_reporting::report::{can_problem, type_problem, RocDocAllocator};
|
||||
use roc_solve::FunctionKind;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReplOutput {
|
||||
|
@ -49,7 +49,7 @@ pub fn compile_to_mono<'a, 'i, I: Iterator<Item = &'i str>>(
|
|||
arena: &'a Bump,
|
||||
defs: I,
|
||||
expr: &str,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
palette: Palette,
|
||||
) -> (Option<MonomorphizedModule<'a>>, Problems) {
|
||||
let filename = PathBuf::from("replfile.roc");
|
||||
|
@ -62,7 +62,7 @@ pub fn compile_to_mono<'a, 'i, I: Iterator<Item = &'i str>>(
|
|||
src_dir,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind: FunctionKind::LambdaSet,
|
||||
render: roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
palette,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Provides the functionality for the REPL to evaluate Roc expressions.
|
||||
use roc_parse::ast::Expr;
|
||||
use roc_std::RocDec;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
pub mod eval;
|
||||
pub mod gen;
|
||||
|
@ -28,7 +28,7 @@ pub trait ReplApp<'a> {
|
|||
/// When the executed code calls roc_panic, this function will return None
|
||||
fn call_function_returns_roc_str<T, F>(
|
||||
&mut self,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
main_fn_name: &str,
|
||||
transform: F,
|
||||
) -> Option<T>
|
||||
|
@ -36,7 +36,7 @@ pub trait ReplApp<'a> {
|
|||
F: Fn(&'a Self::Memory, usize) -> T,
|
||||
Self::Memory: 'a,
|
||||
{
|
||||
let roc_str_width = match target_info.ptr_width() {
|
||||
let roc_str_width = match target.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => 12,
|
||||
roc_target::PtrWidth::Bytes8 => 24,
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use roc_parse::ast::Expr;
|
||||
use roc_repl_eval::{ReplApp, ReplAppMemory};
|
||||
use roc_std::RocStr;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
pub(crate) struct ExpectMemory {
|
||||
pub(crate) start: *const u8,
|
||||
|
@ -118,7 +118,7 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
|
|||
|
||||
fn call_function_returns_roc_str<T, F>(
|
||||
&mut self,
|
||||
_target_info: TargetInfo,
|
||||
_target: Target,
|
||||
main_fn_name: &str,
|
||||
transform: F,
|
||||
) -> Option<T>
|
||||
|
|
|
@ -8,7 +8,7 @@ use {
|
|||
},
|
||||
roc_parse::ast::Expr,
|
||||
roc_repl_eval::{eval::jit_to_ast, ReplAppMemory},
|
||||
roc_target::TargetInfo,
|
||||
roc_target::Target,
|
||||
roc_types::subs::{Subs, Variable},
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@ use app::{ExpectMemory, ExpectReplApp};
|
|||
#[cfg(not(windows))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn get_values<'a>(
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
arena: &'a bumpalo::Bump,
|
||||
subs: &Subs,
|
||||
interns: &'a Interns,
|
||||
|
@ -58,7 +58,7 @@ pub fn get_values<'a>(
|
|||
app.offset = start;
|
||||
|
||||
// TODO: pass layout_cache to jit_to_ast directly
|
||||
let mut layout_cache = LayoutCache::new(layout_interner.fork(), target_info);
|
||||
let mut layout_cache = LayoutCache::new(layout_interner.fork(), target);
|
||||
let layout = layout_cache.from_var(arena, variable, subs).unwrap();
|
||||
|
||||
let proc_layout = ProcLayout {
|
||||
|
@ -76,7 +76,7 @@ pub fn get_values<'a>(
|
|||
subs,
|
||||
interns,
|
||||
layout_interner.fork(),
|
||||
target_info,
|
||||
target,
|
||||
);
|
||||
|
||||
app.offset += layout_cache.interner.stack_size_and_alignment(layout).0 as usize;
|
||||
|
@ -102,17 +102,13 @@ mod test {
|
|||
|
||||
use crate::run::expect_mono_module_to_dylib;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn run_expect_test(source: &str, expected: &str) {
|
||||
let arena = bumpalo::Bump::new();
|
||||
let arena = &arena;
|
||||
|
||||
let triple = Triple::host();
|
||||
let target = &triple;
|
||||
let target = Triple::host().into();
|
||||
|
||||
let opt_level = roc_mono::ir::OptLevel::Normal;
|
||||
let target_info = TargetInfo::from(target);
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
|
||||
// Step 1: compile the app and generate the .o file
|
||||
|
@ -122,7 +118,7 @@ mod test {
|
|||
std::fs::write(&filename, source).unwrap();
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render: RenderTarget::ColorTerminal,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
@ -150,13 +146,8 @@ mod test {
|
|||
|
||||
let interns = loaded.interns.clone();
|
||||
|
||||
let (dy_lib, expects_by_module, layout_interner) = expect_mono_module_to_dylib(
|
||||
arena,
|
||||
target.clone(),
|
||||
loaded,
|
||||
opt_level,
|
||||
LlvmBackendMode::CliTest,
|
||||
)
|
||||
let (dy_lib, expects_by_module, layout_interner) =
|
||||
expect_mono_module_to_dylib(arena, target, loaded, opt_level, LlvmBackendMode::CliTest)
|
||||
.unwrap();
|
||||
|
||||
let arena = &bumpalo::Bump::new();
|
||||
|
|
|
@ -26,9 +26,8 @@ use roc_mono::{
|
|||
};
|
||||
use roc_region::all::Region;
|
||||
use roc_reporting::{error::expect::Renderer, report::RenderTarget};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_types::subs::Subs;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
pub struct ExpectMemory<'a> {
|
||||
ptr: *mut u8,
|
||||
|
@ -469,7 +468,7 @@ fn render_expect_failure<'a>(
|
|||
offset: usize,
|
||||
) -> std::io::Result<usize> {
|
||||
// we always run programs as the host
|
||||
let target_info = (&target_lexicon::Triple::host()).into();
|
||||
let target = target_lexicon::Triple::host().into();
|
||||
|
||||
let frame = ExpectFrame::at_offset(start, offset);
|
||||
let module_id = frame.module_id;
|
||||
|
@ -487,7 +486,7 @@ fn render_expect_failure<'a>(
|
|||
let symbols = split_expect_lookups(&data.subs, current);
|
||||
|
||||
let (offset, expressions, variables) = crate::get_values(
|
||||
target_info,
|
||||
target,
|
||||
arena,
|
||||
&data.subs,
|
||||
interns,
|
||||
|
@ -613,7 +612,7 @@ pub struct ExpectFunctions<'a> {
|
|||
|
||||
pub fn expect_mono_module_to_dylib<'a>(
|
||||
arena: &'a Bump,
|
||||
target: Triple,
|
||||
target: Target,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
opt_level: OptLevel,
|
||||
mode: LlvmBackendMode,
|
||||
|
@ -625,8 +624,6 @@ pub fn expect_mono_module_to_dylib<'a>(
|
|||
),
|
||||
libloading::Error,
|
||||
> {
|
||||
let target_info = TargetInfo::from(&target);
|
||||
|
||||
let MonomorphizedModule {
|
||||
toplevel_expects,
|
||||
procedures,
|
||||
|
@ -638,7 +635,7 @@ pub fn expect_mono_module_to_dylib<'a>(
|
|||
let context = Context::create();
|
||||
let builder = context.create_builder();
|
||||
let module = arena.alloc(roc_gen_llvm::llvm::build::module_from_builtins(
|
||||
&target, &context, "",
|
||||
target, &context, "",
|
||||
));
|
||||
|
||||
let module = arena.alloc(module);
|
||||
|
@ -656,7 +653,7 @@ pub fn expect_mono_module_to_dylib<'a>(
|
|||
context: &context,
|
||||
interns,
|
||||
module,
|
||||
target_info,
|
||||
target,
|
||||
mode,
|
||||
// important! we don't want any procedures to get the C calling convention
|
||||
exposed_to_host: MutSet::default(),
|
||||
|
@ -753,6 +750,6 @@ pub fn expect_mono_module_to_dylib<'a>(
|
|||
env.module.print_to_file(path).unwrap();
|
||||
}
|
||||
|
||||
llvm_module_to_dylib(env.module, &target, opt_level)
|
||||
llvm_module_to_dylib(env.module, target, opt_level)
|
||||
.map(|dy_lib| (dy_lib, modules_expects, layout_interner))
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ use roc_repl_cli::{evaluate, ReplHelper};
|
|||
use roc_repl_ui::is_incomplete;
|
||||
use roc_repl_ui::repl_state::{ReplAction, ReplState};
|
||||
use roc_reporting::report::DEFAULT_PALETTE;
|
||||
use roc_target::TargetInfo;
|
||||
use rustyline::Editor;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
|
@ -128,9 +127,8 @@ fn partial_record_definition() {
|
|||
fn tips() {
|
||||
assert!(!is_incomplete(""));
|
||||
let arena = Bump::new();
|
||||
let target = Triple::host();
|
||||
let target_info = TargetInfo::from(&target);
|
||||
let action = ReplState::default().step(&arena, "", target_info, DEFAULT_PALETTE);
|
||||
let target = Triple::host().into();
|
||||
let action = ReplState::default().step(&arena, "", target, DEFAULT_PALETTE);
|
||||
assert!(matches!(action, ReplAction::Help));
|
||||
}
|
||||
|
||||
|
@ -142,9 +140,8 @@ fn standalone_annotation() {
|
|||
incomplete(&mut input);
|
||||
assert!(!is_incomplete(&input));
|
||||
let arena = Bump::new();
|
||||
let target = Triple::host();
|
||||
let target_info = TargetInfo::from(&target);
|
||||
let action = state.step(&arena, &input, target_info, DEFAULT_PALETTE);
|
||||
let target = Triple::host().into();
|
||||
let action = state.step(&arena, &input, target, DEFAULT_PALETTE);
|
||||
assert!(matches!(action, ReplAction::Nothing));
|
||||
}
|
||||
|
||||
|
@ -153,16 +150,15 @@ fn standalone_annotation() {
|
|||
fn complete(input: &str, state: &mut ReplState, expected_start: &str) {
|
||||
assert!(!is_incomplete(input));
|
||||
let arena = Bump::new();
|
||||
let target = Triple::host();
|
||||
let target_info = TargetInfo::from(&target);
|
||||
let action = state.step(&arena, input, target_info, DEFAULT_PALETTE);
|
||||
let target = Triple::host().into();
|
||||
let action = state.step(&arena, input, target, DEFAULT_PALETTE);
|
||||
let repl_helper = ReplHelper::default();
|
||||
let mut editor = Editor::<ReplHelper>::new();
|
||||
editor.set_helper(Some(repl_helper));
|
||||
|
||||
match action {
|
||||
ReplAction::Eval { opt_mono, problems } => {
|
||||
let string = evaluate(opt_mono, problems, &target);
|
||||
let string = evaluate(opt_mono, problems, target);
|
||||
let escaped =
|
||||
std::string::String::from_utf8(strip_ansi_escapes::strip(string.trim()).unwrap())
|
||||
.unwrap();
|
||||
|
@ -190,16 +186,15 @@ fn incomplete(input: &mut String) {
|
|||
fn error(input: &str, state: &mut ReplState, expected_step_result: String) {
|
||||
assert!(!is_incomplete(input));
|
||||
let arena = Bump::new();
|
||||
let target = Triple::host();
|
||||
let target_info = TargetInfo::from(&target);
|
||||
let action = state.step(&arena, input, target_info, DEFAULT_PALETTE);
|
||||
let target = Triple::host().into();
|
||||
let action = state.step(&arena, input, target, DEFAULT_PALETTE);
|
||||
let repl_helper = ReplHelper::default();
|
||||
let mut editor = Editor::<ReplHelper>::new();
|
||||
editor.set_helper(Some(repl_helper));
|
||||
|
||||
match action {
|
||||
ReplAction::Eval { opt_mono, problems } => {
|
||||
let string = evaluate(opt_mono, problems, &target);
|
||||
let string = evaluate(opt_mono, problems, target);
|
||||
let escaped =
|
||||
std::string::String::from_utf8(strip_ansi_escapes::strip(string.trim()).unwrap())
|
||||
.unwrap();
|
||||
|
|
|
@ -11,7 +11,7 @@ use roc_parse::{join_alias_to_body, join_ann_to_body};
|
|||
use roc_region::all::Loc;
|
||||
use roc_repl_eval::gen::{compile_to_mono, Problems};
|
||||
use roc_reporting::report::Palette;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct PastDef {
|
||||
|
@ -54,7 +54,7 @@ impl ReplState {
|
|||
&mut self,
|
||||
arena: &'a Bump,
|
||||
line: &str,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
palette: Palette,
|
||||
) -> ReplAction<'a> {
|
||||
let pending_past_def;
|
||||
|
@ -170,7 +170,7 @@ impl ReplState {
|
|||
arena,
|
||||
self.past_defs.iter().map(|def| def.src.as_str()),
|
||||
src,
|
||||
target_info,
|
||||
target,
|
||||
palette,
|
||||
);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ use roc_repl_ui::{
|
|||
repl_state::{ReplAction, ReplState},
|
||||
TIPS,
|
||||
};
|
||||
use roc_target::TargetInfo;
|
||||
use roc_target::Target;
|
||||
use roc_types::pretty_print::{name_and_print_var, DebugPrint};
|
||||
|
||||
use crate::{js_create_app, js_get_result_and_memory, js_run_app};
|
||||
|
@ -189,12 +189,12 @@ pub async fn entrypoint_from_js(src: String) -> String {
|
|||
let arena = &Bump::new();
|
||||
|
||||
// Compile the app
|
||||
let target_info = TargetInfo::default_wasm32();
|
||||
let target = Target::Wasm32;
|
||||
|
||||
// Advance the REPL state machine
|
||||
let action = REPL_STATE.with(|repl_state_cell| {
|
||||
let mut repl_state = repl_state_cell.borrow_mut();
|
||||
repl_state.step(arena, &src, target_info, DEFAULT_PALETTE_HTML)
|
||||
repl_state.step(arena, &src, target, DEFAULT_PALETTE_HTML)
|
||||
});
|
||||
|
||||
// Perform the action the state machine asked for, and return the appropriate output string
|
||||
|
@ -206,7 +206,7 @@ pub async fn entrypoint_from_js(src: String) -> String {
|
|||
ReplAction::Nothing => String::new(),
|
||||
ReplAction::Eval { opt_mono, problems } => {
|
||||
let opt_output = match opt_mono {
|
||||
Some(mono) => eval_wasm(arena, target_info, mono).await,
|
||||
Some(mono) => eval_wasm(arena, target, mono).await,
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
@ -217,7 +217,7 @@ pub async fn entrypoint_from_js(src: String) -> String {
|
|||
|
||||
async fn eval_wasm<'a>(
|
||||
arena: &'a Bump,
|
||||
target_info: TargetInfo,
|
||||
target: Target,
|
||||
mono: MonomorphizedModule<'a>,
|
||||
) -> Option<ReplOutput> {
|
||||
let MonomorphizedModule {
|
||||
|
@ -311,7 +311,7 @@ async fn eval_wasm<'a>(
|
|||
&subs,
|
||||
&interns,
|
||||
layout_interner.into_global().fork(),
|
||||
target_info,
|
||||
target,
|
||||
);
|
||||
|
||||
// Transform the Expr to a string
|
||||
|
|
|
@ -14,11 +14,11 @@ fn build_host() {
|
|||
roc_command_utils::root_dir().join("crates/valgrind/zig-platform/main.roc");
|
||||
|
||||
// tests always run on the host
|
||||
let target = target_lexicon::Triple::host();
|
||||
let target = target_lexicon::Triple::host().into();
|
||||
|
||||
// the preprocessed host is stored beside the platform's main.roc
|
||||
let preprocessed_host_path =
|
||||
platform_main_roc.with_file_name(preprocessed_host_filename(&target).unwrap());
|
||||
platform_main_roc.with_file_name(preprocessed_host_filename(target));
|
||||
|
||||
// valgrind does not support avx512 yet: https://bugs.kde.org/show_bug.cgi?id=383010
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
|
@ -28,7 +28,7 @@ fn build_host() {
|
|||
|
||||
build_and_preprocess_host(
|
||||
roc_mono::ir::OptLevel::Normal,
|
||||
&target,
|
||||
target,
|
||||
&platform_main_roc,
|
||||
&preprocessed_host_path,
|
||||
roc_linker::ExposedSymbols {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue