rustc: Add a #[wasm_import_module]
attribute
This commit adds a new attribute to the Rust compiler specific to the wasm target (and no other targets). The `#[wasm_import_module]` attribute is used to specify the module that a name is imported from, and is used like so: #[wasm_import_module = "./foo.js"] extern { fn some_js_function(); } Here the import of the symbol `some_js_function` is tagged with the `./foo.js` module in the wasm output file. Wasm-the-format includes two fields on all imports, a module and a field. The field is the symbol name (`some_js_function` above) and the module has historically unconditionally been `"env"`. I'm not sure if this `"env"` convention has asm.js or LLVM roots, but regardless we'd like the ability to configure it! The proposed ES module integration with wasm (aka a wasm module is "just another ES module") requires that the import module of wasm imports is interpreted as an ES module import, meaning that you'll need to encode paths, NPM packages, etc. As a result, we'll need this to be something other than `"env"`! Unfortunately neither our version of LLVM nor LLD supports custom import modules (aka anything not `"env"`). My hope is that by the time LLVM 7 is released both will have support, but in the meantime this commit adds some primitive encoding/decoding of wasm files to the compiler. This way rustc postprocesses the wasm module that LLVM emits to ensure it's got all the imports we'd like to have in it. Eventually I'd ideally like to unconditionally require this attribute to be placed on all `extern { ... }` blocks. For now though it seemed prudent to add it as an unstable attribute, so for now it's not required (as that'd force usage of a feature gate). Hopefully it doesn't take too long to "stabilize" this! cc rust-lang-nursery/rust-wasm#29
This commit is contained in:
parent
7df6f4161c
commit
d889957dab
33 changed files with 662 additions and 84 deletions
|
@ -26,6 +26,7 @@ enum Target {
|
|||
Union,
|
||||
Enum,
|
||||
Const,
|
||||
ForeignMod,
|
||||
Other,
|
||||
}
|
||||
|
||||
|
@ -37,6 +38,7 @@ impl Target {
|
|||
hir::ItemUnion(..) => Target::Union,
|
||||
hir::ItemEnum(..) => Target::Enum,
|
||||
hir::ItemConst(..) => Target::Const,
|
||||
hir::ItemForeignMod(..) => Target::ForeignMod,
|
||||
_ => Target::Other,
|
||||
}
|
||||
}
|
||||
|
@ -57,25 +59,42 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||
.emit();
|
||||
}
|
||||
|
||||
let mut has_wasm_import_module = false;
|
||||
for attr in &item.attrs {
|
||||
if let Some(name) = attr.name() {
|
||||
if name == "inline" {
|
||||
self.check_inline(attr, item, target)
|
||||
if attr.check_name("inline") {
|
||||
self.check_inline(attr, item, target)
|
||||
} else if attr.check_name("wasm_import_module") {
|
||||
has_wasm_import_module = true;
|
||||
if attr.value_str().is_none() {
|
||||
self.tcx.sess.span_err(attr.span, "\
|
||||
must be of the form #[wasm_import_module = \"...\"]");
|
||||
}
|
||||
if target != Target::ForeignMod {
|
||||
self.tcx.sess.span_err(attr.span, "\
|
||||
must only be attached to foreign modules");
|
||||
}
|
||||
} else if attr.check_name("wasm_custom_section") {
|
||||
if target != Target::Const {
|
||||
self.tcx.sess.span_err(attr.span, "only allowed on consts");
|
||||
}
|
||||
|
||||
if name == "wasm_custom_section" {
|
||||
if target != Target::Const {
|
||||
self.tcx.sess.span_err(attr.span, "only allowed on consts");
|
||||
}
|
||||
|
||||
if attr.value_str().is_none() {
|
||||
self.tcx.sess.span_err(attr.span, "must be of the form \
|
||||
#[wasm_custom_section = \"foo\"]");
|
||||
}
|
||||
if attr.value_str().is_none() {
|
||||
self.tcx.sess.span_err(attr.span, "must be of the form \
|
||||
#[wasm_custom_section = \"foo\"]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if target == Target::ForeignMod &&
|
||||
!has_wasm_import_module &&
|
||||
self.tcx.sess.target.target.arch == "wasm32" &&
|
||||
false // FIXME: eventually enable this warning when stable
|
||||
{
|
||||
self.tcx.sess.span_warn(item.span, "\
|
||||
must have a #[wasm_import_module = \"...\"] attribute, this \
|
||||
will become a hard error before too long");
|
||||
}
|
||||
|
||||
self.check_repr(item, target);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue