Skip to content

Commit 441fb53

Browse files
committed
[GR-54736] WASI proc_exit should respect useSystemExit(true).
PullRequest: graal/20026
2 parents d2d7d44 + 326b187 commit 441fb53

File tree

6 files changed

+56
-130
lines changed

6 files changed

+56
-130
lines changed

wasm/mx.wasm/mx_wasm.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
emcc_dir = mx.get_env("EMCC_DIR", None)
6262
gcc_dir = mx.get_env("GCC_DIR", "")
63-
wabt_dir = mx.get_env("WABT_DIR", None)
63+
wabt_dir = mx.get_env("WABT_DIR", "")
6464

6565
NODE_BENCH_DIR = "node"
6666
NATIVE_BENCH_DIR = "native"
@@ -96,14 +96,11 @@ class GraalWasmDefaultTags:
9696
coverage = "coverage"
9797

9898

99-
def wat2wasm_binary():
100-
return mx.exe_suffix("wat2wasm")
101-
10299
def wabt_test_args():
103100
if not wabt_dir:
104101
mx.warn("No WABT_DIR specified")
105102
return []
106-
return ["-Dwasmtest.watToWasmExecutable=" + os.path.join(wabt_dir, wat2wasm_binary())]
103+
return ["-Dwasmtest.watToWasmExecutable=" + os.path.join(wabt_dir, mx.exe_suffix("wat2wasm"))]
107104

108105

109106
def graal_wasm_gate_runner(args, tasks):
@@ -277,14 +274,15 @@ def __str__(self):
277274
def build(self):
278275
source_dir = self.subject.getSourceDir()
279276
output_dir = self.subject.getOutputDir()
280-
if not wabt_dir:
281-
mx.abort("No WABT_DIR specified - the source programs will not be compiled to .wasm.")
282-
wat2wasm_cmd = os.path.join(wabt_dir, "wat2wasm")
283277

284-
wat2wasm_version_cmd = [wat2wasm_cmd] + ["--version"]
278+
wat2wasm_cmd = os.path.join(wabt_dir, "wat2wasm")
285279
out = mx.OutputCapture()
286280
bulk_memory_option = None
287-
mx.run(wat2wasm_version_cmd, nonZeroIsFatal=False, out=out)
281+
if mx.run([wat2wasm_cmd, "--version"], nonZeroIsFatal=False, out=out) != 0:
282+
if not wabt_dir:
283+
mx.warn("No WABT_DIR specified.")
284+
mx.abort("Could not check the wat2wasm version.")
285+
288286
wat2wasm_version = str(out.data).split(".")
289287
major = int(wat2wasm_version[0])
290288
build = int(wat2wasm_version[2])
@@ -407,12 +405,17 @@ def build(self):
407405
mx.abort("No EMCC_DIR specified - the source programs will not be compiled to .wasm.")
408406
emcc_cmd = os.path.join(emcc_dir, "emcc")
409407
gcc_cmd = os.path.join(gcc_dir, "gcc")
408+
wat2wasm_cmd = os.path.join(wabt_dir, "wat2wasm")
409+
wasm2wat_cmd = os.path.join(wabt_dir, "wasm2wat")
410410
if mx.run([emcc_cmd, "-v"], nonZeroIsFatal=False) != 0:
411411
mx.abort("Could not check the emcc version.")
412412
if mx.run([gcc_cmd, "--version"], nonZeroIsFatal=False) != 0:
413413
mx.abort("Could not check the gcc version.")
414-
if not wabt_dir:
415-
mx.abort("Set WABT_DIR if you want the binary to include .wat files.")
414+
if mx.run([wat2wasm_cmd, "--version"], nonZeroIsFatal=False) != 0:
415+
if not wabt_dir:
416+
mx.warn("No WABT_DIR specified.")
417+
mx.abort("Could not check the wat2wasm version.")
418+
416419
mx.log("Building files from the source dir: " + source_dir)
417420
cc_flags = ["-g2", "-O3"]
418421
include_flags = []
@@ -448,7 +451,6 @@ def build(self):
448451
mx.abort("Could not build the wasm-only output of " + filename + " with emcc.")
449452
elif filename.endswith(".wat"):
450453
# Step 1: compile the .wat file to .wasm.
451-
wat2wasm_cmd = os.path.join(wabt_dir, "wat2wasm")
452454
build_cmd_line = [wat2wasm_cmd, "-o", output_wasm_path, source_path]
453455
if mx.run(build_cmd_line, nonZeroIsFatal=False) != 0:
454456
mx.abort("Could not translate " + filename + " to binary format.")
@@ -474,7 +476,6 @@ def build(self):
474476
if mustRebuild:
475477
if filename.endswith(".c"):
476478
# Step 4: produce the .wat files, for easier debugging.
477-
wasm2wat_cmd = os.path.join(wabt_dir, "wasm2wat")
478479
if mx.run([wasm2wat_cmd, "-o", output_wat_path, output_wasm_path], nonZeroIsFatal=False) != 0:
479480
mx.abort("Could not compile .wat file for " + filename)
480481
elif filename.endswith(".wat"):

wasm/src/org.graalvm.wasm.test/src/org/graalvm/wasm/test/WasmFileSuite.java

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -222,37 +222,40 @@ private void runInContext(WasmCase testCase, Context context, List<Source> sourc
222222
e.setStackTrace(new StackTraceElement[0]);
223223
throw e;
224224
} finally {
225-
// Save context state, and check that it's consistent with the previous one.
226-
if (iterationNeedsStateCheck(i)) {
227-
final ContextState contextState = saveContext(wasmContext);
228-
if (firstIterationContextState == null) {
229-
firstIterationContextState = contextState;
230-
} else {
231-
assertContextEqual(firstIterationContextState, contextState);
225+
// Context may have already been closed, e.g. by __wasi_proc_exit.
226+
if (!wasmContext.environment().getContext().isClosed()) {
227+
// Save context state, and check that it's consistent with the previous one.
228+
if (iterationNeedsStateCheck(i)) {
229+
final ContextState contextState = saveContext(wasmContext);
230+
if (firstIterationContextState == null) {
231+
firstIterationContextState = contextState;
232+
} else {
233+
assertContextEqual(firstIterationContextState, contextState);
234+
}
232235
}
233-
}
234236

235-
// Reset context state.
236-
final boolean reinitMemory = requiresZeroMemory || iterationNeedsStateCheck(i + 1);
237-
if (reinitMemory) {
238-
for (int j = 0; j < wasmContext.memories().count(); ++j) {
239-
WasmMemoryLibrary.getUncached().reset(wasmContext.memories().memory(j));
240-
}
241-
for (int j = 0; j < wasmContext.tables().tableCount(); ++j) {
242-
wasmContext.tables().table(j).reset();
237+
// Reset context state.
238+
final boolean reinitMemory = requiresZeroMemory || iterationNeedsStateCheck(i + 1);
239+
if (reinitMemory) {
240+
for (int j = 0; j < wasmContext.memories().count(); ++j) {
241+
WasmMemoryLibrary.getUncached().reset(wasmContext.memories().memory(j));
242+
}
243+
for (int j = 0; j < wasmContext.tables().tableCount(); ++j) {
244+
wasmContext.tables().table(j).reset();
245+
}
243246
}
244-
}
245-
List<WasmInstance> instanceList = new ArrayList<>(wasmContext.moduleInstances().values());
246-
instanceList.sort(Comparator.comparingInt(RuntimeState::startFunctionIndex));
247-
for (WasmInstance instance : instanceList) {
248-
if (!instance.isBuiltin()) {
249-
wasmContext.reinitInstance(instance, reinitMemory);
247+
List<WasmInstance> instanceList = new ArrayList<>(wasmContext.moduleInstances().values());
248+
instanceList.sort(Comparator.comparingInt(RuntimeState::startFunctionIndex));
249+
for (WasmInstance instance : instanceList) {
250+
if (!instance.isBuiltin()) {
251+
wasmContext.reinitInstance(instance, reinitMemory);
252+
}
250253
}
251-
}
252254

253-
// Reset stdin
254-
if (wasmContext.environment().in() instanceof ByteArrayInputStream) {
255-
wasmContext.environment().in().reset();
255+
// Reset stdin
256+
if (wasmContext.environment().in() instanceof ByteArrayInputStream) {
257+
wasmContext.environment().in().reset();
258+
}
256259
}
257260
}
258261
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
exception Program exited with status code 11.
1+
exception Exit was called with exit code 11.

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/Linker.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
109109
import com.oracle.truffle.api.RootCallTarget;
110110
import com.oracle.truffle.api.TruffleContext;
111+
import com.oracle.truffle.api.exception.AbstractTruffleException;
111112
import com.oracle.truffle.api.nodes.Node;
112113

113114
public class Linker {
@@ -305,10 +306,12 @@ static void runStartFunction(WasmInstance instance) {
305306
private static void checkFailures(ArrayList<Throwable> failures) {
306307
if (!failures.isEmpty()) {
307308
final Throwable first = failures.get(0);
308-
if (first instanceof WasmException) {
309-
throw (WasmException) first;
310-
} else if (first instanceof RuntimeException) {
311-
throw (RuntimeException) first;
309+
if (first instanceof AbstractTruffleException e) {
310+
throw e;
311+
} else if (first instanceof RuntimeException e) {
312+
throw e;
313+
} else if (first instanceof Error e) { // includes ThreadDeath
314+
throw e;
312315
} else {
313316
throw new RuntimeException(first);
314317
}

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/exception/WasmExit.java

Lines changed: 0 additions & 82 deletions
This file was deleted.

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/predefined/wasi/WasiProcExitNode.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,11 +41,11 @@
4141
package org.graalvm.wasm.predefined.wasi;
4242

4343
import org.graalvm.wasm.WasmArguments;
44+
import org.graalvm.wasm.WasmConstant;
4445
import org.graalvm.wasm.WasmContext;
4546
import org.graalvm.wasm.WasmInstance;
4647
import org.graalvm.wasm.WasmLanguage;
4748
import org.graalvm.wasm.WasmModule;
48-
import org.graalvm.wasm.exception.WasmExit;
4949
import org.graalvm.wasm.predefined.WasmBuiltinRootNode;
5050

5151
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -59,7 +59,8 @@ public WasiProcExitNode(WasmLanguage language, WasmModule module) {
5959
@Override
6060
public Object executeWithContext(VirtualFrame frame, WasmContext context, WasmInstance instance) {
6161
final int exitCode = (int) WasmArguments.getArgument(frame.getArguments(), 0);
62-
throw new WasmExit(this, exitCode);
62+
context.environment().getContext().closeExited(this, exitCode);
63+
return WasmConstant.VOID;
6364
}
6465

6566
@Override

0 commit comments

Comments
 (0)