Skip to content

Commit e0d2778

Browse files
committed
Simplify exception handler dispatch.
Use separate local for exceptionTableOffset. Outline pushing exception fields and/or reference onto the stack.
1 parent d29db53 commit e0d2778

File tree

1 file changed

+55
-54
lines changed

1 file changed

+55
-54
lines changed

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/nodes/WasmFunctionNode.java

Lines changed: 55 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,20 +1734,13 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
17341734
CompilerAsserts.partialEvaluationConstant(stackPointer);
17351735
CompilerAsserts.partialEvaluationConstant(offset);
17361736

1737-
/*
1738-
* The source of the exception, i.e., the throw/throw_ref raising the exception or
1739-
* the call that forwarded the exception.
1740-
*/
1741-
final int sourceOffset = offset;
1742-
1743-
offset = this.exceptionTableOffset;
1737+
int exceptionTableOffset = this.exceptionTableOffset;
17441738

1745-
if (offset == BytecodeBitEncoding.INVALID_EXCEPTION_TABLE_OFFSET) {
1739+
if (exceptionTableOffset == BytecodeBitEncoding.INVALID_EXCEPTION_TABLE_OFFSET) {
17461740
// no exception table, directly throw to the next function on the call stack
17471741
throw e;
17481742
}
17491743

1750-
final WasmTag actualTag = e.tag();
17511744
/*
17521745
* The exception table is encoded in the following format:
17531746
*
@@ -1757,9 +1750,11 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
17571750
* inside this range, the entry defines a possible exception handler for the
17581751
* exception. If the type of the exception handler is catch or catch_ref, we check
17591752
* whether the expected tag defined by the tag index and the tag of the exception
1760-
* object match. For catch_all and catch_all_ref we don't have this check. The catch
1761-
* and catch_all types push the values of the exception onto the stack, while
1762-
* catch_ref and catch_all_ref also push a reference to the exception itself.
1753+
* object match. For catch_all and catch_all_ref we don't have this check.
1754+
*
1755+
* The catch and catch_ref types push the fields of the exception onto the stack,
1756+
* catch_ref also pushes a reference to the exception itself, while catch_all_ref
1757+
* only pushes the reference, and catch_all doesn't push anything onto the stack.
17631758
*
17641759
* If we find a matching entry, execution continues at the label defined by target.
17651760
*
@@ -1768,56 +1763,44 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
17681763
* exception to the next function on the call stack.
17691764
*/
17701765
while (true) {
1771-
final int from = rawPeekI32(bytecode, offset);
1766+
final int from = rawPeekI32(bytecode, exceptionTableOffset);
17721767
if (from == -1) {
17731768
// we reached the end of the table
17741769
break;
17751770
}
1776-
offset += 4;
1777-
final int to = rawPeekI32(bytecode, offset);
1778-
offset += 4;
1779-
if (from < sourceOffset && sourceOffset <= to) {
1780-
final int type = rawPeekU8(bytecode, offset);
1781-
offset++;
1782-
switch (type) {
1783-
case ExceptionHandlerType.CATCH, ExceptionHandlerType.CATCH_REF -> {
1784-
final int tagIndex = rawPeekI32(bytecode, offset);
1785-
offset += 4;
1786-
final WasmTag expectedTag = instance.tag(tagIndex);
1787-
if (expectedTag == actualTag) {
1788-
final int functionTypeIndex = module.tagTypeIndex(tagIndex);
1789-
final int numFields = module.functionTypeParamCount(functionTypeIndex);
1790-
if (numFields != 0) {
1791-
pushExceptionFields(frame, e, functionTypeIndex, numFields, stackPointer);
1792-
stackPointer += numFields;
1793-
}
1794-
if (type == ExceptionHandlerType.CATCH_REF) {
1795-
pushReference(frame, stackPointer, e);
1796-
stackPointer++;
1797-
}
1798-
// load target
1799-
offset = rawPeekI32(bytecode, offset);
1800-
continue loop;
1801-
} else {
1802-
// skip target
1803-
offset += 4;
1804-
}
1805-
}
1806-
case ExceptionHandlerType.CATCH_ALL, ExceptionHandlerType.CATCH_ALL_REF -> {
1807-
// skip 0 tag
1808-
offset += 4;
1809-
if (type == ExceptionHandlerType.CATCH_ALL_REF) {
1810-
pushReference(frame, stackPointer, e);
1811-
stackPointer++;
1812-
}
1813-
// load target
1814-
offset = rawPeekI32(bytecode, offset);
1815-
continue loop;
1771+
exceptionTableOffset += 4;
1772+
final int to = rawPeekI32(bytecode, exceptionTableOffset);
1773+
exceptionTableOffset += 4;
1774+
1775+
/*
1776+
* offset is the source of the exception, i.e., the throw or throw_ref raising
1777+
* the exception or the call that forwarded the exception.
1778+
*/
1779+
if (from < offset && offset <= to) {
1780+
final int catchType = rawPeekU8(bytecode, exceptionTableOffset);
1781+
exceptionTableOffset++;
1782+
final int tagIndex;
1783+
if (catchType == ExceptionHandlerType.CATCH || catchType == ExceptionHandlerType.CATCH_REF) {
1784+
tagIndex = rawPeekI32(bytecode, exceptionTableOffset);
1785+
exceptionTableOffset += 4;
1786+
if (e.tag() != instance.tag(tagIndex)) {
1787+
// skip target
1788+
exceptionTableOffset += 4;
1789+
continue;
18161790
}
1791+
} else {
1792+
assert catchType == ExceptionHandlerType.CATCH_ALL || catchType == ExceptionHandlerType.CATCH_ALL_REF : catchType;
1793+
// skip 0 tag
1794+
tagIndex = -1;
1795+
exceptionTableOffset += 4;
18171796
}
1797+
stackPointer = pushExceptionFieldsAndReference(frame, e, stackPointer, catchType, tagIndex);
1798+
// load target
1799+
offset = rawPeekI32(bytecode, exceptionTableOffset);
1800+
continue loop;
18181801
} else {
18191802
// skip the entry
1820-
offset += 9;
1803+
exceptionTableOffset += 9;
18211804
}
18221805
}
18231806
throw e;
@@ -1826,6 +1809,24 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
18261809
return WasmConstant.RETURN_VALUE;
18271810
}
18281811

1812+
private int pushExceptionFieldsAndReference(VirtualFrame frame, WasmRuntimeException e, int sourceStackPointer, int catchType, int tagIndex) {
1813+
int stackPointer = sourceStackPointer;
1814+
if (catchType == ExceptionHandlerType.CATCH || catchType == ExceptionHandlerType.CATCH_REF) {
1815+
final int functionTypeIndex = module.tagTypeIndex(tagIndex);
1816+
final int numFields = module.functionTypeParamCount(functionTypeIndex);
1817+
if (numFields != 0) {
1818+
pushExceptionFields(frame, e, functionTypeIndex, numFields, stackPointer);
1819+
stackPointer += numFields;
1820+
}
1821+
}
1822+
if (catchType == ExceptionHandlerType.CATCH_REF || catchType == ExceptionHandlerType.CATCH_ALL_REF) {
1823+
pushReference(frame, stackPointer, e);
1824+
stackPointer++;
1825+
}
1826+
CompilerAsserts.partialEvaluationConstant(stackPointer);
1827+
return stackPointer;
1828+
}
1829+
18291830
@TruffleBoundary
18301831
private void failFunctionTypeCheck(WasmFunction function, int expectedFunctionTypeIndex) {
18311832
throw WasmException.format(Failure.INDIRECT_CALL_TYPE__MISMATCH, this,

0 commit comments

Comments
 (0)