Skip to content

Commit 676c0b3

Browse files
committed
wasi: fast calls
1 parent 7233b18 commit 676c0b3

28 files changed

+849
-1181
lines changed

β€Žsrc/node_wasi.cc

Lines changed: 705 additions & 1118 deletions
Large diffs are not rendered by default.

β€Žsrc/node_wasi.h

Lines changed: 134 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
namespace node {
1111
namespace wasi {
1212

13+
struct WasmMemory {
14+
char* data;
15+
size_t size;
16+
};
1317

1418
class WASI : public BaseObject,
1519
public mem::NgLibMemoryManager<WASI, uvwasi_mem_t> {
@@ -23,57 +27,120 @@ class WASI : public BaseObject,
2327
SET_MEMORY_INFO_NAME(WASI)
2428
SET_SELF_SIZE(WASI)
2529

26-
static void ArgsGet(const v8::FunctionCallbackInfo<v8::Value>& args);
27-
static void ArgsSizesGet(const v8::FunctionCallbackInfo<v8::Value>& args);
28-
static void ClockResGet(const v8::FunctionCallbackInfo<v8::Value>& args);
29-
static void ClockTimeGet(const v8::FunctionCallbackInfo<v8::Value>& args);
30-
static void EnvironGet(const v8::FunctionCallbackInfo<v8::Value>& args);
31-
static void EnvironSizesGet(const v8::FunctionCallbackInfo<v8::Value>& args);
32-
static void FdAdvise(const v8::FunctionCallbackInfo<v8::Value>& args);
33-
static void FdAllocate(const v8::FunctionCallbackInfo<v8::Value>& args);
34-
static void FdClose(const v8::FunctionCallbackInfo<v8::Value>& args);
35-
static void FdDatasync(const v8::FunctionCallbackInfo<v8::Value>& args);
36-
static void FdFdstatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
37-
static void FdFdstatSetFlags(const v8::FunctionCallbackInfo<v8::Value>& args);
38-
static void FdFdstatSetRights(
39-
const v8::FunctionCallbackInfo<v8::Value>& args);
40-
static void FdFilestatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
41-
static void FdFilestatSetSize(
42-
const v8::FunctionCallbackInfo<v8::Value>& args);
43-
static void FdFilestatSetTimes(
44-
const v8::FunctionCallbackInfo<v8::Value>& args);
45-
static void FdPread(const v8::FunctionCallbackInfo<v8::Value>& args);
46-
static void FdPrestatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
47-
static void FdPrestatDirName(const v8::FunctionCallbackInfo<v8::Value>& args);
48-
static void FdPwrite(const v8::FunctionCallbackInfo<v8::Value>& args);
49-
static void FdRead(const v8::FunctionCallbackInfo<v8::Value>& args);
50-
static void FdReaddir(const v8::FunctionCallbackInfo<v8::Value>& args);
51-
static void FdRenumber(const v8::FunctionCallbackInfo<v8::Value>& args);
52-
static void FdSeek(const v8::FunctionCallbackInfo<v8::Value>& args);
53-
static void FdSync(const v8::FunctionCallbackInfo<v8::Value>& args);
54-
static void FdTell(const v8::FunctionCallbackInfo<v8::Value>& args);
55-
static void FdWrite(const v8::FunctionCallbackInfo<v8::Value>& args);
56-
static void PathCreateDirectory(
57-
const v8::FunctionCallbackInfo<v8::Value>& args);
58-
static void PathFilestatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
59-
static void PathFilestatSetTimes(
60-
const v8::FunctionCallbackInfo<v8::Value>& args);
61-
static void PathLink(const v8::FunctionCallbackInfo<v8::Value>& args);
62-
static void PathOpen(const v8::FunctionCallbackInfo<v8::Value>& args);
63-
static void PathReadlink(const v8::FunctionCallbackInfo<v8::Value>& args);
64-
static void PathRemoveDirectory(
65-
const v8::FunctionCallbackInfo<v8::Value>& args);
66-
static void PathRename(const v8::FunctionCallbackInfo<v8::Value>& args);
67-
static void PathSymlink(const v8::FunctionCallbackInfo<v8::Value>& args);
68-
static void PathUnlinkFile(const v8::FunctionCallbackInfo<v8::Value>& args);
69-
static void PollOneoff(const v8::FunctionCallbackInfo<v8::Value>& args);
70-
static void ProcExit(const v8::FunctionCallbackInfo<v8::Value>& args);
71-
static void ProcRaise(const v8::FunctionCallbackInfo<v8::Value>& args);
72-
static void RandomGet(const v8::FunctionCallbackInfo<v8::Value>& args);
73-
static void SchedYield(const v8::FunctionCallbackInfo<v8::Value>& args);
74-
static void SockRecv(const v8::FunctionCallbackInfo<v8::Value>& args);
75-
static void SockSend(const v8::FunctionCallbackInfo<v8::Value>& args);
76-
static void SockShutdown(const v8::FunctionCallbackInfo<v8::Value>& args);
30+
static uint32_t ArgsGet(WASI&, WasmMemory, uint32_t, uint32_t);
31+
static uint32_t ArgsSizesGet(WASI&, WasmMemory, uint32_t, uint32_t);
32+
static uint32_t ClockResGet(WASI&, WasmMemory, uint32_t, uint32_t);
33+
static uint32_t ClockTimeGet(WASI&, WasmMemory, uint32_t, uint64_t, uint32_t);
34+
static uint32_t EnvironGet(WASI&, WasmMemory, uint32_t, uint32_t);
35+
static uint32_t EnvironSizesGet(WASI&, WasmMemory, uint32_t, uint32_t);
36+
static uint32_t FdAdvise(
37+
WASI&, WasmMemory, uint32_t, uint64_t, uint64_t, uint32_t);
38+
static uint32_t FdAllocate(WASI&, WasmMemory, uint32_t, uint64_t, uint64_t);
39+
static uint32_t FdClose(WASI&, WasmMemory, uint32_t);
40+
static uint32_t FdDatasync(WASI&, WasmMemory, uint32_t);
41+
static uint32_t FdFdstatGet(WASI&, WasmMemory, uint32_t, uint32_t);
42+
static uint32_t FdFdstatSetFlags(WASI&, WasmMemory, uint32_t, uint32_t);
43+
static uint32_t FdFdstatSetRights(
44+
WASI&, WasmMemory, uint32_t, uint64_t, uint64_t);
45+
static uint32_t FdFilestatGet(WASI&, WasmMemory, uint32_t, uint32_t);
46+
static uint32_t FdFilestatSetSize(WASI&, WasmMemory, uint32_t, uint64_t);
47+
static uint32_t FdFilestatSetTimes(
48+
WASI&, WasmMemory, uint32_t, uint64_t, uint64_t, uint32_t);
49+
static uint32_t FdPread(WASI&,
50+
WasmMemory memory,
51+
uint32_t,
52+
uint32_t,
53+
uint32_t,
54+
uint64_t,
55+
uint32_t);
56+
static uint32_t FdPrestatGet(WASI&, WasmMemory, uint32_t, uint32_t);
57+
static uint32_t FdPrestatDirName(
58+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
59+
static uint32_t FdPwrite(
60+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t);
61+
static uint32_t FdRead(
62+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t);
63+
static uint32_t FdReaddir(
64+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t);
65+
static uint32_t FdRenumber(WASI&, WasmMemory, uint32_t, uint32_t);
66+
static uint32_t FdSeek(
67+
WASI&, WasmMemory, uint32_t, int64_t, uint32_t, uint32_t);
68+
static uint32_t FdSync(WASI&, WasmMemory, uint32_t);
69+
static uint32_t FdTell(WASI&, WasmMemory, uint32_t, uint32_t);
70+
static uint32_t FdWrite(
71+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t);
72+
static uint32_t PathCreateDirectory(
73+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
74+
static uint32_t PathFilestatGet(
75+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
76+
static uint32_t PathFilestatSetTimes(WASI&,
77+
WasmMemory,
78+
uint32_t,
79+
uint32_t,
80+
uint32_t,
81+
uint32_t,
82+
uint64_t,
83+
uint64_t,
84+
uint32_t);
85+
static uint32_t PathLink(WASI&,
86+
WasmMemory,
87+
uint32_t,
88+
uint32_t,
89+
uint32_t,
90+
uint32_t,
91+
uint32_t,
92+
uint32_t,
93+
uint32_t);
94+
static uint32_t PathOpen(WASI&,
95+
WasmMemory,
96+
uint32_t,
97+
uint32_t,
98+
uint32_t,
99+
uint32_t,
100+
uint32_t,
101+
uint64_t,
102+
uint64_t,
103+
uint32_t,
104+
uint32_t);
105+
static uint32_t PathReadlink(WASI&,
106+
WasmMemory,
107+
uint32_t,
108+
uint32_t,
109+
uint32_t,
110+
uint32_t,
111+
uint32_t,
112+
uint32_t);
113+
static uint32_t PathRemoveDirectory(
114+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
115+
static uint32_t PathRename(WASI&,
116+
WasmMemory,
117+
uint32_t,
118+
uint32_t,
119+
uint32_t,
120+
uint32_t,
121+
uint32_t,
122+
uint32_t);
123+
static uint32_t PathSymlink(
124+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
125+
static uint32_t PathUnlinkFile(
126+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
127+
static uint32_t PollOneoff(
128+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t);
129+
static void ProcExit(WASI&, WasmMemory, uint32_t);
130+
static uint32_t ProcRaise(WASI&, WasmMemory, uint32_t);
131+
static uint32_t RandomGet(WASI&, WasmMemory, uint32_t, uint32_t);
132+
static uint32_t SchedYield(WASI&, WasmMemory);
133+
static uint32_t SockRecv(WASI&,
134+
WasmMemory,
135+
uint32_t,
136+
uint32_t,
137+
uint32_t,
138+
uint32_t,
139+
uint32_t,
140+
uint32_t);
141+
static uint32_t SockSend(
142+
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
143+
static uint32_t SockShutdown(WASI&, WasmMemory, uint32_t, uint32_t);
77144

78145
static void _SetMemory(const v8::FunctionCallbackInfo<v8::Value>& args);
79146

@@ -82,17 +149,24 @@ class WASI : public BaseObject,
82149
void IncreaseAllocatedSize(size_t size);
83150
void DecreaseAllocatedSize(size_t size);
84151

152+
// <typename FT, FT F> as a C++14 desugaring of `<auto F>`
153+
template <typename FT, FT F, typename R, typename... Args>
154+
class WasiFunction {
155+
public:
156+
static void SetFunction(Environment*,
157+
const char*,
158+
v8::Local<v8::FunctionTemplate>);
159+
160+
private:
161+
static R FastCallback(v8::Local<v8::Object> receiver,
162+
Args...,
163+
v8::FastApiCallbackOptions&);
164+
165+
static void SlowCallback(const v8::FunctionCallbackInfo<v8::Value>&);
166+
};
167+
85168
private:
86169
~WASI() override;
87-
inline void readUInt8(char* memory, uint8_t* value, uint32_t offset);
88-
inline void readUInt16(char* memory, uint16_t* value, uint32_t offset);
89-
inline void readUInt32(char* memory, uint32_t* value, uint32_t offset);
90-
inline void readUInt64(char* memory, uint64_t* value, uint32_t offset);
91-
inline void writeUInt8(char* memory, uint8_t value, uint32_t offset);
92-
inline void writeUInt16(char* memory, uint16_t value, uint32_t offset);
93-
inline void writeUInt32(char* memory, uint32_t value, uint32_t offset);
94-
inline void writeUInt64(char* memory, uint64_t value, uint32_t offset);
95-
uvwasi_errno_t backingStore(char** store, size_t* byte_length);
96170
uvwasi_t uvw_;
97171
v8::Global<v8::WasmMemoryObject> memory_;
98172
uvwasi_mem_t alloc_info_;

β€Žtest/wasi/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
CC = /opt/wasi-sdk/bin/clang
2-
TARGET = wasm32-unknown-wasi
2+
TARGET = wasm32-wasi
33
SYSROOT =
4+
CFLAGS = -D_WASI_EMULATED_PROCESS_CLOCKS -lwasi-emulated-process-clocks
45

56
OBJ = $(patsubst c/%.c, wasm/%.wasm, $(wildcard c/*.c))
67
all: $(OBJ)
78

89
wasm/%.wasm : c/%.c
9-
$(CC) $< --target=$(TARGET) --sysroot=$(SYSROOT) -s -o $@
10+
$(CC) $< $(CFLAGS) --target=$(TARGET) --sysroot=$(SYSROOT) -s -o $@
1011

1112
.PHONY clean:
1213
rm -f $(OBJ)

β€Žtest/wasi/test-wasi.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ if (process.argv[2] === 'wasi-child') {
3636
const cp = require('child_process');
3737
const { checkoutEOL } = common;
3838

39-
function runWASI(options) {
39+
function innerRunWASI(options, args) {
4040
console.log('executing', options.test);
4141
const opts = {
4242
env: {
@@ -50,6 +50,7 @@ if (process.argv[2] === 'wasi-child') {
5050
opts.input = options.stdin;
5151

5252
const child = cp.spawnSync(process.execPath, [
53+
...args,
5354
'--experimental-wasi-unstable-preview1',
5455
__filename,
5556
'wasi-child',
@@ -61,6 +62,11 @@ if (process.argv[2] === 'wasi-child') {
6162
assert.strictEqual(child.stdout.toString(), options.stdout || '');
6263
}
6364

65+
function runWASI(options) {
66+
innerRunWASI(options, ['--no-turbo-fast-api-calls']);
67+
innerRunWASI(options, ['--turbo-fast-api-calls', '--trace-opt']);
68+
}
69+
6470
runWASI({ test: 'cant_dotdot' });
6571

6672
// Tests that are currently unsupported on IBM i PASE.

β€Žtest/wasi/wasm/cant_dotdot.wasm

-1.83 KB
Binary file not shown.

β€Žtest/wasi/wasm/clock_getres.wasm

-11.5 KB
Binary file not shown.

β€Žtest/wasi/wasm/create_symlink.wasm

-2.72 KB
Binary file not shown.

β€Žtest/wasi/wasm/exitcode.wasm

-11.6 KB
Binary file not shown.
-11.5 KB
Binary file not shown.

β€Žtest/wasi/wasm/follow_symlink.wasm

-2.9 KB
Binary file not shown.

0 commit comments

Comments
Β (0)