Merge branch 'trunk' into linker

This commit is contained in:
Brendan Hansknecht 2021-09-08 20:20:18 -07:00 committed by GitHub
commit 1caa92b173
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 138 additions and 89 deletions

32
Cargo.lock generated
View file

@ -1959,9 +1959,9 @@ dependencies = [
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.53" version = "0.3.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" checksum = "1866b355d9c878e5e607473cbe3f63282c0b7aad2db1dbebf55076c686918254"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
@ -4154,9 +4154,9 @@ dependencies = [
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.9.6" version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" checksum = "91e36fa7752016a6c4483706d634fd82c48860dd2df17a0cfaaebc714f23b2dd"
dependencies = [ dependencies = [
"block-buffer 0.9.0", "block-buffer 0.9.0",
"cfg-if 1.0.0", "cfg-if 1.0.0",
@ -4819,9 +4819,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.76" version = "0.2.77"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" checksum = "5e68338db6becec24d3c7977b5bf8a48be992c934b5d07177e3931f5dc9b076c"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@ -4829,9 +4829,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.76" version = "0.2.77"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" checksum = "f34c405b4f0658583dba0c1c7c9b694f3cac32655db463b56c254a1c75269523"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static", "lazy_static",
@ -4844,9 +4844,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.26" version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" checksum = "a87d738d4abc4cf22f6eb142f5b9a81301331ee3c767f2fef2fda4e325492060"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"js-sys", "js-sys",
@ -4856,9 +4856,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.76" version = "0.2.77"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" checksum = "b9d5a6580be83b19dc570a8f9c324251687ab2184e57086f71625feb57ec77c8"
dependencies = [ dependencies = [
"quote 1.0.9", "quote 1.0.9",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -4866,9 +4866,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.76" version = "0.2.77"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" checksum = "e3775a030dc6f5a0afd8a84981a21cc92a781eb429acef9ecce476d0c9113e92"
dependencies = [ dependencies = [
"proc-macro2 1.0.29", "proc-macro2 1.0.29",
"quote 1.0.9", "quote 1.0.9",
@ -4879,9 +4879,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.76" version = "0.2.77"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" checksum = "c279e376c7a8e8752a8f1eaa35b7b0bee6bb9fb0cdacfa97cc3f1f289c87e2b4"
[[package]] [[package]]
name = "wasmer" name = "wasmer"

View file

@ -327,7 +327,7 @@ mod cli_run {
// TODO fix QuicksortApp and then remove this! // TODO fix QuicksortApp and then remove this!
match benchmark.filename { match benchmark.filename {
"QuicksortApp.roc" | "TestBase64.roc" => { "QuicksortApp.roc" => {
eprintln!("WARNING: skipping testing benchmark {} because the test is broken right now!", benchmark.filename); eprintln!("WARNING: skipping testing benchmark {} because the test is broken right now!", benchmark.filename);
return; return;
} }
@ -608,6 +608,14 @@ fn run_with_wasmer(wasm_path: &std::path::Path, stdin: &[&str]) -> String {
use std::io::Write; use std::io::Write;
use wasmer::{Instance, Module, Store}; use wasmer::{Instance, Module, Store};
// std::process::Command::new("cp")
// .args(&[
// wasm_path.to_str().unwrap(),
// "/home/folkertdev/roc/wasm/nqueens.wasm",
// ])
// .output()
// .unwrap();
let store = Store::default(); let store = Store::default();
let module = Module::from_file(&store, &wasm_path).unwrap(); let module = Module::from_file(&store, &wasm_path).unwrap();

View file

@ -618,8 +618,7 @@ fn link_wasm32(
) -> io::Result<(Child, PathBuf)> { ) -> io::Result<(Child, PathBuf)> {
let zig_str_path = find_zig_str_path(); let zig_str_path = find_zig_str_path();
let child = let child = Command::new("zig9")
Command::new("/home/folkertdev/Downloads/zig-linux-x86_64-0.9.0-dev.848+d5ef5da59/zig")
// .env_clear() // .env_clear()
// .env("PATH", &env_path) // .env("PATH", &env_path)
.args(&["build-exe"]) .args(&["build-exe"])
@ -629,11 +628,13 @@ fn link_wasm32(
// include libc // include libc
"-lc", "-lc",
"-target", "-target",
"wasm32-wasi", "wasm32-wasi-musl",
"--pkg-begin", "--pkg-begin",
"str", "str",
zig_str_path.to_str().unwrap(), zig_str_path.to_str().unwrap(),
"--pkg-end", "--pkg-end",
"--strip",
// "-O", "ReleaseSmall",
// useful for debugging // useful for debugging
// "-femit-llvm-ir=/home/folkertdev/roc/roc/examples/benchmarks/platform/host.ll", // "-femit-llvm-ir=/home/folkertdev/roc/roc/examples/benchmarks/platform/host.ll",
]) ])

View file

@ -1150,8 +1150,8 @@ fn strToBytes(arg: RocStr) RocList {
} }
const FromUtf8Result = extern struct { const FromUtf8Result = extern struct {
byte_index: usize,
string: RocStr, string: RocStr,
byte_index: usize,
is_ok: bool, is_ok: bool,
problem_code: Utf8ByteProblem, problem_code: Utf8ByteProblem,
}; };

View file

@ -2189,8 +2189,15 @@ fn list_literal<'a, 'ctx, 'env>(
let global = { let global = {
let mut global_elements = Vec::with_capacity_in(list_length, env.arena); let mut global_elements = Vec::with_capacity_in(list_length, env.arena);
// insert NULL bytes for the refcount // Add zero bytes that represent the refcount
// these elements are (dropped again if the list contains non-constants) //
// - if all elements are const, then we store the whole list as a constant.
// It then needs a refcount before the first element.
// - but if the list is not all constants, then we will just copy the constant values,
// and we do not need that refcount at the start
//
// In the latter case, we won't store the zeros in the globals
// (we slice them off again below)
for _ in 0..zero_elements { for _ in 0..zero_elements {
global_elements.push(element_type.const_zero()); global_elements.push(element_type.const_zero());
} }

View file

@ -1,5 +1,5 @@
use crate::llvm::bitcode::{call_bitcode_fn, call_void_bitcode_fn}; use crate::llvm::bitcode::{call_bitcode_fn, call_void_bitcode_fn};
use crate::llvm::build::{complex_bitcast, Env, Scope}; use crate::llvm::build::{complex_bitcast, struct_from_fields, Env, Scope};
use crate::llvm::build_list::{allocate_list, call_bitcode_fn_returns_list, store_list}; use crate::llvm::build_list::{allocate_list, call_bitcode_fn_returns_list, store_list};
use inkwell::builder::Builder; use inkwell::builder::Builder;
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue};
@ -260,6 +260,73 @@ pub fn str_to_utf8<'a, 'ctx, 'env>(
call_bitcode_fn_returns_list(env, &[string], bitcode::STR_TO_UTF8) call_bitcode_fn_returns_list(env, &[string], bitcode::STR_TO_UTF8)
} }
fn decode_from_utf8_result<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
pointer: PointerValue<'ctx>,
) -> StructValue<'ctx> {
let builder = env.builder;
let ctx = env.context;
let fields = match env.ptr_bytes {
8 => [
env.ptr_int().into(),
super::convert::zig_str_type(env).into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
4 => [
super::convert::zig_str_type(env).into(),
env.ptr_int().into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
_ => unreachable!(),
};
let record_type = env.context.struct_type(&fields, false);
match env.ptr_bytes {
8 => {
let zig_struct = builder
.build_load(pointer, "load_utf8_validate_bytes_result")
.into_struct_value();
let string = builder
.build_extract_value(zig_struct, 0, "string")
.unwrap();
let byte_index = builder
.build_extract_value(zig_struct, 1, "byte_index")
.unwrap();
let is_ok = builder.build_extract_value(zig_struct, 2, "is_ok").unwrap();
let problem_code = builder
.build_extract_value(zig_struct, 3, "problem_code")
.unwrap();
let values = [byte_index, string, is_ok, problem_code];
struct_from_fields(env, record_type, values.iter().copied().enumerate())
}
4 => {
let result_ptr_cast = env
.builder
.build_bitcast(
pointer,
record_type.ptr_type(AddressSpace::Generic),
"to_unnamed",
)
.into_pointer_value();
builder
.build_load(result_ptr_cast, "load_utf8_validate_bytes_result")
.into_struct_value()
}
_ => unreachable!(),
}
}
/// Str.fromUtf8 : List U8, { count : Nat, start : Nat } -> { a : Bool, b : Str, c : Nat, d : I8 } /// Str.fromUtf8 : List U8, { count : Nat, start : Nat } -> { a : Bool, b : Str, c : Nat, d : I8 }
pub fn str_from_utf8_range<'a, 'ctx, 'env>( pub fn str_from_utf8_range<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
@ -268,7 +335,6 @@ pub fn str_from_utf8_range<'a, 'ctx, 'env>(
count_and_start: StructValue<'ctx>, count_and_start: StructValue<'ctx>,
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let ctx = env.context;
let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap(); let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap();
let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result"); let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result");
@ -293,26 +359,7 @@ pub fn str_from_utf8_range<'a, 'ctx, 'env>(
bitcode::STR_FROM_UTF8_RANGE, bitcode::STR_FROM_UTF8_RANGE,
); );
let record_type = env.context.struct_type( decode_from_utf8_result(env, result_ptr).into()
&[
env.ptr_int().into(),
super::convert::zig_str_type(env).into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
false,
);
let result_ptr_cast = env
.builder
.build_bitcast(
result_ptr,
record_type.ptr_type(AddressSpace::Generic),
"to_unnamed",
)
.into_pointer_value();
builder.build_load(result_ptr_cast, "load_utf8_validate_bytes_result")
} }
/// Str.fromUtf8 : List U8 -> { a : Bool, b : Str, c : Nat, d : I8 } /// Str.fromUtf8 : List U8 -> { a : Bool, b : Str, c : Nat, d : I8 }
@ -322,7 +369,6 @@ pub fn str_from_utf8<'a, 'ctx, 'env>(
original_wrapper: StructValue<'ctx>, original_wrapper: StructValue<'ctx>,
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let ctx = env.context;
let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap(); let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap();
let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result"); let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result");
@ -341,26 +387,7 @@ pub fn str_from_utf8<'a, 'ctx, 'env>(
bitcode::STR_FROM_UTF8, bitcode::STR_FROM_UTF8,
); );
let record_type = env.context.struct_type( decode_from_utf8_result(env, result_ptr).into()
&[
env.ptr_int().into(),
super::convert::zig_str_type(env).into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
false,
);
let result_ptr_cast = env
.builder
.build_bitcast(
result_ptr,
record_type.ptr_type(AddressSpace::Generic),
"to_unnamed",
)
.into_pointer_value();
builder.build_load(result_ptr_cast, "load_utf8_validate_bytes_result")
} }
/// Str.fromInt : Int -> Str /// Str.fromInt : Int -> Str

View file

@ -1151,10 +1151,15 @@ impl<'a> Builtin<'a> {
Float64 => align_of::<f64>() as u32, Float64 => align_of::<f64>() as u32,
Float32 => align_of::<f32>() as u32, Float32 => align_of::<f32>() as u32,
Float16 => align_of::<i16>() as u32, Float16 => align_of::<i16>() as u32,
Str | EmptyStr => pointer_size,
Dict(_, _) | EmptyDict => pointer_size, Dict(_, _) | EmptyDict => pointer_size,
Set(_) | EmptySet => pointer_size, Set(_) | EmptySet => pointer_size,
List(_) | EmptyList => pointer_size, // we often treat these as i128 (64-bit systems)
// or i64 (32-bit systems).
//
// In webassembly, For that to be safe
// they must be aligned to allow such access
List(_) | EmptyList => pointer_size.max(8),
Str | EmptyStr => pointer_size.max(8),
} }
} }
@ -1240,9 +1245,10 @@ impl<'a> Builtin<'a> {
Builtin::Str => pointer_size, Builtin::Str => pointer_size,
Builtin::Dict(k, v) => k Builtin::Dict(k, v) => k
.alignment_bytes(pointer_size) .alignment_bytes(pointer_size)
.max(v.alignment_bytes(pointer_size)), .max(v.alignment_bytes(pointer_size))
Builtin::Set(k) => k.alignment_bytes(pointer_size), .max(pointer_size),
Builtin::List(e) => e.alignment_bytes(pointer_size), Builtin::Set(k) => k.alignment_bytes(pointer_size).max(pointer_size),
Builtin::List(e) => e.alignment_bytes(pointer_size).max(pointer_size),
Builtin::EmptyStr | Builtin::EmptyList | Builtin::EmptyDict | Builtin::EmptySet => { Builtin::EmptyStr | Builtin::EmptyList | Builtin::EmptyDict | Builtin::EmptySet => {
unreachable!("not heap-allocated") unreachable!("not heap-allocated")
} }

View file

@ -366,7 +366,7 @@ pub fn helper_wasm<'a>(
use std::process::Command; use std::process::Command;
Command::new("/home/folkertdev/Downloads/zig-linux-x86_64-0.9.0-dev.848+d5ef5da59/zig") Command::new("zig9")
.current_dir(dir_path) .current_dir(dir_path)
.args(&[ .args(&[
"wasm-ld", "wasm-ld",