Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8fe65da

Browse files
committedAug 28, 2019
std: Remove the wasm_syscall feature
This commit removes the `wasm_syscall` feature from the wasm32-unknown-unknown build of the standard library. This feature was originally intended to allow an opt-in way to interact with the operating system in a posix-like way but it was never stabilized. Nowadays with the advent of the `wasm32-wasi` target that should entirely replace the intentions of the `wasm_syscall` feature.
1 parent ac21131 commit 8fe65da

File tree

11 files changed

+19
-379
lines changed

11 files changed

+19
-379
lines changed
 

‎config.toml.example

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,6 @@
382382
# This is the name of the directory in which codegen backends will get installed
383383
#codegen-backends-dir = "codegen-backends"
384384

385-
# Flag indicating whether `libstd` calls an imported function to handle basic IO
386-
# when targeting WebAssembly. Enable this to debug tests for the `wasm32-unknown-unknown`
387-
# target, as without this option the test output will not be captured.
388-
#wasm-syscall = false
389-
390385
# Indicates whether LLD will be compiled and made available in the sysroot for
391386
# rustc to execute.
392387
#lld = false

‎src/bootstrap/config.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ pub struct Config {
122122

123123
// libstd features
124124
pub backtrace: bool, // support for RUST_BACKTRACE
125-
pub wasm_syscall: bool,
126125

127126
// misc
128127
pub low_priority: bool,
@@ -318,7 +317,6 @@ struct Rust {
318317
save_toolstates: Option<String>,
319318
codegen_backends: Option<Vec<String>>,
320319
codegen_backends_dir: Option<String>,
321-
wasm_syscall: Option<bool>,
322320
lld: Option<bool>,
323321
lldb: Option<bool>,
324322
llvm_tools: Option<bool>,
@@ -558,7 +556,6 @@ impl Config {
558556
if let Some(true) = rust.incremental {
559557
config.incremental = true;
560558
}
561-
set(&mut config.wasm_syscall, rust.wasm_syscall);
562559
set(&mut config.lld_enabled, rust.lld);
563560
set(&mut config.lldb_enabled, rust.lldb);
564561
set(&mut config.llvm_tools_enabled, rust.llvm_tools);

‎src/bootstrap/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,6 @@ impl Build {
498498
if self.config.profiler {
499499
features.push_str(" profiler");
500500
}
501-
if self.config.wasm_syscall {
502-
features.push_str(" wasm_syscall");
503-
}
504501
features
505502
}
506503

‎src/bootstrap/test.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,16 +1811,6 @@ impl Step for Crate {
18111811
.expect("nodejs not configured"),
18121812
);
18131813
} else if target.starts_with("wasm32") {
1814-
// Warn about running tests without the `wasm_syscall` feature enabled.
1815-
// The javascript shim implements the syscall interface so that test
1816-
// output can be correctly reported.
1817-
if !builder.config.wasm_syscall {
1818-
builder.info(
1819-
"Libstd was built without `wasm_syscall` feature enabled: \
1820-
test output may not be visible."
1821-
);
1822-
}
1823-
18241814
// On the wasm32-unknown-unknown target we're using LTO which is
18251815
// incompatible with `-C prefer-dynamic`, so disable that here
18261816
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");

‎src/etc/wasm32-shim.js

Lines changed: 1 addition & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -15,113 +15,7 @@ const buffer = fs.readFileSync(process.argv[2]);
1515
Error.stackTraceLimit = 20;
1616

1717
let m = new WebAssembly.Module(buffer);
18-
19-
let memory = null;
20-
21-
function viewstruct(data, fields) {
22-
return new Uint32Array(memory.buffer).subarray(data/4, data/4 + fields);
23-
}
24-
25-
function copystr(a, b) {
26-
let view = new Uint8Array(memory.buffer).subarray(a, a + b);
27-
return String.fromCharCode.apply(null, view);
28-
}
29-
30-
function syscall_write([fd, ptr, len]) {
31-
let s = copystr(ptr, len);
32-
switch (fd) {
33-
case 1: process.stdout.write(s); break;
34-
case 2: process.stderr.write(s); break;
35-
}
36-
}
37-
38-
function syscall_exit([code]) {
39-
process.exit(code);
40-
}
41-
42-
function syscall_args(params) {
43-
let [ptr, len] = params;
44-
45-
// Calculate total required buffer size
46-
let totalLen = -1;
47-
for (let i = 2; i < process.argv.length; ++i) {
48-
totalLen += Buffer.byteLength(process.argv[i]) + 1;
49-
}
50-
if (totalLen < 0) { totalLen = 0; }
51-
params[2] = totalLen;
52-
53-
// If buffer is large enough, copy data
54-
if (len >= totalLen) {
55-
let view = new Uint8Array(memory.buffer);
56-
for (let i = 2; i < process.argv.length; ++i) {
57-
let value = process.argv[i];
58-
Buffer.from(value).copy(view, ptr);
59-
ptr += Buffer.byteLength(process.argv[i]) + 1;
60-
}
61-
}
62-
}
63-
64-
function syscall_getenv(params) {
65-
let [keyPtr, keyLen, valuePtr, valueLen] = params;
66-
67-
let key = copystr(keyPtr, keyLen);
68-
let value = process.env[key];
69-
70-
if (value == null) {
71-
params[4] = 0xFFFFFFFF;
72-
} else {
73-
let view = new Uint8Array(memory.buffer);
74-
let totalLen = Buffer.byteLength(value);
75-
params[4] = totalLen;
76-
if (valueLen >= totalLen) {
77-
Buffer.from(value).copy(view, valuePtr);
78-
}
79-
}
80-
}
81-
82-
function syscall_time(params) {
83-
let t = Date.now();
84-
let secs = Math.floor(t / 1000);
85-
let millis = t % 1000;
86-
params[1] = Math.floor(secs / 0x100000000);
87-
params[2] = secs % 0x100000000;
88-
params[3] = Math.floor(millis * 1000000);
89-
}
90-
91-
let imports = {};
92-
imports.env = {
93-
// These are generated by LLVM itself for various intrinsic calls. Hopefully
94-
// one day this is not necessary and something will automatically do this.
95-
fmod: function(x, y) { return x % y; },
96-
exp2: function(x) { return Math.pow(2, x); },
97-
exp2f: function(x) { return Math.pow(2, x); },
98-
ldexp: function(x, y) { return x * Math.pow(2, y); },
99-
ldexpf: function(x, y) { return x * Math.pow(2, y); },
100-
sin: Math.sin,
101-
sinf: Math.sin,
102-
cos: Math.cos,
103-
cosf: Math.cos,
104-
log: Math.log,
105-
log2: Math.log2,
106-
log10: Math.log10,
107-
log10f: Math.log10,
108-
109-
rust_wasm_syscall: function(index, data) {
110-
switch (index) {
111-
case 1: syscall_write(viewstruct(data, 3)); return true;
112-
case 2: syscall_exit(viewstruct(data, 1)); return true;
113-
case 3: syscall_args(viewstruct(data, 3)); return true;
114-
case 4: syscall_getenv(viewstruct(data, 5)); return true;
115-
case 6: syscall_time(viewstruct(data, 4)); return true;
116-
default:
117-
console.log("Unsupported syscall: " + index);
118-
return false;
119-
}
120-
}
121-
};
122-
123-
let instance = new WebAssembly.Instance(m, imports);
124-
memory = instance.exports.memory;
18+
let instance = new WebAssembly.Instance(m, {});
12519
try {
12620
instance.exports.main();
12721
} catch (e) {

‎src/libstd/Cargo.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ llvm-libunwind = ["unwind/llvm-libunwind"]
7070
# Make panics and failed asserts immediately abort without formatting any message
7171
panic_immediate_abort = ["core/panic_immediate_abort"]
7272

73-
# An off-by-default feature which enables a linux-syscall-like ABI for libstd to
74-
# interoperate with the host environment. Currently not well documented and
75-
# requires rebuilding the standard library to use it.
76-
wasm_syscall = []
77-
7873
# Enable std_detect default features for stdarch/crates/std_detect:
7974
# https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml
8075
std_detect_file_io = []

‎src/libstd/sys/wasm/args.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::ffi::OsString;
22
use crate::marker::PhantomData;
33
use crate::vec;
4-
use crate::sys::ArgsSysCall;
54

65
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
76
// On wasm these should always be null, so there's nothing for us to do here
@@ -11,9 +10,8 @@ pub unsafe fn cleanup() {
1110
}
1211

1312
pub fn args() -> Args {
14-
let v = ArgsSysCall::perform();
1513
Args {
16-
iter: v.into_iter(),
14+
iter: Vec::new().into_iter(),
1715
_dont_send_or_sync_me: PhantomData,
1816
}
1917
}

‎src/libstd/sys/wasm/mod.rs

Lines changed: 1 addition & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515
//! guaranteed to be a runtime error!
1616
1717
use crate::os::raw::c_char;
18-
use crate::ptr;
19-
use crate::sys::os_str::Buf;
20-
use crate::sys_common::{AsInner, FromInner};
21-
use crate::ffi::{OsString, OsStr};
22-
use crate::time::Duration;
2318

2419
pub mod alloc;
2520
pub mod args;
@@ -89,7 +84,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
8984
}
9085

9186
pub unsafe fn abort_internal() -> ! {
92-
ExitSysCall::perform(1)
87+
crate::arch::wasm32::unreachable()
9388
}
9489

9590
// We don't have randomness yet, but I totally used a random number generator to
@@ -100,218 +95,3 @@ pub unsafe fn abort_internal() -> ! {
10095
pub fn hashmap_random_keys() -> (u64, u64) {
10196
(1, 2)
10297
}
103-
104-
// Implement a minimal set of system calls to enable basic IO
105-
pub enum SysCallIndex {
106-
Read = 0,
107-
Write = 1,
108-
Exit = 2,
109-
Args = 3,
110-
GetEnv = 4,
111-
SetEnv = 5,
112-
Time = 6,
113-
}
114-
115-
#[repr(C)]
116-
pub struct ReadSysCall {
117-
fd: usize,
118-
ptr: *mut u8,
119-
len: usize,
120-
result: usize,
121-
}
122-
123-
impl ReadSysCall {
124-
pub fn perform(fd: usize, buffer: &mut [u8]) -> usize {
125-
let mut call_record = ReadSysCall {
126-
fd,
127-
len: buffer.len(),
128-
ptr: buffer.as_mut_ptr(),
129-
result: 0
130-
};
131-
if unsafe { syscall(SysCallIndex::Read, &mut call_record) } {
132-
call_record.result
133-
} else {
134-
0
135-
}
136-
}
137-
}
138-
139-
#[repr(C)]
140-
pub struct WriteSysCall {
141-
fd: usize,
142-
ptr: *const u8,
143-
len: usize,
144-
}
145-
146-
impl WriteSysCall {
147-
pub fn perform(fd: usize, buffer: &[u8]) {
148-
let mut call_record = WriteSysCall {
149-
fd,
150-
len: buffer.len(),
151-
ptr: buffer.as_ptr()
152-
};
153-
unsafe { syscall(SysCallIndex::Write, &mut call_record); }
154-
}
155-
}
156-
157-
#[repr(C)]
158-
pub struct ExitSysCall {
159-
code: usize,
160-
}
161-
162-
impl ExitSysCall {
163-
pub fn perform(code: usize) -> ! {
164-
let mut call_record = ExitSysCall {
165-
code
166-
};
167-
unsafe {
168-
syscall(SysCallIndex::Exit, &mut call_record);
169-
crate::intrinsics::abort();
170-
}
171-
}
172-
}
173-
174-
fn receive_buffer<E, F: FnMut(&mut [u8]) -> Result<usize, E>>(estimate: usize, mut f: F)
175-
-> Result<Vec<u8>, E>
176-
{
177-
let mut buffer = vec![0; estimate];
178-
loop {
179-
let result = f(&mut buffer)?;
180-
if result <= buffer.len() {
181-
buffer.truncate(result);
182-
break;
183-
}
184-
buffer.resize(result, 0);
185-
}
186-
Ok(buffer)
187-
}
188-
189-
#[repr(C)]
190-
pub struct ArgsSysCall {
191-
ptr: *mut u8,
192-
len: usize,
193-
result: usize
194-
}
195-
196-
impl ArgsSysCall {
197-
pub fn perform() -> Vec<OsString> {
198-
receive_buffer(1024, |buffer| -> Result<usize, !> {
199-
let mut call_record = ArgsSysCall {
200-
len: buffer.len(),
201-
ptr: buffer.as_mut_ptr(),
202-
result: 0
203-
};
204-
if unsafe { syscall(SysCallIndex::Args, &mut call_record) } {
205-
Ok(call_record.result)
206-
} else {
207-
Ok(0)
208-
}
209-
})
210-
.unwrap()
211-
.split(|b| *b == 0)
212-
.map(|s| FromInner::from_inner(Buf { inner: s.to_owned() }))
213-
.collect()
214-
}
215-
}
216-
217-
#[repr(C)]
218-
pub struct GetEnvSysCall {
219-
key_ptr: *const u8,
220-
key_len: usize,
221-
value_ptr: *mut u8,
222-
value_len: usize,
223-
result: usize
224-
}
225-
226-
impl GetEnvSysCall {
227-
pub fn perform(key: &OsStr) -> Option<OsString> {
228-
let key_buf = &AsInner::as_inner(key).inner;
229-
receive_buffer(64, |buffer| {
230-
let mut call_record = GetEnvSysCall {
231-
key_len: key_buf.len(),
232-
key_ptr: key_buf.as_ptr(),
233-
value_len: buffer.len(),
234-
value_ptr: buffer.as_mut_ptr(),
235-
result: !0usize
236-
};
237-
if unsafe { syscall(SysCallIndex::GetEnv, &mut call_record) } {
238-
if call_record.result == !0usize {
239-
Err(())
240-
} else {
241-
Ok(call_record.result)
242-
}
243-
} else {
244-
Err(())
245-
}
246-
}).ok().map(|s| {
247-
FromInner::from_inner(Buf { inner: s })
248-
})
249-
}
250-
}
251-
252-
#[repr(C)]
253-
pub struct SetEnvSysCall {
254-
key_ptr: *const u8,
255-
key_len: usize,
256-
value_ptr: *const u8,
257-
value_len: usize
258-
}
259-
260-
impl SetEnvSysCall {
261-
pub fn perform(key: &OsStr, value: Option<&OsStr>) {
262-
let key_buf = &AsInner::as_inner(key).inner;
263-
let value_buf = value.map(|v| &AsInner::as_inner(v).inner);
264-
let mut call_record = SetEnvSysCall {
265-
key_len: key_buf.len(),
266-
key_ptr: key_buf.as_ptr(),
267-
value_len: value_buf.map(|v| v.len()).unwrap_or(!0usize),
268-
value_ptr: value_buf.map(|v| v.as_ptr()).unwrap_or(ptr::null())
269-
};
270-
unsafe { syscall(SysCallIndex::SetEnv, &mut call_record); }
271-
}
272-
}
273-
274-
pub enum TimeClock {
275-
Monotonic = 0,
276-
System = 1,
277-
}
278-
279-
#[repr(C)]
280-
pub struct TimeSysCall {
281-
clock: usize,
282-
secs_hi: usize,
283-
secs_lo: usize,
284-
nanos: usize
285-
}
286-
287-
impl TimeSysCall {
288-
pub fn perform(clock: TimeClock) -> Duration {
289-
let mut call_record = TimeSysCall {
290-
clock: clock as usize,
291-
secs_hi: 0,
292-
secs_lo: 0,
293-
nanos: 0
294-
};
295-
if unsafe { syscall(SysCallIndex::Time, &mut call_record) } {
296-
Duration::new(
297-
((call_record.secs_hi as u64) << 32) | (call_record.secs_lo as u64),
298-
call_record.nanos as u32
299-
)
300-
} else {
301-
panic!("Time system call is not implemented by WebAssembly host");
302-
}
303-
}
304-
}
305-
306-
unsafe fn syscall<T>(index: SysCallIndex, data: &mut T) -> bool {
307-
#[cfg(feature = "wasm_syscall")]
308-
extern {
309-
#[no_mangle]
310-
fn rust_wasm_syscall(index: usize, data: *mut Void) -> usize;
311-
}
312-
313-
#[cfg(not(feature = "wasm_syscall"))]
314-
unsafe fn rust_wasm_syscall(_index: usize, _data: *mut Void) -> usize { 0 }
315-
316-
rust_wasm_syscall(index as usize, data as *mut T as *mut Void) != 0
317-
}

‎src/libstd/sys/wasm/os.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::fmt;
44
use crate::io;
55
use crate::path::{self, PathBuf};
66
use crate::str;
7-
use crate::sys::{unsupported, Void, ExitSysCall, GetEnvSysCall, SetEnvSysCall};
7+
use crate::sys::{unsupported, Void};
88

99
pub fn errno() -> i32 {
1010
0
@@ -73,16 +73,16 @@ pub fn env() -> Env {
7373
panic!("not supported on web assembly")
7474
}
7575

76-
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
77-
Ok(GetEnvSysCall::perform(k))
76+
pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
77+
Ok(None)
7878
}
7979

80-
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
81-
Ok(SetEnvSysCall::perform(k, Some(v)))
80+
pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
81+
Err(io::Error::new(io::ErrorKind::Other, "cannot set env vars on wasm32-unknown-unknown"))
8282
}
8383

84-
pub fn unsetenv(k: &OsStr) -> io::Result<()> {
85-
Ok(SetEnvSysCall::perform(k, None))
84+
pub fn unsetenv(_: &OsStr) -> io::Result<()> {
85+
Err(io::Error::new(io::ErrorKind::Other, "cannot unset env vars on wasm32-unknown-unknown"))
8686
}
8787

8888
pub fn temp_dir() -> PathBuf {
@@ -94,7 +94,9 @@ pub fn home_dir() -> Option<PathBuf> {
9494
}
9595

9696
pub fn exit(_code: i32) -> ! {
97-
ExitSysCall::perform(_code as isize as usize)
97+
unsafe {
98+
crate::arch::wasm32::unreachable();
99+
}
98100
}
99101

100102
pub fn getpid() -> u32 {

‎src/libstd/sys/wasm/stdio.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::io;
2-
use crate::sys::{ReadSysCall, WriteSysCall};
32

43
pub struct Stdin;
54
pub struct Stdout;
@@ -12,8 +11,8 @@ impl Stdin {
1211
}
1312

1413
impl io::Read for Stdin {
15-
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
16-
Ok(ReadSysCall::perform(0, buf))
14+
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
15+
Ok(0)
1716
}
1817
}
1918

@@ -25,7 +24,6 @@ impl Stdout {
2524

2625
impl io::Write for Stdout {
2726
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
28-
WriteSysCall::perform(1, buf);
2927
Ok(buf.len())
3028
}
3129

@@ -42,7 +40,6 @@ impl Stderr {
4240

4341
impl io::Write for Stderr {
4442
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
45-
WriteSysCall::perform(2, buf);
4643
Ok(buf.len())
4744
}
4845

@@ -57,10 +54,6 @@ pub fn is_ebadf(_err: &io::Error) -> bool {
5754
true
5855
}
5956

60-
pub fn panic_output() -> Option<impl io::Write> {
61-
if cfg!(feature = "wasm_syscall") {
62-
Stderr::new().ok()
63-
} else {
64-
None
65-
}
57+
pub fn panic_output() -> Option<Vec<u8>> {
58+
None
6659
}

‎src/libstd/sys/wasm/time.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::time::Duration;
2-
use crate::sys::{TimeSysCall, TimeClock};
32

43
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
54
pub struct Instant(Duration);
@@ -11,7 +10,7 @@ pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
1110

1211
impl Instant {
1312
pub fn now() -> Instant {
14-
Instant(TimeSysCall::perform(TimeClock::Monotonic))
13+
panic!("time not implemented on wasm32-unknown-unknown")
1514
}
1615

1716
pub const fn zero() -> Instant {
@@ -37,7 +36,7 @@ impl Instant {
3736

3837
impl SystemTime {
3938
pub fn now() -> SystemTime {
40-
SystemTime(TimeSysCall::perform(TimeClock::System))
39+
panic!("time not implemented on wasm32-unknown-unknown")
4140
}
4241

4342
pub fn sub_time(&self, other: &SystemTime)

0 commit comments

Comments
 (0)
Please sign in to comment.