Copilot commented on code in PR #6356:
URL: https://github.com/apache/shenyu/pull/6356#discussion_r3354296257
##########
shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java:
##########
@@ -93,91 +92,270 @@ public WasmLoader(final Class<?> wasmClass, final
Function<Store<Void>, Map<Stri
if (Objects.isNull(resource)) {
throw new ShenyuWasmInitException("Can't find wasm file: " +
wasmName);
}
- // Reads the WebAssembly module as bytes.
- byte[] wasmBytes = Files.readAllBytes(Paths.get(resource.toURI()));
// Instantiates the WebAssembly module.
+
+ this.store = new Store();
+
+ // Register WASI preview1 stubs. Both Go and Rust modules need
these,
+ // but we implement our own no-op versions instead of using
Chicory's
+ // WasiPreview1 to avoid WasiExitException from proc_exit(0).
+ registerWasiStubs(store);
+
+ // Allow subclasses to register custom host functions
(get_args/put_result).
if (Objects.nonNull(initializer)) {
- Map<String, Func> wasmFunctionMap = initializer.apply(store);
- if (Objects.nonNull(wasmFunctionMap) &&
!wasmFunctionMap.isEmpty()) {
- wasmCallJavaFuncMap.putAll(wasmFunctionMap);
- }
+ initializer.accept(store);
+ } else {
+ registerBuiltinHostFunctions(store);
}
- Map<String, Func> wasmFunctionMap = initWasmCallJavaFunc(store);
- if (Objects.nonNull(wasmFunctionMap) &&
!wasmFunctionMap.isEmpty()) {
- wasmCallJavaFuncMap.putAll(wasmFunctionMap);
+
+ // Allow WasmLoader subclasses to override and register additional
host functions.
+ // Only called when not using Consumer initializer, to avoid
double invocation.
+ if (Objects.isNull(initializer)) {
+ initWasmCallJavaFunc(store);
}
- this.module = Module.fromBinary(store.engine(), wasmBytes);
- WasiCtx.addToLinker(linker);
- // maybe need define many functions
- if (!wasmCallJavaFuncMap.isEmpty()) {
- wasmCallJavaFuncMap.forEach((funcName, wasmCallJavaFunc) ->
- linker.define(store, IMPORT_WASM_MODULE_NAME,
funcName, Extern.fromFunc(wasmCallJavaFunc)));
+
+ // Reads the WebAssembly module as bytes.
+ byte[] wasmBytes = Files.readAllBytes(Paths.get(resource.toURI()));
+ WasmModule module = Parser.parse(wasmBytes);
+
+ // Try runtime compiler (WASM β JVM bytecode) for better execution
speed.
+ // Falls back gracefully to interpreter if something goes wrong.
+ try {
+ this.instance = Instance.builder(module)
+ .withImportValues(store.toImportValues())
+
.withMachineFactory(MachineFactoryCompiler.compile(module))
+ .withStart(false)
+ .build();
+ LOG.debug("Using runtime compiler for {}", wasmName);
+ } catch (LinkageError | RuntimeException compilerError) {
+ LOG.warn("Runtime compiler unavailable, falling back to
interpreter for {}: {}",
+ wasmName, compilerError.getMessage());
+ this.instance = store.instantiate(wasmName, module);
}
- linker.module(store, "", module);
- // Let the `wasmCallJavaFunc` function to refer this as a
placeholder of Memory because
- // we have to add the function as import before loading the module
exporting Memory.
- Optional<Extern> extern = this.getWasmExtern(MEMORY_METHOD_NAME);
- if (!extern.isPresent()) {
- throw new ShenyuWasmInitException(MEMORY_METHOD_NAME + "
function not find in wasm file: " + wasmName);
+
+ // Call _initialize if present (required by TinyGo -target
wasm-unknown).
+ try {
+ ExportFunction initFn = instance.export("_initialize");
+ if (Objects.nonNull(initFn)) {
+ initFn.apply();
+ LOG.debug("Called _initialize for {}", wasmName);
+ }
+ } catch (com.dylibso.chicory.wasm.InvalidException e) {
+ LOG.debug("No _initialize export in {}", wasmName);
+ }
+
+ if (Objects.isNull(instance.memory())) {
+ throw new ShenyuWasmInitException("memory not available in
wasm file: " + wasmName);
}
- this.memRef = extern.get().memory();
+
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
} catch (URISyntaxException | IOException e) {
throw new ShenyuWasmInitException(e);
}
}
-
- protected Map<String, Func> initWasmCallJavaFunc(final Store<Void> store) {
- return null;
+
+ private void registerWasiStubs(final Store store) {
+ // proc_exit(code: i32) -> ()
+ store.addFunction(new HostFunction(
+ "wasi_snapshot_preview1", "proc_exit",
+ FunctionType.of(List.of(ValType.I32), List.of()),
+ (inst, args) -> null
+ ));
Review Comment:
The proc_exit WASI stub returns null from the HostFunction callback. Chicory
host functions are expected to return a (possibly empty) long[]; returning null
can trigger a NullPointerException when the WASM module calls proc_exit.
##########
shenyu-plugin/shenyu-plugin-wasm-base/src/test/pkg/wasmabi/abi.go:
##########
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package wasmabi provides helper functions for communicating with the Java
+// ShenYu host via shared memory. TinyGo WASM plugins should use GetArgs and
+// PutResult instead of calling the raw host imports directly.
+package wasmabi
+
+import "unsafe"
+
+//go:wasmimport shenyu get_args
+func getArgsRaw(argId int64, addr int64, len int32) int32
+
+//go:wasmimport shenyu put_result
+func putResultRaw(argId int64, addr int64, len int32) int32
+
+// GetArgs reads serialized data from the Java host via shared memory.
+// The caller provides a pre-allocated buffer; the returned slice is a
+// sub-slice of buf containing the actual data that was written.
+func GetArgs(argId int64, buf []byte) []byte {
+ ptr := unsafe.Pointer(&buf[0])
+ n := getArgsRaw(argId, int64(uintptr(ptr)), int32(len(buf)))
+ return buf[:n]
+}
Review Comment:
GetArgs will panic on an empty buffer ("index out of range" at &buf[0]) and
can also panic if the host returns a negative length or a length larger than
the provided buffer (buf[:n]). This makes the TinyGo ABI helper unsafe for
general use and can crash plugins on host-side errors.
##########
pom.xml:
##########
@@ -799,6 +809,10 @@
<!-- document files -->
<exclude>**/*.md</exclude>
<excldue>**/*.MD</excldue>
+ <!-- wasm build files -->
+ <exclude>**/Cargo.lock</exclude>
+ <exclude>**/go.mod</exclude>
+ <exclude>**/go.sum</exclude>
Review Comment:
apache-rat-plugin is configured to exclude go.mod. Unlike go.sum/Cargo.lock,
go.mod files in this PR already include an ASF license header, so excluding
them weakens license checking and makes it easier to accidentally add
unlicensed go.mod files in the future.
##########
shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java:
##########
@@ -93,91 +92,270 @@ public WasmLoader(final Class<?> wasmClass, final
Function<Store<Void>, Map<Stri
if (Objects.isNull(resource)) {
throw new ShenyuWasmInitException("Can't find wasm file: " +
wasmName);
}
- // Reads the WebAssembly module as bytes.
- byte[] wasmBytes = Files.readAllBytes(Paths.get(resource.toURI()));
// Instantiates the WebAssembly module.
+
+ this.store = new Store();
+
+ // Register WASI preview1 stubs. Both Go and Rust modules need
these,
+ // but we implement our own no-op versions instead of using
Chicory's
+ // WasiPreview1 to avoid WasiExitException from proc_exit(0).
+ registerWasiStubs(store);
+
+ // Allow subclasses to register custom host functions
(get_args/put_result).
if (Objects.nonNull(initializer)) {
- Map<String, Func> wasmFunctionMap = initializer.apply(store);
- if (Objects.nonNull(wasmFunctionMap) &&
!wasmFunctionMap.isEmpty()) {
- wasmCallJavaFuncMap.putAll(wasmFunctionMap);
- }
+ initializer.accept(store);
+ } else {
+ registerBuiltinHostFunctions(store);
}
- Map<String, Func> wasmFunctionMap = initWasmCallJavaFunc(store);
- if (Objects.nonNull(wasmFunctionMap) &&
!wasmFunctionMap.isEmpty()) {
- wasmCallJavaFuncMap.putAll(wasmFunctionMap);
+
+ // Allow WasmLoader subclasses to override and register additional
host functions.
+ // Only called when not using Consumer initializer, to avoid
double invocation.
+ if (Objects.isNull(initializer)) {
+ initWasmCallJavaFunc(store);
}
- this.module = Module.fromBinary(store.engine(), wasmBytes);
- WasiCtx.addToLinker(linker);
- // maybe need define many functions
- if (!wasmCallJavaFuncMap.isEmpty()) {
- wasmCallJavaFuncMap.forEach((funcName, wasmCallJavaFunc) ->
- linker.define(store, IMPORT_WASM_MODULE_NAME,
funcName, Extern.fromFunc(wasmCallJavaFunc)));
+
+ // Reads the WebAssembly module as bytes.
+ byte[] wasmBytes = Files.readAllBytes(Paths.get(resource.toURI()));
+ WasmModule module = Parser.parse(wasmBytes);
+
+ // Try runtime compiler (WASM β JVM bytecode) for better execution
speed.
+ // Falls back gracefully to interpreter if something goes wrong.
+ try {
+ this.instance = Instance.builder(module)
+ .withImportValues(store.toImportValues())
+
.withMachineFactory(MachineFactoryCompiler.compile(module))
+ .withStart(false)
+ .build();
+ LOG.debug("Using runtime compiler for {}", wasmName);
+ } catch (LinkageError | RuntimeException compilerError) {
+ LOG.warn("Runtime compiler unavailable, falling back to
interpreter for {}: {}",
+ wasmName, compilerError.getMessage());
+ this.instance = store.instantiate(wasmName, module);
}
- linker.module(store, "", module);
- // Let the `wasmCallJavaFunc` function to refer this as a
placeholder of Memory because
- // we have to add the function as import before loading the module
exporting Memory.
- Optional<Extern> extern = this.getWasmExtern(MEMORY_METHOD_NAME);
- if (!extern.isPresent()) {
- throw new ShenyuWasmInitException(MEMORY_METHOD_NAME + "
function not find in wasm file: " + wasmName);
+
+ // Call _initialize if present (required by TinyGo -target
wasm-unknown).
+ try {
+ ExportFunction initFn = instance.export("_initialize");
+ if (Objects.nonNull(initFn)) {
+ initFn.apply();
+ LOG.debug("Called _initialize for {}", wasmName);
+ }
+ } catch (com.dylibso.chicory.wasm.InvalidException e) {
+ LOG.debug("No _initialize export in {}", wasmName);
+ }
+
+ if (Objects.isNull(instance.memory())) {
+ throw new ShenyuWasmInitException("memory not available in
wasm file: " + wasmName);
}
- this.memRef = extern.get().memory();
+
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
} catch (URISyntaxException | IOException e) {
throw new ShenyuWasmInitException(e);
}
}
-
- protected Map<String, Func> initWasmCallJavaFunc(final Store<Void> store) {
- return null;
+
+ private void registerWasiStubs(final Store store) {
+ // proc_exit(code: i32) -> ()
+ store.addFunction(new HostFunction(
+ "wasi_snapshot_preview1", "proc_exit",
+ FunctionType.of(List.of(ValType.I32), List.of()),
+ (inst, args) -> null
+ ));
+ // random_get(buf: i32, buf_len: i32) -> errno: i32
+ store.addFunction(new HostFunction(
+ "wasi_snapshot_preview1", "random_get",
+ FunctionType.of(List.of(ValType.I32, ValType.I32),
List.of(ValType.I32)),
+ (inst, args) -> {
+ int buf = (int) args[0];
+ int bufLen = (int) args[1];
+ byte[] randomBytes = new byte[bufLen];
+ ThreadLocalRandom.current().nextBytes(randomBytes);
+ inst.memory().write(buf, randomBytes);
+ return new long[]{0};
+ }
+ ));
+ // fd_write(fd: i32, iovs: i32, iovs_len: i32, nwritten: i32) ->
errno: i32
+ store.addFunction(new HostFunction(
+ "wasi_snapshot_preview1", "fd_write",
+ FunctionType.of(List.of(ValType.I32, ValType.I32, ValType.I32,
ValType.I32), List.of(ValType.I32)),
+ (inst, args) -> {
+ int fd = (int) args[0];
+ int iovs = (int) args[1];
+ int iovsLen = (int) args[2];
+ int nwrittenPtr = (int) args[3];
+ long total = 0;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < iovsLen; i++) {
+ int off = iovs + i * 8;
+ int bufOff = (int) inst.memory().readI32(off);
+ int bufLen = (int) inst.memory().readI32(off + 4);
+ if (bufLen > 0) {
+ sb.append(new
String(inst.memory().readBytes(bufOff, bufLen),
java.nio.charset.StandardCharsets.UTF_8));
+ }
+ total += bufLen;
+ }
+ String output = sb.toString();
+ if (fd == 1) {
+ System.out.print(output);
+ } else if (fd == 2) {
+ System.err.print(output);
+ }
+ inst.memory().writeI32(nwrittenPtr, (int) total);
+ return new long[]{0};
+ }
+ ));
+ // environ_get(environ: i32, environ_buf: i32) -> errno: i32
+ store.addFunction(new HostFunction(
+ "wasi_snapshot_preview1", "environ_get",
+ FunctionType.of(List.of(ValType.I32, ValType.I32),
List.of(ValType.I32)),
+ (inst, args) -> new long[]{0}
+ ));
+ // environ_sizes_get(count: i32, buf_size: i32) -> errno: i32
+ store.addFunction(new HostFunction(
+ "wasi_snapshot_preview1", "environ_sizes_get",
+ FunctionType.of(List.of(ValType.I32, ValType.I32),
List.of(ValType.I32)),
+ (inst, args) -> {
+ int countPtr = (int) args[0];
+ int sizePtr = (int) args[1];
+ inst.memory().writeI32(countPtr, 0);
+ inst.memory().writeI32(sizePtr, 0);
+ return new long[]{0};
+ }
+ ));
+ }
+
+ private void registerBuiltinHostFunctions(final Store store) {
+ store.addFunction(new HostFunction(
+ IMPORT_WASM_MODULE_NAME, "get_args",
+ FunctionType.of(List.of(ValType.I64, ValType.I64,
ValType.I32), List.of(ValType.I32)),
+ (instance, args) -> new long[]{onGetArgs(args[0], args[1],
(int) args[2])}
+ ));
+ store.addFunction(new HostFunction(
+ IMPORT_WASM_MODULE_NAME, "put_result",
+ FunctionType.of(List.of(ValType.I64, ValType.I64,
ValType.I32), List.of(ValType.I32)),
+ (instance, args) -> new long[]{onPutResult(args[0], args[1],
(int) args[2])}
+ ));
}
/**
- * get the WASI function.
+ * Override in subclasses to register additional host functions exposed to
the
+ * WASM module. This is called during construction after the built-in host
+ * functions (WASI stubs and {@code get_args}/{@code put_result}) have been
+ * registered, allowing subclasses to add their own imports.
+ *
+ * <p>Example: register a custom host function in the "shenyu" namespace:
+ * <pre>{@code
+ * @Override
+ * protected void initWasmCallJavaFunc(final Store store) {
+ * store.addFunction(new HostFunction(
+ * "shenyu", "my_func",
+ * FunctionType.of(List.of(ValType.I32), List.of(ValType.I32)),
+ * (instance, args) -> new long[]{(int) args[0] + 1}
+ * ));
+ * }
+ * }</pre>
*
- * @param wasiFuncName the WASI function name
- * @return the WASI function
+ * @param store the Chicory Store where host functions can be registered
*/
- public Optional<Extern> getWasmExtern(final String wasiFuncName) {
- return linker.get(store, "", wasiFuncName);
+ protected void initWasmCallJavaFunc(final Store store) {
+ // no-op by default
}
-
+
/**
- * get the wasm file name.
+ * Called when the WASM module invokes the {@code get_args} host import
+ * ({@code (argId: i64, addr: i64, len: i32) -> i32}).
*
- * @return wasm file name
+ * <p>The WASM side passes a buffer address and length in its linear
memory.
+ * The Java implementation should write serialized argument data into that
+ * buffer and return the number of bytes actually written. Returning 0
+ * signals "no data".
+ *
+ * <p>Corresponding WASM-side call (via {@code wasmabi} Go helper):
+ * <pre>{@code
+ * buf := make([]byte, 1024)
+ * input := wasmabi.GetArgs(argId, buf)
+ * }</pre>
+ *
+ * @param argId the argument identifier passed from WASM (maps to a
Java-side argument)
+ * @param addr the starting address in WASM linear memory to write into
+ * @param len the maximum number of bytes to write
+ * @return the number of bytes actually written, or 0 if no data is
available
*/
- public String getWasmName() {
- return wasmName;
+ protected long onGetArgs(final long argId, final long addr, final int len)
{
+ return 0;
}
-
+
/**
- * use this when call WASI.
+ * Called when the WASM module invokes the {@code put_result} host import
+ * ({@code (argId: i64, addr: i64, len: i32) -> i32}).
+ *
+ * <p>The WASM side passes a pointer and length referencing result data in
+ * its linear memory. The Java implementation should read and process that
+ * data. Returning 0 signals "success".
+ *
+ * <p>Corresponding WASM-side call (via {@code wasmabi} Go helper):
+ * <pre>{@code
+ * wasmabi.PutResult(argId, []byte("my result"))
+ * }</pre>
*
- * @return the Store
+ * @param argId the argument identifier passed from WASM (maps to a
Java-side argument)
+ * @param addr the starting address in WASM linear memory to read from
+ * @param len the number of bytes to read
+ * @return 0 on success, or a non-zero error code
*/
- public Store<Void> getStore() {
- return store;
+ protected long onPutResult(final long argId, final long addr, final int
len) {
+ return 0;
+ }
+
+ /**
+ * Get the WASM exported function.
+ *
+ * @param funcName the name of the WASM exported function
+ * @return an Optional containing the ExportFunction if found, otherwise
empty
+ */
+ public Optional<ExportFunction> getWasmExtern(final String funcName) {
+ ExportFunction fn = instance.export(funcName);
+ if (Objects.isNull(fn)) {
+ LOG.warn("WASM export function '{}' not found in {}", funcName,
wasmName);
+ }
+ return Optional.ofNullable(fn);
Review Comment:
getWasmExtern logs WARN whenever an export is missing, even when callers
intentionally treat missing exports as optional via ifPresent(...) (e.g.,
before/after hooks, optional handler methods). This can generate noisy logs in
normal operation; consider downgrading to DEBUG (or only warning in call sites
that require the function).
##########
shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java:
##########
@@ -93,91 +92,270 @@ public WasmLoader(final Class<?> wasmClass, final
Function<Store<Void>, Map<Stri
if (Objects.isNull(resource)) {
throw new ShenyuWasmInitException("Can't find wasm file: " +
wasmName);
}
- // Reads the WebAssembly module as bytes.
- byte[] wasmBytes = Files.readAllBytes(Paths.get(resource.toURI()));
// Instantiates the WebAssembly module.
+
+ this.store = new Store();
+
+ // Register WASI preview1 stubs. Both Go and Rust modules need
these,
+ // but we implement our own no-op versions instead of using
Chicory's
+ // WasiPreview1 to avoid WasiExitException from proc_exit(0).
+ registerWasiStubs(store);
+
+ // Allow subclasses to register custom host functions
(get_args/put_result).
if (Objects.nonNull(initializer)) {
- Map<String, Func> wasmFunctionMap = initializer.apply(store);
- if (Objects.nonNull(wasmFunctionMap) &&
!wasmFunctionMap.isEmpty()) {
- wasmCallJavaFuncMap.putAll(wasmFunctionMap);
- }
+ initializer.accept(store);
+ } else {
+ registerBuiltinHostFunctions(store);
}
- Map<String, Func> wasmFunctionMap = initWasmCallJavaFunc(store);
- if (Objects.nonNull(wasmFunctionMap) &&
!wasmFunctionMap.isEmpty()) {
- wasmCallJavaFuncMap.putAll(wasmFunctionMap);
+
+ // Allow WasmLoader subclasses to override and register additional
host functions.
+ // Only called when not using Consumer initializer, to avoid
double invocation.
+ if (Objects.isNull(initializer)) {
+ initWasmCallJavaFunc(store);
}
- this.module = Module.fromBinary(store.engine(), wasmBytes);
- WasiCtx.addToLinker(linker);
- // maybe need define many functions
- if (!wasmCallJavaFuncMap.isEmpty()) {
- wasmCallJavaFuncMap.forEach((funcName, wasmCallJavaFunc) ->
- linker.define(store, IMPORT_WASM_MODULE_NAME,
funcName, Extern.fromFunc(wasmCallJavaFunc)));
+
+ // Reads the WebAssembly module as bytes.
+ byte[] wasmBytes = Files.readAllBytes(Paths.get(resource.toURI()));
+ WasmModule module = Parser.parse(wasmBytes);
+
+ // Try runtime compiler (WASM β JVM bytecode) for better execution
speed.
+ // Falls back gracefully to interpreter if something goes wrong.
+ try {
+ this.instance = Instance.builder(module)
+ .withImportValues(store.toImportValues())
+
.withMachineFactory(MachineFactoryCompiler.compile(module))
+ .withStart(false)
+ .build();
+ LOG.debug("Using runtime compiler for {}", wasmName);
+ } catch (LinkageError | RuntimeException compilerError) {
+ LOG.warn("Runtime compiler unavailable, falling back to
interpreter for {}: {}",
+ wasmName, compilerError.getMessage());
+ this.instance = store.instantiate(wasmName, module);
}
Review Comment:
When runtime compilation is unavailable, the fallback uses
store.instantiate(wasmName, module). In Chicory, instantiation runs the module
start function by default, which is inconsistent with the compiled path
(.withStart(false)) and can cause unexpected execution (e.g., TinyGo/Rust WASI
_start + proc_exit) during module load.
##########
shenyu-plugin/shenyu-plugin-wasm-base/src/test/pkg/wasmabi/abi.go:
##########
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package wasmabi provides helper functions for communicating with the Java
+// ShenYu host via shared memory. TinyGo WASM plugins should use GetArgs and
+// PutResult instead of calling the raw host imports directly.
+package wasmabi
+
+import "unsafe"
+
+//go:wasmimport shenyu get_args
+func getArgsRaw(argId int64, addr int64, len int32) int32
+
+//go:wasmimport shenyu put_result
+func putResultRaw(argId int64, addr int64, len int32) int32
+
+// GetArgs reads serialized data from the Java host via shared memory.
+// The caller provides a pre-allocated buffer; the returned slice is a
+// sub-slice of buf containing the actual data that was written.
+func GetArgs(argId int64, buf []byte) []byte {
+ ptr := unsafe.Pointer(&buf[0])
+ n := getArgsRaw(argId, int64(uintptr(ptr)), int32(len(buf)))
+ return buf[:n]
+}
+
+// PutResult writes serialized data back to the Java host via shared memory.
+func PutResult(argId int64, data []byte) {
+ ptr := unsafe.Pointer(&data[0])
+ _ = putResultRaw(argId, int64(uintptr(ptr)), int32(len(data)))
+}
Review Comment:
PutResult will panic when called with an empty slice because it takes
&data[0]. Even if current tests always pass non-empty results, this helper
should be safe for callers that legitimately want to return an empty payload.
##########
shenyu-plugin/shenyu-plugin-wasm-api/pom.xml:
##########
@@ -32,8 +32,16 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>io.github.kawamuray.wasmtime</groupId>
- <artifactId>wasmtime-java</artifactId>
+ <groupId>com.dylibso.chicory</groupId>
+ <artifactId>runtime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.dylibso.chicory</groupId>
+ <artifactId>wasi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.dylibso.chicory</groupId>
+ <artifactId>compiler</artifactId>
</dependency>
Review Comment:
The module adds a com.dylibso.chicory:wasi dependency, but there are no
references to com.dylibso.chicory.wasi.* in the codebase (WASI functions are
stubbed manually in WasmLoader). If itβs not needed transitively, removing it
reduces artifact size and avoids carrying an unused dependency.
##########
shenyu-dist/shenyu-bootstrap-dist/src/main/release-docs/LICENSE:
##########
@@ -268,6 +268,11 @@ The text of each license is the standard Apache 2.0
license.
curator-framework 5.7.0: https://github.com/apache/curator, Apache 2.0
curator-recipes 5.7.0: https://github.com/apache/curator, Apache 2.0
curator-x-discovery 4.3.0:
https://mvnrepository.com/artifact/org.apache.curator/curator-x-discovery,
Apache 2.0
+ chicory-runtime 1.7.3: https://github.com/dylibso/chicory, Apache 2.0
+ chicory-wasi 1.7.3: https://github.com/dylibso/chicory, Apache 2.0
+ chicory-compiler 1.7.3: https://github.com/dylibso/chicory, Apache 2.0
+ chicory-log 1.7.3: https://github.com/dylibso/chicory, Apache 2.0
+ chicory-wasm 1.7.3: https://github.com/dylibso/chicory, Apache 2.0
Review Comment:
The dependency list now includes several Chicory artifacts
(runtime/wasi/compiler/log/wasm), but there are no corresponding LICENSE-*.txt
files for Chicory under shenyu-bootstrap-dist/src/main/release-docs/licenses/.
For ASF release compliance, each listed third-party component should have its
license text included in that directory.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]