Skip to content

Commit

Permalink
wasi: fast calls
Browse files Browse the repository at this point in the history
PR-URL: #43697
Backport-PR-URL: #45908
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
devsnek authored and targos committed Dec 28, 2022
1 parent e294410 commit 7bd6a2c
Show file tree
Hide file tree
Showing 28 changed files with 850 additions and 1,184 deletions.
1,826 changes: 705 additions & 1,121 deletions src/node_wasi.cc

Large diffs are not rendered by default.

195 changes: 135 additions & 60 deletions src/node_wasi.h
Expand Up @@ -6,10 +6,15 @@
#include "base_object.h"
#include "node_mem.h"
#include "uvwasi.h"
#include "v8-fast-api-calls.h"

namespace node {
namespace wasi {

struct WasmMemory {
char* data;
size_t size;
};

class WASI : public BaseObject,
public mem::NgLibMemoryManager<WASI, uvwasi_mem_t> {
Expand All @@ -23,57 +28,120 @@ class WASI : public BaseObject,
SET_MEMORY_INFO_NAME(WASI)
SET_SELF_SIZE(WASI)

static void ArgsGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ArgsSizesGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ClockResGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ClockTimeGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void EnvironGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void EnvironSizesGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdAdvise(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdAllocate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdClose(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdDatasync(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdFdstatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdFdstatSetFlags(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdFdstatSetRights(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdFilestatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdFilestatSetSize(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdFilestatSetTimes(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdPread(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdPrestatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdPrestatDirName(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdPwrite(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdRead(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdReaddir(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdRenumber(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdSeek(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdSync(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdTell(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdWrite(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathCreateDirectory(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathFilestatGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathFilestatSetTimes(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathLink(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathOpen(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathReadlink(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathRemoveDirectory(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathRename(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathSymlink(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PathUnlinkFile(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PollOneoff(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ProcExit(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ProcRaise(const v8::FunctionCallbackInfo<v8::Value>& args);
static void RandomGet(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SchedYield(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SockRecv(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SockSend(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SockShutdown(const v8::FunctionCallbackInfo<v8::Value>& args);
static uint32_t ArgsGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t ArgsSizesGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t ClockResGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t ClockTimeGet(WASI&, WasmMemory, uint32_t, uint64_t, uint32_t);
static uint32_t EnvironGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t EnvironSizesGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t FdAdvise(
WASI&, WasmMemory, uint32_t, uint64_t, uint64_t, uint32_t);
static uint32_t FdAllocate(WASI&, WasmMemory, uint32_t, uint64_t, uint64_t);
static uint32_t FdClose(WASI&, WasmMemory, uint32_t);
static uint32_t FdDatasync(WASI&, WasmMemory, uint32_t);
static uint32_t FdFdstatGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t FdFdstatSetFlags(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t FdFdstatSetRights(
WASI&, WasmMemory, uint32_t, uint64_t, uint64_t);
static uint32_t FdFilestatGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t FdFilestatSetSize(WASI&, WasmMemory, uint32_t, uint64_t);
static uint32_t FdFilestatSetTimes(
WASI&, WasmMemory, uint32_t, uint64_t, uint64_t, uint32_t);
static uint32_t FdPread(WASI&,
WasmMemory memory,
uint32_t,
uint32_t,
uint32_t,
uint64_t,
uint32_t);
static uint32_t FdPrestatGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t FdPrestatDirName(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
static uint32_t FdPwrite(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t);
static uint32_t FdRead(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t);
static uint32_t FdReaddir(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t);
static uint32_t FdRenumber(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t FdSeek(
WASI&, WasmMemory, uint32_t, int64_t, uint32_t, uint32_t);
static uint32_t FdSync(WASI&, WasmMemory, uint32_t);
static uint32_t FdTell(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t FdWrite(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t);
static uint32_t PathCreateDirectory(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
static uint32_t PathFilestatGet(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
static uint32_t PathFilestatSetTimes(WASI&,
WasmMemory,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint64_t,
uint64_t,
uint32_t);
static uint32_t PathLink(WASI&,
WasmMemory,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t);
static uint32_t PathOpen(WASI&,
WasmMemory,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint64_t,
uint64_t,
uint32_t,
uint32_t);
static uint32_t PathReadlink(WASI&,
WasmMemory,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t);
static uint32_t PathRemoveDirectory(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
static uint32_t PathRename(WASI&,
WasmMemory,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t);
static uint32_t PathSymlink(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
static uint32_t PathUnlinkFile(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t);
static uint32_t PollOneoff(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t);
static void ProcExit(WASI&, WasmMemory, uint32_t);
static uint32_t ProcRaise(WASI&, WasmMemory, uint32_t);
static uint32_t RandomGet(WASI&, WasmMemory, uint32_t, uint32_t);
static uint32_t SchedYield(WASI&, WasmMemory);
static uint32_t SockRecv(WASI&,
WasmMemory,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t,
uint32_t);
static uint32_t SockSend(
WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
static uint32_t SockShutdown(WASI&, WasmMemory, uint32_t, uint32_t);

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

Expand All @@ -82,17 +150,24 @@ class WASI : public BaseObject,
void IncreaseAllocatedSize(size_t size);
void DecreaseAllocatedSize(size_t size);

// <typename FT, FT F> as a C++14 desugaring of `<auto F>`
template <typename FT, FT F, typename R, typename... Args>
class WasiFunction {
public:
static void SetFunction(Environment*,
const char*,
v8::Local<v8::FunctionTemplate>);

private:
static R FastCallback(v8::Local<v8::Object> receiver,
Args...,
v8::FastApiCallbackOptions&);

static void SlowCallback(const v8::FunctionCallbackInfo<v8::Value>&);
};

private:
~WASI() override;
inline void readUInt8(char* memory, uint8_t* value, uint32_t offset);
inline void readUInt16(char* memory, uint16_t* value, uint32_t offset);
inline void readUInt32(char* memory, uint32_t* value, uint32_t offset);
inline void readUInt64(char* memory, uint64_t* value, uint32_t offset);
inline void writeUInt8(char* memory, uint8_t value, uint32_t offset);
inline void writeUInt16(char* memory, uint16_t value, uint32_t offset);
inline void writeUInt32(char* memory, uint32_t value, uint32_t offset);
inline void writeUInt64(char* memory, uint64_t value, uint32_t offset);
uvwasi_errno_t backingStore(char** store, size_t* byte_length);
uvwasi_t uvw_;
v8::Global<v8::WasmMemoryObject> memory_;
uvwasi_mem_t alloc_info_;
Expand Down
5 changes: 3 additions & 2 deletions test/wasi/Makefile
@@ -1,12 +1,13 @@
CC = /opt/wasi-sdk/bin/clang
TARGET = wasm32-unknown-wasi
TARGET = wasm32-wasi
SYSROOT =
CFLAGS = -D_WASI_EMULATED_PROCESS_CLOCKS -lwasi-emulated-process-clocks

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

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

.PHONY clean:
rm -f $(OBJ)
8 changes: 7 additions & 1 deletion test/wasi/test-wasi.js
Expand Up @@ -35,7 +35,7 @@ if (process.argv[2] === 'wasi-child') {
const cp = require('child_process');
const { checkoutEOL } = common;

function runWASI(options) {
function innerRunWASI(options, args) {
console.log('executing', options.test);
const opts = {
env: {
Expand All @@ -49,6 +49,7 @@ if (process.argv[2] === 'wasi-child') {
opts.input = options.stdin;

const child = cp.spawnSync(process.execPath, [
...args,
'--experimental-wasi-unstable-preview1',
__filename,
'wasi-child',
Expand All @@ -60,6 +61,11 @@ if (process.argv[2] === 'wasi-child') {
assert.strictEqual(child.stdout.toString(), options.stdout || '');
}

function runWASI(options) {
innerRunWASI(options, ['--no-turbo-fast-api-calls']);
innerRunWASI(options, ['--turbo-fast-api-calls']);
}

runWASI({ test: 'cant_dotdot' });

// Tests that are currently unsupported on IBM i PASE.
Expand Down
Binary file modified test/wasi/wasm/cant_dotdot.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/clock_getres.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/create_symlink.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/exitcode.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/fd_prestat_get_refresh.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/follow_symlink.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/freopen.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/ftruncate.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/getentropy.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/getrusage.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/gettimeofday.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/link.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/main_args.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/notdir.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/poll.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/preopen_populates.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/read_file.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/read_file_twice.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/readdir.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/stat.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/stdin.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/symlink_escape.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/symlink_loop.wasm
Binary file not shown.
Binary file modified test/wasi/wasm/write_file.wasm
Binary file not shown.

0 comments on commit 7bd6a2c

Please sign in to comment.