gnodet-bot commented on code in PR #27793:
URL: https://github.com/apache/camel/pull/27793#discussion_r4265444237


##########
components/camel-wasm/src/main/java/org/apache/camel/wasm/WasiCommand.java:
##########
@@ -73,10 +91,77 @@ public final class WasiCommand {
      *                                  than the initial memory the module 
declares
      */
     public WasiCommand(WasmModule module, List<String> arguments, int 
maxMemoryPages) {
+        this(module, arguments, maxMemoryPages, false);
+    }
+
+    /**
+     * @param  module                   the parsed module
+     * @param  arguments                the program's arguments, the program 
name first
+     * @param  maxMemoryPages           the maximum number of 64 KiB pages the 
module's memory may grow to, or 0 to keep
+     *                                  the maximum the module declares
+     * @param  compile                  whether to translate the module to JVM 
bytecode now, with the Endive runtime
+     *                                  compiler, instead of interpreting it. 
This defines classes at run time, which a
+     *                                  GraalVM native image cannot do. A 
function that is too large for a JVM method is
+     *                                  left to the interpreter, which is 
logged once, at WARN
+     * @throws IllegalArgumentException if the module is not a WASI Preview 1 
command module, or maxMemoryPages is lower
+     *                                  than the initial memory the module 
declares
+     * @throws IllegalStateException    if compile is set and the Endive 
runtime compiler is not on the classpath, or
+     *                                  cannot compile the module. The message 
names the module by its program name (the
+     *                                  first argument)
+     */
+    public WasiCommand(WasmModule module, List<String> arguments, int 
maxMemoryPages, boolean compile) {
         this.module = Objects.requireNonNull(module);
         this.arguments = List.copyOf(arguments);
         validate(module);
         this.memoryLimits = memoryLimits(module, maxMemoryPages);
+
+        Function<Instance, Machine> factory = null;
+        boolean fallback = false;
+        if (compile) {
+            String name = this.arguments.isEmpty() ? "(no name)" : 
this.arguments.get(0);
+            try {
+                try {
+                    factory = RuntimeCompiler.compile(module, false);
+                } catch (WasmEngineException e) {
+                    // Endive could not compile every function. When the 
reason is a function that is too large for a
+                    // JVM method, the module still works with that function 
interpreted, so compile again with the
+                    // interpreter as fallback; for any other reason this 
second attempt fails as the first one did.
+                    factory = RuntimeCompiler.compile(module, true);
+                    fallback = true;
+                    LOG.warn("The Wasm module {} is compiled in part only: it 
has functions that are too large for a"

Review Comment:
   💡 **Log level question.** `WARN` for partial compilation (interpreter 
fallback for oversized functions) may surprise operators monitoring for 
warnings, since the module still works correctly — just with lower performance 
for those specific functions. `INFO` would better match the semantics. That 
said, `WARN` is defensible for startup visibility — this is a configuration 
decision worth a deliberate call either way.



##########
components/camel-wasm/pom.xml:
##########
@@ -54,6 +54,12 @@
             <artifactId>wasi</artifactId>
             <version>${endive-version}</version>
         </dependency>
+        <!-- used with compile=true only: translates a module to JVM bytecode, 
once per endpoint -->
+        <dependency>
+            <groupId>run.endive</groupId>
+            <artifactId>compiler</artifactId>
+            <version>${endive-version}</version>
+        </dependency>

Review Comment:
   💡 **Optional dependency worth considering.** The code already handles the 
compiler's absence gracefully: `RuntimeCompiler` is isolated behind an 
inner-class boundary (classloading barrier), `NoClassDefFoundError` is caught 
with a clear error message, and there is a dedicated test for that scenario. 
Making the dependency `<optional>true</optional>` would avoid pulling 
`run.endive:compiler` and its ASM transitive deps for users who never set 
`compile=true` (the default). The trade-off is that users who do want 
compilation would need to add it explicitly.
   
   ```suggestion
           <!-- used with compile=true only: translates a module to JVM 
bytecode, once per endpoint -->
           <dependency>
               <groupId>run.endive</groupId>
               <artifactId>compiler</artifactId>
               <version>${endive-version}</version>
               <optional>true</optional>
           </dependency>
   ```



-- 
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]

Reply via email to