Skip to content

Commit fe06a2f

Browse files
authored
fix: Use shared temporary buffer for WASI out values (#2059)
1 parent 5dce4e4 commit fe06a2f

11 files changed

+149
-158
lines changed

std/assembly/bindings/wasi.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
export * from "./wasi_snapshot_preview1";
2+
3+
// A WASI-wide reusable temporary buffer to store and work with out values. Must
4+
// be large enough to fit any operation it is used in, i.e. process/writeString.
5+
// @ts-ignore: decorator
6+
@lazy export const tempbuf = memory.data(4 * sizeof<usize>());

std/assembly/process.ts

+27-29
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ import {
1010
clock_time_get,
1111
clockid,
1212
errnoToString,
13-
fd
14-
} from "bindings/wasi_snapshot_preview1";
13+
fd,
14+
tempbuf
15+
} from "bindings/wasi";
1516

1617
import {
1718
E_INDEXOUTOFRANGE
1819
} from "util/error";
1920

20-
// @ts-ignore: decorator
21-
@lazy const iobuf = memory.data(4 * sizeof<usize>());
22-
2321
export namespace process {
2422

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

5149
export function time(): i64 {
52-
var err = clock_time_get(clockid.REALTIME, 1000000, iobuf);
50+
var err = clock_time_get(clockid.REALTIME, 1000000, tempbuf);
5351
if (err) throw new Error(errnoToString(err));
54-
return load<u64>(iobuf) / 1000000;
52+
return load<u64>(tempbuf) / 1000000;
5553
}
5654

5755
export function hrtime(): u64 {
58-
var err = clock_time_get(clockid.MONOTONIC, 0, iobuf);
56+
var err = clock_time_get(clockid.MONOTONIC, 0, tempbuf);
5957
if (err) throw new Error(errnoToString(err));
60-
return load<u64>(iobuf);
58+
return load<u64>(tempbuf);
6159
}
6260
}
6361

6462
function lazyArgv(): string[] {
65-
var err = args_sizes_get(iobuf, iobuf + sizeof<usize>());
63+
var err = args_sizes_get(tempbuf, tempbuf + sizeof<usize>());
6664
if (err) throw new Error(errnoToString(err));
67-
var count = load<usize>(iobuf);
65+
var count = load<usize>(tempbuf);
6866
var ptrsSize = count * sizeof<usize>();
69-
var dataSize = load<usize>(iobuf, sizeof<usize>());
67+
var dataSize = load<usize>(tempbuf, sizeof<usize>());
7068
var bufSize = ptrsSize + dataSize;
7169
var buf = __alloc(bufSize);
7270
err = args_get(buf, buf + ptrsSize);
@@ -83,11 +81,11 @@ function lazyArgv(): string[] {
8381
}
8482

8583
function lazyEnv(): Map<string,string> {
86-
var err = environ_sizes_get(iobuf, iobuf + 4);
84+
var err = environ_sizes_get(tempbuf, tempbuf + 4);
8785
if (err) throw new Error(errnoToString(err));
88-
var count = load<usize>(iobuf);
86+
var count = load<usize>(tempbuf);
8987
var ptrsSize = count * sizeof<usize>();
90-
var dataSize = load<usize>(iobuf, sizeof<usize>());
88+
var dataSize = load<usize>(tempbuf, sizeof<usize>());
9189
var bufSize = ptrsSize + dataSize;
9290
var buf = __alloc(bufSize);
9391
err = environ_get(buf, buf + ptrsSize);
@@ -136,18 +134,18 @@ abstract class ReadableStream extends Stream {
136134
if (offset < 0 || <usize>offset > end) {
137135
throw new Error(E_INDEXOUTOFRANGE);
138136
}
139-
store<usize>(iobuf, changetype<usize>(buffer) + offset);
140-
store<usize>(iobuf, end - offset, sizeof<usize>());
141-
var err = fd_read(<u32>changetype<usize>(this), iobuf, 1, iobuf + 2 * sizeof<usize>());
137+
store<usize>(tempbuf, changetype<usize>(buffer) + offset);
138+
store<usize>(tempbuf, end - offset, sizeof<usize>());
139+
var err = fd_read(<u32>changetype<usize>(this), tempbuf, 1, tempbuf + 2 * sizeof<usize>());
142140
if (err) throw new Error(errnoToString(err));
143-
return <i32>load<isize>(iobuf, 2 * sizeof<usize>());
141+
return <i32>load<isize>(tempbuf, 2 * sizeof<usize>());
144142
}
145143
}
146144

147145
function writeBuffer(fd: fd, data: ArrayBuffer): void {
148-
store<usize>(iobuf, changetype<usize>(data));
149-
store<usize>(iobuf, data.byteLength, sizeof<usize>());
150-
var err = fd_write(<u32>fd, iobuf, 1, iobuf + 2 * sizeof<usize>());
146+
store<usize>(tempbuf, changetype<usize>(data));
147+
store<usize>(tempbuf, data.byteLength, sizeof<usize>());
148+
var err = fd_write(<u32>fd, tempbuf, 1, tempbuf + 2 * sizeof<usize>());
151149
if (err) throw new Error(errnoToString(err));
152150
}
153151

@@ -173,20 +171,20 @@ function writeString(fd: fd, data: string): void {
173171
case 1: { // "\n"
174172
let char1 = <u32>load<u16>(changetype<usize>(data));
175173
if (char1 >= 0x80) break;
176-
store<usize>(iobuf, iobuf + 2 * sizeof<usize>());
177-
store<usize>(iobuf, len, sizeof<usize>());
178-
store<u32>(iobuf, char1 | char2 << 8 | char3 << 16 | char4 << 24, 2 * sizeof<usize>());
179-
let err = fd_write(<u32>fd, iobuf, 1, iobuf + 3 * sizeof<usize>());
174+
store<usize>(tempbuf, tempbuf + 2 * sizeof<usize>());
175+
store<usize>(tempbuf, len, sizeof<usize>());
176+
store<u32>(tempbuf, char1 | char2 << 8 | char3 << 16 | char4 << 24, 2 * sizeof<usize>());
177+
let err = fd_write(<u32>fd, tempbuf, 1, tempbuf + 3 * sizeof<usize>());
180178
if (err) throw new Error(errnoToString(err));
181179
}
182180
case 0: return;
183181
}
184182
var utf8len = <usize>String.UTF8.byteLength(data);
185183
var utf8buf = __alloc(utf8len);
186184
assert(String.UTF8.encodeUnsafe(changetype<usize>(data), len, utf8buf) == utf8len);
187-
store<usize>(iobuf, utf8buf);
188-
store<usize>(iobuf, utf8len, sizeof<usize>());
189-
var err = fd_write(<u32>fd, iobuf, 1, iobuf + 2 * sizeof<usize>());
185+
store<usize>(tempbuf, utf8buf);
186+
store<usize>(tempbuf, utf8len, sizeof<usize>());
187+
var err = fd_write(<u32>fd, tempbuf, 1, tempbuf + 2 * sizeof<usize>());
190188
__free(utf8buf);
191189
if (err) throw new Error(errnoToString(err));
192190
}

std/assembly/wasi/index.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import {
22
proc_exit,
33
fd_write,
44
iovec,
5-
random_get
5+
random_get,
6+
tempbuf
67
} from "bindings/wasi";
78

89
import {
@@ -108,13 +109,11 @@ function trace( // eslint-disable-line @typescript-eslint/no-unused-vars
108109
}
109110

110111
function seed(): f64 { // eslint-disable-line @typescript-eslint/no-unused-vars
111-
var temp = load<u64>(0);
112112
var rand: u64;
113113
do {
114-
random_get(0, 8); // to be sure
115-
rand = load<u64>(0);
114+
random_get(tempbuf, 8);
115+
rand = load<u64>(tempbuf);
116116
} while (!rand);
117-
store<u64>(0, temp);
118117
return reinterpret<f64>(rand);
119118
}
120119

tests/compiler/std-wasi/console.optimized.wat

+4-4
Original file line numberDiff line numberDiff line change
@@ -2065,7 +2065,7 @@
20652065
local.get $0
20662066
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
20672067
i32.const 4272
2068-
i32.const 180
2068+
i32.const 178
20692069
i32.const 16
20702070
call $~lib/wasi/index/abort
20712071
unreachable
@@ -2168,7 +2168,7 @@
21682168
if
21692169
i32.const 0
21702170
i32.const 4272
2171-
i32.const 186
2171+
i32.const 184
21722172
i32.const 3
21732173
call $~lib/wasi/index/abort
21742174
unreachable
@@ -2194,7 +2194,7 @@
21942194
local.get $0
21952195
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
21962196
i32.const 4272
2197-
i32.const 191
2197+
i32.const 189
21982198
i32.const 12
21992199
call $~lib/wasi/index/abort
22002200
unreachable
@@ -3190,7 +3190,7 @@
31903190
local.get $0
31913191
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
31923192
i32.const 4272
3193-
i32.const 59
3193+
i32.const 57
31943194
i32.const 14
31953195
call $~lib/wasi/index/abort
31963196
unreachable

tests/compiler/std-wasi/console.untouched.wat

+17-17
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
(import "wasi_snapshot_preview1" "proc_exit" (func $~lib/bindings/wasi_snapshot_preview1/proc_exit (param i32)))
2424
(import "wasi_snapshot_preview1" "clock_time_get" (func $~lib/bindings/wasi_snapshot_preview1/clock_time_get (param i32 i64 i32) (result i32)))
2525
(global $~lib/process/process.stderr i32 (i32.const 2))
26-
(global $~lib/process/iobuf i32 (i32.const 112))
26+
(global $~lib/bindings/wasi/tempbuf i32 (i32.const 112))
2727
(global $~argumentsLength (mut i32) (i32.const 0))
2828
(global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0))
2929
(global $~lib/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0))
@@ -2920,17 +2920,17 @@
29202920
if
29212921
br $break|0
29222922
end
2923-
global.get $~lib/process/iobuf
2924-
global.get $~lib/process/iobuf
2923+
global.get $~lib/bindings/wasi/tempbuf
2924+
global.get $~lib/bindings/wasi/tempbuf
29252925
i32.const 2
29262926
i32.const 4
29272927
i32.mul
29282928
i32.add
29292929
i32.store
2930-
global.get $~lib/process/iobuf
2930+
global.get $~lib/bindings/wasi/tempbuf
29312931
local.get $2
29322932
i32.store offset=4
2933-
global.get $~lib/process/iobuf
2933+
global.get $~lib/bindings/wasi/tempbuf
29342934
local.get $6
29352935
local.get $3
29362936
i32.const 8
@@ -2946,9 +2946,9 @@
29462946
i32.or
29472947
i32.store offset=8
29482948
local.get $0
2949-
global.get $~lib/process/iobuf
2949+
global.get $~lib/bindings/wasi/tempbuf
29502950
i32.const 1
2951-
global.get $~lib/process/iobuf
2951+
global.get $~lib/bindings/wasi/tempbuf
29522952
i32.const 3
29532953
i32.const 4
29542954
i32.mul
@@ -2962,7 +2962,7 @@
29622962
local.get $7
29632963
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
29642964
i32.const 3248
2965-
i32.const 180
2965+
i32.const 178
29662966
i32.const 16
29672967
call $~lib/wasi/index/abort
29682968
unreachable
@@ -2991,21 +2991,21 @@
29912991
if
29922992
i32.const 0
29932993
i32.const 3248
2994-
i32.const 186
2994+
i32.const 184
29952995
i32.const 3
29962996
call $~lib/wasi/index/abort
29972997
unreachable
29982998
end
2999-
global.get $~lib/process/iobuf
2999+
global.get $~lib/bindings/wasi/tempbuf
30003000
local.get $9
30013001
i32.store
3002-
global.get $~lib/process/iobuf
3002+
global.get $~lib/bindings/wasi/tempbuf
30033003
local.get $8
30043004
i32.store offset=4
30053005
local.get $0
3006-
global.get $~lib/process/iobuf
3006+
global.get $~lib/bindings/wasi/tempbuf
30073007
i32.const 1
3008-
global.get $~lib/process/iobuf
3008+
global.get $~lib/bindings/wasi/tempbuf
30093009
i32.const 2
30103010
i32.const 4
30113011
i32.mul
@@ -3021,7 +3021,7 @@
30213021
local.get $10
30223022
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
30233023
i32.const 3248
3024-
i32.const 191
3024+
i32.const 189
30253025
i32.const 12
30263026
call $~lib/wasi/index/abort
30273027
unreachable
@@ -4427,7 +4427,7 @@
44274427
(local $0 i32)
44284428
i32.const 1
44294429
i64.const 0
4430-
global.get $~lib/process/iobuf
4430+
global.get $~lib/bindings/wasi/tempbuf
44314431
call $~lib/bindings/wasi_snapshot_preview1/clock_time_get
44324432
local.set $0
44334433
local.get $0
@@ -4437,12 +4437,12 @@
44374437
local.get $0
44384438
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
44394439
i32.const 3248
4440-
i32.const 59
4440+
i32.const 57
44414441
i32.const 14
44424442
call $~lib/wasi/index/abort
44434443
unreachable
44444444
end
4445-
global.get $~lib/process/iobuf
4445+
global.get $~lib/bindings/wasi/tempbuf
44464446
i64.load
44474447
)
44484448
(func $~lib/map/MapEntry<~lib/string/String,u64>#set:value (param $0 i32) (param $1 i64)

tests/compiler/std-wasi/crypto.optimized.wat

+3-3
Original file line numberDiff line numberDiff line change
@@ -4340,7 +4340,7 @@
43404340
local.get $0
43414341
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
43424342
i32.const 6720
4343-
i32.const 180
4343+
i32.const 178
43444344
i32.const 16
43454345
call $~lib/wasi/index/abort
43464346
unreachable
@@ -4440,7 +4440,7 @@
44404440
if
44414441
i32.const 0
44424442
i32.const 6720
4443-
i32.const 186
4443+
i32.const 184
44444444
i32.const 3
44454445
call $~lib/wasi/index/abort
44464446
unreachable
@@ -4466,7 +4466,7 @@
44664466
local.get $0
44674467
call $~lib/bindings/wasi_snapshot_preview1/errnoToString
44684468
i32.const 6720
4469-
i32.const 191
4469+
i32.const 189
44704470
i32.const 12
44714471
call $~lib/wasi/index/abort
44724472
unreachable

0 commit comments

Comments
 (0)