mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Merge pull request #2268 from rtfeldman/update_zig_09
Update to Zig 0.9 + LLVM 13
This commit is contained in:
commit
5d3b83f5a6
43 changed files with 1037 additions and 555 deletions
|
@ -126,7 +126,7 @@ sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Zig
|
### Zig
|
||||||
**version: 0.8.0**
|
**version: 0.9.1**
|
||||||
|
|
||||||
For any OS, you can use [`zigup`](https://github.com/marler8997/zigup) to manage zig installations.
|
For any OS, you can use [`zigup`](https://github.com/marler8997/zigup) to manage zig installations.
|
||||||
|
|
||||||
|
@ -138,14 +138,14 @@ If you prefer a package manager, you can try the following:
|
||||||
If you want to install it manually, you can also download Zig directly [here](https://ziglang.org/download/). Just make sure you download the right version, the bleeding edge master build is the first download link on this page.
|
If you want to install it manually, you can also download Zig directly [here](https://ziglang.org/download/). Just make sure you download the right version, the bleeding edge master build is the first download link on this page.
|
||||||
|
|
||||||
### LLVM
|
### LLVM
|
||||||
**version: 12.0.x**
|
**version: 13.0.x**
|
||||||
|
|
||||||
For macOS, you can install LLVM 12 using `brew install llvm@12` and then adding
|
For macOS, you can install LLVM 13 using `brew install llvm@13` and then adding
|
||||||
`$(brew --prefix llvm@12)/bin` to your `PATH`. You can confirm this worked by
|
`$(brew --prefix llvm@13)/bin` to your `PATH`. You can confirm this worked by
|
||||||
running `llc --version` - it should mention "LLVM version 12.0.0" at the top.
|
running `llc --version` - it should mention "LLVM version 13.0.0" at the top.
|
||||||
You may also need to manually specify a prefix env var like so:
|
You may also need to manually specify a prefix env var like so:
|
||||||
```
|
```
|
||||||
export LLVM_SYS_120_PREFIX=/usr/local/opt/llvm@12
|
export LLVM_SYS_130_PREFIX=/usr/local/opt/llvm@13
|
||||||
```
|
```
|
||||||
|
|
||||||
For Ubuntu and Debian:
|
For Ubuntu and Debian:
|
||||||
|
@ -153,19 +153,15 @@ For Ubuntu and Debian:
|
||||||
sudo apt -y install lsb-release software-properties-common gnupg
|
sudo apt -y install lsb-release software-properties-common gnupg
|
||||||
wget https://apt.llvm.org/llvm.sh
|
wget https://apt.llvm.org/llvm.sh
|
||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
./llvm.sh 12
|
./llvm.sh 13
|
||||||
```
|
```
|
||||||
|
|
||||||
If you use this script, you'll need to add `clang` and `llvm-as` to your `PATH`.
|
If you use this script, you'll need to add `clang` to your `PATH`.
|
||||||
By default, the script installs them as `clang-12` and `llvm-as-12`,
|
By default, the script installs it as `clang-13`. You can address this with symlinks like so:
|
||||||
respectively. You can address this with symlinks like so:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo ln -s /usr/bin/clang-12 /usr/bin/clang
|
sudo ln -s /usr/bin/clang-13 /usr/bin/clang
|
||||||
```
|
```
|
||||||
```
|
|
||||||
sudo ln -s /usr/bin/llvm-as-12 /usr/bin/llvm-as
|
|
||||||
````
|
|
||||||
|
|
||||||
There are also alternative installation options at http://releases.llvm.org/download.html
|
There are also alternative installation options at http://releases.llvm.org/download.html
|
||||||
|
|
||||||
|
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -2071,9 +2071,9 @@ checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "llvm-sys"
|
name = "llvm-sys"
|
||||||
version = "120.2.4"
|
version = "130.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09b716322964966a62377cf86e64f00ca7043505fdf27bd2ec7d41ae6682d1e7"
|
checksum = "95eb03b4f7ae21f48ef7c565a3e3aa22c50616aea64645fb1fd7f6f56b51c274"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
13
Earthfile
13
Earthfile
|
@ -17,9 +17,9 @@ install-zig-llvm-valgrind-clippy-rustfmt:
|
||||||
# editor
|
# editor
|
||||||
RUN apt -y install libxkbcommon-dev
|
RUN apt -y install libxkbcommon-dev
|
||||||
# zig
|
# zig
|
||||||
RUN wget -c https://ziglang.org/download/0.8.0/zig-linux-x86_64-0.8.0.tar.xz --no-check-certificate
|
RUN wget -c https://ziglang.org/download/0.9.1/zig-linux-x86_64-0.9.1.tar.xz --no-check-certificate
|
||||||
RUN tar -xf zig-linux-x86_64-0.8.0.tar.xz
|
RUN tar -xf zig-linux-x86_64-0.9.1.tar.xz
|
||||||
RUN ln -s /earthbuild/zig-linux-x86_64-0.8.0/zig /bin/zig
|
RUN ln -s /earthbuild/zig-linux-x86_64-0.9.1/zig /bin/zig
|
||||||
# zig builtins wasm tests
|
# zig builtins wasm tests
|
||||||
RUN apt -y install build-essential
|
RUN apt -y install build-essential
|
||||||
RUN cargo install wasmer-cli --features "singlepass"
|
RUN cargo install wasmer-cli --features "singlepass"
|
||||||
|
@ -27,11 +27,10 @@ install-zig-llvm-valgrind-clippy-rustfmt:
|
||||||
RUN apt -y install lsb-release software-properties-common gnupg
|
RUN apt -y install lsb-release software-properties-common gnupg
|
||||||
RUN wget https://apt.llvm.org/llvm.sh
|
RUN wget https://apt.llvm.org/llvm.sh
|
||||||
RUN chmod +x llvm.sh
|
RUN chmod +x llvm.sh
|
||||||
RUN ./llvm.sh 12
|
RUN ./llvm.sh 13
|
||||||
RUN ln -s /usr/bin/clang-12 /usr/bin/clang
|
RUN ln -s /usr/bin/clang-13 /usr/bin/clang
|
||||||
RUN ln -s /usr/bin/llvm-as-12 /usr/bin/llvm-as
|
|
||||||
# use lld as linker
|
# use lld as linker
|
||||||
RUN ln -s /usr/bin/lld-12 /usr/bin/ld.lld
|
RUN ln -s /usr/bin/lld-13 /usr/bin/ld.lld
|
||||||
ENV RUSTFLAGS="-C link-arg=-fuse-ld=lld -C target-cpu=native"
|
ENV RUSTFLAGS="-C link-arg=-fuse-ld=lld -C target-cpu=native"
|
||||||
# valgrind
|
# valgrind
|
||||||
RUN apt -y install valgrind
|
RUN apt -y install valgrind
|
||||||
|
|
|
@ -76,9 +76,9 @@ popd
|
||||||
valgrind --version
|
valgrind --version
|
||||||
|
|
||||||
# install zig - can't use apt-get since we require at least a specific commit later then the most recent tag (0.6.0)
|
# install zig - can't use apt-get since we require at least a specific commit later then the most recent tag (0.6.0)
|
||||||
wget -c https://ziglang.org/download/0.7.1/zig-linux-x86_64-0.7.1.tar.xz --no-check-certificate
|
wget -c https://ziglang.org/download/0.9.1/zig-linux-x86_64-0.9.1.tar.xz --no-check-certificate
|
||||||
tar -xf zig-linux-x86_64-0.7.1.tar.xz
|
tar -xf zig-linux-x86_64-0.9.1.tar.xz
|
||||||
ln -s "$PWD/zig-linux-x86_64-0.7.1/zig" /usr/local/bin/zig
|
ln -s "$PWD/zig-linux-x86_64-0.9.1/zig" /usr/local/bin/zig
|
||||||
|
|
||||||
# test sccache
|
# test sccache
|
||||||
./ci/sccache -V
|
./ci/sccache -V
|
||||||
|
|
|
@ -756,7 +756,7 @@ mod cli_run {
|
||||||
stdin: &[],
|
stdin: &[],
|
||||||
input_file: None,
|
input_file: None,
|
||||||
expected_ending: "",
|
expected_ending: "",
|
||||||
use_valgrind: true,
|
use_valgrind: false,
|
||||||
},
|
},
|
||||||
issue2279 => Example {
|
issue2279 => Example {
|
||||||
filename: "Issue2279.roc",
|
filename: "Issue2279.roc",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
const str = @import("str");
|
const str = @import("str");
|
||||||
const RocStr = str.RocStr;
|
const RocStr = str.RocStr;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
@ -14,7 +15,7 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,23 +23,28 @@ comptime {
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
|
|
||||||
extern fn roc__mainForHost_1_exposed() RocStr;
|
extern fn roc__mainForHost_1_exposed_generic(*RocStr) void;
|
||||||
|
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*c_void;
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn realloc(c_ptr: [*]align(@alignOf(u128)) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(@alignOf(u128)) u8) callconv(.C) void;
|
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
|
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
||||||
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
|
_ = alignment;
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
|
_ = old_size;
|
||||||
|
_ = alignment;
|
||||||
return realloc(@alignCast(16, @ptrCast([*]u8, c_ptr)), new_size);
|
return realloc(@alignCast(16, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
|
_ = alignment;
|
||||||
free(@alignCast(16, @ptrCast([*]u8, c_ptr)));
|
free(@alignCast(16, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +56,9 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||||
return memset(dst, value, size);
|
return memset(dst, value, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
const msg = @ptrCast([*:0]const u8, c_ptr);
|
const msg = @ptrCast([*:0]const u8, c_ptr);
|
||||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||||
|
@ -65,14 +73,15 @@ pub export fn main() i32 {
|
||||||
|
|
||||||
// start time
|
// start time
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
// actually call roc to populate the callresult
|
// actually call roc to populate the callresult
|
||||||
const callresult = roc__mainForHost_1_exposed();
|
var callresult = RocStr.empty();
|
||||||
|
roc__mainForHost_1_exposed_generic(&callresult);
|
||||||
|
|
||||||
// end time
|
// end time
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
// stdout the result
|
// stdout the result
|
||||||
stdout.print("{s}\n", .{callresult.asSlice()}) catch unreachable;
|
stdout.print("{s}\n", .{callresult.asSlice()}) catch unreachable;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
const str = @import("str");
|
const str = @import("str");
|
||||||
const RocStr = str.RocStr;
|
const RocStr = str.RocStr;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
@ -14,7 +15,7 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,23 +23,27 @@ comptime {
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
|
|
||||||
extern fn roc__mainForHost_1_exposed() RocStr;
|
extern fn roc__mainForHost_1_exposed_generic(*RocStr) void;
|
||||||
|
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*anyopaque;
|
||||||
extern fn realloc(c_ptr: [*]align(@alignOf(u128)) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn realloc(c_ptr: [*]align(@alignOf(u128)) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(@alignOf(u128)) u8) callconv(.C) void;
|
extern fn free(c_ptr: [*]align(@alignOf(u128)) u8) callconv(.C) void;
|
||||||
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
|
_ = alignment;
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
|
_ = old_size;
|
||||||
|
_ = alignment;
|
||||||
return realloc(@alignCast(16, @ptrCast([*]u8, c_ptr)), new_size);
|
return realloc(@alignCast(16, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
|
_ = alignment;
|
||||||
free(@alignCast(16, @ptrCast([*]u8, c_ptr)));
|
free(@alignCast(16, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +55,9 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||||
return memset(dst, value, size);
|
return memset(dst, value, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
const msg = @ptrCast([*:0]const u8, c_ptr);
|
const msg = @ptrCast([*:0]const u8, c_ptr);
|
||||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||||
|
@ -65,14 +72,15 @@ pub export fn main() i32 {
|
||||||
|
|
||||||
// start time
|
// start time
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
// actually call roc to populate the callresult
|
// actually call roc to populate the callresult
|
||||||
const callresult = roc__mainForHost_1_exposed();
|
var callresult = RocStr.empty();
|
||||||
|
roc__mainForHost_1_exposed_generic(&callresult);
|
||||||
|
|
||||||
// end time
|
// end time
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
// stdout the result
|
// stdout the result
|
||||||
stdout.print("{s}\n", .{callresult.asSlice()}) catch unreachable;
|
stdout.print("{s}\n", .{callresult.asSlice()}) catch unreachable;
|
||||||
|
|
332
cli_utils/Cargo.lock
generated
332
cli_utils/Cargo.lock
generated
|
@ -124,9 +124,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.1"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
|
@ -188,10 +188,22 @@ version = "0.22.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527"
|
checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"funty",
|
"funty 1.2.0",
|
||||||
"radium",
|
"radium 0.6.2",
|
||||||
"tap",
|
"tap",
|
||||||
"wyz",
|
"wyz 0.4.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitvec"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b"
|
||||||
|
dependencies = [
|
||||||
|
"funty 2.0.0",
|
||||||
|
"radium 0.7.0",
|
||||||
|
"tap",
|
||||||
|
"wyz 0.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -346,17 +358,26 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.0.0-beta.5"
|
version = "3.1.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63"
|
checksum = "47582c09be7c8b32c0ab3a6181825ababb713fde6fff20fc573a3870dd45c6a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"clap_lex",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"os_str_bytes",
|
|
||||||
"strsim 0.10.0",
|
"strsim 0.10.0",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"textwrap 0.14.2",
|
"textwrap 0.15.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
|
||||||
|
dependencies = [
|
||||||
|
"os_str_bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -958,7 +979,7 @@ checksum = "a16910e685088843d53132b04e0f10a571fdb193224fc589685b3ba1ce4cb03d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys 0.28.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1015,6 +1036,12 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
|
checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "funty"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
|
@ -1297,7 +1324,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46e977036f7f5139d580c7f19ad62df9cb8ebd8410bb569e73585226be80a86f"
|
checksum = "46e977036f7f5139d580c7f19ad62df9cb8ebd8410bb569e73585226be80a86f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"static_assertions",
|
"static_assertions 1.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1348,26 +1375,26 @@ dependencies = [
|
||||||
name = "inkwell"
|
name = "inkwell"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"inkwell 0.1.0 (git+https://github.com/rtfeldman/inkwell?tag=llvm13-0.release1)",
|
"inkwell 0.1.0 (git+https://github.com/rtfeldman/inkwell?branch=master)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inkwell"
|
name = "inkwell"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/rtfeldman/inkwell?tag=llvm13-0.release1#e15d665227b2acad4ca949820d80048e09f3f4e5"
|
source = "git+https://github.com/rtfeldman/inkwell?branch=master#accd406858a40ca2a1463ff77d79f3c5e4c96f4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
"inkwell_internals",
|
"inkwell_internals",
|
||||||
"libc",
|
"libc",
|
||||||
"llvm-sys",
|
"llvm-sys",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot 0.12.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inkwell_internals"
|
name = "inkwell_internals"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/rtfeldman/inkwell?tag=llvm13-0.release1#e15d665227b2acad4ca949820d80048e09f3f4e5"
|
source = "git+https://github.com/rtfeldman/inkwell?branch=master#accd406858a40ca2a1463ff77d79f3c5e4c96f4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1496,9 +1523,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "llvm-sys"
|
name = "llvm-sys"
|
||||||
version = "120.2.1"
|
version = "130.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4a810627ac62b396f5fd2214ba9bbd8748d4d6efdc4d2c1c1303ea7a75763ce"
|
checksum = "95eb03b4f7ae21f48ef7c565a3e3aa22c50616aea64645fb1fd7f6f56b51c274"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -1509,10 +1536,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.5"
|
version = "0.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1566,9 +1594,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.5.0"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4647a11b578fead29cdbb34d4adef8dd3dc35b876c9c6d5240d83f205abfe96e"
|
checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
@ -1949,12 +1977,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
version = "4.2.0"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799"
|
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owned_ttf_parser"
|
name = "owned_ttf_parser"
|
||||||
|
@ -1980,7 +2005,7 @@ version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c48e482b9a59ad6c2cdb06f7725e7bd33fe3525baaf4699fde7bfea6a5b77b1"
|
checksum = "9c48e482b9a59ad6c2cdb06f7725e7bd33fe3525baaf4699fde7bfea6a5b77b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitvec",
|
"bitvec 0.22.3",
|
||||||
"packed_struct_codegen",
|
"packed_struct_codegen",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -2038,7 +2063,17 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"instant",
|
"instant",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"parking_lot_core",
|
"parking_lot_core 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core 0.9.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2055,6 +2090,46 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-sys 0.34.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peg"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af728fe826811af3b38c37e93de6d104485953ea373d656eebae53d6987fcd2c"
|
||||||
|
dependencies = [
|
||||||
|
"peg-macros",
|
||||||
|
"peg-runtime",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peg-macros"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4536be147b770b824895cbad934fccce8e49f14b4c4946eaa46a6e4a12fcdc16"
|
||||||
|
dependencies = [
|
||||||
|
"peg-runtime",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peg-runtime"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9b0efd3ba03c3a409d44d60425f279ec442bcf0b9e63ff4e410da31c8b0f69f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
@ -2280,6 +2355,12 @@ version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
|
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "radix_trie"
|
name = "radix_trie"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -2451,6 +2532,17 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roc_alias_analysis"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"morphic_lib",
|
||||||
|
"roc_collections",
|
||||||
|
"roc_debug_flags",
|
||||||
|
"roc_module",
|
||||||
|
"roc_mono",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_ast"
|
name = "roc_ast"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2468,11 +2560,13 @@ dependencies = [
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_problem",
|
"roc_problem",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
|
"roc_reporting",
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"roc_unify",
|
"roc_unify",
|
||||||
"snafu",
|
"snafu",
|
||||||
"ven_graph",
|
"ven_graph",
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2486,6 +2580,7 @@ dependencies = [
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_constrain",
|
"roc_constrain",
|
||||||
|
"roc_error_macros",
|
||||||
"roc_gen_dev",
|
"roc_gen_dev",
|
||||||
"roc_gen_llvm",
|
"roc_gen_llvm",
|
||||||
"roc_gen_wasm",
|
"roc_gen_wasm",
|
||||||
|
@ -2504,6 +2599,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
"wasi_libc_sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2511,6 +2607,7 @@ name = "roc_builtins"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dunce",
|
"dunce",
|
||||||
|
"lazy_static",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
|
@ -2522,16 +2619,17 @@ dependencies = [
|
||||||
name = "roc_can"
|
name = "roc_can"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitvec 1.0.0",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"roc_builtins",
|
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_error_macros",
|
"roc_error_macros",
|
||||||
|
"roc_exhaustive",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_problem",
|
"roc_problem",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"ven_graph",
|
"static_assertions 1.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2539,7 +2637,7 @@ name = "roc_cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"clap 3.0.0-beta.5",
|
"clap 3.1.17",
|
||||||
"const_format",
|
"const_format",
|
||||||
"mimalloc",
|
"mimalloc",
|
||||||
"roc_build",
|
"roc_build",
|
||||||
|
@ -2592,6 +2690,7 @@ dependencies = [
|
||||||
name = "roc_constrain"
|
name = "roc_constrain"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arrayvec 0.7.2",
|
||||||
"roc_builtins",
|
"roc_builtins",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
@ -2602,21 +2701,28 @@ dependencies = [
|
||||||
"roc_types",
|
"roc_types",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roc_debug_flags"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_docs"
|
name = "roc_docs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
|
"peg",
|
||||||
"pulldown-cmark",
|
"pulldown-cmark",
|
||||||
"roc_ast",
|
"roc_ast",
|
||||||
"roc_builtins",
|
"roc_builtins",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_code_markup",
|
"roc_code_markup",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_highlight",
|
||||||
"roc_load",
|
"roc_load",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
|
"roc_reporting",
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"snafu",
|
"snafu",
|
||||||
|
@ -2671,6 +2777,16 @@ dependencies = [
|
||||||
name = "roc_error_macros"
|
name = "roc_error_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roc_exhaustive"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"roc_collections",
|
||||||
|
"roc_module",
|
||||||
|
"roc_region",
|
||||||
|
"roc_std",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_fmt"
|
name = "roc_fmt"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2696,7 +2812,6 @@ dependencies = [
|
||||||
"roc_mono",
|
"roc_mono",
|
||||||
"roc_problem",
|
"roc_problem",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
"roc_reporting",
|
|
||||||
"roc_solve",
|
"roc_solve",
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
|
@ -2711,8 +2826,10 @@ dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"inkwell 0.1.0",
|
"inkwell 0.1.0",
|
||||||
"morphic_lib",
|
"morphic_lib",
|
||||||
|
"roc_alias_analysis",
|
||||||
"roc_builtins",
|
"roc_builtins",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_debug_flags",
|
||||||
"roc_error_macros",
|
"roc_error_macros",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_mono",
|
"roc_mono",
|
||||||
|
@ -2735,6 +2852,14 @@ dependencies = [
|
||||||
"roc_target",
|
"roc_target",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roc_highlight"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"peg",
|
||||||
|
"roc_code_markup",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_ident"
|
name = "roc_ident"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2745,9 +2870,9 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"clap 3.0.0-beta.5",
|
"clap 3.1.17",
|
||||||
"iced-x86",
|
"iced-x86",
|
||||||
"memmap2 0.5.0",
|
"memmap2 0.5.3",
|
||||||
"object 0.26.2",
|
"object 0.26.2",
|
||||||
"roc_build",
|
"roc_build",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
@ -2760,16 +2885,31 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_load"
|
name = "roc_load"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"roc_builtins",
|
||||||
|
"roc_collections",
|
||||||
|
"roc_constrain",
|
||||||
|
"roc_load_internal",
|
||||||
|
"roc_module",
|
||||||
|
"roc_reporting",
|
||||||
|
"roc_target",
|
||||||
|
"roc_types",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roc_load_internal"
|
||||||
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
"morphic_lib",
|
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"parking_lot",
|
"parking_lot 0.12.0",
|
||||||
"roc_builtins",
|
"roc_builtins",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_constrain",
|
"roc_constrain",
|
||||||
|
"roc_debug_flags",
|
||||||
"roc_error_macros",
|
"roc_error_macros",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_mono",
|
"roc_mono",
|
||||||
|
@ -2795,7 +2935,7 @@ dependencies = [
|
||||||
"roc_ident",
|
"roc_ident",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
"snafu",
|
"snafu",
|
||||||
"static_assertions",
|
"static_assertions 1.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2804,11 +2944,12 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"hashbrown 0.11.2",
|
"hashbrown 0.11.2",
|
||||||
"morphic_lib",
|
|
||||||
"roc_builtins",
|
"roc_builtins",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_debug_flags",
|
||||||
"roc_error_macros",
|
"roc_error_macros",
|
||||||
|
"roc_exhaustive",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_problem",
|
"roc_problem",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
|
@ -2817,7 +2958,7 @@ dependencies = [
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"roc_unify",
|
"roc_unify",
|
||||||
"static_assertions",
|
"static_assertions 1.1.0",
|
||||||
"ven_graph",
|
"ven_graph",
|
||||||
"ven_pretty",
|
"ven_pretty",
|
||||||
]
|
]
|
||||||
|
@ -2841,13 +2982,14 @@ dependencies = [
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
|
"roc_types",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_region"
|
name = "roc_region"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"static_assertions",
|
"static_assertions 1.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2866,6 +3008,8 @@ dependencies = [
|
||||||
"roc_mono",
|
"roc_mono",
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_repl_eval",
|
"roc_repl_eval",
|
||||||
|
"roc_reporting",
|
||||||
|
"roc_std",
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
|
@ -2888,6 +3032,7 @@ dependencies = [
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
"roc_reporting",
|
"roc_reporting",
|
||||||
|
"roc_std",
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
]
|
]
|
||||||
|
@ -2900,8 +3045,8 @@ dependencies = [
|
||||||
"distance",
|
"distance",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_exhaustive",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_mono",
|
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_problem",
|
"roc_problem",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
|
@ -2918,6 +3063,9 @@ dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_debug_flags",
|
||||||
|
"roc_error_macros",
|
||||||
|
"roc_exhaustive",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
|
@ -2927,6 +3075,9 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_std"
|
name = "roc_std"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"static_assertions 0.1.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roc_target"
|
name = "roc_target"
|
||||||
|
@ -2941,10 +3092,11 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_debug_flags",
|
||||||
"roc_error_macros",
|
"roc_error_macros",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
"static_assertions",
|
"static_assertions 1.1.0",
|
||||||
"ven_ena",
|
"ven_ena",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2954,6 +3106,8 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_debug_flags",
|
||||||
|
"roc_error_macros",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
]
|
]
|
||||||
|
@ -2999,7 +3153,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustyline"
|
name = "rustyline"
|
||||||
version = "9.1.1"
|
version = "9.1.1"
|
||||||
source = "git+https://github.com/rtfeldman/rustyline?tag=v9.1.1#7053ae0fe0ee710d38ed5845dd979113382994dc"
|
source = "git+https://github.com/rtfeldman/rustyline?rev=e74333c#e74333c0d618896b88175bf06645108f996fe6d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
|
@ -3022,7 +3176,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustyline-derive"
|
name = "rustyline-derive"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/rtfeldman/rustyline?tag=v9.1.1#7053ae0fe0ee710d38ed5845dd979113382994dc"
|
source = "git+https://github.com/rtfeldman/rustyline?rev=e74333c#e74333c0d618896b88175bf06645108f996fe6d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -3285,6 +3439,12 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f406d6ee68db6796e11ffd7b4d171864c58b7451e79ef9460ea33c287a1f89a7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -3337,9 +3497,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.12.2"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff"
|
checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
|
@ -3375,9 +3535,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.14.2"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
|
@ -3447,7 +3607,7 @@ checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"rand",
|
"rand",
|
||||||
"static_assertions",
|
"static_assertions 1.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3567,6 +3727,10 @@ version = "0.10.2+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi_libc_sys"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.79"
|
version = "0.2.79"
|
||||||
|
@ -3798,7 +3962,7 @@ dependencies = [
|
||||||
"arrayvec 0.7.2",
|
"arrayvec 0.7.2",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"parking_lot",
|
"parking_lot 0.11.2",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
@ -3822,7 +3986,7 @@ dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"log",
|
"log",
|
||||||
"naga",
|
"naga",
|
||||||
"parking_lot",
|
"parking_lot 0.11.2",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
@ -3857,7 +4021,7 @@ dependencies = [
|
||||||
"metal",
|
"metal",
|
||||||
"naga",
|
"naga",
|
||||||
"objc",
|
"objc",
|
||||||
"parking_lot",
|
"parking_lot 0.11.2",
|
||||||
"profiling",
|
"profiling",
|
||||||
"range-alloc",
|
"range-alloc",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
|
@ -3927,11 +4091,24 @@ version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6"
|
checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc 0.28.0",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu 0.28.0",
|
||||||
"windows_i686_msvc",
|
"windows_i686_msvc 0.28.0",
|
||||||
"windows_x86_64_gnu",
|
"windows_x86_64_gnu 0.28.0",
|
||||||
"windows_x86_64_msvc",
|
"windows_x86_64_msvc 0.28.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_msvc 0.34.0",
|
||||||
|
"windows_i686_gnu 0.34.0",
|
||||||
|
"windows_i686_msvc 0.34.0",
|
||||||
|
"windows_x86_64_gnu 0.34.0",
|
||||||
|
"windows_x86_64_msvc 0.34.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3940,30 +4117,60 @@ version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2"
|
checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.28.0"
|
version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a"
|
checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.28.0"
|
version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64"
|
checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.28.0"
|
version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954"
|
checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.28.0"
|
version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
|
checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winit"
|
name = "winit"
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
|
@ -3986,7 +4193,7 @@ dependencies = [
|
||||||
"ndk-glue",
|
"ndk-glue",
|
||||||
"ndk-sys",
|
"ndk-sys",
|
||||||
"objc",
|
"objc",
|
||||||
"parking_lot",
|
"parking_lot 0.11.2",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
|
@ -4014,6 +4221,15 @@ dependencies = [
|
||||||
"tap",
|
"tap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e"
|
||||||
|
dependencies = [
|
||||||
|
"tap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x11-clipboard"
|
name = "x11-clipboard"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
|
|
@ -19,11 +19,6 @@ pub struct CodeGenTiming {
|
||||||
pub emit_o_file: Duration,
|
pub emit_o_file: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: If modules besides this one start needing to know which version of
|
|
||||||
// llvm we're using, consider moving me somewhere else.
|
|
||||||
#[cfg(feature = "llvm")]
|
|
||||||
const LLVM_VERSION: &str = "12";
|
|
||||||
|
|
||||||
pub fn report_problems_monomorphized(loaded: &mut MonomorphizedModule) -> Problems {
|
pub fn report_problems_monomorphized(loaded: &mut MonomorphizedModule) -> Problems {
|
||||||
report_problems_help(
|
report_problems_help(
|
||||||
loaded.total_problems(),
|
loaded.total_problems(),
|
||||||
|
@ -357,9 +352,11 @@ pub fn gen_from_mono_module_llvm(
|
||||||
|
|
||||||
use target_lexicon::Architecture;
|
use target_lexicon::Architecture;
|
||||||
match target.architecture {
|
match target.architecture {
|
||||||
Architecture::X86_64 | Architecture::X86_32(_) | Architecture::Aarch64(_) => {
|
Architecture::X86_64
|
||||||
// assemble the .ll into a .bc
|
| Architecture::X86_32(_)
|
||||||
let _ = Command::new("llvm-as")
|
| Architecture::Aarch64(_)
|
||||||
|
| Architecture::Wasm32 => {
|
||||||
|
let ll_to_bc = Command::new("llvm-as")
|
||||||
.args(&[
|
.args(&[
|
||||||
app_ll_dbg_file.to_str().unwrap(),
|
app_ll_dbg_file.to_str().unwrap(),
|
||||||
"-o",
|
"-o",
|
||||||
|
@ -368,6 +365,8 @@ pub fn gen_from_mono_module_llvm(
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(ll_to_bc.stderr.is_empty(), "{:#?}", ll_to_bc);
|
||||||
|
|
||||||
let llc_args = &[
|
let llc_args = &[
|
||||||
"-relocation-model=pic",
|
"-relocation-model=pic",
|
||||||
"-filetype=obj",
|
"-filetype=obj",
|
||||||
|
@ -381,26 +380,9 @@ pub fn gen_from_mono_module_llvm(
|
||||||
//
|
//
|
||||||
// different systems name this executable differently, so we shotgun for
|
// different systems name this executable differently, so we shotgun for
|
||||||
// the most common ones and then give up.
|
// the most common ones and then give up.
|
||||||
let _: Result<std::process::Output, std::io::Error> =
|
let bc_to_object = Command::new("llc").args(llc_args).output().unwrap();
|
||||||
Command::new(format!("llc-{}", LLVM_VERSION))
|
|
||||||
.args(llc_args)
|
|
||||||
.output()
|
|
||||||
.or_else(|_| Command::new("llc").args(llc_args).output())
|
|
||||||
.map_err(|_| {
|
|
||||||
panic!("We couldn't find llc-{} on your machine!", LLVM_VERSION);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Architecture::Wasm32 => {
|
assert!(bc_to_object.stderr.is_empty(), "{:#?}", bc_to_object);
|
||||||
// assemble the .ll into a .bc
|
|
||||||
let _ = Command::new("llvm-as")
|
|
||||||
.args(&[
|
|
||||||
app_ll_dbg_file.to_str().unwrap(),
|
|
||||||
"-o",
|
|
||||||
app_o_file.to_str().unwrap(),
|
|
||||||
])
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ const CrossTarget = std.zig.CrossTarget;
|
||||||
const Arch = std.Target.Cpu.Arch;
|
const Arch = std.Target.Cpu.Arch;
|
||||||
|
|
||||||
pub fn build(b: *Builder) void {
|
pub fn build(b: *Builder) void {
|
||||||
// b.setPreferredReleaseMode(builtin.Mode.Debug
|
// b.setPreferredReleaseMode(.Debug);
|
||||||
b.setPreferredReleaseMode(.ReleaseFast);
|
b.setPreferredReleaseMode(.ReleaseFast);
|
||||||
const mode = b.standardReleaseOptions();
|
const mode = b.standardReleaseOptions();
|
||||||
|
|
||||||
|
@ -57,8 +57,9 @@ fn generateLlvmIrFile(
|
||||||
const obj = b.addObject(object_name, main_path);
|
const obj = b.addObject(object_name, main_path);
|
||||||
obj.setBuildMode(mode);
|
obj.setBuildMode(mode);
|
||||||
obj.strip = true;
|
obj.strip = true;
|
||||||
obj.emit_llvm_ir = true;
|
obj.emit_llvm_ir = .emit;
|
||||||
obj.emit_bin = false;
|
obj.emit_llvm_bc = .emit;
|
||||||
|
obj.emit_bin = .no_emit;
|
||||||
obj.target = target;
|
obj.target = target;
|
||||||
|
|
||||||
const ir = b.step(step_name, "Build LLVM ir");
|
const ir = b.step(step_name, "Build LLVM ir");
|
||||||
|
|
|
@ -4,6 +4,8 @@ set -euxo pipefail
|
||||||
|
|
||||||
# Test failures will always point at the _start function
|
# Test failures will always point at the _start function
|
||||||
# Make sure to look at the rest of the stack trace!
|
# Make sure to look at the rest of the stack trace!
|
||||||
warning_about_non_native_binary=$(zig test -target wasm32-wasi-musl -O ReleaseFast src/main.zig 2>&1)
|
|
||||||
wasm_test_binary=$(echo $warning_about_non_native_binary | cut -d' ' -f 3)
|
# Zig will try to run the test binary it produced, but it is a wasm object and hence your OS won't
|
||||||
wasmer $wasm_test_binary dummyArgForZigTestBinary
|
# know how to run it. In the error message, it prints the binary it tried to run. We use some fun
|
||||||
|
# unix tools to get that path, then feed it to wasmer
|
||||||
|
zig test -target wasm32-wasi-musl -O ReleaseFast src/main.zig --test-cmd wasmer --test-cmd-bin
|
||||||
|
|
|
@ -139,7 +139,7 @@ pub const RocDec = extern struct {
|
||||||
|
|
||||||
// Format the backing i128 into an array of digit (ascii) characters (u8s)
|
// Format the backing i128 into an array of digit (ascii) characters (u8s)
|
||||||
var digit_bytes_storage: [max_digits + 1]u8 = undefined;
|
var digit_bytes_storage: [max_digits + 1]u8 = undefined;
|
||||||
var num_digits = std.fmt.formatIntBuf(digit_bytes_storage[0..], num, 10, false, .{});
|
var num_digits = std.fmt.formatIntBuf(digit_bytes_storage[0..], num, 10, .lower, .{});
|
||||||
var digit_bytes: [*]u8 = digit_bytes_storage[0..];
|
var digit_bytes: [*]u8 = digit_bytes_storage[0..];
|
||||||
|
|
||||||
// space where we assemble all the characters that make up the final string
|
// space where we assemble all the characters that make up the final string
|
||||||
|
|
|
@ -27,18 +27,8 @@ pub fn expectFailed(
|
||||||
|
|
||||||
// Lock the failures mutex before reading from any of the failures globals,
|
// Lock the failures mutex before reading from any of the failures globals,
|
||||||
// and then release the lock once we're done modifying things.
|
// and then release the lock once we're done modifying things.
|
||||||
|
failures_mutex.lock();
|
||||||
// TODO FOR ZIG 0.9: this API changed in https://github.com/ziglang/zig/commit/008b0ec5e58fc7e31f3b989868a7d1ea4df3f41d
|
defer failures_mutex.unlock();
|
||||||
// to this: https://github.com/ziglang/zig/blob/c710d5eefe3f83226f1651947239730e77af43cb/lib/std/Thread/Mutex.zig
|
|
||||||
//
|
|
||||||
// ...so just use these two lines of code instead of the non-commented-out ones to make this work in Zig 0.9:
|
|
||||||
//
|
|
||||||
// failures_mutex.lock();
|
|
||||||
// defer failures_mutex.release();
|
|
||||||
//
|
|
||||||
// 👆 👆 👆 IF UPGRADING TO ZIG 0.9, LOOK HERE! 👆 👆 👆
|
|
||||||
const held = failures_mutex.acquire();
|
|
||||||
defer held.release();
|
|
||||||
|
|
||||||
// If we don't have enough capacity to add a failure, allocate a new failures pointer.
|
// If we don't have enough capacity to add a failure, allocate a new failures pointer.
|
||||||
if (failure_length >= failure_capacity) {
|
if (failure_length >= failure_capacity) {
|
||||||
|
@ -87,17 +77,8 @@ pub fn expectFailedC(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getExpectFailures() []Failure {
|
pub fn getExpectFailures() []Failure {
|
||||||
// TODO FOR ZIG 0.9: this API changed in https://github.com/ziglang/zig/commit/008b0ec5e58fc7e31f3b989868a7d1ea4df3f41d
|
failures_mutex.lock();
|
||||||
// to this: https://github.com/ziglang/zig/blob/c710d5eefe3f83226f1651947239730e77af43cb/lib/std/Thread/Mutex.zig
|
defer failures_mutex.unlock();
|
||||||
//
|
|
||||||
// ...so just use these two lines of code instead of the non-commented-out ones to make this work in Zig 0.9:
|
|
||||||
//
|
|
||||||
// failures_mutex.lock();
|
|
||||||
// defer failures_mutex.release();
|
|
||||||
//
|
|
||||||
// 👆 👆 👆 IF UPGRADING TO ZIG 0.9, LOOK HERE! 👆 👆 👆
|
|
||||||
const held = failures_mutex.acquire();
|
|
||||||
defer held.release();
|
|
||||||
|
|
||||||
if (failure_length > 0) {
|
if (failure_length > 0) {
|
||||||
// defensively clone failures, in case someone modifies the originals after the mutex has been released.
|
// defensively clone failures, in case someone modifies the originals after the mutex has been released.
|
||||||
|
@ -116,23 +97,14 @@ pub fn getExpectFailures() []Failure {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getExpectFailuresC() callconv(.C) CSlice {
|
pub fn getExpectFailuresC() callconv(.C) CSlice {
|
||||||
var bytes = @ptrCast(*c_void, failures);
|
var bytes = @ptrCast(*anyopaque, failures);
|
||||||
|
|
||||||
return .{ .pointer = bytes, .len = failure_length };
|
return .{ .pointer = bytes, .len = failure_length };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinitFailures() void {
|
pub fn deinitFailures() void {
|
||||||
// TODO FOR ZIG 0.9: this API changed in https://github.com/ziglang/zig/commit/008b0ec5e58fc7e31f3b989868a7d1ea4df3f41d
|
failures_mutex.lock();
|
||||||
// to this: https://github.com/ziglang/zig/blob/c710d5eefe3f83226f1651947239730e77af43cb/lib/std/Thread/Mutex.zig
|
defer failures_mutex.unlock();
|
||||||
//
|
|
||||||
// ...so just use these two lines of code instead of the non-commented-out ones to make this work in Zig 0.9:
|
|
||||||
//
|
|
||||||
// failures_mutex.lock();
|
|
||||||
// defer failures_mutex.release();
|
|
||||||
//
|
|
||||||
// 👆 👆 👆 IF UPGRADING TO ZIG 0.9, LOOK HERE! 👆 👆 👆
|
|
||||||
const held = failures_mutex.acquire();
|
|
||||||
defer held.release();
|
|
||||||
|
|
||||||
utils.dealloc(@ptrCast([*]u8, failures), @alignOf(Failure));
|
utils.dealloc(@ptrCast([*]u8, failures), @alignOf(Failure));
|
||||||
failure_length = 0;
|
failure_length = 0;
|
||||||
|
|
|
@ -1326,7 +1326,6 @@ pub fn listFindUnsafe(
|
||||||
data: Opaque,
|
data: Opaque,
|
||||||
inc_n_data: IncN,
|
inc_n_data: IncN,
|
||||||
data_is_owned: bool,
|
data_is_owned: bool,
|
||||||
alignment: u32,
|
|
||||||
element_width: usize,
|
element_width: usize,
|
||||||
inc: Inc,
|
inc: Inc,
|
||||||
dec: Dec,
|
dec: Dec,
|
||||||
|
|
|
@ -177,7 +177,6 @@ comptime {
|
||||||
// setjmp/longjmp. LLVM is unable to generate code for longjmp on AArch64 (https://github.com/rtfeldman/roc/issues/2965),
|
// setjmp/longjmp. LLVM is unable to generate code for longjmp on AArch64 (https://github.com/rtfeldman/roc/issues/2965),
|
||||||
// so instead we ask Zig to please provide implementations for us, which is does
|
// so instead we ask Zig to please provide implementations for us, which is does
|
||||||
// (seemingly via musl).
|
// (seemingly via musl).
|
||||||
pub usingnamespace @import("std").c.builtins;
|
|
||||||
pub extern fn setjmp([*c]c_int) c_int;
|
pub extern fn setjmp([*c]c_int) c_int;
|
||||||
pub extern fn longjmp([*c]c_int, c_int) noreturn;
|
pub extern fn longjmp([*c]c_int, c_int) noreturn;
|
||||||
pub extern fn _setjmp([*c]c_int) c_int;
|
pub extern fn _setjmp([*c]c_int) c_int;
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub fn exportParseInt(comptime T: type, comptime name: []const u8) void {
|
||||||
const radix = 0;
|
const radix = 0;
|
||||||
if (std.fmt.parseInt(T, buf.asSlice(), radix)) |success| {
|
if (std.fmt.parseInt(T, buf.asSlice(), radix)) |success| {
|
||||||
return .{ .errorcode = 0, .value = success };
|
return .{ .errorcode = 0, .value = success };
|
||||||
} else |err| {
|
} else |_| {
|
||||||
return .{ .errorcode = 1, .value = 0 };
|
return .{ .errorcode = 1, .value = 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ pub fn exportParseFloat(comptime T: type, comptime name: []const u8) void {
|
||||||
fn func(buf: RocStr) callconv(.C) NumParseResult(T) {
|
fn func(buf: RocStr) callconv(.C) NumParseResult(T) {
|
||||||
if (std.fmt.parseFloat(T, buf.asSlice())) |success| {
|
if (std.fmt.parseFloat(T, buf.asSlice())) |success| {
|
||||||
return .{ .errorcode = 0, .value = success };
|
return .{ .errorcode = 0, .value = success };
|
||||||
} else |err| {
|
} else |_| {
|
||||||
return .{ .errorcode = 1, .value = 0 };
|
return .{ .errorcode = 1, .value = 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2041,7 +2041,7 @@ test "ReverseUtf8View: empty" {
|
||||||
const original_bytes = "";
|
const original_bytes = "";
|
||||||
|
|
||||||
var iter = ReverseUtf8View.initUnchecked(original_bytes).iterator();
|
var iter = ReverseUtf8View.initUnchecked(original_bytes).iterator();
|
||||||
while (iter.nextCodepoint()) |codepoint| {
|
while (iter.nextCodepoint()) |_| {
|
||||||
try expect(false);
|
try expect(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,17 +7,17 @@ pub fn WithOverflow(comptime T: type) type {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If allocation fails, this must cxa_throw - it must not return a null pointer!
|
// If allocation fails, this must cxa_throw - it must not return a null pointer!
|
||||||
extern fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void;
|
extern fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque;
|
||||||
|
|
||||||
// This should never be passed a null pointer.
|
// This should never be passed a null pointer.
|
||||||
// If allocation fails, this must cxa_throw - it must not return a null pointer!
|
// If allocation fails, this must cxa_throw - it must not return a null pointer!
|
||||||
extern fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void;
|
extern fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque;
|
||||||
|
|
||||||
// This should never be passed a null pointer.
|
// This should never be passed a null pointer.
|
||||||
extern fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void;
|
extern fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void;
|
||||||
|
|
||||||
// Signals to the host that the program has panicked
|
// Signals to the host that the program has panicked
|
||||||
extern fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void;
|
extern fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void;
|
||||||
|
|
||||||
// should work just like libc memcpy (we can't assume libc is present)
|
// should work just like libc memcpy (we can't assume libc is present)
|
||||||
extern fn roc_memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn roc_memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
|
@ -34,31 +34,31 @@ comptime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_roc_alloc(size: usize, _: u32) callconv(.C) ?*c_void {
|
fn testing_roc_alloc(size: usize, _: u32) callconv(.C) ?*anyopaque {
|
||||||
return @ptrCast(?*c_void, std.testing.allocator.alloc(u8, size) catch unreachable);
|
return @ptrCast(?*anyopaque, std.testing.allocator.alloc(u8, size) catch unreachable);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, _: u32) callconv(.C) ?*c_void {
|
fn testing_roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, _: u32) callconv(.C) ?*anyopaque {
|
||||||
const ptr = @ptrCast([*]u8, @alignCast(2 * @alignOf(usize), c_ptr));
|
const ptr = @ptrCast([*]u8, @alignCast(2 * @alignOf(usize), c_ptr));
|
||||||
const slice = ptr[0..old_size];
|
const slice = ptr[0..old_size];
|
||||||
|
|
||||||
return @ptrCast(?*c_void, std.testing.allocator.realloc(slice, new_size) catch unreachable);
|
return @ptrCast(?*anyopaque, std.testing.allocator.realloc(slice, new_size) catch unreachable);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_roc_dealloc(c_ptr: *c_void, _: u32) callconv(.C) void {
|
fn testing_roc_dealloc(c_ptr: *anyopaque, _: u32) callconv(.C) void {
|
||||||
const ptr = @ptrCast([*]u8, @alignCast(2 * @alignOf(usize), c_ptr));
|
const ptr = @ptrCast([*]u8, @alignCast(2 * @alignOf(usize), c_ptr));
|
||||||
|
|
||||||
std.testing.allocator.destroy(ptr);
|
std.testing.allocator.destroy(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
fn testing_roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
_ = c_ptr;
|
_ = c_ptr;
|
||||||
_ = tag_id;
|
_ = tag_id;
|
||||||
|
|
||||||
@panic("Roc panicked");
|
@panic("Roc panicked");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_roc_memcpy(dest: *c_void, src: *c_void, bytes: usize) callconv(.C) ?*c_void {
|
fn testing_roc_memcpy(dest: *anyopaque, src: *anyopaque, bytes: usize) callconv(.C) ?*anyopaque {
|
||||||
const zig_dest = @ptrCast([*]u8, dest);
|
const zig_dest = @ptrCast([*]u8, dest);
|
||||||
const zig_src = @ptrCast([*]u8, src);
|
const zig_src = @ptrCast([*]u8, src);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ pub fn dealloc(c_ptr: [*]u8, alignment: u32) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// must export this explicitly because right now it is not used from zig code
|
// must export this explicitly because right now it is not used from zig code
|
||||||
pub fn panic(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
pub fn panic(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
return @call(.{ .modifier = always_inline }, roc_panic, .{ c_ptr, alignment });
|
return @call(.{ .modifier = always_inline }, roc_panic, .{ c_ptr, alignment });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ pub fn memcpy(dst: [*]u8, src: [*]u8, size: usize) void {
|
||||||
|
|
||||||
// indirection because otherwise zig creates an alias to the panic function which our LLVM code
|
// indirection because otherwise zig creates an alias to the panic function which our LLVM code
|
||||||
// does not know how to deal with
|
// does not know how to deal with
|
||||||
pub fn test_panic(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
pub fn test_panic(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
_ = c_ptr;
|
_ = c_ptr;
|
||||||
_ = alignment;
|
_ = alignment;
|
||||||
// const cstr = @ptrCast([*:0]u8, c_ptr);
|
// const cstr = @ptrCast([*:0]u8, c_ptr);
|
||||||
|
@ -240,7 +240,7 @@ pub fn allocateWithRefcount(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CSlice = extern struct {
|
pub const CSlice = extern struct {
|
||||||
pointer: *c_void,
|
pointer: *anyopaque,
|
||||||
len: usize,
|
len: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,30 +36,15 @@ fn main() {
|
||||||
|
|
||||||
// LLVM .bc FILES
|
// LLVM .bc FILES
|
||||||
|
|
||||||
generate_bc_file(&bitcode_path, &build_script_dir_path, "ir", "builtins-host");
|
generate_bc_file(&bitcode_path, "ir", "builtins-host");
|
||||||
|
|
||||||
if !DEBUG {
|
if !DEBUG {
|
||||||
generate_bc_file(
|
generate_bc_file(&bitcode_path, "ir-wasm32", "builtins-wasm32");
|
||||||
&bitcode_path,
|
|
||||||
&build_script_dir_path,
|
|
||||||
"ir-wasm32",
|
|
||||||
"builtins-wasm32",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_bc_file(
|
generate_bc_file(&bitcode_path, "ir-i386", "builtins-i386");
|
||||||
&bitcode_path,
|
|
||||||
&build_script_dir_path,
|
|
||||||
"ir-i386",
|
|
||||||
"builtins-i386",
|
|
||||||
);
|
|
||||||
|
|
||||||
generate_bc_file(
|
generate_bc_file(&bitcode_path, "ir-x86_64", "builtins-x86_64");
|
||||||
&bitcode_path,
|
|
||||||
&build_script_dir_path,
|
|
||||||
"ir-x86_64",
|
|
||||||
"builtins-x86_64",
|
|
||||||
);
|
|
||||||
|
|
||||||
// OBJECT FILES
|
// OBJECT FILES
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -131,35 +116,23 @@ fn generate_object_file(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_bc_file(
|
fn generate_bc_file(bitcode_path: &Path, zig_object: &str, file_name: &str) {
|
||||||
bitcode_path: &Path,
|
|
||||||
build_script_dir_path: &Path,
|
|
||||||
zig_object: &str,
|
|
||||||
file_name: &str,
|
|
||||||
) {
|
|
||||||
let mut ll_path = bitcode_path.join(file_name);
|
let mut ll_path = bitcode_path.join(file_name);
|
||||||
ll_path.set_extension("ll");
|
ll_path.set_extension("ll");
|
||||||
let dest_ir_host = ll_path.to_str().expect("Invalid dest ir path");
|
let dest_ir_host = ll_path.to_str().expect("Invalid dest ir path");
|
||||||
|
|
||||||
println!("Compiling host ir to: {}", dest_ir_host);
|
println!("Compiling host ir to: {}", dest_ir_host);
|
||||||
|
|
||||||
|
let mut bc_path = bitcode_path.join(file_name);
|
||||||
|
bc_path.set_extension("bc");
|
||||||
|
let dest_bc_64bit = bc_path.to_str().expect("Invalid dest bc path");
|
||||||
|
println!("Compiling 64-bit bitcode to: {}", dest_bc_64bit);
|
||||||
|
|
||||||
run_command(
|
run_command(
|
||||||
&bitcode_path,
|
&bitcode_path,
|
||||||
&zig_executable(),
|
&zig_executable(),
|
||||||
&["build", zig_object, "-Drelease=true"],
|
&["build", zig_object, "-Drelease=true"],
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut bc_path = bitcode_path.join(file_name);
|
|
||||||
bc_path.set_extension("bc");
|
|
||||||
let dest_bc_64bit = bc_path.to_str().expect("Invalid dest bc path");
|
|
||||||
|
|
||||||
println!("Compiling 64-bit bitcode to: {}", dest_bc_64bit);
|
|
||||||
|
|
||||||
run_command(
|
|
||||||
&build_script_dir_path,
|
|
||||||
"llvm-as",
|
|
||||||
&[dest_ir_host, "-o", dest_bc_64bit],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command<S, I, P: AsRef<Path>>(path: P, command_str: &str, args: I)
|
fn run_command<S, I, P: AsRef<Path>>(path: P, command_str: &str, args: I)
|
||||||
|
|
|
@ -68,6 +68,8 @@ use roc_mono::layout::{Builtin, LambdaSet, Layout, LayoutIds, TagIdIntType, Unio
|
||||||
use roc_target::{PtrWidth, TargetInfo};
|
use roc_target::{PtrWidth, TargetInfo};
|
||||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||||
|
|
||||||
|
use super::convert::zig_with_overflow_roc_dec;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn print_fn_verification_output() -> bool {
|
fn print_fn_verification_output() -> bool {
|
||||||
dbg_do!(ROC_PRINT_LLVM_FN_VERIFICATION, {
|
dbg_do!(ROC_PRINT_LLVM_FN_VERIFICATION, {
|
||||||
|
@ -5246,6 +5248,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
Layout::Builtin(Builtin::Bool),
|
Layout::Builtin(Builtin::Bool),
|
||||||
);
|
);
|
||||||
|
|
||||||
list_find_unsafe(env, layout_ids, roc_function_call, list, element_layout)
|
list_find_unsafe(env, layout_ids, roc_function_call, list, element_layout)
|
||||||
}
|
}
|
||||||
_ => unreachable!("invalid list layout"),
|
_ => unreachable!("invalid list layout"),
|
||||||
|
@ -5368,7 +5371,17 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let string = load_symbol(scope, &args[0]);
|
let string = load_symbol(scope, &args[0]);
|
||||||
|
|
||||||
call_bitcode_fn(env, &[string], intrinsic)
|
let result = call_bitcode_fn(env, &[string], intrinsic);
|
||||||
|
|
||||||
|
// zig passes the result as a packed integer sometimes, instead of a struct. So we cast
|
||||||
|
let expected_type = basic_type_from_layout(env, layout);
|
||||||
|
let actual_type = result.get_type();
|
||||||
|
|
||||||
|
if expected_type != actual_type {
|
||||||
|
complex_bitcast_check_size(env, result, expected_type, "str_to_num_cast")
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
StrFromInt => {
|
StrFromInt => {
|
||||||
// Str.fromInt : Int -> Str
|
// Str.fromInt : Int -> Str
|
||||||
|
@ -7054,6 +7067,76 @@ fn build_float_binop<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dec_binop_with_overflow<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
fn_name: &str,
|
||||||
|
lhs: BasicValueEnum<'ctx>,
|
||||||
|
rhs: BasicValueEnum<'ctx>,
|
||||||
|
) -> StructValue<'ctx> {
|
||||||
|
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.build_alloca(return_type, "return_alloca");
|
||||||
|
|
||||||
|
let int_64 = env.context.i128_type().const_int(64, false);
|
||||||
|
let int_64_type = env.context.i64_type();
|
||||||
|
|
||||||
|
let lhs1 = env
|
||||||
|
.builder
|
||||||
|
.build_right_shift(lhs, int_64, false, "lhs_left_bits");
|
||||||
|
let rhs1 = env
|
||||||
|
.builder
|
||||||
|
.build_right_shift(rhs, int_64, false, "rhs_left_bits");
|
||||||
|
|
||||||
|
call_void_bitcode_fn(
|
||||||
|
env,
|
||||||
|
&[
|
||||||
|
return_alloca.into(),
|
||||||
|
env.builder.build_int_cast(lhs, int_64_type, "").into(),
|
||||||
|
env.builder.build_int_cast(lhs1, int_64_type, "").into(),
|
||||||
|
env.builder.build_int_cast(rhs, int_64_type, "").into(),
|
||||||
|
env.builder.build_int_cast(rhs1, int_64_type, "").into(),
|
||||||
|
],
|
||||||
|
fn_name,
|
||||||
|
);
|
||||||
|
|
||||||
|
env.builder
|
||||||
|
.build_load(return_alloca, "load_dec")
|
||||||
|
.into_struct_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dec_binop_with_unchecked<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
fn_name: &str,
|
||||||
|
lhs: BasicValueEnum<'ctx>,
|
||||||
|
rhs: BasicValueEnum<'ctx>,
|
||||||
|
) -> BasicValueEnum<'ctx> {
|
||||||
|
let lhs = lhs.into_int_value();
|
||||||
|
let rhs = rhs.into_int_value();
|
||||||
|
|
||||||
|
let int_64 = env.context.i128_type().const_int(64, false);
|
||||||
|
let int_64_type = env.context.i64_type();
|
||||||
|
|
||||||
|
let lhs1 = env
|
||||||
|
.builder
|
||||||
|
.build_right_shift(lhs, int_64, false, "lhs_left_bits");
|
||||||
|
let rhs1 = env
|
||||||
|
.builder
|
||||||
|
.build_right_shift(rhs, int_64, false, "rhs_left_bits");
|
||||||
|
|
||||||
|
call_bitcode_fn(
|
||||||
|
env,
|
||||||
|
&[
|
||||||
|
env.builder.build_int_cast(lhs, int_64_type, "").into(),
|
||||||
|
env.builder.build_int_cast(lhs1, int_64_type, "").into(),
|
||||||
|
env.builder.build_int_cast(rhs, int_64_type, "").into(),
|
||||||
|
env.builder.build_int_cast(rhs1, int_64_type, "").into(),
|
||||||
|
],
|
||||||
|
fn_name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn build_dec_binop<'a, 'ctx, 'env>(
|
fn build_dec_binop<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
parent: FunctionValue<'ctx>,
|
parent: FunctionValue<'ctx>,
|
||||||
|
@ -7093,7 +7176,7 @@ fn build_dec_binop<'a, 'ctx, 'env>(
|
||||||
rhs,
|
rhs,
|
||||||
"decimal multiplication overflowed",
|
"decimal multiplication overflowed",
|
||||||
),
|
),
|
||||||
NumDivUnchecked => call_bitcode_fn(env, &[lhs, rhs], bitcode::DEC_DIV),
|
NumDivUnchecked => dec_binop_with_unchecked(env, bitcode::DEC_DIV, lhs, rhs),
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Unrecognized int binary operation: {:?}", op);
|
unreachable!("Unrecognized int binary operation: {:?}", op);
|
||||||
}
|
}
|
||||||
|
@ -7108,15 +7191,7 @@ fn build_dec_binop_throw_on_overflow<'a, 'ctx, 'env>(
|
||||||
rhs: BasicValueEnum<'ctx>,
|
rhs: BasicValueEnum<'ctx>,
|
||||||
message: &str,
|
message: &str,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let overflow_type = crate::llvm::convert::zig_with_overflow_roc_dec(env);
|
let result = dec_binop_with_overflow(env, operation, lhs, rhs);
|
||||||
|
|
||||||
let result_ptr = env.builder.build_alloca(overflow_type, "result_ptr");
|
|
||||||
call_void_bitcode_fn(env, &[result_ptr.into(), lhs, rhs], operation);
|
|
||||||
|
|
||||||
let result = env
|
|
||||||
.builder
|
|
||||||
.build_load(result_ptr, "load_overflow")
|
|
||||||
.into_struct_value();
|
|
||||||
|
|
||||||
let value = throw_on_overflow(env, parent, result, message).into_struct_value();
|
let value = throw_on_overflow(env, parent, result, message).into_struct_value();
|
||||||
|
|
||||||
|
@ -7211,6 +7286,9 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
|| // Or if the two types are the same, they trivially fit.
|
|| // Or if the two types are the same, they trivially fit.
|
||||||
arg_width == target_int_width;
|
arg_width == target_int_width;
|
||||||
|
|
||||||
|
let return_type =
|
||||||
|
convert::basic_type_from_layout(env, return_layout).into_struct_type();
|
||||||
|
|
||||||
if arg_always_fits_in_target {
|
if arg_always_fits_in_target {
|
||||||
// This is guaranteed to succeed so we can just make it an int cast and let LLVM
|
// This is guaranteed to succeed so we can just make it an int cast and let LLVM
|
||||||
// optimize it away.
|
// optimize it away.
|
||||||
|
@ -7225,8 +7303,6 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let return_type =
|
|
||||||
convert::basic_type_from_layout(env, return_layout).into_struct_type();
|
|
||||||
let r = return_type.const_zero();
|
let r = return_type.const_zero();
|
||||||
let r = bd
|
let r = bd
|
||||||
.build_insert_value(r, target_int_val, 0, "converted_int")
|
.build_insert_value(r, target_int_val, 0, "converted_int")
|
||||||
|
@ -7249,7 +7325,14 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
&bitcode::NUM_INT_TO_INT_CHECKING_MAX_AND_MIN[target_int_width][arg_width]
|
&bitcode::NUM_INT_TO_INT_CHECKING_MAX_AND_MIN[target_int_width][arg_width]
|
||||||
};
|
};
|
||||||
|
|
||||||
call_bitcode_fn_fixing_for_convention(env, &[arg.into()], return_layout, bitcode_fn)
|
let result = call_bitcode_fn_fixing_for_convention(
|
||||||
|
env,
|
||||||
|
&[arg.into()],
|
||||||
|
return_layout,
|
||||||
|
bitcode_fn,
|
||||||
|
);
|
||||||
|
|
||||||
|
complex_bitcast_check_size(env, result, return_type.into(), "cast_bitpacked")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -283,6 +283,8 @@ pub fn dict_get<'a, 'ctx, 'env>(
|
||||||
.ptr_int()
|
.ptr_int()
|
||||||
.const_int(value_layout.stack_size(env.target_info) as u64, false);
|
.const_int(value_layout.stack_size(env.target_info) as u64, false);
|
||||||
|
|
||||||
|
let value_bt = basic_type_from_layout(env, value_layout);
|
||||||
|
|
||||||
let alignment = Alignment::from_key_value_layout(key_layout, value_layout, env.target_info);
|
let alignment = Alignment::from_key_value_layout(key_layout, value_layout, env.target_info);
|
||||||
let alignment_iv = alignment.as_int_value(env.context);
|
let alignment_iv = alignment.as_int_value(env.context);
|
||||||
|
|
||||||
|
@ -308,17 +310,26 @@ pub fn dict_get<'a, 'ctx, 'env>(
|
||||||
)
|
)
|
||||||
.into_struct_value();
|
.into_struct_value();
|
||||||
|
|
||||||
let flag = env
|
let flag_u8 = env
|
||||||
.builder
|
.builder
|
||||||
.build_extract_value(result, 1, "get_flag")
|
.build_extract_value(result, 1, "get_flag")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
|
|
||||||
|
let flag = env
|
||||||
|
.builder
|
||||||
|
.build_int_cast(flag_u8, env.context.bool_type(), "to_bool");
|
||||||
|
|
||||||
|
let value_u8_ptr_int = env
|
||||||
|
.builder
|
||||||
|
.build_extract_value(result, 0, "get_value_ptr_int")
|
||||||
|
.unwrap()
|
||||||
|
.into_int_value();
|
||||||
|
|
||||||
|
let ptr_type = value_bt.ptr_type(AddressSpace::Generic);
|
||||||
let value_u8_ptr = env
|
let value_u8_ptr = env
|
||||||
.builder
|
.builder
|
||||||
.build_extract_value(result, 0, "get_value_ptr")
|
.build_int_to_ptr(value_u8_ptr_int, ptr_type, "opaque_value_ptr");
|
||||||
.unwrap()
|
|
||||||
.into_pointer_value();
|
|
||||||
|
|
||||||
let start_block = env.builder.get_insert_block().unwrap();
|
let start_block = env.builder.get_insert_block().unwrap();
|
||||||
let parent = start_block.get_parent().unwrap();
|
let parent = start_block.get_parent().unwrap();
|
||||||
|
@ -326,7 +337,6 @@ pub fn dict_get<'a, 'ctx, 'env>(
|
||||||
let if_not_null = env.context.append_basic_block(parent, "if_not_null");
|
let if_not_null = env.context.append_basic_block(parent, "if_not_null");
|
||||||
let done_block = env.context.append_basic_block(parent, "done");
|
let done_block = env.context.append_basic_block(parent, "done");
|
||||||
|
|
||||||
let value_bt = basic_type_from_layout(env, value_layout);
|
|
||||||
let default = value_bt.const_zero();
|
let default = value_bt.const_zero();
|
||||||
|
|
||||||
env.builder
|
env.builder
|
||||||
|
|
|
@ -494,7 +494,7 @@ pub fn list_walk_generic<'a, 'ctx, 'env>(
|
||||||
layout_width(env, element_layout),
|
layout_width(env, element_layout),
|
||||||
layout_width(env, function_call_return_layout),
|
layout_width(env, function_call_return_layout),
|
||||||
layout_width(env, default_layout),
|
layout_width(env, default_layout),
|
||||||
has_tag_id.as_global_value().as_pointer_value().into(),
|
has_tag_id_helper(env, has_tag_id).into(),
|
||||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||||
pass_as_opaque(env, result_ptr),
|
pass_as_opaque(env, result_ptr),
|
||||||
],
|
],
|
||||||
|
@ -603,6 +603,30 @@ fn empty_list<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValueEnum<'ctx>
|
||||||
BasicValueEnum::StructValue(struct_type.const_zero())
|
BasicValueEnum::StructValue(struct_type.const_zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_tag_id_helper<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
has_tag_id: FunctionValue<'ctx>,
|
||||||
|
) -> PointerValue<'ctx> {
|
||||||
|
let u8_t = env.context.i8_type();
|
||||||
|
let u16_t = env.context.i16_type();
|
||||||
|
|
||||||
|
let u8_ptr_t = u8_t.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
let struct_t = env
|
||||||
|
.context
|
||||||
|
.struct_type(&[u8_t.into(), env.ptr_int().into()], false);
|
||||||
|
|
||||||
|
let has_tag_id_type = struct_t
|
||||||
|
.fn_type(&[u16_t.into(), u8_ptr_t.into()], false)
|
||||||
|
.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
env.builder.build_pointer_cast(
|
||||||
|
has_tag_id.as_global_value().as_pointer_value(),
|
||||||
|
has_tag_id_type,
|
||||||
|
"has_tag_id_cast",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// List.keepOks : List before, (before -> Result after *) -> List after
|
/// List.keepOks : List before, (before -> Result after *) -> List after
|
||||||
pub fn list_keep_oks<'a, 'ctx, 'env>(
|
pub fn list_keep_oks<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
@ -626,7 +650,7 @@ pub fn list_keep_oks<'a, 'ctx, 'env>(
|
||||||
let has_tag_id = match result_layout {
|
let has_tag_id = match result_layout {
|
||||||
Layout::Union(union_layout) => build_has_tag_id(env, function, *union_layout),
|
Layout::Union(union_layout) => build_has_tag_id(env, function, *union_layout),
|
||||||
Layout::Builtin(Builtin::Bool) => {
|
Layout::Builtin(Builtin::Bool) => {
|
||||||
// a `Result [] whatever`, so there is nothing to keep
|
// a `Result whatever []`, so there is nothing to keep
|
||||||
return empty_list(env);
|
return empty_list(env);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -644,7 +668,7 @@ pub fn list_keep_oks<'a, 'ctx, 'env>(
|
||||||
layout_width(env, before_layout),
|
layout_width(env, before_layout),
|
||||||
layout_width(env, result_layout),
|
layout_width(env, result_layout),
|
||||||
layout_width(env, after_layout),
|
layout_width(env, after_layout),
|
||||||
has_tag_id.as_global_value().as_pointer_value().into(),
|
has_tag_id_helper(env, has_tag_id).into(),
|
||||||
dec_result_fn.as_global_value().as_pointer_value().into(),
|
dec_result_fn.as_global_value().as_pointer_value().into(),
|
||||||
],
|
],
|
||||||
bitcode::LIST_KEEP_OKS,
|
bitcode::LIST_KEEP_OKS,
|
||||||
|
@ -692,7 +716,7 @@ pub fn list_keep_errs<'a, 'ctx, 'env>(
|
||||||
layout_width(env, before_layout),
|
layout_width(env, before_layout),
|
||||||
layout_width(env, result_layout),
|
layout_width(env, result_layout),
|
||||||
layout_width(env, after_layout),
|
layout_width(env, after_layout),
|
||||||
has_tag_id.as_global_value().as_pointer_value().into(),
|
has_tag_id_helper(env, has_tag_id).into(),
|
||||||
dec_result_fn.as_global_value().as_pointer_value().into(),
|
dec_result_fn.as_global_value().as_pointer_value().into(),
|
||||||
],
|
],
|
||||||
bitcode::LIST_KEEP_ERRS,
|
bitcode::LIST_KEEP_ERRS,
|
||||||
|
@ -968,7 +992,6 @@ pub fn list_find_unsafe<'a, 'ctx, 'env>(
|
||||||
pass_as_opaque(env, roc_function_call.data),
|
pass_as_opaque(env, roc_function_call.data),
|
||||||
roc_function_call.inc_n_data.into(),
|
roc_function_call.inc_n_data.into(),
|
||||||
roc_function_call.data_is_owned.into(),
|
roc_function_call.data_is_owned.into(),
|
||||||
env.alignment_intvalue(element_layout),
|
|
||||||
layout_width(env, element_layout),
|
layout_width(env, element_layout),
|
||||||
inc_element_fn.as_global_value().as_pointer_value().into(),
|
inc_element_fn.as_global_value().as_pointer_value().into(),
|
||||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||||
|
@ -982,18 +1005,22 @@ pub fn list_find_unsafe<'a, 'ctx, 'env>(
|
||||||
// in the Zig definition called above, because we don't know the size of the
|
// in the Zig definition called above, because we don't know the size of the
|
||||||
// element until user compile time, which is later than the compile time of bitcode defs.
|
// element until user compile time, which is later than the compile time of bitcode defs.
|
||||||
|
|
||||||
let value_u8_ptr = env
|
let value_u8_ptr_int = env
|
||||||
.builder
|
.builder
|
||||||
.build_extract_value(result, 0, "get_value_ptr")
|
.build_extract_value(result, 0, "get_value_ptr_int")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_pointer_value();
|
.into_int_value();
|
||||||
|
|
||||||
let found = env
|
let found_u8 = env
|
||||||
.builder
|
.builder
|
||||||
.build_extract_value(result, 1, "get_found")
|
.build_extract_value(result, 1, "get_found")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
|
|
||||||
|
let found = env
|
||||||
|
.builder
|
||||||
|
.build_int_cast(found_u8, env.context.bool_type(), "found_as_bool");
|
||||||
|
|
||||||
let start_block = env.builder.get_insert_block().unwrap();
|
let start_block = env.builder.get_insert_block().unwrap();
|
||||||
let parent = start_block.get_parent().unwrap();
|
let parent = start_block.get_parent().unwrap();
|
||||||
|
|
||||||
|
@ -1007,14 +1034,13 @@ pub fn list_find_unsafe<'a, 'ctx, 'env>(
|
||||||
.build_conditional_branch(found, if_not_null, done_block);
|
.build_conditional_branch(found, if_not_null, done_block);
|
||||||
|
|
||||||
env.builder.position_at_end(if_not_null);
|
env.builder.position_at_end(if_not_null);
|
||||||
let value_ptr = env
|
|
||||||
.builder
|
let value_ptr = env.builder.build_int_to_ptr(
|
||||||
.build_bitcast(
|
value_u8_ptr_int,
|
||||||
value_u8_ptr,
|
value_bt.ptr_type(AddressSpace::Generic),
|
||||||
value_bt.ptr_type(AddressSpace::Generic),
|
"get_value_ptr",
|
||||||
"from_opaque",
|
);
|
||||||
)
|
|
||||||
.into_pointer_value();
|
|
||||||
let loaded = env.builder.build_load(value_ptr, "load_value");
|
let loaded = env.builder.build_load(value_ptr, "load_value");
|
||||||
env.builder.build_unconditional_branch(done_block);
|
env.builder.build_unconditional_branch(done_block);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::llvm::bitcode::{call_bitcode_fn, call_str_bitcode_fn, call_void_bitcode_fn};
|
use crate::llvm::bitcode::{call_bitcode_fn, call_str_bitcode_fn, call_void_bitcode_fn};
|
||||||
use crate::llvm::build::{complex_bitcast, Env, Scope};
|
use crate::llvm::build::{Env, Scope};
|
||||||
use crate::llvm::build_list::{allocate_list, pass_update_mode, store_list};
|
use crate::llvm::build_list::{allocate_list, pass_update_mode, store_list};
|
||||||
use inkwell::builder::Builder;
|
use inkwell::builder::Builder;
|
||||||
use inkwell::values::{BasicValueEnum, IntValue, PointerValue, StructValue};
|
use inkwell::values::{BasicValueEnum, IntValue, PointerValue, StructValue};
|
||||||
|
@ -155,16 +155,22 @@ pub fn str_from_utf8_range<'a, 'ctx, 'env>(
|
||||||
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");
|
||||||
|
|
||||||
|
let count = env
|
||||||
|
.builder
|
||||||
|
.build_extract_value(count_and_start, 0, "get_count")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let start = env
|
||||||
|
.builder
|
||||||
|
.build_extract_value(count_and_start, 1, "get_start")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
call_void_bitcode_fn(
|
call_void_bitcode_fn(
|
||||||
env,
|
env,
|
||||||
&[
|
&[
|
||||||
list_symbol_to_c_abi(env, scope, list).into(),
|
list_symbol_to_c_abi(env, scope, list).into(),
|
||||||
complex_bitcast(
|
count,
|
||||||
env.builder,
|
start,
|
||||||
count_and_start.into(),
|
|
||||||
env.twice_ptr_int().into(),
|
|
||||||
"to_i128",
|
|
||||||
),
|
|
||||||
result_ptr.into(),
|
result_ptr.into(),
|
||||||
],
|
],
|
||||||
bitcode::STR_FROM_UTF8_RANGE,
|
bitcode::STR_FROM_UTF8_RANGE,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::llvm::bitcode::call_bitcode_fn;
|
|
||||||
use crate::llvm::build::{get_tag_id, tag_pointer_clear_tag_id, Env, FAST_CALL_CONV};
|
use crate::llvm::build::{get_tag_id, tag_pointer_clear_tag_id, Env, FAST_CALL_CONV};
|
||||||
use crate::llvm::build_list::{list_len, load_list_ptr};
|
use crate::llvm::build_list::{list_len, load_list_ptr};
|
||||||
use crate::llvm::build_str::str_equal;
|
use crate::llvm::build_str::str_equal;
|
||||||
|
@ -14,7 +13,7 @@ use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout};
|
use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout};
|
||||||
|
|
||||||
use super::build::{load_roc_value, use_roc_value};
|
use super::build::{dec_binop_with_unchecked, load_roc_value, use_roc_value};
|
||||||
use super::convert::argument_type_from_union_layout;
|
use super::convert::argument_type_from_union_layout;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -124,7 +123,7 @@ fn build_eq_builtin<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Builtin::Bool => int_cmp(IntPredicate::EQ, "eq_i1"),
|
Builtin::Bool => int_cmp(IntPredicate::EQ, "eq_i1"),
|
||||||
Builtin::Decimal => call_bitcode_fn(env, &[lhs_val, rhs_val], bitcode::DEC_EQ),
|
Builtin::Decimal => dec_binop_with_unchecked(env, bitcode::DEC_EQ, lhs_val, rhs_val),
|
||||||
|
|
||||||
Builtin::Str => str_equal(env, lhs_val, rhs_val),
|
Builtin::Str => str_equal(env, lhs_val, rhs_val),
|
||||||
Builtin::List(elem) => build_list_eq(
|
Builtin::List(elem) => build_list_eq(
|
||||||
|
@ -289,7 +288,7 @@ fn build_neq_builtin<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Builtin::Bool => int_cmp(IntPredicate::NE, "neq_i1"),
|
Builtin::Bool => int_cmp(IntPredicate::NE, "neq_i1"),
|
||||||
Builtin::Decimal => call_bitcode_fn(env, &[lhs_val, rhs_val], bitcode::DEC_NEQ),
|
Builtin::Decimal => dec_binop_with_unchecked(env, bitcode::DEC_NEQ, lhs_val, rhs_val),
|
||||||
|
|
||||||
Builtin::Str => {
|
Builtin::Str => {
|
||||||
let is_equal = str_equal(env, lhs_val, rhs_val).into_int_value();
|
let is_equal = str_equal(env, lhs_val, rhs_val).into_int_value();
|
||||||
|
|
|
@ -273,7 +273,10 @@ pub fn zig_str_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ct
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zig_has_tag_id_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> {
|
pub fn zig_has_tag_id_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> {
|
||||||
env.module.get_struct_type("list.HasTagId").unwrap()
|
let u8_ptr_t = env.context.i8_type().ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
env.context
|
||||||
|
.struct_type(&[env.context.bool_type().into(), u8_ptr_t.into()], false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zig_with_overflow_roc_dec<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> {
|
pub fn zig_with_overflow_roc_dec<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> {
|
||||||
|
|
|
@ -21,12 +21,11 @@ use crate::storage::{Storage, StoredValue, StoredValueKind};
|
||||||
use crate::wasm_module::linking::{DataSymbol, LinkingSegment, WasmObjectSymbol};
|
use crate::wasm_module::linking::{DataSymbol, LinkingSegment, WasmObjectSymbol};
|
||||||
use crate::wasm_module::sections::{DataMode, DataSegment, Limits};
|
use crate::wasm_module::sections::{DataMode, DataSegment, Limits};
|
||||||
use crate::wasm_module::{
|
use crate::wasm_module::{
|
||||||
code_builder, CodeBuilder, Export, ExportType, LocalId, Signature, SymInfo, ValueType,
|
code_builder, CodeBuilder, ExportType, LocalId, Signature, SymInfo, ValueType, WasmModule,
|
||||||
WasmModule,
|
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
copy_memory, round_up_to_alignment, CopyMemoryConfig, Env, DEBUG_LOG_SETTINGS, MEMORY_NAME,
|
copy_memory, round_up_to_alignment, CopyMemoryConfig, Env, DEBUG_LOG_SETTINGS, PTR_SIZE,
|
||||||
PTR_SIZE, PTR_TYPE, STACK_POINTER_GLOBAL_ID, STACK_POINTER_NAME, TARGET_INFO,
|
PTR_TYPE, TARGET_INFO,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
@ -77,22 +76,32 @@ impl<'a> WasmBackend<'a> {
|
||||||
fn_index_offset: u32,
|
fn_index_offset: u32,
|
||||||
helper_proc_gen: CodeGenHelp<'a>,
|
helper_proc_gen: CodeGenHelp<'a>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
module.export.append(Export {
|
// The preloaded builtins object file exports all functions, but the final app binary doesn't.
|
||||||
name: MEMORY_NAME.as_bytes(),
|
// Remove the function exports and use them to populate the Name section (debug info)
|
||||||
ty: ExportType::Mem,
|
let platform_and_builtins_exports =
|
||||||
index: 0,
|
std::mem::replace(&mut module.export.exports, bumpalo::vec![in env.arena]);
|
||||||
});
|
let mut app_exports = Vec::with_capacity_in(32, env.arena);
|
||||||
module.export.append(Export {
|
for ex in platform_and_builtins_exports.into_iter() {
|
||||||
name: STACK_POINTER_NAME.as_bytes(),
|
match ex.ty {
|
||||||
ty: ExportType::Global,
|
ExportType::Func => module.names.append_function(ex.index, ex.name),
|
||||||
index: STACK_POINTER_GLOBAL_ID,
|
_ => app_exports.push(ex),
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The preloaded binary has a global to tell us where its data section ends
|
// The preloaded binary has a global to tell us where its data section ends
|
||||||
// Note: We need this to account for zero data (.bss), which doesn't have an explicit DataSegment!
|
// Note: We need this to account for zero data (.bss), which doesn't have an explicit DataSegment!
|
||||||
let data_end_idx = module.export.globals_lookup["__data_end".as_bytes()];
|
let data_end_name = "__data_end".as_bytes();
|
||||||
|
let data_end_idx = app_exports
|
||||||
|
.iter()
|
||||||
|
.find(|ex| ex.name == data_end_name)
|
||||||
|
.map(|ex| ex.index)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
internal_error!("Preloaded Wasm binary must export global constant `__data_end`")
|
||||||
|
});
|
||||||
let next_constant_addr = module.global.parse_u32_at_index(data_end_idx);
|
let next_constant_addr = module.global.parse_u32_at_index(data_end_idx);
|
||||||
|
|
||||||
|
module.export.exports = app_exports;
|
||||||
|
|
||||||
WasmBackend {
|
WasmBackend {
|
||||||
env,
|
env,
|
||||||
interns,
|
interns,
|
||||||
|
@ -224,15 +233,19 @@ impl<'a> WasmBackend<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_proc(&mut self, proc: &Proc<'a>) {
|
fn start_proc(&mut self, proc: &Proc<'a>) {
|
||||||
|
use ReturnMethod::*;
|
||||||
let ret_layout = WasmLayout::new(&proc.ret_layout);
|
let ret_layout = WasmLayout::new(&proc.ret_layout);
|
||||||
|
|
||||||
let ret_type = match ret_layout.return_method() {
|
let ret_type = match ret_layout.return_method(CallConv::C) {
|
||||||
ReturnMethod::Primitive(ty, _) => Some(ty),
|
Primitive(ty, _) => Some(ty),
|
||||||
ReturnMethod::NoReturnValue => None,
|
NoReturnValue => None,
|
||||||
ReturnMethod::WriteToPointerArg => {
|
WriteToPointerArg => {
|
||||||
self.storage.arg_types.push(PTR_TYPE);
|
self.storage.arg_types.push(PTR_TYPE);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
ZigPackedStruct => {
|
||||||
|
internal_error!("C calling convention does not return Zig packed structs")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a block so we can exit the function without skipping stack frame "pop" code.
|
// Create a block so we can exit the function without skipping stack frame "pop" code.
|
||||||
|
@ -323,7 +336,7 @@ impl<'a> WasmBackend<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut n_inner_wasm_args = 0;
|
let mut n_inner_wasm_args = 0;
|
||||||
let ret_type_and_size = match inner_ret_layout.return_method() {
|
let ret_type_and_size = match inner_ret_layout.return_method(CallConv::C) {
|
||||||
ReturnMethod::NoReturnValue => None,
|
ReturnMethod::NoReturnValue => None,
|
||||||
ReturnMethod::Primitive(ty, size) => {
|
ReturnMethod::Primitive(ty, size) => {
|
||||||
// If the inner function returns a primitive, load the address to store it at
|
// If the inner function returns a primitive, load the address to store it at
|
||||||
|
@ -337,6 +350,7 @@ impl<'a> WasmBackend<'a> {
|
||||||
n_inner_wasm_args += 1;
|
n_inner_wasm_args += 1;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
x => internal_error!("A Roc function should never use ReturnMethod {:?}", x),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load all the arguments for the inner function
|
// Load all the arguments for the inner function
|
||||||
|
@ -1020,14 +1034,16 @@ impl<'a> WasmBackend<'a> {
|
||||||
return self.expr_call_low_level(lowlevel, arguments, ret_sym, ret_layout, ret_storage);
|
return self.expr_call_low_level(lowlevel, arguments, ret_sym, ret_layout, ret_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (param_types, ret_type) = self.storage.load_symbols_for_call(
|
let (num_wasm_args, has_return_val, ret_zig_packed_struct) =
|
||||||
self.env.arena,
|
self.storage.load_symbols_for_call(
|
||||||
&mut self.code_builder,
|
self.env.arena,
|
||||||
arguments,
|
&mut self.code_builder,
|
||||||
ret_sym,
|
arguments,
|
||||||
&wasm_layout,
|
ret_sym,
|
||||||
CallConv::C,
|
&wasm_layout,
|
||||||
);
|
CallConv::C,
|
||||||
|
);
|
||||||
|
debug_assert!(!ret_zig_packed_struct);
|
||||||
|
|
||||||
for (roc_proc_index, lookup) in self.proc_lookup.iter().enumerate() {
|
for (roc_proc_index, lookup) in self.proc_lookup.iter().enumerate() {
|
||||||
let ProcLookupData {
|
let ProcLookupData {
|
||||||
|
@ -1038,8 +1054,6 @@ impl<'a> WasmBackend<'a> {
|
||||||
} = lookup;
|
} = lookup;
|
||||||
if *ir_sym == func_sym && pl == proc_layout {
|
if *ir_sym == func_sym && pl == proc_layout {
|
||||||
let wasm_fn_index = self.fn_index_offset + roc_proc_index as u32;
|
let wasm_fn_index = self.fn_index_offset + roc_proc_index as u32;
|
||||||
let num_wasm_args = param_types.len();
|
|
||||||
let has_return_val = ret_type.is_some();
|
|
||||||
self.code_builder.call(
|
self.code_builder.call(
|
||||||
wasm_fn_index,
|
wasm_fn_index,
|
||||||
*linker_sym_index,
|
*linker_sym_index,
|
||||||
|
|
|
@ -4,9 +4,6 @@ use roc_mono::layout::{Layout, UnionLayout};
|
||||||
use crate::wasm_module::ValueType;
|
use crate::wasm_module::ValueType;
|
||||||
use crate::{PTR_SIZE, PTR_TYPE, TARGET_INFO};
|
use crate::{PTR_SIZE, PTR_TYPE, TARGET_INFO};
|
||||||
|
|
||||||
/// Manually keep up to date with the Zig version we are using for builtins
|
|
||||||
pub const BUILTINS_ZIG_VERSION: ZigVersion = ZigVersion::Zig8;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ReturnMethod {
|
pub enum ReturnMethod {
|
||||||
/// This layout is returned from a Wasm function "normally" as a Primitive
|
/// This layout is returned from a Wasm function "normally" as a Primitive
|
||||||
|
@ -15,6 +12,8 @@ pub enum ReturnMethod {
|
||||||
WriteToPointerArg,
|
WriteToPointerArg,
|
||||||
/// This layout is empty and requires no return value or argument (e.g. refcount helpers)
|
/// This layout is empty and requires no return value or argument (e.g. refcount helpers)
|
||||||
NoReturnValue,
|
NoReturnValue,
|
||||||
|
/// This layout is returned as a packed struct in an integer. Only used by Zig, not C.
|
||||||
|
ZigPackedStruct,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -124,33 +123,23 @@ impl WasmLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn return_method(&self) -> ReturnMethod {
|
pub fn return_method(&self, conv: CallConv) -> ReturnMethod {
|
||||||
match self {
|
match self {
|
||||||
Self::Primitive(ty, size) => ReturnMethod::Primitive(*ty, *size),
|
Self::Primitive(ty, size) => ReturnMethod::Primitive(*ty, *size),
|
||||||
Self::StackMemory { size, .. } => {
|
Self::StackMemory { size, format, .. } => {
|
||||||
if *size == 0 {
|
conv.stack_memory_return_method(*size, *format)
|
||||||
ReturnMethod::NoReturnValue
|
|
||||||
} else {
|
|
||||||
ReturnMethod::WriteToPointerArg
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
|
||||||
pub enum ZigVersion {
|
|
||||||
Zig8,
|
|
||||||
Zig9,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum CallConv {
|
pub enum CallConv {
|
||||||
/// The C calling convention, as defined here:
|
/// The C calling convention, as defined here:
|
||||||
/// https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md
|
/// https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md
|
||||||
C,
|
C,
|
||||||
/// The calling convention that Zig 0.8 or 0.9 generates for Wasm when we *ask* it
|
/// The calling convention that Zig 0.9 generates for Wasm when we *ask* it
|
||||||
/// for the .C calling convention, due to bugs in both versions of the Zig compiler.
|
/// for the .C calling convention, due to bugs in the Zig compiler.
|
||||||
Zig,
|
Zig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +171,7 @@ impl CallConv {
|
||||||
&[I32] // Small struct: pass by value
|
&[I32] // Small struct: pass by value
|
||||||
} else if size <= 8 {
|
} else if size <= 8 {
|
||||||
&[I64] // Small struct: pass by value
|
&[I64] // Small struct: pass by value
|
||||||
} else if size <= 12 && BUILTINS_ZIG_VERSION == ZigVersion::Zig9 {
|
} else if size <= 12 {
|
||||||
&[I64, I32] // Medium struct: pass by value, as two Wasm arguments
|
&[I64, I32] // Medium struct: pass by value, as two Wasm arguments
|
||||||
} else if size <= 16 {
|
} else if size <= 16 {
|
||||||
&[I64, I64] // Medium struct: pass by value, as two Wasm arguments
|
&[I64, I64] // Medium struct: pass by value, as two Wasm arguments
|
||||||
|
@ -194,4 +183,30 @@ impl CallConv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stack_memory_return_method(&self, size: u32, format: StackMemoryFormat) -> ReturnMethod {
|
||||||
|
use ReturnMethod::*;
|
||||||
|
use StackMemoryFormat::*;
|
||||||
|
|
||||||
|
match format {
|
||||||
|
Int128 | Float128 | Decimal => WriteToPointerArg,
|
||||||
|
|
||||||
|
DataStructure => {
|
||||||
|
if size == 0 {
|
||||||
|
return NoReturnValue;
|
||||||
|
}
|
||||||
|
match self {
|
||||||
|
CallConv::C => WriteToPointerArg,
|
||||||
|
|
||||||
|
CallConv::Zig => {
|
||||||
|
if size <= 8 {
|
||||||
|
ZigPackedStruct
|
||||||
|
} else {
|
||||||
|
WriteToPointerArg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
/// For numerical ops, this just pushes the arguments to the Wasm VM's value stack
|
/// For numerical ops, this just pushes the arguments to the Wasm VM's value stack
|
||||||
/// It implements the calling convention used by Zig for both numbers and structs
|
/// It implements the calling convention used by Zig for both numbers and structs
|
||||||
/// Result is the type signature of the call
|
/// Result is the type signature of the call
|
||||||
fn load_args(&self, backend: &mut WasmBackend<'a>) -> (Vec<'a, ValueType>, Option<ValueType>) {
|
fn load_args(&self, backend: &mut WasmBackend<'a>) -> (usize, bool, bool) {
|
||||||
backend.storage.load_symbols_for_call(
|
backend.storage.load_symbols_for_call(
|
||||||
backend.env.arena,
|
backend.env.arena,
|
||||||
&mut backend.code_builder,
|
&mut backend.code_builder,
|
||||||
|
@ -148,8 +148,29 @@ impl<'a> LowLevelCall<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_args_and_call_zig(&self, backend: &mut WasmBackend<'a>, name: &'a str) {
|
fn load_args_and_call_zig(&self, backend: &mut WasmBackend<'a>, name: &'a str) {
|
||||||
let (param_types, ret_type) = self.load_args(backend);
|
let (num_wasm_args, has_return_val, ret_zig_packed_struct) = self.load_args(backend);
|
||||||
backend.call_zig_builtin_after_loading_args(name, param_types.len(), ret_type.is_some());
|
backend.call_zig_builtin_after_loading_args(name, num_wasm_args, has_return_val);
|
||||||
|
|
||||||
|
if ret_zig_packed_struct {
|
||||||
|
match self.ret_storage {
|
||||||
|
StoredValue::StackMemory {
|
||||||
|
size,
|
||||||
|
alignment_bytes,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
// The address of the return value was already loaded before the call
|
||||||
|
let align = Align::from(alignment_bytes);
|
||||||
|
if size > 4 {
|
||||||
|
backend.code_builder.i64_store(align, 0);
|
||||||
|
} else {
|
||||||
|
backend.code_builder.i32_store(align, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
internal_error!("Zig packed struct should always be stored to StackMemory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrap an integer whose Wasm representation is i32
|
/// Wrap an integer whose Wasm representation is i32
|
||||||
|
|
|
@ -6,9 +6,7 @@ use roc_error_macros::internal_error;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_mono::layout::Layout;
|
use roc_mono::layout::Layout;
|
||||||
|
|
||||||
use crate::layout::{
|
use crate::layout::{CallConv, ReturnMethod, StackMemoryFormat, WasmLayout};
|
||||||
CallConv, ReturnMethod, StackMemoryFormat, WasmLayout, ZigVersion, BUILTINS_ZIG_VERSION,
|
|
||||||
};
|
|
||||||
use crate::wasm_module::{Align, CodeBuilder, LocalId, ValueType, VmSymbolState};
|
use crate::wasm_module::{Align, CodeBuilder, LocalId, ValueType, VmSymbolState};
|
||||||
use crate::{copy_memory, round_up_to_alignment, CopyMemoryConfig, PTR_TYPE};
|
use crate::{copy_memory, round_up_to_alignment, CopyMemoryConfig, PTR_TYPE};
|
||||||
|
|
||||||
|
@ -327,7 +325,7 @@ impl<'a> Storage<'a> {
|
||||||
code_builder.i32_load(align, offset);
|
code_builder.i32_load(align, offset);
|
||||||
} else if *size <= 8 {
|
} else if *size <= 8 {
|
||||||
code_builder.i64_load(align, offset);
|
code_builder.i64_load(align, offset);
|
||||||
} else if *size <= 12 && BUILTINS_ZIG_VERSION == ZigVersion::Zig9 {
|
} else if *size <= 12 {
|
||||||
code_builder.i64_load(align, offset);
|
code_builder.i64_load(align, offset);
|
||||||
code_builder.get_local(local_id);
|
code_builder.get_local(local_id);
|
||||||
code_builder.i32_load(align, offset + 8);
|
code_builder.i32_load(align, offset + 8);
|
||||||
|
@ -397,37 +395,47 @@ impl<'a> Storage<'a> {
|
||||||
return_symbol: Symbol,
|
return_symbol: Symbol,
|
||||||
return_layout: &WasmLayout,
|
return_layout: &WasmLayout,
|
||||||
call_conv: CallConv,
|
call_conv: CallConv,
|
||||||
) -> (Vec<'a, ValueType>, Option<ValueType>) {
|
) -> (usize, bool, bool) {
|
||||||
let mut wasm_arg_types = Vec::with_capacity_in(arguments.len() * 2 + 1, arena);
|
use ReturnMethod::*;
|
||||||
let mut wasm_args = Vec::with_capacity_in(arguments.len() * 2 + 1, arena);
|
|
||||||
|
|
||||||
let return_method = return_layout.return_method();
|
let mut num_wasm_args = 0;
|
||||||
let return_type = match return_method {
|
let mut symbols_to_load = Vec::with_capacity_in(arguments.len() * 2 + 1, arena);
|
||||||
ReturnMethod::Primitive(ty, _) => Some(ty),
|
|
||||||
ReturnMethod::NoReturnValue => None,
|
let return_method = return_layout.return_method(call_conv);
|
||||||
ReturnMethod::WriteToPointerArg => {
|
let has_return_val = match return_method {
|
||||||
wasm_arg_types.push(PTR_TYPE);
|
Primitive(..) => true,
|
||||||
wasm_args.push(return_symbol);
|
NoReturnValue => false,
|
||||||
None
|
WriteToPointerArg => {
|
||||||
|
num_wasm_args += 1;
|
||||||
|
symbols_to_load.push(return_symbol);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
ZigPackedStruct => {
|
||||||
|
// Workaround for Zig's incorrect implementation of the C calling convention.
|
||||||
|
// We need to copy the packed struct into the stack frame
|
||||||
|
// Load the address before the call so that afterward, it will be 2nd on the value stack,
|
||||||
|
// ready for the store instruction.
|
||||||
|
symbols_to_load.push(return_symbol);
|
||||||
|
true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for arg in arguments {
|
for arg in arguments {
|
||||||
let stored = self.symbol_storage_map.get(arg).unwrap();
|
let stored = self.symbol_storage_map.get(arg).unwrap();
|
||||||
let arg_types = stored.arg_types(call_conv);
|
let arg_types = stored.arg_types(call_conv);
|
||||||
wasm_arg_types.extend_from_slice(arg_types);
|
num_wasm_args += arg_types.len();
|
||||||
match arg_types.len() {
|
match arg_types.len() {
|
||||||
0 => {}
|
0 => {}
|
||||||
1 => wasm_args.push(*arg),
|
1 => symbols_to_load.push(*arg),
|
||||||
2 => wasm_args.extend_from_slice(&[*arg, *arg]),
|
2 => symbols_to_load.extend_from_slice(&[*arg, *arg]),
|
||||||
n => internal_error!("Cannot have {} Wasm arguments for 1 Roc argument", n),
|
n => internal_error!("Cannot have {} Wasm arguments for 1 Roc argument", n),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the symbols were already at the top of the stack, do nothing!
|
// If the symbols were already at the top of the stack, do nothing!
|
||||||
// Should be common for simple cases, due to the structure of the Mono IR
|
// Should be common for simple cases, due to the structure of the Mono IR
|
||||||
if !code_builder.verify_stack_match(&wasm_args) {
|
if !code_builder.verify_stack_match(&symbols_to_load) {
|
||||||
if return_method == ReturnMethod::WriteToPointerArg {
|
if matches!(return_method, WriteToPointerArg | ZigPackedStruct) {
|
||||||
self.load_return_address_ccc(code_builder, return_symbol);
|
self.load_return_address_ccc(code_builder, return_symbol);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -439,7 +447,11 @@ impl<'a> Storage<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(wasm_arg_types, return_type)
|
(
|
||||||
|
num_wasm_args,
|
||||||
|
has_return_val,
|
||||||
|
return_method == ZigPackedStruct,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate code to copy a StoredValue to an arbitrary memory location
|
/// Generate code to copy a StoredValue to an arbitrary memory location
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub mod opcodes;
|
||||||
pub mod sections;
|
pub mod sections;
|
||||||
pub mod serialize;
|
pub mod serialize;
|
||||||
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::{collections::Vec, Bump};
|
||||||
pub use code_builder::{Align, CodeBuilder, LocalId, ValueType, VmSymbolState};
|
pub use code_builder::{Align, CodeBuilder, LocalId, ValueType, VmSymbolState};
|
||||||
pub use linking::SymInfo;
|
pub use linking::SymInfo;
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
|
@ -145,7 +145,7 @@ impl<'a> WasmModule<'a> {
|
||||||
|
|
||||||
let global = GlobalSection::preload(arena, bytes, &mut cursor);
|
let global = GlobalSection::preload(arena, bytes, &mut cursor);
|
||||||
|
|
||||||
let export = ExportSection::preload_globals(arena, bytes, &mut cursor);
|
let export = ExportSection::preload(arena, bytes, &mut cursor);
|
||||||
|
|
||||||
let start = OpaqueSection::preload(SectionId::Start, arena, bytes, &mut cursor);
|
let start = OpaqueSection::preload(SectionId::Start, arena, bytes, &mut cursor);
|
||||||
|
|
||||||
|
@ -191,10 +191,18 @@ impl<'a> WasmModule<'a> {
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
called_preload_fns: T,
|
called_preload_fns: T,
|
||||||
) {
|
) {
|
||||||
|
let exported_fn_iter = self
|
||||||
|
.export
|
||||||
|
.exports
|
||||||
|
.iter()
|
||||||
|
.filter(|ex| ex.ty == ExportType::Func)
|
||||||
|
.map(|ex| ex.index);
|
||||||
|
let function_indices = Vec::from_iter_in(exported_fn_iter, arena);
|
||||||
|
|
||||||
self.code.remove_dead_preloads(
|
self.code.remove_dead_preloads(
|
||||||
arena,
|
arena,
|
||||||
self.import.function_count,
|
self.import.function_count,
|
||||||
&self.export.function_indices,
|
&function_indices,
|
||||||
called_preload_fns,
|
called_preload_fns,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ fn section_size(bytes: &[u8]) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_section<'a>(id: SectionId, module_bytes: &'a [u8], cursor: &mut usize) -> (u32, &'a [u8]) {
|
fn parse_section<'a>(id: SectionId, module_bytes: &'a [u8], cursor: &mut usize) -> (u32, &'a [u8]) {
|
||||||
if module_bytes[*cursor] != id as u8 {
|
if (*cursor >= module_bytes.len()) || (module_bytes[*cursor] != id as u8) {
|
||||||
return (0, &[]);
|
return (0, &[]);
|
||||||
}
|
}
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
@ -809,56 +809,35 @@ impl Serialize for Export<'_> {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExportSection<'a> {
|
pub struct ExportSection<'a> {
|
||||||
pub count: u32,
|
pub exports: Vec<'a, Export<'a>>,
|
||||||
pub bytes: Vec<'a, u8>,
|
|
||||||
/// List of exported functions to keep during dead-code-elimination
|
|
||||||
pub function_indices: Vec<'a, u32>,
|
|
||||||
/// name -> index
|
|
||||||
pub globals_lookup: MutMap<&'a [u8], u32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ExportSection<'a> {
|
impl<'a> ExportSection<'a> {
|
||||||
const ID: SectionId = SectionId::Export;
|
const ID: SectionId = SectionId::Export;
|
||||||
|
|
||||||
pub fn append(&mut self, export: Export) {
|
pub fn append(&mut self, export: Export<'a>) {
|
||||||
export.serialize(&mut self.bytes);
|
self.exports.push(export);
|
||||||
self.count += 1;
|
|
||||||
if matches!(export.ty, ExportType::Func) {
|
|
||||||
self.function_indices.push(export.index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> usize {
|
pub fn size(&self) -> usize {
|
||||||
section_size(&self.bytes)
|
self.exports
|
||||||
|
.iter()
|
||||||
|
.map(|ex| ex.name.len() + 1 + MAX_SIZE_ENCODED_U32)
|
||||||
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty(arena: &'a Bump) -> Self {
|
/// Preload from object file.
|
||||||
ExportSection {
|
pub fn preload(arena: &'a Bump, module_bytes: &[u8], cursor: &mut usize) -> Self {
|
||||||
count: 0,
|
|
||||||
bytes: Vec::with_capacity_in(256, arena),
|
|
||||||
function_indices: Vec::with_capacity_in(4, arena),
|
|
||||||
globals_lookup: MutMap::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Preload from object file. Keep only the Global exports, ignore the rest.
|
|
||||||
pub fn preload_globals(arena: &'a Bump, module_bytes: &[u8], cursor: &mut usize) -> Self {
|
|
||||||
let (num_exports, body_bytes) = parse_section(Self::ID, module_bytes, cursor);
|
let (num_exports, body_bytes) = parse_section(Self::ID, module_bytes, cursor);
|
||||||
|
|
||||||
let mut export_section = ExportSection::empty(arena);
|
let mut export_section = ExportSection {
|
||||||
|
exports: Vec::with_capacity_in(num_exports as usize, arena),
|
||||||
|
};
|
||||||
|
|
||||||
let mut body_cursor = 0;
|
let mut body_cursor = 0;
|
||||||
for _ in 0..num_exports {
|
while body_cursor < body_bytes.len() {
|
||||||
let export_start = body_cursor;
|
|
||||||
let export = Export::parse(arena, body_bytes, &mut body_cursor);
|
let export = Export::parse(arena, body_bytes, &mut body_cursor);
|
||||||
if matches!(export.ty, ExportType::Global) {
|
export_section.exports.push(export);
|
||||||
let global_bytes = &body_bytes[export_start..body_cursor];
|
|
||||||
export_section.bytes.extend_from_slice(global_bytes);
|
|
||||||
export_section.count += 1;
|
|
||||||
export_section
|
|
||||||
.globals_lookup
|
|
||||||
.insert(export.name, export.index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export_section
|
export_section
|
||||||
|
@ -867,10 +846,9 @@ impl<'a> ExportSection<'a> {
|
||||||
|
|
||||||
impl<'a> Serialize for ExportSection<'a> {
|
impl<'a> Serialize for ExportSection<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
if !self.bytes.is_empty() {
|
if !self.exports.is_empty() {
|
||||||
let header_indices = write_section_header(buffer, Self::ID);
|
let header_indices = write_section_header(buffer, Self::ID);
|
||||||
buffer.encode_u32(self.count);
|
self.exports.serialize(buffer);
|
||||||
buffer.append_slice(&self.bytes);
|
|
||||||
update_section_size(buffer, header_indices);
|
update_section_size(buffer, header_indices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1291,6 +1269,14 @@ impl<'a> NameSection<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(arena: &'a Bump, module_bytes: &[u8], cursor: &mut usize) -> Self {
|
pub fn parse(arena: &'a Bump, module_bytes: &[u8], cursor: &mut usize) -> Self {
|
||||||
|
// If we're already past the end of the preloaded file then there is no Name section
|
||||||
|
if *cursor >= module_bytes.len() {
|
||||||
|
return NameSection {
|
||||||
|
bytes: bumpalo::vec![in arena],
|
||||||
|
functions: MutMap::default(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Custom section ID
|
// Custom section ID
|
||||||
let section_id_byte = module_bytes[*cursor];
|
let section_id_byte = module_bytes[*cursor];
|
||||||
if section_id_byte != Self::ID as u8 {
|
if section_id_byte != Self::ID as u8 {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use roc_builtins::bitcode;
|
use roc_builtins::bitcode;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
const PLATFORM_FILENAME: &str = "wasm_test_platform";
|
const PLATFORM_FILENAME: &str = "wasm_test_platform";
|
||||||
|
@ -15,11 +15,44 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_wasm() {
|
fn build_wasm() {
|
||||||
let out_dir = env::var("OUT_DIR").unwrap();
|
let source_path = format!("src/helpers/{}.c", PLATFORM_FILENAME);
|
||||||
|
println!("cargo:rerun-if-changed={}", source_path);
|
||||||
|
|
||||||
|
let out_dir = env::var("OUT_DIR").unwrap();
|
||||||
println!("cargo:rustc-env={}={}", OUT_DIR_VAR, out_dir);
|
println!("cargo:rustc-env={}={}", OUT_DIR_VAR, out_dir);
|
||||||
|
|
||||||
build_wasm_platform_and_builtins(&out_dir);
|
// Zig can produce *either* an object containing relocations OR an object containing libc code
|
||||||
|
// But we want both, so we have to compile twice with different flags, then link them
|
||||||
|
|
||||||
|
// Create an object file with relocations
|
||||||
|
let platform_path = build_wasm_platform(&out_dir, &source_path);
|
||||||
|
|
||||||
|
// Compile again to get libc path
|
||||||
|
let (libc_path, compiler_rt_path) = build_wasm_libc_compilerrt(&out_dir, &source_path);
|
||||||
|
let mut libc_pathbuf = PathBuf::from(&libc_path);
|
||||||
|
libc_pathbuf.pop();
|
||||||
|
let libc_dir = libc_pathbuf.to_str().unwrap();
|
||||||
|
|
||||||
|
let args = &[
|
||||||
|
"wasm-ld",
|
||||||
|
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
||||||
|
&platform_path,
|
||||||
|
&compiler_rt_path,
|
||||||
|
"-L",
|
||||||
|
libc_dir,
|
||||||
|
"-lc",
|
||||||
|
"-o",
|
||||||
|
&format!("{}/{}.o", out_dir, PLATFORM_FILENAME),
|
||||||
|
"--export-all",
|
||||||
|
"--no-entry",
|
||||||
|
// "--emit-relocs", // TODO: resize stack by relocating __heap_base (issue #2480) here and in repl_test build
|
||||||
|
];
|
||||||
|
|
||||||
|
let zig = zig_executable();
|
||||||
|
|
||||||
|
// println!("{} {}", zig, args.join(" "));
|
||||||
|
|
||||||
|
run_command(&zig, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zig_executable() -> String {
|
fn zig_executable() -> String {
|
||||||
|
@ -29,29 +62,46 @@ fn zig_executable() -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an all-in-one object file: platform + builtins + libc
|
fn build_wasm_platform(out_dir: &str, source_path: &str) -> String {
|
||||||
fn build_wasm_platform_and_builtins(out_dir: &str) {
|
let platform_path = format!("{}/{}.o", out_dir, PLATFORM_FILENAME);
|
||||||
println!("cargo:rerun-if-changed=src/helpers/{}.c", PLATFORM_FILENAME);
|
|
||||||
|
|
||||||
// See discussion with Luuk de Gram (Zig contributor)
|
run_command(
|
||||||
// https://github.com/rtfeldman/roc/pull/2181#pullrequestreview-839608063
|
&zig_executable(),
|
||||||
// This builds a library file that exports everything. It has no linker data but we don't need that.
|
&[
|
||||||
let args = [
|
"build-lib",
|
||||||
"build-lib",
|
"-target",
|
||||||
"-target",
|
"wasm32-wasi",
|
||||||
"wasm32-wasi",
|
"-lc",
|
||||||
"-lc",
|
source_path,
|
||||||
"-dynamic", // -dynamic ensures libc code goes into the binary
|
&format!("-femit-bin={}", &platform_path),
|
||||||
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
],
|
||||||
&format!("src/helpers/{}.c", PLATFORM_FILENAME),
|
);
|
||||||
&format!("-femit-bin={}/{}.o", out_dir, PLATFORM_FILENAME),
|
|
||||||
];
|
|
||||||
|
|
||||||
let zig = zig_executable();
|
platform_path
|
||||||
|
}
|
||||||
|
|
||||||
// println!("{} {}", zig, args.join(" "));
|
fn build_wasm_libc_compilerrt(out_dir: &str, source_path: &str) -> (String, String) {
|
||||||
|
let zig_cache_dir = format!("{}/zig-cache-wasm32", out_dir);
|
||||||
|
|
||||||
run_command(Path::new("."), &zig, args);
|
run_command(
|
||||||
|
&zig_executable(),
|
||||||
|
&[
|
||||||
|
"build-lib",
|
||||||
|
"-dynamic", // ensure libc code is actually generated (not just linked against header)
|
||||||
|
"-target",
|
||||||
|
"wasm32-wasi",
|
||||||
|
"-lc",
|
||||||
|
source_path,
|
||||||
|
"-femit-bin=/dev/null",
|
||||||
|
"--global-cache-dir",
|
||||||
|
&zig_cache_dir,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
(
|
||||||
|
run_command("find", &[&zig_cache_dir, "-name", "libc.a"]),
|
||||||
|
run_command("find", &[&zig_cache_dir, "-name", "compiler_rt.o"]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn feature_is_enabled(feature_name: &str) -> bool {
|
fn feature_is_enabled(feature_name: &str) -> bool {
|
||||||
|
@ -62,26 +112,35 @@ fn feature_is_enabled(feature_name: &str) -> bool {
|
||||||
env::var(cargo_env_var).is_ok()
|
env::var(cargo_env_var).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command<S, I, P: AsRef<Path>>(path: P, command_str: &str, args: I) -> String
|
fn run_command(command_str: &str, args: &[&str]) -> String {
|
||||||
where
|
|
||||||
I: IntoIterator<Item = S>,
|
|
||||||
S: AsRef<OsStr>,
|
|
||||||
{
|
|
||||||
let output_result = Command::new(OsStr::new(&command_str))
|
let output_result = Command::new(OsStr::new(&command_str))
|
||||||
.current_dir(path)
|
.current_dir(Path::new("."))
|
||||||
.args(args)
|
.args(args)
|
||||||
.output();
|
.output();
|
||||||
|
|
||||||
|
let fail = |err: String| {
|
||||||
|
panic!(
|
||||||
|
"\n\nFailed command:\n\t{} {}\n\n{}",
|
||||||
|
command_str,
|
||||||
|
args.join(" "),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
match output_result {
|
match output_result {
|
||||||
Ok(output) => match output.status.success() {
|
Ok(output) => match output.status.success() {
|
||||||
true => std::str::from_utf8(&output.stdout).unwrap().to_string(),
|
true => std::str::from_utf8(&output.stdout)
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.to_string(),
|
||||||
false => {
|
false => {
|
||||||
let error_str = match std::str::from_utf8(&output.stderr) {
|
let error_str = match std::str::from_utf8(&output.stderr) {
|
||||||
Ok(stderr) => stderr.to_string(),
|
Ok(stderr) => stderr.to_string(),
|
||||||
Err(_) => format!("Failed to run \"{}\"", command_str),
|
Err(_) => format!("Failed to run \"{}\"", command_str),
|
||||||
};
|
};
|
||||||
panic!("{} failed: {}", command_str, error_str);
|
fail(error_str)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(reason) => panic!("{} failed: {}", command_str, reason),
|
Err(reason) => fail(reason.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// Makes test runs take 50% longer, due to linking
|
// Makes test runs take 50% longer, due to linking
|
||||||
#define ENABLE_PRINTF 0
|
#define ENABLE_PRINTF 0
|
||||||
|
@ -138,9 +139,9 @@ void roc_panic(char *msg, unsigned int tag_id)
|
||||||
|
|
||||||
//--------------------------
|
//--------------------------
|
||||||
|
|
||||||
void *roc_memcpy(void *dest, const void *src, size_t n)
|
void roc_memcpy(void *dest, const void *src, size_t n)
|
||||||
{
|
{
|
||||||
return memcpy(dest, src, n);
|
memcpy(dest, src, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------
|
//--------------------------
|
||||||
|
|
|
@ -2,6 +2,7 @@ const std = @import("std");
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const expectEqual = testing.expectEqual;
|
const expectEqual = testing.expectEqual;
|
||||||
const expect = testing.expect;
|
const expect = testing.expect;
|
||||||
|
const maxInt = std.math.maxInt;
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
||||||
|
@ -12,7 +13,8 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
const builtin = @import("builtin");
|
||||||
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,14 +26,16 @@ const Allocator = mem.Allocator;
|
||||||
// extern fn roc__mainForHost_1_exposed(i64, *i64) void;
|
// extern fn roc__mainForHost_1_exposed(i64, *i64) void;
|
||||||
extern fn roc__mainForHost_1_exposed(i64) i64;
|
extern fn roc__mainForHost_1_exposed(i64) i64;
|
||||||
|
|
||||||
const Align = extern struct { a: usize, b: usize };
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*align(@alignOf(Align)) c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
extern fn realloc(c_ptr: [*]align(@alignOf(Align)) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(@alignOf(Align)) u8) callconv(.C) void;
|
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
||||||
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
const DEBUG: bool = false;
|
const DEBUG: bool = false;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
var ptr = malloc(size);
|
var ptr = malloc(size);
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
@ -42,25 +46,25 @@ export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
return realloc(@alignCast(@alignOf(Align), @ptrCast([*]u8, c_ptr)), new_size);
|
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(@alignCast(@alignOf(Align), @ptrCast([*]u8, c_ptr)));
|
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
_ = tag_id;
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
@ -69,19 +73,27 @@ export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
||||||
std.process.exit(0);
|
std.process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export fn roc_memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void {
|
||||||
|
return memcpy(dst, src, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||||
|
return memset(dst, value, size);
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn main() u8 {
|
pub export fn main() u8 {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
|
||||||
// start time
|
// start time
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
const result = roc__mainForHost_1_exposed(10);
|
const result = roc__mainForHost_1_exposed(10);
|
||||||
|
|
||||||
// end time
|
// end time
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
stdout.print("{d}\n", .{result}) catch unreachable;
|
stdout.print("{d}\n", .{result}) catch unreachable;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const str = @import("str");
|
||||||
|
const RocStr = str.RocStr;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const expectEqual = testing.expectEqual;
|
const expectEqual = testing.expectEqual;
|
||||||
const expect = testing.expect;
|
const expect = testing.expect;
|
||||||
|
@ -12,7 +15,7 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,18 +24,17 @@ const mem = std.mem;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
|
|
||||||
extern fn roc__mainForHost_1_exposed_generic(output: *RocList, input: *RocList) void;
|
extern fn roc__mainForHost_1_exposed_generic(output: *RocList, input: *RocList) void;
|
||||||
// extern fn roc__mainForHost_1_exposed_generic(input: *RocList) RocList;
|
|
||||||
|
|
||||||
const Align = extern struct { a: usize, b: usize };
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*align(@alignOf(Align)) c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
extern fn realloc(c_ptr: [*]align(@alignOf(Align)) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(@alignOf(Align)) u8) callconv(.C) void;
|
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
||||||
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
const DEBUG: bool = false;
|
const DEBUG: bool = false;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
var ptr = malloc(size);
|
var ptr = malloc(size);
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
@ -43,25 +45,25 @@ export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
return realloc(@alignCast(@alignOf(Align), @ptrCast([*]u8, c_ptr)), new_size);
|
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(@alignCast(@alignOf(Align), @ptrCast([*]u8, c_ptr)));
|
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
_ = tag_id;
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
@ -87,7 +89,6 @@ const Unit = extern struct {};
|
||||||
|
|
||||||
pub export fn main() u8 {
|
pub export fn main() u8 {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
const stderr = std.io.getStdErr().writer();
|
|
||||||
|
|
||||||
var raw_numbers: [NUM_NUMS + 1]i64 = undefined;
|
var raw_numbers: [NUM_NUMS + 1]i64 = undefined;
|
||||||
|
|
||||||
|
@ -104,7 +105,7 @@ pub export fn main() u8 {
|
||||||
|
|
||||||
// start time
|
// start time
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
// actually call roc to populate the callresult
|
// actually call roc to populate the callresult
|
||||||
var callresult: RocList = undefined;
|
var callresult: RocList = undefined;
|
||||||
|
@ -118,7 +119,7 @@ pub export fn main() u8 {
|
||||||
|
|
||||||
// end time
|
// end time
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
for (result) |x, i| {
|
for (result) |x, i| {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
|
|
@ -15,7 +15,8 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
const builtin = @import("builtin");
|
||||||
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,15 +31,15 @@ extern fn roc__mainForHost_1_Fx_size() i64;
|
||||||
extern fn roc__mainForHost_1_Fx_result_size() i64;
|
extern fn roc__mainForHost_1_Fx_result_size() i64;
|
||||||
|
|
||||||
const Align = 2 * @alignOf(usize);
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*align(Align) c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
||||||
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
const DEBUG: bool = false;
|
const DEBUG: bool = false;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
var ptr = malloc(size);
|
var ptr = malloc(size);
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
@ -49,7 +50,7 @@ export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
||||||
|
@ -58,7 +59,7 @@ export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignmen
|
||||||
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
||||||
|
@ -67,7 +68,7 @@ export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
||||||
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
_ = tag_id;
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
@ -98,7 +99,7 @@ pub export fn main() callconv(.C) u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
roc__mainForHost_1_exposed_generic(output);
|
roc__mainForHost_1_exposed_generic(output);
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ pub export fn main() callconv(.C) u8 {
|
||||||
call_the_closure(closure_data_pointer);
|
call_the_closure(closure_data_pointer);
|
||||||
|
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
const delta = to_seconds(ts2) - to_seconds(ts1);
|
const delta = to_seconds(ts2) - to_seconds(ts1);
|
||||||
|
|
||||||
|
@ -214,8 +215,3 @@ fn roc_fx_getInt_help() !i64 {
|
||||||
|
|
||||||
return std.fmt.parseInt(i64, line, 10);
|
return std.fmt.parseInt(i64, line, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readLine() []u8 {
|
|
||||||
const stdin = std.io.getStdIn().reader();
|
|
||||||
return (stdin.readUntilDelimiterOrEof(&line_buf, '\n') catch unreachable) orelse "";
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
const str = @import("str");
|
const str = @import("str");
|
||||||
const RocStr = str.RocStr;
|
const RocStr = str.RocStr;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
@ -14,21 +15,21 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Align = 2 * @alignOf(usize);
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*align(Align) c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
||||||
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
const DEBUG: bool = false;
|
const DEBUG: bool = false;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
var ptr = malloc(size);
|
var ptr = malloc(size);
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
@ -39,7 +40,7 @@ export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
||||||
|
@ -48,7 +49,7 @@ export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignmen
|
||||||
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
||||||
|
@ -57,7 +58,7 @@ export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
||||||
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
_ = tag_id;
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
@ -87,7 +88,7 @@ pub fn main() u8 {
|
||||||
|
|
||||||
// start time
|
// start time
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
// actually call roc to populate the callresult
|
// actually call roc to populate the callresult
|
||||||
var callresult = RocStr.empty();
|
var callresult = RocStr.empty();
|
||||||
|
@ -95,7 +96,7 @@ pub fn main() u8 {
|
||||||
|
|
||||||
// end time
|
// end time
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
// stdout the result
|
// stdout the result
|
||||||
stdout.print("{s}", .{callresult.asSlice()}) catch unreachable;
|
stdout.print("{s}", .{callresult.asSlice()}) catch unreachable;
|
||||||
|
|
|
@ -15,7 +15,8 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
const builtin = @import("builtin");
|
||||||
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,25 +30,47 @@ extern fn roc__mainForHost_1_Fx_caller(*const u8, [*]u8, [*]u8) void;
|
||||||
extern fn roc__mainForHost_1_Fx_size() i64;
|
extern fn roc__mainForHost_1_Fx_size() i64;
|
||||||
extern fn roc__mainForHost_1_Fx_result_size() i64;
|
extern fn roc__mainForHost_1_Fx_result_size() i64;
|
||||||
|
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*c_void;
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn realloc(c_ptr: [*]align(@alignOf(u128)) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(@alignOf(u128)) u8) callconv(.C) void;
|
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
|
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
||||||
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
const DEBUG: bool = false;
|
||||||
return malloc(size);
|
|
||||||
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
|
if (DEBUG) {
|
||||||
|
var ptr = malloc(size);
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
stdout.print("alloc: {d} (alignment {d}, size {d})\n", .{ ptr, alignment, size }) catch unreachable;
|
||||||
|
return ptr;
|
||||||
|
} else {
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
return realloc(@alignCast(16, @ptrCast([*]u8, c_ptr)), new_size);
|
if (DEBUG) {
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
free(@alignCast(16, @ptrCast([*]u8, c_ptr)));
|
if (DEBUG) {
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
const msg = @ptrCast([*:0]const u8, c_ptr);
|
const msg = @ptrCast([*:0]const u8, c_ptr);
|
||||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||||
|
@ -67,7 +90,6 @@ const Unit = extern struct {};
|
||||||
pub export fn main() u8 {
|
pub export fn main() u8 {
|
||||||
const allocator = std.heap.page_allocator;
|
const allocator = std.heap.page_allocator;
|
||||||
|
|
||||||
const stdout = std.io.getStdOut().writer();
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
|
||||||
// NOTE the return size can be zero, which will segfault. Always allocate at least 8 bytes
|
// NOTE the return size can be zero, which will segfault. Always allocate at least 8 bytes
|
||||||
|
@ -80,14 +102,14 @@ pub export fn main() u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
roc__mainForHost_1_exposed_generic(output);
|
roc__mainForHost_1_exposed_generic(output);
|
||||||
|
|
||||||
call_the_closure(output);
|
call_the_closure(output);
|
||||||
|
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
const delta = to_seconds(ts2) - to_seconds(ts1);
|
const delta = to_seconds(ts2) - to_seconds(ts1);
|
||||||
|
|
||||||
|
@ -130,11 +152,7 @@ fn call_the_closure(closure_data_pointer: [*]u8) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn roc_fx_getLine() str.RocStr {
|
pub export fn roc_fx_getLine() str.RocStr {
|
||||||
if (roc_fx_getLine_help()) |value| {
|
return roc_fx_getLine_help() catch return str.RocStr.empty();
|
||||||
return value;
|
|
||||||
} else |err| {
|
|
||||||
return str.RocStr.empty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn roc_fx_getLine_help() !RocStr {
|
fn roc_fx_getLine_help() !RocStr {
|
||||||
|
@ -188,8 +206,3 @@ fn roc_fx_getInt_help() !i64 {
|
||||||
|
|
||||||
return std.fmt.parseInt(i64, line, 10);
|
return std.fmt.parseInt(i64, line, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readLine() []u8 {
|
|
||||||
const stdin = std.io.getStdIn().reader();
|
|
||||||
return (stdin.readUntilDelimiterOrEof(&line_buf, '\n') catch unreachable) orelse "";
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ comptime {
|
||||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||||
// workaround is present in many host.zig files, so make sure to undo
|
// workaround is present in many host.zig files, so make sure to undo
|
||||||
// it everywhere!
|
// it everywhere!
|
||||||
if (std.builtin.os.tag == .macos) {
|
const builtin = @import("builtin");
|
||||||
|
if (builtin.os.tag == .macos) {
|
||||||
_ = @import("compiler_rt");
|
_ = @import("compiler_rt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,15 +80,15 @@ fn view(input: ConstModel) RocStr {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Align = 2 * @alignOf(usize);
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*align(Align) c_void;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*c_void;
|
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
|
||||||
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
|
||||||
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
|
||||||
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
|
||||||
|
|
||||||
const DEBUG: bool = false;
|
const DEBUG: bool = false;
|
||||||
|
|
||||||
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
var ptr = malloc(size);
|
var ptr = malloc(size);
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
@ -98,7 +99,7 @@ export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*c_void {
|
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
|
||||||
|
@ -107,7 +108,7 @@ export fn roc_realloc(c_ptr: *c_void, new_size: usize, old_size: usize, alignmen
|
||||||
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
return realloc(@alignCast(Align, @ptrCast([*]u8, c_ptr)), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
|
||||||
|
@ -116,7 +117,7 @@ export fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
||||||
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
free(@alignCast(Align, @ptrCast([*]u8, c_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
_ = tag_id;
|
_ = tag_id;
|
||||||
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
@ -136,17 +137,15 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||||
const Unit = extern struct {};
|
const Unit = extern struct {};
|
||||||
|
|
||||||
pub export fn main() callconv(.C) u8 {
|
pub export fn main() callconv(.C) u8 {
|
||||||
const allocator = std.heap.page_allocator;
|
|
||||||
|
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
const program = roc__mainForHost_1_exposed();
|
const program = roc__mainForHost_1_exposed();
|
||||||
|
|
||||||
call_the_closure(program);
|
call_the_closure(program);
|
||||||
|
|
||||||
var ts2: std.os.timespec = undefined;
|
var ts2: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts2) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
|
||||||
|
|
||||||
const delta = to_seconds(ts2) - to_seconds(ts1);
|
const delta = to_seconds(ts2) - to_seconds(ts1);
|
||||||
|
|
||||||
|
@ -161,13 +160,15 @@ fn to_seconds(tms: std.os.timespec) f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_the_closure(program: Program) void {
|
fn call_the_closure(program: Program) void {
|
||||||
const allocator = std.heap.page_allocator;
|
_ = program;
|
||||||
|
|
||||||
|
var allocator = std.heap.page_allocator;
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
const stdin = std.io.getStdIn().reader();
|
const stdin = std.io.getStdIn().reader();
|
||||||
|
|
||||||
var buf: [1000]u8 = undefined;
|
var buf: [1000]u8 = undefined;
|
||||||
|
|
||||||
var model = init(allocator);
|
var model = init(&allocator);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const line = (stdin.readUntilDelimiterOrEof(buf[0..], '\n') catch unreachable) orelse return;
|
const line = (stdin.readUntilDelimiterOrEof(buf[0..], '\n') catch unreachable) orelse return;
|
||||||
|
@ -178,7 +179,7 @@ fn call_the_closure(program: Program) void {
|
||||||
|
|
||||||
const to_append = RocStr.init(line.ptr, line.len);
|
const to_append = RocStr.init(line.ptr, line.len);
|
||||||
|
|
||||||
model = update(allocator, model, to_append);
|
model = update(&allocator, model, to_append);
|
||||||
|
|
||||||
const viewed = view(model);
|
const viewed = view(model);
|
||||||
for (viewed.asSlice()) |char| {
|
for (viewed.asSlice()) |char| {
|
||||||
|
@ -266,8 +267,3 @@ fn roc_fx_getInt_help() !i64 {
|
||||||
|
|
||||||
return std.fmt.parseInt(i64, line, 10);
|
return std.fmt.parseInt(i64, line, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readLine() []u8 {
|
|
||||||
const stdin = std.io.getStdIn().reader();
|
|
||||||
return (stdin.readUntilDelimiterOrEof(&line_buf, '\n') catch unreachable) orelse "";
|
|
||||||
}
|
|
||||||
|
|
10
nix/zig.nix
10
nix/zig.nix
|
@ -1,7 +1,7 @@
|
||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "0.8.1";
|
version = "0.9.1";
|
||||||
|
|
||||||
osName = if pkgs.stdenv.isDarwin then "macos" else "linux";
|
osName = if pkgs.stdenv.isDarwin then "macos" else "linux";
|
||||||
|
|
||||||
|
@ -14,13 +14,13 @@ let
|
||||||
# If your system is not aarch64, we assume it's x86_64
|
# If your system is not aarch64, we assume it's x86_64
|
||||||
sha256 = if pkgs.stdenv.isDarwin then
|
sha256 = if pkgs.stdenv.isDarwin then
|
||||||
if isAarch64 then
|
if isAarch64 then
|
||||||
"5351297e3b8408213514b29c0a938002c5cf9f97eee28c2f32920e1227fd8423" # macos-aarch64
|
"8c473082b4f0f819f1da05de2dbd0c1e891dff7d85d2c12b6ee876887d438287" # macos-aarch64
|
||||||
else
|
else
|
||||||
"16b0e1defe4c1807f2e128f72863124bffdd906cefb21043c34b673bf85cd57f" # macos-x86_64
|
"2d94984972d67292b55c1eb1c00de46580e9916575d083003546e9a01166754c" # macos-x86_64
|
||||||
else if isAarch64 then
|
else if isAarch64 then
|
||||||
"2166dc9f2d8df387e8b4122883bb979d739281e1ff3f3d5483fec3a23b957510" # linux-aarch64
|
"5d99a39cded1870a3fa95d4de4ce68ac2610cca440336cfd252ffdddc2b90e66" # linux-aarch64
|
||||||
else
|
else
|
||||||
"6c032fc61b5d77a3f3cf781730fa549f8f059ffdb3b3f6ad1c2994d2b2d87983"; # linux-x86_64
|
"be8da632c1d3273f766b69244d80669fe4f5e27798654681d77c992f17c237d7"; # linux-x86_64
|
||||||
in pkgs.stdenv.mkDerivation {
|
in pkgs.stdenv.mkDerivation {
|
||||||
pname = "zig";
|
pname = "zig";
|
||||||
version = version;
|
version = version;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use roc_builtins::bitcode;
|
use roc_builtins::bitcode;
|
||||||
|
@ -10,7 +10,8 @@ const PRE_LINKED_BINARY: &str = "data/pre_linked_binary.o";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
println!("cargo:rerun-if-changed=src/{}.c", PLATFORM_FILENAME);
|
let source_path = format!("src/{}.c", PLATFORM_FILENAME);
|
||||||
|
println!("cargo:rerun-if-changed={}", source_path);
|
||||||
|
|
||||||
// When we build on Netlify, zig is not installed (but also not used,
|
// When we build on Netlify, zig is not installed (but also not used,
|
||||||
// since all we're doing is generating docs), so we can skip the steps
|
// since all we're doing is generating docs), so we can skip the steps
|
||||||
|
@ -23,26 +24,38 @@ fn main() {
|
||||||
|
|
||||||
std::fs::create_dir_all("./data").unwrap();
|
std::fs::create_dir_all("./data").unwrap();
|
||||||
|
|
||||||
// Build a pre-linked binary with platform, builtins and all their libc dependencies
|
// Zig can produce *either* an object containing relocations OR an object containing libc code
|
||||||
// This builds a library file that exports all symbols. It has no linker data but we don't need it.
|
// But we want both, so we have to compile twice with different flags, then link them
|
||||||
// See discussion with Luuk de Gram (Zig contributor)
|
|
||||||
// https://github.com/rtfeldman/roc/pull/2181#pullrequestreview-839608063
|
// Create an object file with relocations
|
||||||
let args = [
|
let out_dir = env::var("OUT_DIR").unwrap();
|
||||||
"build-lib",
|
let platform_obj = build_wasm_platform(&out_dir, &source_path);
|
||||||
"-target",
|
|
||||||
"wasm32-wasi",
|
// Compile again to get libc path
|
||||||
"-lc",
|
let (libc_archive, compiler_rt_obj) = build_wasm_libc_compilerrt(&out_dir, &source_path);
|
||||||
"-dynamic", // -dynamic ensures libc code goes into the binary
|
let mut libc_pathbuf = PathBuf::from(&libc_archive);
|
||||||
|
libc_pathbuf.pop();
|
||||||
|
let libc_dir = libc_pathbuf.to_str().unwrap();
|
||||||
|
|
||||||
|
let args = &[
|
||||||
|
"wasm-ld",
|
||||||
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
||||||
&format!("src/{}.c", PLATFORM_FILENAME),
|
&platform_obj,
|
||||||
&format!("-femit-bin={}", PRE_LINKED_BINARY),
|
&compiler_rt_obj,
|
||||||
|
"-L",
|
||||||
|
libc_dir,
|
||||||
|
"-lc",
|
||||||
|
"-o",
|
||||||
|
PRE_LINKED_BINARY,
|
||||||
|
"--export-all",
|
||||||
|
"--no-entry",
|
||||||
];
|
];
|
||||||
|
|
||||||
let zig = zig_executable();
|
let zig = zig_executable();
|
||||||
|
|
||||||
// println!("{} {}", zig, args.join(" "));
|
// println!("{} {}", zig, args.join(" "));
|
||||||
|
|
||||||
run_command(Path::new("."), &zig, args);
|
run_command(&zig, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zig_executable() -> String {
|
fn zig_executable() -> String {
|
||||||
|
@ -52,26 +65,77 @@ fn zig_executable() -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command<S, I, P: AsRef<Path>>(path: P, command_str: &str, args: I) -> String
|
fn build_wasm_platform(out_dir: &str, source_path: &str) -> String {
|
||||||
where
|
let platform_obj = format!("{}/{}.o", out_dir, PLATFORM_FILENAME);
|
||||||
I: IntoIterator<Item = S>,
|
|
||||||
S: AsRef<OsStr>,
|
run_command(
|
||||||
{
|
&zig_executable(),
|
||||||
|
&[
|
||||||
|
"build-lib",
|
||||||
|
"-target",
|
||||||
|
"wasm32-wasi",
|
||||||
|
"-lc",
|
||||||
|
source_path,
|
||||||
|
&format!("-femit-bin={}", &platform_obj),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
platform_obj
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_wasm_libc_compilerrt(out_dir: &str, source_path: &str) -> (String, String) {
|
||||||
|
let zig_cache_dir = format!("{}/zig-cache-wasm32", out_dir);
|
||||||
|
|
||||||
|
run_command(
|
||||||
|
&zig_executable(),
|
||||||
|
&[
|
||||||
|
"build-lib",
|
||||||
|
"-dynamic", // ensure libc code is actually generated (not just linked against header)
|
||||||
|
"-target",
|
||||||
|
"wasm32-wasi",
|
||||||
|
"-lc",
|
||||||
|
source_path,
|
||||||
|
"-femit-bin=/dev/null",
|
||||||
|
"--global-cache-dir",
|
||||||
|
&zig_cache_dir,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
(
|
||||||
|
run_command("find", &[&zig_cache_dir, "-name", "libc.a"]),
|
||||||
|
run_command("find", &[&zig_cache_dir, "-name", "compiler_rt.o"]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_command(command_str: &str, args: &[&str]) -> String {
|
||||||
let output_result = Command::new(OsStr::new(&command_str))
|
let output_result = Command::new(OsStr::new(&command_str))
|
||||||
.current_dir(path)
|
.current_dir(Path::new("."))
|
||||||
.args(args)
|
.args(args)
|
||||||
.output();
|
.output();
|
||||||
|
|
||||||
|
let fail = |err: String| {
|
||||||
|
panic!(
|
||||||
|
"\n\nFailed command:\n\t{} {}\n\n{}",
|
||||||
|
command_str,
|
||||||
|
args.join(" "),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
match output_result {
|
match output_result {
|
||||||
Ok(output) => match output.status.success() {
|
Ok(output) => match output.status.success() {
|
||||||
true => std::str::from_utf8(&output.stdout).unwrap().to_string(),
|
true => std::str::from_utf8(&output.stdout)
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.to_string(),
|
||||||
false => {
|
false => {
|
||||||
let error_str = match std::str::from_utf8(&output.stderr) {
|
let error_str = match std::str::from_utf8(&output.stderr) {
|
||||||
Ok(stderr) => stderr.to_string(),
|
Ok(stderr) => stderr.to_string(),
|
||||||
Err(_) => format!("Failed to run \"{}\"", command_str),
|
Err(_) => format!("Failed to run \"{}\"", command_str),
|
||||||
};
|
};
|
||||||
panic!("{} failed: {}", command_str, error_str);
|
fail(error_str)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(reason) => panic!("{} failed: {}", command_str, reason),
|
Err(reason) => fail(reason.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ let
|
||||||
alsa-lib
|
alsa-lib
|
||||||
];
|
];
|
||||||
|
|
||||||
llvmPkgs = pkgs.llvmPackages_12;
|
llvmPkgs = pkgs.llvmPackages_13;
|
||||||
|
|
||||||
zig = import ./nix/zig.nix { inherit pkgs; };
|
zig = import ./nix/zig.nix { inherit pkgs; };
|
||||||
debugir = import ./nix/debugir.nix { inherit pkgs; };
|
debugir = import ./nix/debugir.nix { inherit pkgs; };
|
||||||
|
@ -78,7 +78,7 @@ in pkgs.mkShell {
|
||||||
buildInputs = inputs ++ darwinInputs ++ linuxInputs;
|
buildInputs = inputs ++ darwinInputs ++ linuxInputs;
|
||||||
|
|
||||||
# Additional Env vars
|
# Additional Env vars
|
||||||
LLVM_SYS_120_PREFIX = "${llvmPkgs.llvm.dev}";
|
LLVM_SYS_130_PREFIX = "${llvmPkgs.llvm.dev}";
|
||||||
NIX_GLIBC_PATH =
|
NIX_GLIBC_PATH =
|
||||||
if pkgs.stdenv.isLinux then "${pkgs.glibc_multi.out}/lib" else "";
|
if pkgs.stdenv.isLinux then "${pkgs.glibc_multi.out}/lib" else "";
|
||||||
LD_LIBRARY_PATH = with pkgs;
|
LD_LIBRARY_PATH = with pkgs;
|
||||||
|
|
2
vendor/inkwell/Cargo.toml
vendored
2
vendor/inkwell/Cargo.toml
vendored
|
@ -23,7 +23,7 @@ edition = "2018"
|
||||||
# commit of TheDan64/inkwell, push a new tag which points to the latest commit,
|
# commit of TheDan64/inkwell, push a new tag which points to the latest commit,
|
||||||
# change the tag value in this Cargo.toml to point to that tag, and `cargo update`.
|
# change the tag value in this Cargo.toml to point to that tag, and `cargo update`.
|
||||||
# This way, GitHub Actions works and nobody's builds get broken.
|
# This way, GitHub Actions works and nobody's builds get broken.
|
||||||
inkwell = { git = "https://github.com/rtfeldman/inkwell", branch = "master", features = [ "llvm12-0" ] }
|
inkwell = { git = "https://github.com/rtfeldman/inkwell", branch = "master", features = [ "llvm13-0" ] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
target-arm = []
|
target-arm = []
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue