Skip to content

Commit 8337e08

Browse files
committed
Report synthetic stack frame for main().
Instead of failing hard with an `UnsupportedOperationException`.
1 parent 5284d08 commit 8337e08

File tree

2 files changed

+76
-13
lines changed

2 files changed

+76
-13
lines changed

web-image/src/com.oracle.svm.webimage/src/com/oracle/svm/webimage/substitute/system/Target_java_lang_StackWalker_Web.java

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,90 @@
3030
import java.util.function.Function;
3131
import java.util.stream.Stream;
3232

33+
import com.oracle.svm.core.SubstrateOptions;
3334
import com.oracle.svm.core.annotate.Substitute;
3435
import com.oracle.svm.core.annotate.TargetClass;
3536

3637
@TargetClass(value = java.lang.StackWalker.class)
38+
@SuppressWarnings({"static-method", "unused"})
3739
final class Target_java_lang_StackWalker_Web {
3840

3941
@Substitute
40-
@SuppressWarnings({"static-method", "unused"})
4142
private void forEach(Consumer<? super StackFrame> action) {
4243
throw new UnsupportedOperationException("StackWalker.forEach");
4344
}
4445

4546
@Substitute
46-
@SuppressWarnings("static-method")
4747
private Class<?> getCallerClass() {
4848
throw new UnsupportedOperationException("StackWalker.getCallerClass");
4949
}
5050

5151
@Substitute
52-
@SuppressWarnings({"static-method", "unused"})
5352
private <T> T walk(Function<? super Stream<StackFrame>, ? extends T> function) {
54-
throw new UnsupportedOperationException("StackWalker.walk");
53+
if (SyntheticStackSupport.MAIN_STACK_FRAME == null) {
54+
throw new UnsupportedOperationException("StackWalker.walk");
55+
}
56+
return function.apply(Stream.of(SyntheticStackSupport.MAIN_STACK_FRAME));
57+
}
58+
}
59+
60+
final class SyntheticStackSupport {
61+
public static final StackTraceElement MAIN_STACK_TRACE_ELEMENT;
62+
static final StackFrame MAIN_STACK_FRAME;
63+
64+
static {
65+
String mainClassName = SubstrateOptions.Class.getValue();
66+
String mainMethodName = SubstrateOptions.Method.getValue();
67+
if (mainClassName.isEmpty() || mainMethodName.isEmpty()) {
68+
MAIN_STACK_TRACE_ELEMENT = null;
69+
MAIN_STACK_FRAME = null;
70+
} else {
71+
MAIN_STACK_TRACE_ELEMENT = new StackTraceElement(mainClassName, mainMethodName, "", 0);
72+
MAIN_STACK_FRAME = new StackFrame() {
73+
@Override
74+
public String getClassName() {
75+
return mainClassName;
76+
}
77+
78+
@Override
79+
public String getMethodName() {
80+
return mainMethodName;
81+
}
82+
83+
@Override
84+
public Class<?> getDeclaringClass() {
85+
try {
86+
return Class.forName(mainClassName);
87+
} catch (ClassNotFoundException e) {
88+
throw new UnsupportedOperationException("getDeclaringClass in StackWalker.walk");
89+
}
90+
}
91+
92+
@Override
93+
public int getByteCodeIndex() {
94+
return 0;
95+
}
96+
97+
@Override
98+
public String getFileName() {
99+
return MAIN_STACK_TRACE_ELEMENT.getFileName();
100+
}
101+
102+
@Override
103+
public int getLineNumber() {
104+
return MAIN_STACK_TRACE_ELEMENT.getLineNumber();
105+
}
106+
107+
@Override
108+
public boolean isNativeMethod() {
109+
return false;
110+
}
111+
112+
@Override
113+
public StackTraceElement toStackTraceElement() {
114+
return MAIN_STACK_TRACE_ELEMENT;
115+
}
116+
};
117+
}
55118
}
56119
}

web-image/src/com.oracle.svm.webimage/src/com/oracle/svm/webimage/substitute/system/Target_java_lang_Throwable_Web.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,6 @@ private Throwable fillInStackTrace_WasmLM() {
114114
public void setStackTrace(StackTraceElement[] stackTrace) {
115115
}
116116

117-
@Substitute
118-
private StackTraceElement[] getOurStackTrace() {
119-
if (stackTrace != null) {
120-
return stackTrace;
121-
} else {
122-
return new StackTraceElement[0];
123-
}
124-
}
125-
126117
@Substitute
127118
public void printStackTrace(PrintStream s) {
128119
JSExceptionSupport.printStackTrace(this, s::println);
@@ -133,3 +124,12 @@ public void printStackTrace(PrintWriter w) {
133124
JSExceptionSupport.printStackTrace(this, w::println);
134125
}
135126
}
127+
128+
@TargetClass(java.lang.StackTraceElement.class)
129+
@SuppressWarnings({"static-method", "unused"})
130+
final class Target_java_lang_StackTraceElement_Web {
131+
@Substitute
132+
static StackTraceElement[] of(Object x, int depth) {
133+
return new StackTraceElement[]{SyntheticStackSupport.MAIN_STACK_TRACE_ELEMENT};
134+
}
135+
}

0 commit comments

Comments
 (0)