]> git.proxmox.com Git - rustc.git/blob - src/librustc_back/target/wasm32_unknown_unknown.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / librustc_back / target / wasm32_unknown_unknown.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // The wasm32-unknown-unknown target is currently a highly experimental version
12 // of a wasm-based target which does *not* use the Emscripten toolchain. Instead
13 // this is a pretty flavorful (aka hacked up) target right now. The definition
14 // and semantics of this target are likely to change and so this shouldn't be
15 // relied on just yet.
16 //
17 // In general everyone is currently waiting on a linker for wasm code. In the
18 // meantime we have no means of actually making use of the traditional separate
19 // compilation model. At a high level this means that assembling Rust programs
20 // into a WebAssembly program looks like:
21 //
22 // 1. All intermediate artifacts are LLVM bytecode. We'll be using LLVM as
23 // a linker later on.
24 // 2. For the final artifact we emit one giant assembly file (WebAssembly
25 // doesn't have an object file format). To do this we force LTO to be turned
26 // on (`requires_lto` below) to ensure all Rust code is in one module. Any
27 // "linked" C library is basically just ignored.
28 // 3. Using LLVM we emit a `foo.s` file (assembly) with some... what I can only
29 // describe as arcane syntax. From there we need to actually change this
30 // into a wasm module. For this step we use the `binaryen` project. This
31 // project is mostly intended as a WebAssembly code generator, but for now
32 // we're just using its LLVM-assembly-to-wasm-module conversion utilities.
33 //
34 // And voila, out comes a web assembly module! There's some various tweaks here
35 // and there, but that's the high level at least. Note that this will be
36 // rethought from the ground up once a linker (lld) is available, so this is all
37 // temporary and should improve in the future.
38
39 use LinkerFlavor;
40 use super::{Target, TargetOptions, PanicStrategy};
41
42 pub fn target() -> Result<Target, String> {
43 let opts = TargetOptions {
44 linker: "not-used".to_string(),
45
46 // we allow dynamic linking, but only cdylibs. Basically we allow a
47 // final library artifact that exports some symbols (a wasm module) but
48 // we don't allow intermediate `dylib` crate types
49 dynamic_linking: true,
50 only_cdylib: true,
51
52 // This means we'll just embed a `start` function in the wasm module
53 executables: true,
54
55 // relatively self-explanatory!
56 exe_suffix: ".wasm".to_string(),
57 dll_prefix: "".to_string(),
58 dll_suffix: ".wasm".to_string(),
59 linker_is_gnu: false,
60
61 // We're storing bitcode for now in all the rlibs
62 obj_is_bitcode: true,
63
64 // A bit of a lie, but "eh"
65 max_atomic_width: Some(32),
66
67 // Unwinding doesn't work right now, so the whole target unconditionally
68 // defaults to panic=abort. Note that this is guaranteed to change in
69 // the future once unwinding is implemented. Don't rely on this.
70 panic_strategy: PanicStrategy::Abort,
71
72 // There's no linker yet so we're forced to use LLVM as a linker. This
73 // means that we must always enable LTO for final artifacts.
74 requires_lto: true,
75
76 // Wasm doesn't have atomics yet, so tell LLVM that we're in a single
77 // threaded model which will legalize atomics to normal operations.
78 singlethread: true,
79
80 // Because we're always enabling LTO we can't enable builtin lowering as
81 // otherwise we'll lower the definition of the `memcpy` function to
82 // memcpy itself. Note that this is specifically because we're
83 // performing LTO with compiler-builtins.
84 no_builtins: true,
85
86 .. Default::default()
87 };
88 Ok(Target {
89 llvm_target: "wasm32-unknown-unknown".to_string(),
90 target_endian: "little".to_string(),
91 target_pointer_width: "32".to_string(),
92 target_c_int_width: "32".to_string(),
93 // This is basically guaranteed to change in the future, don't rely on
94 // this. Use `not(target_os = "emscripten")` for now.
95 target_os: "unknown".to_string(),
96 target_env: "".to_string(),
97 target_vendor: "unknown".to_string(),
98 data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
99 arch: "wasm32".to_string(),
100 // A bit of a lie, but it gets the job done
101 linker_flavor: LinkerFlavor::Binaryen,
102 options: opts,
103 })
104 }