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