@@ -535,9 +535,9 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
535535 break ;
536536 }
537537 case Bytecode .CALL_INDIRECT_U8 :
538- case Bytecode .CALL_INDIRECT_I32 : {
539- // Extract the function object.
540- stackPointer --;
538+ case Bytecode .CALL_INDIRECT_I32 :
539+ case Bytecode . CALL_REF_U8 :
540+ case Bytecode . CALL_REF_I32 : {
541541 final SymbolTable symtab = module .symbolTable ();
542542
543543 final int callNodeIndex ;
@@ -548,53 +548,83 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
548548 expectedFunctionTypeIndex = rawPeekU8 (bytecode , offset + 1 );
549549 tableIndex = rawPeekU8 (bytecode , offset + 2 );
550550 offset += 3 ;
551- } else {
551+ } else if ( opcode == Bytecode . CALL_INDIRECT_I32 ) {
552552 callNodeIndex = rawPeekI32 (bytecode , offset );
553553 expectedFunctionTypeIndex = rawPeekI32 (bytecode , offset + 4 );
554554 tableIndex = rawPeekI32 (bytecode , offset + 8 );
555555 offset += 12 ;
556+ } else if (opcode == Bytecode .CALL_REF_U8 ) {
557+ callNodeIndex = rawPeekU8 (bytecode , offset );
558+ expectedFunctionTypeIndex = rawPeekU8 (bytecode , offset + 1 );
559+ tableIndex = -1 ;
560+ offset += 2 ;
561+ } else {
562+ assert opcode == Bytecode .CALL_REF_I32 ;
563+ callNodeIndex = rawPeekI32 (bytecode , offset );
564+ expectedFunctionTypeIndex = rawPeekI32 (bytecode , offset + 4 );
565+ tableIndex = -1 ;
566+ offset += 8 ;
556567 }
557- final WasmTable table = instance .store ().tables ().table (instance .tableAddress (tableIndex ));
558- final Object [] elements = table .elements ();
559- final int elementIndex = popInt (frame , stackPointer );
560- if (elementIndex < 0 || elementIndex >= elements .length ) {
561- enterErrorBranch ();
562- throw WasmException .format (Failure .UNDEFINED_ELEMENT , this , "Element index '%d' out of table bounds." , elementIndex );
563- }
564- // Currently, table elements may only be functions.
565- // We can add a check here when this changes in the future.
566- final Object element = elements [elementIndex ];
567- if (element == WasmConstant .NULL ) {
568- enterErrorBranch ();
569- throw WasmException .format (Failure .UNINITIALIZED_ELEMENT , this , "Table element at index %d is uninitialized." , elementIndex );
568+
569+ // Extract the function object.
570+ final Object functionCandidate ;
571+ final int elementIndex ;
572+ if (opcode == Bytecode .CALL_INDIRECT_U8 || opcode == Bytecode .CALL_INDIRECT_I32 ) {
573+ final WasmTable table = instance .store ().tables ().table (instance .tableAddress (tableIndex ));
574+ final Object [] elements = table .elements ();
575+ elementIndex = popInt (frame , --stackPointer );
576+ if (elementIndex < 0 || elementIndex >= elements .length ) {
577+ enterErrorBranch ();
578+ throw WasmException .format (Failure .UNDEFINED_ELEMENT , this , "Element index '%d' out of table bounds." , elementIndex );
579+ }
580+ // Currently, table elements may only be functions.
581+ // We can add a check here when this changes in the future.
582+ functionCandidate = elements [elementIndex ];
583+ } else {
584+ assert opcode == Bytecode .CALL_REF_U8 || opcode == Bytecode .CALL_REF_I32 ;
585+ functionCandidate = popReference (frame , --stackPointer );
586+ elementIndex = -1 ;
570587 }
571588 final WasmFunctionInstance functionInstance ;
572589 final WasmFunction function ;
573590 final CallTarget target ;
574591 final WasmContext functionInstanceContext ;
575- if (element instanceof WasmFunctionInstance ) {
576- functionInstance = (WasmFunctionInstance ) element ;
592+ if (functionCandidate == WasmConstant .NULL ) {
593+ enterErrorBranch ();
594+ if (opcode == Bytecode .CALL_INDIRECT_U8 || opcode == Bytecode .CALL_INDIRECT_I32 ) {
595+ throw WasmException .format (Failure .UNINITIALIZED_ELEMENT , this , "Table element at index %d is uninitialized." , elementIndex );
596+ } else {
597+ assert opcode == Bytecode .CALL_REF_U8 || opcode == Bytecode .CALL_REF_I32 ;
598+ throw WasmException .format (Failure .NULL_FUNCTION_REFERENCE , this , "Function reference is null" );
599+ }
600+ } else if (functionCandidate instanceof WasmFunctionInstance ) {
601+ functionInstance = (WasmFunctionInstance ) functionCandidate ;
577602 function = functionInstance .function ();
578603 target = functionInstance .target ();
579604 functionInstanceContext = functionInstance .context ();
580605 } else {
581606 enterErrorBranch ();
582- throw WasmException .format (Failure .UNSPECIFIED_TRAP , this , "Unknown table element type: %s" , element );
607+ if (opcode == Bytecode .CALL_INDIRECT_U8 || opcode == Bytecode .CALL_INDIRECT_I32 ) {
608+ throw WasmException .format (Failure .UNSPECIFIED_TRAP , this , "Unknown table element type: %s" , functionCandidate );
609+ } else {
610+ assert opcode == Bytecode .CALL_REF_U8 || opcode == Bytecode .CALL_REF_I32 ;
611+ throw WasmException .format (Failure .UNSPECIFIED_TRAP , this , "Unknown function object: %s" , functionCandidate );
612+ }
583613 }
584614
585- int expectedTypeEquivalenceClass = symtab .equivalenceClass (expectedFunctionTypeIndex );
586-
587615 // Target function instance must be from the same context.
588616 assert functionInstanceContext == WasmContext .get (this );
589617
590- // Validate that the target function type matches the expected type of the
591- // indirect call. We first try if the types are equivalent using the
592- // equivalence classes. If they are not equivalent, we run the full subtype
593- // matching procedure.
594- if (expectedTypeEquivalenceClass != function .typeEquivalenceClass () &&
595- !symtab .closedTypeAt (expectedFunctionTypeIndex ).isSupertypeOf (function .closedType ())) {
596- enterErrorBranch ();
597- failFunctionTypeCheck (function , expectedFunctionTypeIndex );
618+ if (opcode == Bytecode .CALL_INDIRECT_U8 || opcode == Bytecode .CALL_INDIRECT_I32 ) {
619+ // Validate that the target function type matches the expected type of
620+ // the indirect call. We first try if the types are equivalent using the
621+ // equivalence classes. If they are not equivalent, we run the full
622+ // subtype matching procedure.
623+ if (symtab .equivalenceClass (expectedFunctionTypeIndex ) != function .typeEquivalenceClass () &&
624+ !symtab .closedTypeAt (expectedFunctionTypeIndex ).isSupertypeOf (function .closedType ())) {
625+ enterErrorBranch ();
626+ failFunctionTypeCheck (function , expectedFunctionTypeIndex );
627+ }
598628 }
599629
600630 // Invoke the resolved function.
@@ -1509,19 +1539,6 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
15091539 offset += 4 ;
15101540 break ;
15111541 }
1512- case Bytecode .TABLE_GET : {
1513- final int tableIndex = rawPeekI32 (bytecode , offset );
1514- table_get (instance , frame , stackPointer , tableIndex );
1515- offset += 4 ;
1516- break ;
1517- }
1518- case Bytecode .TABLE_SET : {
1519- final int tableIndex = rawPeekI32 (bytecode , offset );
1520- table_set (instance , frame , stackPointer , tableIndex );
1521- stackPointer -= 2 ;
1522- offset += 4 ;
1523- break ;
1524- }
15251542 case Bytecode .MISC : {
15261543 final int miscOpcode = rawPeekU8 (bytecode , offset );
15271544 offset ++;
@@ -1548,51 +1565,6 @@ public Object executeBodyFromOffset(WasmInstance instance, VirtualFrame frame, i
15481565 assert exception instanceof WasmRuntimeException : "Only wasm exceptions can be thrown by throw_ref" ;
15491566 throw (WasmRuntimeException ) exception ;
15501567 }
1551- case Bytecode .CALL_REF_U8 :
1552- case Bytecode .CALL_REF_I32 : {
1553- final int callNodeIndex ;
1554- final int expectedFunctionTypeIndex ;
1555- if (miscOpcode == Bytecode .CALL_REF_U8 ) {
1556- callNodeIndex = rawPeekU8 (bytecode , offset );
1557- expectedFunctionTypeIndex = rawPeekU8 (bytecode , offset + 1 );
1558- offset += 2 ;
1559- } else {
1560- callNodeIndex = rawPeekI32 (bytecode , offset );
1561- expectedFunctionTypeIndex = rawPeekI32 (bytecode , offset + 4 );
1562- offset += 8 ;
1563- }
1564-
1565- // Extract the function object.
1566- final WasmFunctionInstance functionInstance ;
1567- final CallTarget target ;
1568- final WasmContext functionInstanceContext ;
1569- final Object functionOrNull = popReference (frame , --stackPointer );
1570- if (functionOrNull == WasmConstant .NULL ) {
1571- enterErrorBranch ();
1572- throw WasmException .format (Failure .NULL_FUNCTION_REFERENCE , this , "Function reference is null" );
1573- } else if (functionOrNull instanceof WasmFunctionInstance ) {
1574- functionInstance = (WasmFunctionInstance ) functionOrNull ;
1575- target = functionInstance .target ();
1576- functionInstanceContext = functionInstance .context ();
1577- } else {
1578- enterErrorBranch ();
1579- throw WasmException .format (Failure .UNSPECIFIED_TRAP , this , "Unknown function object: %s" , functionOrNull );
1580- }
1581-
1582- // Target function instance must be from the same context.
1583- assert functionInstanceContext == WasmContext .get (this );
1584-
1585- // Invoke the resolved function.
1586- int paramCount = module .symbolTable ().functionTypeParamCount (expectedFunctionTypeIndex );
1587- Object [] args = createArgumentsForCall (frame , expectedFunctionTypeIndex , paramCount , stackPointer );
1588- stackPointer -= paramCount ;
1589- WasmArguments .setModuleInstance (args , functionInstance .moduleInstance ());
1590-
1591- final Object result = executeIndirectCallNode (callNodeIndex , target , args );
1592- stackPointer = pushIndirectCallResult (frame , stackPointer , expectedFunctionTypeIndex , result , WasmLanguage .get (this ));
1593- CompilerAsserts .partialEvaluationConstant (stackPointer );
1594- break ;
1595- }
15961568 case Bytecode .BR_ON_NULL_U8 : {
15971569 Object reference = popReference (frame , --stackPointer );
15981570 if (profileCondition (bytecode , offset + 1 , reference == WasmConstant .NULL )) {
@@ -2271,6 +2243,19 @@ private int executeMisc(WasmInstance instance, VirtualFrame frame, int startingO
22712243 pushLong (frame , stackPointer - 1 , previousSize );
22722244 break ;
22732245 }
2246+ case Bytecode .TABLE_GET : {
2247+ final int tableIndex = rawPeekI32 (bytecode , offset );
2248+ table_get (instance , frame , stackPointer , tableIndex );
2249+ offset += 4 ;
2250+ break ;
2251+ }
2252+ case Bytecode .TABLE_SET : {
2253+ final int tableIndex = rawPeekI32 (bytecode , offset );
2254+ table_set (instance , frame , stackPointer , tableIndex );
2255+ stackPointer -= 2 ;
2256+ offset += 4 ;
2257+ break ;
2258+ }
22742259 case Bytecode .REF_AS_NON_NULL : {
22752260 Object reference = popReference (frame , stackPointer - 1 );
22762261 if (reference == WasmConstant .NULL ) {
0 commit comments