Skip to content

Commit 0079a73

Browse files
committed
[GR-34193] Espresso in the browser
PullRequest: graal/22515
2 parents 0a5694a + 7378260 commit 0079a73

File tree

3 files changed

+82
-35
lines changed

3 files changed

+82
-35
lines changed

substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,9 @@ private static Class<?> loadClass(String name) {
12531253

12541254
private static final class StaticObjectPodBasedSupport {
12551255
static void onBuildInvocation(Class<?> storageSuperClass, Class<?> factoryInterface) {
1256-
PodSupport.singleton().registerSuperclass(storageSuperClass, factoryInterface);
1256+
if (PodSupport.isPresent()) {
1257+
PodSupport.singleton().registerSuperclass(storageSuperClass, factoryInterface);
1258+
}
12571259
}
12581260

12591261
}

web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/codegen/WebImageCodeGen.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ private void doEmitJSFile() {
396396

397397
codeBuffer.emitText(codeGenTool.vmClassName() + ".");
398398
WebImageEntryFunctionLowerer.FUNCTION.emitCall(codeGenTool, Emitter.of("load_cmd_args()"), Emitter.of("config"));
399-
codeBuffer.emitText(".catch(console.error)");
399+
codeBuffer.emitText(".catch(e => { console.error(e); throw e; })");
400400

401401
codeBuffer.emitInsEnd();
402402
} else {

web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasmgc/WasmGCUnalignedUnsafeSupport.java

Lines changed: 78 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import static jdk.graal.compiler.core.common.spi.ForeignCallDescriptor.CallSideEffect.HAS_SIDE_EFFECT;
2929

30+
import java.lang.reflect.Array;
3031
import java.util.HashMap;
3132
import java.util.List;
3233
import java.util.Map;
@@ -106,29 +107,40 @@ public static byte readArrayByte(Object o, long offset) {
106107
int scaledOffset = getScaledOffset(o, offset);
107108
int indexScale = getArrayIndexScale(o);
108109
int index = scaledOffset / indexScale;
109-
/*
110-
* The raw bits read from the array expanded to a long. The indexScale number of least
111-
* significant bytes contain the actual data, the rest is not relevant.
112-
*/
113-
long longBits = switch (o) {
114-
case boolean[] bools -> bools[index] ? 1 : 0;
115-
case byte[] bytes -> bytes[index];
116-
case short[] shorts -> shorts[index];
117-
case char[] chars -> chars[index];
118-
case int[] ints -> ints[index];
119-
case long[] longs -> longs[index];
120-
case float[] floats -> Float.floatToRawIntBits(floats[index]);
121-
case double[] doubles -> Double.doubleToRawLongBits(doubles[index]);
122-
default -> {
123-
if (WasmGCUnsafeSupport.includeErrorMessage()) {
124-
WasmGCUnsafeSupport.fatalAccessError(o, "Unsupported type for unaligned array access", offset, true);
110+
if (inWordRemainder(o, offset)) {
111+
return 0;
112+
}
113+
try {
114+
/*
115+
* The raw bits read from the array expanded to a long. The indexScale number of least
116+
* significant bytes contain the actual data, the rest is not relevant.
117+
*/
118+
long longBits = switch (o) {
119+
case boolean[] bools -> bools[index] ? 1 : 0;
120+
case byte[] bytes -> bytes[index];
121+
case short[] shorts -> shorts[index];
122+
case char[] chars -> chars[index];
123+
case int[] ints -> ints[index];
124+
case long[] longs -> longs[index];
125+
case float[] floats -> Float.floatToRawIntBits(floats[index]);
126+
case double[] doubles -> Double.doubleToRawLongBits(doubles[index]);
127+
default -> {
128+
if (WasmGCUnsafeSupport.includeErrorMessage()) {
129+
WasmGCUnsafeSupport.fatalAccessError(o, "Unsupported type for unaligned array access", offset, true);
130+
}
131+
throw new UnsupportedOperationException();
125132
}
126-
throw new UnsupportedOperationException();
133+
};
134+
135+
int rightShift = 8 * elementByteOffset(scaledOffset, indexScale);
136+
return (byte) (longBits >> rightShift);
137+
} catch (ArrayIndexOutOfBoundsException e) {
138+
if (WasmGCUnsafeSupport.includeErrorMessage()) {
139+
WasmGCUnsafeSupport.fatalAccessError(o, e.toString(), offset, true);
127140
}
128-
};
129141

130-
int rightShift = 8 * elementByteOffset(scaledOffset, indexScale);
131-
return (byte) (longBits >> rightShift);
142+
throw e;
143+
}
132144
}
133145

134146
@SubstrateForeignCallTarget(stubCallingConvention = false)
@@ -208,21 +220,35 @@ public static void writeArrayByte(Object o, long offset, byte value) {
208220
int index = scaledOffset / indexScale;
209221
// Byte offset within the array element value
210222
int valueOffset = elementByteOffset(scaledOffset, indexScale);
211-
switch (o) {
212-
case boolean[] bools -> bools[index] = value != 0;
213-
case byte[] bytes -> bytes[index] = value;
214-
case short[] shorts -> shorts[index] = (short) setByte(shorts[index], valueOffset, value);
215-
case char[] chars -> chars[index] = (char) setByte(chars[index], valueOffset, value);
216-
case int[] ints -> ints[index] = (int) setByte(ints[index], valueOffset, value);
217-
case long[] longs -> longs[index] = setByte(longs[index], valueOffset, value);
218-
case float[] floats -> floats[index] = Float.intBitsToFloat((int) setByte(Float.floatToRawIntBits(floats[index]), valueOffset, value));
219-
case double[] doubles -> doubles[index] = Double.longBitsToDouble(setByte(Double.doubleToRawLongBits(doubles[index]), valueOffset, value));
220-
default -> {
221-
if (WasmGCUnsafeSupport.includeErrorMessage()) {
222-
WasmGCUnsafeSupport.fatalAccessError(o, "Unsupported type for unaligned array access", offset, true);
223+
224+
if (inWordRemainder(o, offset)) {
225+
return;
226+
}
227+
try {
228+
switch (o) {
229+
case boolean[] bools -> bools[index] = value != 0;
230+
case byte[] bytes -> bytes[index] = value;
231+
case short[] shorts -> shorts[index] = (short) setByte(shorts[index], valueOffset, value);
232+
case char[] chars -> chars[index] = (char) setByte(chars[index], valueOffset, value);
233+
case int[] ints -> ints[index] = (int) setByte(ints[index], valueOffset, value);
234+
case long[] longs -> longs[index] = setByte(longs[index], valueOffset, value);
235+
case float[] floats ->
236+
floats[index] = Float.intBitsToFloat((int) setByte(Float.floatToRawIntBits(floats[index]), valueOffset, value));
237+
case double[] doubles ->
238+
doubles[index] = Double.longBitsToDouble(setByte(Double.doubleToRawLongBits(doubles[index]), valueOffset, value));
239+
default -> {
240+
if (WasmGCUnsafeSupport.includeErrorMessage()) {
241+
WasmGCUnsafeSupport.fatalAccessError(o, "Unsupported type for unaligned array access", offset, false);
242+
}
243+
throw new UnsupportedOperationException();
223244
}
224-
throw new UnsupportedOperationException();
225245
}
246+
} catch (ArrayIndexOutOfBoundsException e) {
247+
if (WasmGCUnsafeSupport.includeErrorMessage()) {
248+
WasmGCUnsafeSupport.fatalAccessError(o, e.toString(), offset, false);
249+
}
250+
251+
throw e;
226252
}
227253
}
228254

@@ -343,4 +369,23 @@ private static int getArrayBaseOffset(JavaKind kind) {
343369
private static int getArrayIndexScale(JavaKind kind) {
344370
return ImageSingletons.lookup(ObjectLayout.class).getArrayIndexScale(kind);
345371
}
372+
373+
/**
374+
* Detect out of bounds access that is still within the same 4-byte aligned 4-byte word as the
375+
* last element. Such accesses are usually undefined behaviour, but to not produce unexpected
376+
* behavior (i.e. a crash), out of bounds accesses where this method returns {@code true} should
377+
* not crash and just return an arbitrary value and ignore any writes.
378+
* <p>
379+
* {@code jdk.internal.misc.Unsafe#compareAndExchangeByte} uses int accesses that may go out of
380+
* bounds and does not expect a crash in that case, though it ignores the out-of-bounds bytes.
381+
* For example, there might be an int access at the first element of a 1-element byte array.
382+
*
383+
*/
384+
private static boolean inWordRemainder(Object o, long offset) {
385+
int scaledOffset = getScaledOffset(o, offset);
386+
int indexScale = getArrayIndexScale(o);
387+
int index = scaledOffset / indexScale;
388+
int length = Array.getLength(o);
389+
return index >= length && scaledOffset < ((index * indexScale + 4) & ~0x03);
390+
}
346391
}

0 commit comments

Comments
 (0)