Skip to content

Use shared temporary buffer for WASI out values #2059

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions std/assembly/bindings/wasi.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export * from "./wasi_snapshot_preview1";

// A WASI-wide reusable temporary buffer to store and work with out values. Must
// be large enough to fit any operation it is used in, i.e. process/writeString.
// @ts-ignore: decorator
@lazy export const tempbuf = memory.data(4 * sizeof<usize>());
56 changes: 27 additions & 29 deletions std/assembly/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ import {
clock_time_get,
clockid,
errnoToString,
fd
} from "bindings/wasi_snapshot_preview1";
fd,
tempbuf
} from "bindings/wasi";

import {
E_INDEXOUTOFRANGE
} from "util/error";

// @ts-ignore: decorator
@lazy const iobuf = memory.data(4 * sizeof<usize>());

export namespace process {

// @ts-ignore: decorator
Expand Down Expand Up @@ -49,24 +47,24 @@ export namespace process {
@lazy export const stderr = changetype<WritableStream>(2);

export function time(): i64 {
var err = clock_time_get(clockid.REALTIME, 1000000, iobuf);
var err = clock_time_get(clockid.REALTIME, 1000000, tempbuf);
if (err) throw new Error(errnoToString(err));
return load<u64>(iobuf) / 1000000;
return load<u64>(tempbuf) / 1000000;
}

export function hrtime(): u64 {
var err = clock_time_get(clockid.MONOTONIC, 0, iobuf);
var err = clock_time_get(clockid.MONOTONIC, 0, tempbuf);
if (err) throw new Error(errnoToString(err));
return load<u64>(iobuf);
return load<u64>(tempbuf);
}
}

function lazyArgv(): string[] {
var err = args_sizes_get(iobuf, iobuf + sizeof<usize>());
var err = args_sizes_get(tempbuf, tempbuf + sizeof<usize>());
if (err) throw new Error(errnoToString(err));
var count = load<usize>(iobuf);
var count = load<usize>(tempbuf);
var ptrsSize = count * sizeof<usize>();
var dataSize = load<usize>(iobuf, sizeof<usize>());
var dataSize = load<usize>(tempbuf, sizeof<usize>());
var bufSize = ptrsSize + dataSize;
var buf = __alloc(bufSize);
err = args_get(buf, buf + ptrsSize);
Expand All @@ -83,11 +81,11 @@ function lazyArgv(): string[] {
}

function lazyEnv(): Map<string,string> {
var err = environ_sizes_get(iobuf, iobuf + 4);
var err = environ_sizes_get(tempbuf, tempbuf + 4);
if (err) throw new Error(errnoToString(err));
var count = load<usize>(iobuf);
var count = load<usize>(tempbuf);
var ptrsSize = count * sizeof<usize>();
var dataSize = load<usize>(iobuf, sizeof<usize>());
var dataSize = load<usize>(tempbuf, sizeof<usize>());
var bufSize = ptrsSize + dataSize;
var buf = __alloc(bufSize);
err = environ_get(buf, buf + ptrsSize);
Expand Down Expand Up @@ -136,18 +134,18 @@ abstract class ReadableStream extends Stream {
if (offset < 0 || <usize>offset > end) {
throw new Error(E_INDEXOUTOFRANGE);
}
store<usize>(iobuf, changetype<usize>(buffer) + offset);
store<usize>(iobuf, end - offset, sizeof<usize>());
var err = fd_read(<u32>changetype<usize>(this), iobuf, 1, iobuf + 2 * sizeof<usize>());
store<usize>(tempbuf, changetype<usize>(buffer) + offset);
store<usize>(tempbuf, end - offset, sizeof<usize>());
var err = fd_read(<u32>changetype<usize>(this), tempbuf, 1, tempbuf + 2 * sizeof<usize>());
if (err) throw new Error(errnoToString(err));
return <i32>load<isize>(iobuf, 2 * sizeof<usize>());
return <i32>load<isize>(tempbuf, 2 * sizeof<usize>());
}
}

function writeBuffer(fd: fd, data: ArrayBuffer): void {
store<usize>(iobuf, changetype<usize>(data));
store<usize>(iobuf, data.byteLength, sizeof<usize>());
var err = fd_write(<u32>fd, iobuf, 1, iobuf + 2 * sizeof<usize>());
store<usize>(tempbuf, changetype<usize>(data));
store<usize>(tempbuf, data.byteLength, sizeof<usize>());
var err = fd_write(<u32>fd, tempbuf, 1, tempbuf + 2 * sizeof<usize>());
if (err) throw new Error(errnoToString(err));
}

Expand All @@ -173,20 +171,20 @@ function writeString(fd: fd, data: string): void {
case 1: { // "\n"
let char1 = <u32>load<u16>(changetype<usize>(data));
if (char1 >= 0x80) break;
store<usize>(iobuf, iobuf + 2 * sizeof<usize>());
store<usize>(iobuf, len, sizeof<usize>());
store<u32>(iobuf, char1 | char2 << 8 | char3 << 16 | char4 << 24, 2 * sizeof<usize>());
let err = fd_write(<u32>fd, iobuf, 1, iobuf + 3 * sizeof<usize>());
store<usize>(tempbuf, tempbuf + 2 * sizeof<usize>());
store<usize>(tempbuf, len, sizeof<usize>());
store<u32>(tempbuf, char1 | char2 << 8 | char3 << 16 | char4 << 24, 2 * sizeof<usize>());
let err = fd_write(<u32>fd, tempbuf, 1, tempbuf + 3 * sizeof<usize>());
if (err) throw new Error(errnoToString(err));
}
case 0: return;
}
var utf8len = <usize>String.UTF8.byteLength(data);
var utf8buf = __alloc(utf8len);
assert(String.UTF8.encodeUnsafe(changetype<usize>(data), len, utf8buf) == utf8len);
store<usize>(iobuf, utf8buf);
store<usize>(iobuf, utf8len, sizeof<usize>());
var err = fd_write(<u32>fd, iobuf, 1, iobuf + 2 * sizeof<usize>());
store<usize>(tempbuf, utf8buf);
store<usize>(tempbuf, utf8len, sizeof<usize>());
var err = fd_write(<u32>fd, tempbuf, 1, tempbuf + 2 * sizeof<usize>());
__free(utf8buf);
if (err) throw new Error(errnoToString(err));
}
9 changes: 4 additions & 5 deletions std/assembly/wasi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
proc_exit,
fd_write,
iovec,
random_get
random_get,
tempbuf
} from "bindings/wasi";

import {
Expand Down Expand Up @@ -108,13 +109,11 @@ function trace( // eslint-disable-line @typescript-eslint/no-unused-vars
}

function seed(): f64 { // eslint-disable-line @typescript-eslint/no-unused-vars
var temp = load<u64>(0);
var rand: u64;
do {
random_get(0, 8); // to be sure
rand = load<u64>(0);
random_get(tempbuf, 8);
rand = load<u64>(tempbuf);
} while (!rand);
store<u64>(0, temp);
return reinterpret<f64>(rand);
}

Expand Down
8 changes: 4 additions & 4 deletions tests/compiler/std-wasi/console.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -2065,7 +2065,7 @@
local.get $0
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 4272
i32.const 180
i32.const 178
i32.const 16
call $~lib/wasi/index/abort
unreachable
Expand Down Expand Up @@ -2168,7 +2168,7 @@
if
i32.const 0
i32.const 4272
i32.const 186
i32.const 184
i32.const 3
call $~lib/wasi/index/abort
unreachable
Expand All @@ -2194,7 +2194,7 @@
local.get $0
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 4272
i32.const 191
i32.const 189
i32.const 12
call $~lib/wasi/index/abort
unreachable
Expand Down Expand Up @@ -3190,7 +3190,7 @@
local.get $0
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 4272
i32.const 59
i32.const 57
i32.const 14
call $~lib/wasi/index/abort
unreachable
Expand Down
34 changes: 17 additions & 17 deletions tests/compiler/std-wasi/console.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
(import "wasi_snapshot_preview1" "proc_exit" (func $~lib/bindings/wasi_snapshot_preview1/proc_exit (param i32)))
(import "wasi_snapshot_preview1" "clock_time_get" (func $~lib/bindings/wasi_snapshot_preview1/clock_time_get (param i32 i64 i32) (result i32)))
(global $~lib/process/process.stderr i32 (i32.const 2))
(global $~lib/process/iobuf i32 (i32.const 112))
(global $~lib/bindings/wasi/tempbuf i32 (i32.const 112))
(global $~argumentsLength (mut i32) (i32.const 0))
(global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0))
(global $~lib/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0))
Expand Down Expand Up @@ -2920,17 +2920,17 @@
if
br $break|0
end
global.get $~lib/process/iobuf
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
global.get $~lib/bindings/wasi/tempbuf
i32.const 2
i32.const 4
i32.mul
i32.add
i32.store
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
local.get $2
i32.store offset=4
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
local.get $6
local.get $3
i32.const 8
Expand All @@ -2946,9 +2946,9 @@
i32.or
i32.store offset=8
local.get $0
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
i32.const 1
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
i32.const 3
i32.const 4
i32.mul
Expand All @@ -2962,7 +2962,7 @@
local.get $7
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 3248
i32.const 180
i32.const 178
i32.const 16
call $~lib/wasi/index/abort
unreachable
Expand Down Expand Up @@ -2991,21 +2991,21 @@
if
i32.const 0
i32.const 3248
i32.const 186
i32.const 184
i32.const 3
call $~lib/wasi/index/abort
unreachable
end
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
local.get $9
i32.store
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
local.get $8
i32.store offset=4
local.get $0
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
i32.const 1
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
i32.const 2
i32.const 4
i32.mul
Expand All @@ -3021,7 +3021,7 @@
local.get $10
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 3248
i32.const 191
i32.const 189
i32.const 12
call $~lib/wasi/index/abort
unreachable
Expand Down Expand Up @@ -4427,7 +4427,7 @@
(local $0 i32)
i32.const 1
i64.const 0
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
call $~lib/bindings/wasi_snapshot_preview1/clock_time_get
local.set $0
local.get $0
Expand All @@ -4437,12 +4437,12 @@
local.get $0
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 3248
i32.const 59
i32.const 57
i32.const 14
call $~lib/wasi/index/abort
unreachable
end
global.get $~lib/process/iobuf
global.get $~lib/bindings/wasi/tempbuf
i64.load
)
(func $~lib/map/MapEntry<~lib/string/String,u64>#set:value (param $0 i32) (param $1 i64)
Expand Down
6 changes: 3 additions & 3 deletions tests/compiler/std-wasi/crypto.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -4340,7 +4340,7 @@
local.get $0
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 6720
i32.const 180
i32.const 178
i32.const 16
call $~lib/wasi/index/abort
unreachable
Expand Down Expand Up @@ -4440,7 +4440,7 @@
if
i32.const 0
i32.const 6720
i32.const 186
i32.const 184
i32.const 3
call $~lib/wasi/index/abort
unreachable
Expand All @@ -4466,7 +4466,7 @@
local.get $0
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
i32.const 6720
i32.const 191
i32.const 189
i32.const 12
call $~lib/wasi/index/abort
unreachable
Expand Down
Loading