]> git.lizzy.rs Git - rust.git/blob - src/librustc_binaryen/lib.rs
Add an unstable FileTypeExt extension trait for Windows
[rust.git] / src / librustc_binaryen / lib.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 //! Rustc bindings to the binaryen project.
12 //!
13 //! This crate is a small shim around the binaryen project which provides us the
14 //! ability to take LLVM's output and generate a wasm module. Specifically this
15 //! only supports one operation, creating a module from LLVM's assembly format
16 //! and then serializing that module to a wasm module.
17
18 extern crate libc;
19
20 use std::slice;
21 use std::ffi::{CString, CStr};
22
23 /// In-memory representation of a serialized wasm module.
24 pub struct Module {
25     ptr: *mut BinaryenRustModule,
26 }
27
28 impl Module {
29     /// Creates a new wasm module from the LLVM-assembly provided (in a C string
30     /// format).
31     ///
32     /// The actual module creation can be tweaked through the various options in
33     /// `ModuleOptions` as well. Any errors are just returned as a bland string.
34     pub fn new(assembly: &CStr, opts: &ModuleOptions) -> Result<Module, String> {
35         unsafe {
36             let ptr = BinaryenRustModuleCreate(opts.ptr, assembly.as_ptr());
37             if ptr.is_null() {
38                 Err(format!("failed to create binaryen module"))
39             } else {
40                 Ok(Module { ptr })
41             }
42         }
43     }
44
45     /// Returns the data of the serialized wasm module. This is a `foo.wasm`
46     /// file contents.
47     pub fn data(&self) -> &[u8] {
48         unsafe {
49             let ptr = BinaryenRustModulePtr(self.ptr);
50             let len = BinaryenRustModuleLen(self.ptr);
51             slice::from_raw_parts(ptr, len)
52         }
53     }
54 }
55
56 impl Drop for Module {
57     fn drop(&mut self) {
58         unsafe {
59             BinaryenRustModuleFree(self.ptr);
60         }
61     }
62 }
63
64 pub struct ModuleOptions {
65     ptr: *mut BinaryenRustModuleOptions,
66 }
67
68 impl ModuleOptions {
69     pub fn new() -> ModuleOptions {
70         unsafe {
71             let ptr = BinaryenRustModuleOptionsCreate();
72             ModuleOptions { ptr }
73         }
74     }
75
76     /// Turns on or off debug info.
77     ///
78     /// From what I can tell this just creates a "names" section of the wasm
79     /// module which contains a table of the original function names.
80     pub fn debuginfo(&mut self, debug: bool) -> &mut Self {
81         unsafe {
82             BinaryenRustModuleOptionsSetDebugInfo(self.ptr, debug);
83         }
84         self
85     }
86
87     /// Configures a `start` function for the module, to be executed when it's
88     /// loaded.
89     pub fn start(&mut self, func: &str) -> &mut Self {
90         let func = CString::new(func).unwrap();
91         unsafe {
92             BinaryenRustModuleOptionsSetStart(self.ptr, func.as_ptr());
93         }
94         self
95     }
96
97     /// Configures how much stack is initially allocated for the module. 1MB is
98     /// probably good enough for now.
99     pub fn stack(&mut self, amt: u64) -> &mut Self {
100         unsafe {
101             BinaryenRustModuleOptionsSetStackAllocation(self.ptr, amt);
102         }
103         self
104     }
105
106     /// Flags whether the initial memory should be imported or exported. So far
107     /// we export it by default.
108     pub fn import_memory(&mut self, import: bool) -> &mut Self {
109         unsafe {
110             BinaryenRustModuleOptionsSetImportMemory(self.ptr, import);
111         }
112         self
113     }
114 }
115
116 impl Drop for ModuleOptions {
117     fn drop(&mut self) {
118         unsafe {
119             BinaryenRustModuleOptionsFree(self.ptr);
120         }
121     }
122 }
123
124 enum BinaryenRustModule {}
125 enum BinaryenRustModuleOptions {}
126
127 extern {
128     fn BinaryenRustModuleCreate(opts: *const BinaryenRustModuleOptions,
129                                 assembly: *const libc::c_char)
130         -> *mut BinaryenRustModule;
131     fn BinaryenRustModulePtr(module: *const BinaryenRustModule) -> *const u8;
132     fn BinaryenRustModuleLen(module: *const BinaryenRustModule) -> usize;
133     fn BinaryenRustModuleFree(module: *mut BinaryenRustModule);
134
135     fn BinaryenRustModuleOptionsCreate()
136         -> *mut BinaryenRustModuleOptions;
137     fn BinaryenRustModuleOptionsSetDebugInfo(module: *mut BinaryenRustModuleOptions,
138                                              debuginfo: bool);
139     fn BinaryenRustModuleOptionsSetStart(module: *mut BinaryenRustModuleOptions,
140                                          start: *const libc::c_char);
141     fn BinaryenRustModuleOptionsSetStackAllocation(
142         module: *mut BinaryenRustModuleOptions,
143         stack: u64,
144     );
145     fn BinaryenRustModuleOptionsSetImportMemory(
146         module: *mut BinaryenRustModuleOptions,
147         import: bool,
148     );
149     fn BinaryenRustModuleOptionsFree(module: *mut BinaryenRustModuleOptions);
150 }