diff --git a/wasm/CHANGELOG.md b/wasm/CHANGELOG.md
index 724f5edd43eb..3f5f9f4ca94f 100644
--- a/wasm/CHANGELOG.md
+++ b/wasm/CHANGELOG.md
@@ -9,6 +9,7 @@ This changelog summarizes major changes to the WebAssembly engine implemented in
## Version 24.1.0
* Implemented the [SIMD](https://github.com/WebAssembly/simd) proposal. This feature is enabled by default and can be disabled with the option `--wasm.SIMD=false`.
+* Added limited support for `fd_advise` in `wasi_snapshot_preview1`.
## Version 23.1.0
diff --git a/wasm/mx.wasm/mx_wasm.py b/wasm/mx.wasm/mx_wasm.py
index 5758773d7eb8..0c8712124ebf 100644
--- a/wasm/mx.wasm/mx_wasm.py
+++ b/wasm/mx.wasm/mx_wasm.py
@@ -630,7 +630,7 @@ def emscripten_init(args):
@mx.command(_suite.name, "wasm")
def wasm(args, **kwargs):
"""Run a WebAssembly program."""
- vmArgs, wasmArgs = mx.extract_VM_args(args, useDoubleDash=False, defaultAllVMArgs=False)
+ vmArgs, wasmArgs = mx.extract_VM_args(args, useDoubleDash=True, defaultAllVMArgs=False)
path_args = mx.get_runtime_jvm_args([
"TRUFFLE_API",
"org.graalvm.wasm",
diff --git a/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.opts b/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.opts
new file mode 100644
index 000000000000..7bfd1a84a622
--- /dev/null
+++ b/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.opts
@@ -0,0 +1 @@
+enable-io=true
diff --git a/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.result b/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.result
new file mode 100644
index 000000000000..8a50673d0631
--- /dev/null
+++ b/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.result
@@ -0,0 +1 @@
+int 0
\ No newline at end of file
diff --git a/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.wat b/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.wat
new file mode 100644
index 000000000000..e19f0fcc3f92
--- /dev/null
+++ b/wasm/src/org.graalvm.wasm.test/src/test/wasi/fd_advise-file.wat
@@ -0,0 +1,185 @@
+;;
+;; Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+;; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+;;
+;; The Universal Permissive License (UPL), Version 1.0
+;;
+;; Subject to the condition set forth below, permission is hereby granted to any
+;; person obtaining a copy of this software, associated documentation and/or
+;; data (collectively the "Software"), free of charge and under any and all
+;; copyright rights in the Software, and any and all patent rights owned or
+;; freely licensable by each licensor hereunder covering either (i) the
+;; unmodified Software as contributed to or provided by such licensor, or (ii)
+;; the Larger Works (as defined below), to deal in both
+;;
+;; (a) the Software, and
+;;
+;; (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+;; one is included with the Software each a "Larger Work" to which the Software
+;; is contributed by such licensors),
+;;
+;; without restriction, including without limitation the rights to copy, create
+;; derivative works of, display, perform, and distribute the Software and make,
+;; use, sell, offer for sale, import, export, have made, and have sold the
+;; Software and the Larger Work(s), and to sublicense the foregoing rights on
+;; either these or other terms.
+;;
+;; This license is subject to the following condition:
+;;
+;; The above copyright notice and either this complete permission notice or at a
+;; minimum a reference to the UPL must be included in all copies or substantial
+;; portions of the Software.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+;; SOFTWARE.
+;;
+
+(module
+ (import "wasi_snapshot_preview1" "path_open" (func $path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
+ (import "wasi_snapshot_preview1" "fd_advise" (func $fd_advise (param i32 i64 i64 i32) (result i32)))
+ (import "wasi_snapshot_preview1" "fd_close" (func $fd_close (param i32) (result i32)))
+
+ (memory 1)
+
+ (data (i32.const 0) "file.txt")
+
+ (export "memory" (memory 0))
+
+ ;; Pre-opened temporary directory fd
+ (global $directory_fd i32 (i32.const 3))
+
+ ;; Memory location of file path
+ (global $file_path_address i32 (i32.const 0))
+ (global $file_path_length i32 (i32.const 8))
+
+ ;; Address of opened file fd
+ (global $file_fd_address i32 (i32.const 12))
+
+ ;; Rights for path_open
+ (global $all_rights i64 (i64.const 536870911))
+ (global $advise_right i64 (i64.const 128))
+
+ ;; Advice for fd_advise
+ (global $sequential_access_advice i32 (i32.const 1))
+
+ ;; Errno codes
+ (global $errno_inval i32 (i32.const 28))
+ (global $errno_badf i32 (i32.const 8))
+ (global $errno_notcapable i32 (i32.const 76))
+
+ (func (export "_main") (result i32) (local $ret i32)
+ ;; Open file "file.txt" in pre-opened directory
+ (local.set $ret
+ (call $path_open
+ (global.get $directory_fd) ;; pre-opened "test" directory fd
+ (i32.const 0) ;; dirflags
+ (global.get $file_path_address) ;; pointer to path "file.txt"
+ (global.get $file_path_length) ;; path length
+ (i32.const 0) ;; oflags
+ (global.get $all_rights) ;; rights base (all rights set)
+ (global.get $all_rights) ;; rights inherting (all rights set)
+ (i32.const 0) ;; fdflags
+ (global.get $file_fd_address) ;; fd address
+ )
+ )
+ ;; Exit in case of error
+ (if (i32.ne (local.get $ret) (i32.const 0)) (then (return (local.get $ret))))
+
+ ;; Valid advice
+ (local.set $ret
+ (call $fd_advise
+ (i32.load (global.get $file_fd_address)) ;; "file.txt" fd
+ (i64.const 0) ;; offset of advised region
+ (i64.const 0) ;; length of advised region
+ (global.get $sequential_access_advice) ;; sequential access advice
+ )
+ )
+ ;; Exit in case of error
+ (if (i32.ne (local.get $ret) (i32.const 0)) (then (return (local.get $ret))))
+
+ ;; Invalid advice
+ (local.set $ret
+ (call $fd_advise
+ (i32.load (global.get $file_fd_address)) ;; "file.txt" fd
+ (i64.const 0) ;; offset of advised region
+ (i64.const 0) ;; length of advised region
+ (i32.const 42) ;; invalid advice
+ )
+ )
+ ;; Check that error code is inval
+ (if (i32.ne (local.get $ret) (global.get $errno_inval)) (then (return (i32.const -1))))
+
+ ;; Invalid length of advised region
+ (local.set $ret
+ (call $fd_advise
+ (i32.load (global.get $file_fd_address)) ;; "file.txt" fd
+ (i64.const 1) ;; offset of advised region
+ (i64.const -1) ;; length of advised region (must be non-negative)
+ (global.get $sequential_access_advice) ;; sequential access advice
+ )
+ )
+ ;; Check that error code is inval
+ (if (i32.ne (local.get $ret) (global.get $errno_inval)) (then (return (i32.const -2))))
+
+ ;; Invalid file descriptor
+ (local.set $ret
+ (call $fd_advise
+ (i32.add (i32.load (global.get $file_fd_address)) (i32.const 1)) ;; invalid fd
+ (i64.const 0) ;; offset of advised region
+ (i64.const 0) ;; length of advised region
+ (global.get $sequential_access_advice) ;; sequential access advice
+ )
+ )
+ ;; Check that error code is badf
+ (if (i32.ne (local.get $ret) (global.get $errno_badf)) (then (return (i32.const -3))))
+
+ ;; Free opened file
+ (local.set $ret (call $fd_close (i32.load (global.get $file_fd_address))))
+ ;; Exit in case of error
+ (if (i32.ne (local.get $ret) (i32.const 0)) (then (return (local.get $ret))))
+
+ ;; Open file "file.txt" in pre-opened directory 3 without advise capabilities
+ (local.set $ret
+ (call $path_open
+ (global.get $directory_fd) ;; pre-opened "test" directory fd
+ (i32.const 0) ;; dirflags
+ (global.get $file_path_address) ;; pointer to path "file.txt"
+ (global.get $file_path_length) ;; path length
+ (i32.const 0) ;; oflags
+ (i64.sub (global.get $all_rights) (global.get $advise_right)) ;; rights base (all rights set except for fd_advise)
+ (i64.sub (global.get $all_rights) (global.get $advise_right)) ;; rights inheriting (all rights set except for fd_advise)
+ (i32.const 0) ;; fdflags
+ (global.get $file_fd_address) ;; fd address
+ )
+ )
+ ;; Exit in case of error
+ (if (i32.ne (local.get $ret) (i32.const 0)) (then (return (local.get $ret))))
+
+ ;; Insufficient capabilities for advise
+ (local.set $ret
+ (call $fd_advise
+ (i32.load (global.get $file_fd_address)) ;; "file.txt" fd without advise rights
+ (i64.const 0) ;; offset of advised region
+ (i64.const 0) ;; length of advised region
+ (global.get $sequential_access_advice) ;; sequential access advice
+ )
+ )
+ ;; Check that error code is notcapable
+ (if (i32.ne (local.get $ret) (global.get $errno_notcapable)) (then (return (i32.const -4))))
+
+ ;; Free opened file
+ (local.set $ret (call $fd_close (i32.load (global.get $file_fd_address))))
+ ;; Exit in case of error
+ (if (i32.ne (local.get $ret) (i32.const 0)) (then (return (local.get $ret))))
+
+ ;; Clear random fd number so that this test is deterministic
+ (i32.store (global.get $file_fd_address) (i32.const 0))
+ ;; Success
+ (i32.const 0)
+ )
+)
\ No newline at end of file
diff --git a/wasm/src/org.graalvm.wasm.test/src/test/wasi/wasm_test_index b/wasm/src/org.graalvm.wasm.test/src/test/wasi/wasm_test_index
index 949088c17509..06f3942e3d64 100644
--- a/wasm/src/org.graalvm.wasm.test/src/test/wasi/wasm_test_index
+++ b/wasm/src/org.graalvm.wasm.test/src/test/wasi/wasm_test_index
@@ -3,6 +3,7 @@ args-sizes-get
proc-exit
environ-get
environ-sizes-get
+fd_advise-file
fd_prestat_get
fd_prestat_dir_name
fd_read-stdin
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/memory/WasmMemory.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/memory/WasmMemory.java
index 74da7871ec57..dd8cc63464fc 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/memory/WasmMemory.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/memory/WasmMemory.java
@@ -519,7 +519,7 @@ public final String readString(int startOffset, int length, Node node) {
* @param string the string to write
* @param offset memory index where to write the string
* @param length the maximum number of bytes to write, including the trailing null character
- * @return the number of bytes written, including the trailing null character
+ * @return the number of bytes written
*/
@CompilerDirectives.TruffleBoundary
public final int writeString(Node node, String string, int offset, int length) {
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdAdviseNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdAdviseNode.java
new file mode 100644
index 000000000000..01b57dc67487
--- /dev/null
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdAdviseNode.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or
+ * data (collectively the "Software"), free of charge and under any and all
+ * copyright rights in the Software, and any and all patent rights owned or
+ * freely licensable by each licensor hereunder covering either (i) the
+ * unmodified Software as contributed to or provided by such licensor, or (ii)
+ * the Larger Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ *
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ *
+ * The above copyright notice and either this complete permission notice or at a
+ * minimum a reference to the UPL must be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.graalvm.wasm.predefined.wasi;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import org.graalvm.wasm.WasmArguments;
+import org.graalvm.wasm.WasmContext;
+import org.graalvm.wasm.WasmInstance;
+import org.graalvm.wasm.WasmLanguage;
+import org.graalvm.wasm.WasmModule;
+import org.graalvm.wasm.predefined.WasmBuiltinRootNode;
+import org.graalvm.wasm.predefined.wasi.fd.Fd;
+import org.graalvm.wasm.predefined.wasi.types.Advice;
+import org.graalvm.wasm.predefined.wasi.types.Errno;
+
+public class WasiFdAdviseNode extends WasmBuiltinRootNode {
+
+ public WasiFdAdviseNode(WasmLanguage language, WasmModule module) {
+ super(language, module);
+ }
+
+ @Override
+ public Object executeWithContext(VirtualFrame frame, WasmContext context, WasmInstance instance) {
+ final Object[] args = frame.getArguments();
+ return fdAdvise(context, (int) WasmArguments.getArgument(args, 0),
+ (long) WasmArguments.getArgument(args, 1),
+ (long) WasmArguments.getArgument(args, 2),
+ (int) WasmArguments.getArgument(args, 3));
+ }
+
+ @TruffleBoundary
+ private static int fdAdvise(WasmContext context, int fd, long offset, long length, int adviceValue) {
+ final Fd handle = context.fdManager().get(fd);
+ if (handle == null) {
+ return Errno.Badf.ordinal();
+ }
+ if (adviceValue < 0 || adviceValue >= Advice.values().length) {
+ return Errno.Inval.ordinal();
+ }
+ final Advice advice = Advice.values()[adviceValue];
+ if (length < 0) {
+ return Errno.Inval.ordinal();
+ }
+ return handle.advise(offset, length, advice).ordinal();
+ }
+
+ @Override
+ public String builtinNodeName() {
+ return "__wasi_fd_advise";
+ }
+}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdCloseNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdCloseNode.java
index a21f2f937dce..27b504092874 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdCloseNode.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdCloseNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -84,7 +84,7 @@ private static int fdClose(WasmContext context, int fd) {
@Override
public String builtinNodeName() {
- return "___wasi_fd_close";
+ return "__wasi_fd_close";
}
}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdFilestatGetNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdFilestatGetNode.java
index 259326f3927b..f616a01f6854 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdFilestatGetNode.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdFilestatGetNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -76,7 +76,7 @@ private int fdFilestatGet(WasmContext context, WasmMemory memory, int fd, int bu
@Override
public String builtinNodeName() {
- return "___wasi_fd_filestat_get";
+ return "__wasi_fd_filestat_get";
}
}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatDirNameNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatDirNameNode.java
index 9475a60c3b0f..aa311081148b 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatDirNameNode.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatDirNameNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -76,7 +76,7 @@ private int fdPrestatDirName(WasmContext context, WasmMemory memory, int fd, int
@Override
public String builtinNodeName() {
- return "___wasi_fd_prestat_dir_name";
+ return "__wasi_fd_prestat_dir_name";
}
}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatGetNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatGetNode.java
index 71315ffbb307..ac6e567fe344 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatGetNode.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdPrestatGetNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -76,7 +76,7 @@ private int fdPrestatGet(WasmContext context, WasmMemory memory, int fd, int buf
@Override
public String builtinNodeName() {
- return "___wasi_fd_prestat_get";
+ return "__wasi_fd_prestat_get";
}
}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdSeekNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdSeekNode.java
index 20ce92102ecd..9cb642347453 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdSeekNode.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdSeekNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -81,7 +81,7 @@ private int fdSeek(WasmContext context, WasmMemory memory, int fd, long offset,
@Override
public String builtinNodeName() {
- return "___wasi_fd_seek";
+ return "__wasi_fd_seek";
}
}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdWriteNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdWriteNode.java
index 69c95bc4ab8f..d1bc8c60122e 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdWriteNode.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiFdWriteNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -80,7 +80,7 @@ private int fdWrite(WasmContext context, WasmMemory memory, int fd, int iov, int
@Override
public String builtinNodeName() {
- return "___wasi_fd_write";
+ return "__wasi_fd_write";
}
}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiModule.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiModule.java
index ee22298f1b8b..2003961150a0 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiModule.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiModule.java
@@ -50,8 +50,89 @@
import org.graalvm.wasm.WasmModule;
import org.graalvm.wasm.predefined.BuiltinModule;
+@SuppressWarnings("unused")
public final class WasiModule extends BuiltinModule {
+ // The WASI preview1 module's API is expressed using an IDL called witx. witx uses a C-like type
+ // system which is then mapped onto WebAssembly's core types. The following constants give first
+ // the mappings from witx types to WebAssembly types and then they use those witx types to
+ // define the WASI types used in the signature of the WASI module.
+
+ // (@witx pointer) is lowered to i32
+ private static final byte POINTER_TYPE = I32_TYPE;
+ // (@witx const_pointer) is lowered to i32
+ private static final byte CONST_POINTER_TYPE = I32_TYPE;
+ // (record) arguments are lowered to i32 addresses unless there is a flags representation
+ private static final byte RECORD_TYPE = I32_TYPE;
+ // (union) arguments are lowered to i32 addresses unless they are simple enums
+ private static final byte UNION_TYPE = I32_TYPE;
+ // (handle) arguments are lowered to i32 values
+ private static final byte HANDLE_TYPE = I32_TYPE;
+ // (list) arguments are lowered to an address (i32) argument and a length (i32) argument
+ private static final byte LIST_ADDRESS_TYPE = I32_TYPE;
+ private static final byte LIST_LENGTH_TYPE = I32_TYPE;
+ // (string) arguments are lowered the same way as (list) arguments
+ private static final byte STRING_ADDRESS_TYPE = LIST_ADDRESS_TYPE;
+ private static final byte STRING_LENGTH_TYPE = LIST_LENGTH_TYPE;
+ private static final byte U8_TYPE = I32_TYPE;
+ private static final byte U16_TYPE = I32_TYPE;
+ private static final byte U32_TYPE = I32_TYPE;
+ private static final byte U64_TYPE = I64_TYPE;
+ private static final byte S64_TYPE = I64_TYPE;
+ // (result $error (expected X (error $errno))) return values are implemented by returning a
+ // value of type $errno and accepting as arguments pointers for writing any elements of the
+ // expected return value X
+ private static final byte RETURN_VALUE_ADDRESS_TYPE = I32_TYPE;
+
+ private static final byte SIZE_TYPE = U32_TYPE; // u32
+ private static final byte FILESIZE_TYPE = U64_TYPE; // u64
+ private static final byte TIMESTAMP_TYPE = U64_TYPE; // u64
+ private static final byte CLOCKID_TYPE = U32_TYPE; // (enum (@witx tag u32))
+ private static final byte ERRNO_TYPE = U16_TYPE; // (enum (@witx tag u16))
+ private static final byte RIGHTS_TYPE = U64_TYPE; // (flags (@witx repr u64))
+ private static final byte FD_TYPE = HANDLE_TYPE; // (handle)
+ private static final byte IOVEC_TYPE = RECORD_TYPE; // (record)
+ private static final byte CIOVEC_TYPE = RECORD_TYPE; // (record)
+ private static final byte IOVEC_ARRAY_ADDRESS_TYPE = LIST_ADDRESS_TYPE; // (list)
+ private static final byte IOVEC_ARRAY_LENGTH_TYPE = LIST_LENGTH_TYPE; // (list)
+ private static final byte CIOVEC_ARRAY_ADDRESS_TYPE = LIST_ADDRESS_TYPE; // (list)
+ private static final byte CIOVEC_ARRAY_LENGTH_TYPE = LIST_LENGTH_TYPE; // (list)
+ private static final byte FILEDELTA_TYPE = S64_TYPE; // s64
+ private static final byte WHENCE_TYPE = U8_TYPE; // (enum (@witx tag u8))
+ private static final byte DIRCOOKIE_TYPE = U64_TYPE; // u64
+ private static final byte DIRNAMLEN_TYPE = U32_TYPE; // u32
+ private static final byte INODE_TYPE = U64_TYPE; // u64
+ private static final byte FILETYPE_TYPE = U8_TYPE; // (enum (@witx tag u8))
+ private static final byte DIRENT_TYPE = RECORD_TYPE; // (record)
+ private static final byte ADVICE_TYPE = U8_TYPE; // (enum (@witx tag u8))
+ private static final byte FDFLAGS_TYPE = U16_TYPE; // (flags (@witx repr u16))
+ private static final byte FDSTAT_TYPE = RECORD_TYPE; // (record)
+ private static final byte DEVICE_TYPE = U64_TYPE; // u64
+ private static final byte FSTFLAGS_TYPE = U16_TYPE; // (flags (@witx repr u16))
+ private static final byte LOOKUPFLAGS_TYPE = U32_TYPE; // (flags (@witx repr u32))
+ private static final byte OFLAGS_TYPE = U16_TYPE; // (flags (@witx repr u16))
+ private static final byte LINKCOUNT_TYPE = U64_TYPE; // u64
+ private static final byte FILESTAT_TYPE = RECORD_TYPE; // (record)
+ private static final byte USERDATA_TYPE = U64_TYPE; // u64
+ private static final byte EVENTTYPE_TYPE = U8_TYPE; // (enum (@witx tag u8))
+ private static final byte EVENTRWFLAGS_TYPE = U16_TYPE; // (flags (@witx repr u16))
+ private static final byte EVENT_FD_READWRITE_TYPE = RECORD_TYPE; // (record)
+ private static final byte EVENT_TYPE = RECORD_TYPE; // (record)
+ private static final byte SUBCLOCKFLAGS_TYPE = U16_TYPE; // (flags (@witx repr u16))
+ private static final byte SUBSCRIPTION_CLOCK_TYPE = RECORD_TYPE; // (record)
+ private static final byte SUBSCRIPTION_FD_READWRITE_TYPE = RECORD_TYPE; // (record)
+ private static final byte SUBSCRIPTION_U_TYPE = UNION_TYPE; // (union)
+ private static final byte SUBSCRIPTION_TYPE = RECORD_TYPE; // (record)
+ private static final byte EXITCODE_TYPE = U32_TYPE; // u32
+ private static final byte SIGNAL_TYPE = U8_TYPE; // (enum (@witx tag u8))
+ private static final byte RIFLAGS_TYPE = U16_TYPE; // (flags (@witx repr u16))
+ private static final byte ROFLAGS_TYPE = U16_TYPE; // (flags (@witx repr u16))
+ private static final byte SIFLAGS_TYPE = U16_TYPE; // u16
+ private static final byte SDFLAGS_TYPE = U8_TYPE; // (flags (@witx repr u8))
+ private static final byte PREOPENTYPE_TYPE = U8_TYPE; // (enum (@witx tag u8))
+ private static final byte PRESTAT_DIR_TYPE = RECORD_TYPE; // (record)
+ private static final byte PRESTAT_TYPE = UNION_TYPE; // (union)
+
@Override
protected WasmModule createModule(WasmLanguage language, WasmContext context, String name) {
WasmModule module = WasmModule.createBuiltin(name);
@@ -60,59 +141,77 @@ protected WasmModule createModule(WasmLanguage language, WasmContext context, St
} else {
importMemory(context, module, "main", "memory", 0, MAX_MEMORY_DECLARATION_SIZE, false, false);
}
- defineFunction(context, module, "args_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiArgsGetNode(language, module));
- defineFunction(context, module, "args_sizes_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiArgsSizesGetNode(language, module));
- defineFunction(context, module, "environ_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiEnvironGetNode(language, module));
- defineFunction(context, module, "environ_sizes_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiEnvironSizesGetNode(language, module));
- defineFunction(context, module, "clock_res_get", types(I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_clock_res_get"));
- defineFunction(context, module, "clock_time_get", types(I32_TYPE, I64_TYPE, I32_TYPE), types(I32_TYPE), new WasiClockTimeGetNode(language, module));
- defineFunction(context, module, "fd_advise", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_advise"));
- defineFunction(context, module, "fd_allocate", types(I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_allocate"));
- defineFunction(context, module, "fd_close", types(I32_TYPE), types(I32_TYPE), new WasiFdCloseNode(language, module));
- defineFunction(context, module, "fd_datasync", types(I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_datasync"));
- defineFunction(context, module, "fd_fdstat_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdFdstatGetNode(language, module));
- defineFunction(context, module, "fd_fdstat_set_flags", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdFdstatSetFlagsNode(language, module));
- defineFunction(context, module, "fd_fdstat_set_rights", types(I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_fdstat_set_rights"));
- defineFunction(context, module, "fd_filestat_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdFilestatGetNode(language, module));
- defineFunction(context, module, "fd_filestat_set_size", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_filestat_set_size"));
- defineFunction(context, module, "fd_filestat_set_times", types(I32_TYPE, I64_TYPE, I64_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdFilestatSetTimesNode(language, module));
- defineFunction(context, module, "fd_pread", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_pread"));
- defineFunction(context, module, "fd_prestat_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdPrestatGetNode(language, module));
- defineFunction(context, module, "fd_prestat_dir_name", types(I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdPrestatDirNameNode(language, module));
- defineFunction(context, module, "fd_pwrite", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_pwrite"));
- defineFunction(context, module, "fd_read", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdReadNode(language, module));
- defineFunction(context, module, "fd_readdir", types(I32_TYPE, I32_TYPE, I32_TYPE, I64_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_readdir"));
- defineFunction(context, module, "fd_renumber", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_renumber"));
- defineFunction(context, module, "fd_seek", types(I32_TYPE, I64_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdSeekNode(language, module));
- defineFunction(context, module, "fd_sync", types(I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_sync"));
- defineFunction(context, module, "fd_tell", types(I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_tell"));
- defineFunction(context, module, "fd_write", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiFdWriteNode(language, module));
- defineFunction(context, module, "path_create_directory", types(I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathCreateDirectoryNode(language, module));
- defineFunction(context, module, "path_filestat_get", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathFileStatGetNode(language, module));
- defineFunction(context, module, "path_filestat_set_times", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I64_TYPE, I64_TYPE, I32_TYPE), types(I32_TYPE),
+
+ defineFunction(context, module, "args_get", types(POINTER_TYPE, POINTER_TYPE), types(ERRNO_TYPE), new WasiArgsGetNode(language, module));
+ defineFunction(context, module, "args_sizes_get", types(RETURN_VALUE_ADDRESS_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiArgsSizesGetNode(language, module));
+ defineFunction(context, module, "environ_get", types(POINTER_TYPE, POINTER_TYPE), types(ERRNO_TYPE), new WasiEnvironGetNode(language, module));
+ defineFunction(context, module, "environ_sizes_get", types(RETURN_VALUE_ADDRESS_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiEnvironSizesGetNode(language, module));
+ defineFunction(context, module, "clock_res_get", types(CLOCKID_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_clock_res_get"));
+ defineFunction(context, module, "clock_time_get", types(CLOCKID_TYPE, TIMESTAMP_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiClockTimeGetNode(language, module));
+ defineFunction(context, module, "fd_advise", types(FD_TYPE, FILESIZE_TYPE, FILESIZE_TYPE, ADVICE_TYPE), types(ERRNO_TYPE),
+ new WasiFdAdviseNode(language, module));
+ defineFunction(context, module, "fd_allocate", types(FD_TYPE, FILESIZE_TYPE, FILESIZE_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_allocate"));
+ defineFunction(context, module, "fd_close", types(FD_TYPE), types(ERRNO_TYPE), new WasiFdCloseNode(language, module));
+ defineFunction(context, module, "fd_datasync", types(FD_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_datasync"));
+ defineFunction(context, module, "fd_fdstat_get", types(FD_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiFdFdstatGetNode(language, module));
+ defineFunction(context, module, "fd_fdstat_set_flags", types(FD_TYPE, FDFLAGS_TYPE), types(ERRNO_TYPE), new WasiFdFdstatSetFlagsNode(language, module));
+ defineFunction(context, module, "fd_fdstat_set_rights", types(FD_TYPE, RIGHTS_TYPE, RIGHTS_TYPE), types(ERRNO_TYPE),
+ new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_fdstat_set_rights"));
+ defineFunction(context, module, "fd_filestat_get", types(FD_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiFdFilestatGetNode(language, module));
+ defineFunction(context, module, "fd_filestat_set_size", types(FD_TYPE, FILESIZE_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_filestat_set_size"));
+ defineFunction(context, module, "fd_filestat_set_times", types(FD_TYPE, TIMESTAMP_TYPE, TIMESTAMP_TYPE, FSTFLAGS_TYPE), types(ERRNO_TYPE), new WasiFdFilestatSetTimesNode(language, module));
+ defineFunction(context, module, "fd_pread", types(FD_TYPE, IOVEC_ARRAY_ADDRESS_TYPE, IOVEC_ARRAY_LENGTH_TYPE, FILESIZE_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_pread"));
+ defineFunction(context, module, "fd_prestat_get", types(FD_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiFdPrestatGetNode(language, module));
+ defineFunction(context, module, "fd_prestat_dir_name", types(FD_TYPE, POINTER_TYPE, SIZE_TYPE), types(ERRNO_TYPE), new WasiFdPrestatDirNameNode(language, module));
+ defineFunction(context, module, "fd_pwrite", types(FD_TYPE, CIOVEC_ARRAY_ADDRESS_TYPE, CIOVEC_ARRAY_LENGTH_TYPE, FILESIZE_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_pwrite"));
+ defineFunction(context, module, "fd_read", types(FD_TYPE, IOVEC_ARRAY_ADDRESS_TYPE, IOVEC_ARRAY_LENGTH_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiFdReadNode(language, module));
+ defineFunction(context, module, "fd_readdir", types(FD_TYPE, POINTER_TYPE, SIZE_TYPE, DIRCOOKIE_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_readdir"));
+ defineFunction(context, module, "fd_renumber", types(FD_TYPE, FD_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_renumber"));
+ defineFunction(context, module, "fd_seek", types(FD_TYPE, FILEDELTA_TYPE, WHENCE_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiFdSeekNode(language, module));
+ defineFunction(context, module, "fd_sync", types(FD_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_sync"));
+ defineFunction(context, module, "fd_tell", types(FD_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_fd_tell"));
+ defineFunction(context, module, "fd_write", types(FD_TYPE, CIOVEC_ARRAY_ADDRESS_TYPE, CIOVEC_ARRAY_LENGTH_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiFdWriteNode(language, module));
+ defineFunction(context, module, "path_create_directory", types(FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE), types(ERRNO_TYPE), new WasiPathCreateDirectoryNode(language, module));
+ defineFunction(context, module, "path_filestat_get", types(FD_TYPE, LOOKUPFLAGS_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiPathFileStatGetNode(language, module));
+ defineFunction(context, module, "path_filestat_set_times", types(FD_TYPE, LOOKUPFLAGS_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE, TIMESTAMP_TYPE, TIMESTAMP_TYPE, FSTFLAGS_TYPE),
+ types(ERRNO_TYPE),
new WasiPathFilestatSetTimesNode(language, module));
- defineFunction(context, module, "path_link", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathLinkNode(language, module));
- defineFunction(context, module, "path_open", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I64_TYPE, I64_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE),
+ defineFunction(context, module, "path_link", types(FD_TYPE, LOOKUPFLAGS_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE, FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE), types(ERRNO_TYPE),
+ new WasiPathLinkNode(language, module));
+ defineFunction(context, module, "path_open",
+ types(FD_TYPE, LOOKUPFLAGS_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE, OFLAGS_TYPE, RIGHTS_TYPE, RIGHTS_TYPE, FDFLAGS_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
new WasiPathOpenNode(language, module));
- defineFunction(context, module, "path_readlink", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathReadLinkNode(language, module));
- defineFunction(context, module, "path_remove_directory", types(I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathRemoveDirectoryNode(language, module));
- defineFunction(context, module, "path_rename", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathRenameNode(language, module));
- defineFunction(context, module, "path_symlink", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathSymlinkNode(language, module));
- defineFunction(context, module, "path_unlink_file", types(I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiPathUnlinkFileNode(language, module));
- defineFunction(context, module, "poll_oneoff", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_poll_oneoff"));
- defineFunction(context, module, "proc_exit", types(I32_TYPE), types(), new WasiProcExitNode(language, module));
- defineFunction(context, module, "proc_raise", types(I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_proc_raise"));
- defineFunction(context, module, "sched_yield", types(), types(I32_TYPE), new WasiSchedYieldNode(language, module));
+ defineFunction(context, module, "path_readlink", types(FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE, POINTER_TYPE, SIZE_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiPathReadLinkNode(language, module));
+ defineFunction(context, module, "path_remove_directory", types(FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE), types(ERRNO_TYPE), new WasiPathRemoveDirectoryNode(language, module));
+ defineFunction(context, module, "path_rename", types(FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE, FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE), types(ERRNO_TYPE),
+ new WasiPathRenameNode(language, module));
+ defineFunction(context, module, "path_symlink", types(STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE, FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE), types(ERRNO_TYPE),
+ new WasiPathSymlinkNode(language, module));
+ defineFunction(context, module, "path_unlink_file", types(FD_TYPE, STRING_ADDRESS_TYPE, STRING_LENGTH_TYPE), types(ERRNO_TYPE), new WasiPathUnlinkFileNode(language, module));
+ defineFunction(context, module, "poll_oneoff", types(CONST_POINTER_TYPE, POINTER_TYPE, SIZE_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiUnsupportedFunctionNode(language, module, "__wasi_poll_oneoff"));
+ defineFunction(context, module, "proc_exit", types(EXITCODE_TYPE), types(), new WasiProcExitNode(language, module));
+ defineFunction(context, module, "proc_raise", types(SIGNAL_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_proc_raise"));
+ defineFunction(context, module, "sched_yield", types(), types(ERRNO_TYPE), new WasiSchedYieldNode(language, module));
if (context.getContextOptions().constantRandomGet()) {
- defineFunction(context, module, "random_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiConstantRandomGetNode(language, module));
+ defineFunction(context, module, "random_get", types(POINTER_TYPE, SIZE_TYPE), types(ERRNO_TYPE), new WasiConstantRandomGetNode(language, module));
} else {
- defineFunction(context, module, "random_get", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiRandomGetNode(language, module));
+ defineFunction(context, module, "random_get", types(POINTER_TYPE, SIZE_TYPE), types(ERRNO_TYPE), new WasiRandomGetNode(language, module));
}
- defineFunction(context, module, "sock_accept", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_accept"));
- defineFunction(context, module, "sock_recv", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_recv"));
- defineFunction(context, module, "sock_send", types(I32_TYPE, I32_TYPE, I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_send"));
- defineFunction(context, module, "sock_shutdown", types(I32_TYPE, I32_TYPE), types(I32_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_shutdown"));
+ defineFunction(context, module, "sock_accept", types(FD_TYPE, FDFLAGS_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_accept"));
+ defineFunction(context, module, "sock_recv", types(FD_TYPE, IOVEC_ARRAY_ADDRESS_TYPE, IOVEC_ARRAY_LENGTH_TYPE, RIFLAGS_TYPE, RETURN_VALUE_ADDRESS_TYPE, RETURN_VALUE_ADDRESS_TYPE),
+ types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_recv"));
+ defineFunction(context, module, "sock_send", types(FD_TYPE, CIOVEC_ARRAY_ADDRESS_TYPE, CIOVEC_ARRAY_LENGTH_TYPE, SIFLAGS_TYPE, RETURN_VALUE_ADDRESS_TYPE), types(ERRNO_TYPE),
+ new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_send"));
+ defineFunction(context, module, "sock_shutdown", types(FD_TYPE, SDFLAGS_TYPE), types(ERRNO_TYPE), new WasiUnsupportedFunctionNode(language, module, "__wasi_sock_shutdown"));
return module;
}
-
}
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiPathReadLinkNode.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiPathReadLinkNode.java
index 19ddb1ff18df..47ec3b93c99b 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiPathReadLinkNode.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiPathReadLinkNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -66,16 +66,17 @@ public Object executeWithContext(VirtualFrame frame, WasmContext context, WasmIn
(int) WasmArguments.getArgument(args, 1),
(int) WasmArguments.getArgument(args, 2),
(int) WasmArguments.getArgument(args, 3),
- (int) WasmArguments.getArgument(args, 4));
+ (int) WasmArguments.getArgument(args, 4),
+ (int) WasmArguments.getArgument(args, 5));
}
@TruffleBoundary
- private int pathReadLink(WasmContext context, WasmMemory memory, int fd, int pathAddress, int pathLength, int buf, int bufLen) {
+ private int pathReadLink(WasmContext context, WasmMemory memory, int fd, int pathAddress, int pathLength, int buf, int bufLen, int sizeAddress) {
final Fd handle = context.fdManager().get(fd);
if (handle == null) {
return Errno.Badf.ordinal();
}
- return handle.pathReadLink(this, memory, pathAddress, pathLength, buf, bufLen);
+ return handle.pathReadLink(this, memory, pathAddress, pathLength, buf, bufLen, sizeAddress);
}
@Override
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/DirectoryFd.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/DirectoryFd.java
index 50b58075b15a..4a6c1fb2c1fc 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/DirectoryFd.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/DirectoryFd.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -315,7 +315,7 @@ public Errno pathOpen(Node node, WasmMemory memory, int dirFlags, int pathAddres
}
@Override
- public int pathReadLink(Node node, WasmMemory memory, int pathAddress, int pathLength, int buf, int bufLen) {
+ public int pathReadLink(Node node, WasmMemory memory, int pathAddress, int pathLength, int buf, int bufLen, int sizeAddress) {
if (!isSet(fsRightsBase, Rights.PathReadlink)) {
return Errno.Notcapable.ordinal();
}
@@ -330,7 +330,9 @@ public int pathReadLink(Node node, WasmMemory memory, int pathAddress, int pathL
return Errno.Noent.ordinal();
}
final String content = virtualLink.getPath();
- return memory.writeString(node, content, buf, bufLen);
+ int bytesWritten = memory.writeString(node, content, buf, bufLen);
+ memory.store_i32(node, sizeAddress, bytesWritten);
+ return Errno.Success.ordinal();
} catch (NotLinkException e) {
return Errno.Nolink.ordinal();
} catch (IOException | UnsupportedOperationException e) {
diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/Fd.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/Fd.java
index 2d95a8ae0b7e..7c0a5923e24f 100644
--- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/Fd.java
+++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/fd/Fd.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -44,6 +44,7 @@
import com.oracle.truffle.api.nodes.Node;
import org.graalvm.wasm.exception.WasmException;
import org.graalvm.wasm.memory.WasmMemory;
+import org.graalvm.wasm.predefined.wasi.types.Advice;
import org.graalvm.wasm.predefined.wasi.types.Errno;
import org.graalvm.wasm.predefined.wasi.types.Fdflags;
import org.graalvm.wasm.predefined.wasi.types.Filetype;
@@ -257,6 +258,14 @@ public Errno seek(Node node, WasmMemory memory, long offset, Whence whence, int
return Errno.Acces;
}
+ @SuppressWarnings("unused")
+ public Errno advise(long offset, long length, Advice advice) {
+ if (!isSet(fsRightsBase, Rights.FdAdvise)) {
+ return Errno.Notcapable;
+ }
+ return Errno.Success;
+ }
+
/**
* Implementation of WASI fd_fdstat_get
:
@@ -480,11 +489,13 @@ public Errno pathLink(Node node, WasmMemory memory, int oldFlags, int oldPathAdd
* @param pathLength length of the path to get, in bytes, including the trailing null character
* @param buf the buffer to which to write the contents of the symbolic link
* @param bufLen the length of the buffer
+ * @param sizeAddress {@code size*}: address at which to write the number of bytes written to
+ * {@code buf}
* @return {@link Errno#Success} in case of success, or another {@link Errno} in case of error
* @throws WasmException if an error happens while writing or reading to {@code memory}
* @see Pre-opened directories
*/
- public int pathReadLink(Node node, WasmMemory memory, int pathAddress, int pathLength, int buf, int bufLen) {
+ public int pathReadLink(Node node, WasmMemory memory, int pathAddress, int pathLength, int buf, int bufLen, int sizeAddress) {
if (!isSet(fsRightsBase, Rights.PathReadlink)) {
return Errno.Notcapable.ordinal();
}