8181import com .oracle .truffle .api .interop .InvalidArrayIndexException ;
8282import com .oracle .truffle .api .interop .UnknownIdentifierException ;
8383import com .oracle .truffle .api .interop .UnsupportedMessageException ;
84+ import com .oracle .truffle .api .nodes .Node ;
8485
8586public class WebAssembly extends Dictionary {
8687 private final WasmContext currentContext ;
@@ -142,6 +143,7 @@ public WasmInstance moduleInstantiate(WasmModule module, Object importObject) {
142143 final Object prev = innerTruffleContext .enter (null );
143144 try {
144145 final WasmContext instanceContext = WasmContext .get (null );
146+ instanceContext .inheritCallbacksFromParentContext (currentContext );
145147 WasmInstance instance = instantiateModule (module , importObject , instanceContext , innerTruffleContext );
146148 instanceContext .linker ().tryLink (instance );
147149 return instance ;
@@ -511,9 +513,6 @@ private static Object tableGrow(Object[] args) {
511513 WasmTable table = (WasmTable ) args [0 ];
512514 int delta = (Integer ) args [1 ];
513515 if (args .length > 2 ) {
514- if (InteropLibrary .getUncached ().isNull (args [2 ])) {
515- return tableGrow (table , delta , WasmConstant .NULL );
516- }
517516 return tableGrow (table , delta , args [2 ]);
518517 }
519518 return tableGrow (table , delta , WasmConstant .NULL );
@@ -705,24 +704,33 @@ public static long memGrow(WasmMemory memory, int delta) {
705704 }
706705
707706 private static Object memSetGrowCallback (Object [] args ) {
707+ checkArgumentCount (args , 1 );
708708 InteropLibrary lib = InteropLibrary .getUncached ();
709- if (!(args [0 ] instanceof WasmMemory )) {
710- throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "First argument must be wasm memory" );
709+ if (args .length > 1 ) {
710+ // TODO: drop this branch after JS adopts the single-argument version
711+ if (!(args [0 ] instanceof WasmMemory )) {
712+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "First argument must be executable" );
713+ }
714+ if (!lib .isExecutable (args [1 ])) {
715+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Second argument must be executable" );
716+ }
717+ return memSetGrowCallback (args [1 ]);
711718 }
712- if (!lib .isExecutable (args [1 ])) {
713- throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Second argument must be executable" );
719+ if (!lib .isExecutable (args [0 ])) {
720+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Argument must be executable" );
714721 }
715- WasmMemory memory = (WasmMemory ) args [0 ];
716- return memSetGrowCallback (memory , args [1 ]);
722+ return memSetGrowCallback (args [0 ]);
717723 }
718724
719- private static Object memSetGrowCallback (WasmMemory memory , Object callback ) {
720- memory .setGrowCallback (callback );
725+ private static Object memSetGrowCallback (Object callback ) {
726+ WasmContext context = WasmContext .get (null );
727+ context .setMemGrowCallback (callback );
721728 return WasmConstant .VOID ;
722729 }
723730
724731 public static void invokeMemGrowCallback (WasmMemory memory ) {
725- Object callback = memory .getGrowCallback ();
732+ WasmContext context = WasmContext .get (null );
733+ Object callback = context .getMemGrowCallback ();
726734 if (callback != null ) {
727735 InteropLibrary lib = InteropLibrary .getUncached ();
728736 try {
@@ -734,24 +742,33 @@ public static void invokeMemGrowCallback(WasmMemory memory) {
734742 }
735743
736744 private static Object memSetNotifyCallback (Object [] args ) {
745+ checkArgumentCount (args , 1 );
737746 InteropLibrary lib = InteropLibrary .getUncached ();
738- if (!(args [0 ] instanceof WasmMemory )) {
739- throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "First argument must be wasm memory" );
747+ if (args .length > 1 ) {
748+ // TODO: drop this branch after JS adopts the single-argument version
749+ if (!(args [0 ] instanceof WasmMemory )) {
750+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "First argument must be executable" );
751+ }
752+ if (!lib .isExecutable (args [1 ])) {
753+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Second argument must be executable" );
754+ }
755+ return memSetNotifyCallback (args [1 ]);
740756 }
741- if (!lib .isExecutable (args [1 ])) {
742- throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Second argument must be executable" );
757+ if (!lib .isExecutable (args [0 ])) {
758+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Argument must be executable" );
743759 }
744- WasmMemory memory = (WasmMemory ) args [0 ];
745- return memSetNotifyCallback (memory , args [1 ]);
760+ return memSetNotifyCallback (args [0 ]);
746761 }
747762
748- private static Object memSetNotifyCallback (WasmMemory memory , Object callback ) {
749- memory .setNotifyCallback (callback );
763+ private static Object memSetNotifyCallback (Object callback ) {
764+ WasmContext context = WasmContext .get (null );
765+ context .setMemNotifyCallback (callback );
750766 return WasmConstant .VOID ;
751767 }
752768
753- public static int invokeMemNotifyCallback (WasmMemory memory , long address , int count ) {
754- Object callback = memory .getNotifyCallback ();
769+ public static int invokeMemNotifyCallback (Node node , WasmMemory memory , long address , int count ) {
770+ WasmContext context = WasmContext .get (node );
771+ Object callback = context .getMemNotifyCallback ();
755772 if (callback != null ) {
756773 InteropLibrary lib = InteropLibrary .getUncached ();
757774 try {
@@ -764,24 +781,33 @@ public static int invokeMemNotifyCallback(WasmMemory memory, long address, int c
764781 }
765782
766783 private static Object memSetWaitCallback (Object [] args ) {
784+ checkArgumentCount (args , 1 );
767785 InteropLibrary lib = InteropLibrary .getUncached ();
768- if (!(args [0 ] instanceof WasmMemory )) {
769- throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "First argument must be wasm memory" );
786+ if (args .length > 1 ) {
787+ // TODO: drop this branch after JS adopts the single-argument version
788+ if (!(args [0 ] instanceof WasmMemory )) {
789+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "First argument must be executable" );
790+ }
791+ if (!lib .isExecutable (args [1 ])) {
792+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Second argument must be executable" );
793+ }
794+ return memSetWaitCallback (args [1 ]);
770795 }
771- if (!lib .isExecutable (args [1 ])) {
772- throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Second argument must be executable" );
796+ if (!lib .isExecutable (args [0 ])) {
797+ throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Argument must be executable" );
773798 }
774- WasmMemory memory = (WasmMemory ) args [0 ];
775- return memSetWaitCallback (memory , args [1 ]);
799+ return memSetWaitCallback (args [0 ]);
776800 }
777801
778- private static Object memSetWaitCallback (WasmMemory memory , Object callback ) {
779- memory .setWaitCallback (callback );
802+ private static Object memSetWaitCallback (Object callback ) {
803+ WasmContext context = WasmContext .get (null );
804+ context .setMemWaitCallback (callback );
780805 return WasmConstant .VOID ;
781806 }
782807
783- public static int invokeMemWaitCallback (WasmMemory memory , long address , long expected , long timeout , boolean is64 ) {
784- Object callback = memory .getWaitCallback ();
808+ public static int invokeMemWaitCallback (Node node , WasmMemory memory , long address , long expected , long timeout , boolean is64 ) {
809+ WasmContext context = WasmContext .get (node );
810+ Object callback = context .getMemWaitCallback ();
785811 if (callback != null ) {
786812 InteropLibrary lib = InteropLibrary .getUncached ();
787813 try {
@@ -839,23 +865,14 @@ public WasmGlobal globalAlloc(ValueType valueType, boolean mutable, Object value
839865 case f64 :
840866 return new DefaultWasmGlobal (valueType , mutable , Double .doubleToRawLongBits (valueInterop .asDouble (value )));
841867 case anyfunc :
842- if (!refTypes ) {
868+ if (!refTypes || !( value == WasmConstant . NULL || value instanceof WasmFunctionInstance ) ) {
843869 throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Invalid value type" );
844870 }
845- if (valueInterop .isNull (value )) {
846- return new DefaultWasmGlobal (valueType , mutable , WasmConstant .NULL );
847- } else if (value instanceof WasmFunctionInstance ) {
848- return new DefaultWasmGlobal (valueType , mutable , value );
849- }
850- throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Invalid value type" );
851-
871+ return new DefaultWasmGlobal (valueType , mutable , value );
852872 case externref :
853873 if (!refTypes ) {
854874 throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Invalid value type" );
855875 }
856- if (valueInterop .isNull (value )) {
857- return new DefaultWasmGlobal (valueType , mutable , WasmConstant .NULL );
858- }
859876 return new DefaultWasmGlobal (valueType , mutable , value );
860877 default :
861878 throw new WasmJsApiException (WasmJsApiException .Kind .TypeError , "Invalid value type" );
@@ -935,9 +952,7 @@ public Object globalWrite(WasmGlobal global, Object value) {
935952 if (!refTypes ) {
936953 throw WasmJsApiException .format (WasmJsApiException .Kind .TypeError , "Invalid value type. Reference types are not enabled" );
937954 }
938- if (InteropLibrary .getUncached (value ).isNull (value )) {
939- global .storeObject (WasmConstant .NULL );
940- } else if (!(value instanceof WasmFunctionInstance )) {
955+ if (!(value == WasmConstant .NULL || value instanceof WasmFunctionInstance )) {
941956 throw WasmJsApiException .format (WasmJsApiException .Kind .TypeError , "Global type %s, value: %s" , valueType , value );
942957 } else {
943958 global .storeObject (value );
@@ -947,11 +962,7 @@ public Object globalWrite(WasmGlobal global, Object value) {
947962 if (!refTypes ) {
948963 throw WasmJsApiException .format (WasmJsApiException .Kind .TypeError , "Invalid value type. Reference types are not enabled" );
949964 }
950- if (InteropLibrary .getUncached (value ).isNull (value )) {
951- global .storeObject (WasmConstant .NULL );
952- } else {
953- global .storeObject (value );
954- }
965+ global .storeObject (value );
955966 break ;
956967 }
957968 return WasmConstant .VOID ;
0 commit comments