46
46
import org .graalvm .wasm .nodes .WasmIndirectCallNode ;
47
47
48
48
import com .oracle .truffle .api .CallTarget ;
49
+ import com .oracle .truffle .api .CompilerDirectives ;
49
50
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
50
51
import com .oracle .truffle .api .RootCallTarget ;
51
52
import com .oracle .truffle .api .TruffleContext ;
@@ -71,10 +72,6 @@ public final class WasmFunctionInstance extends EmbedderDataHolder implements Tr
71
72
* Initialized during linking.
72
73
*/
73
74
private Object importedFunction ;
74
- /**
75
- * Interop call adapter for exported functions, converting parameter and result values.
76
- */
77
- private final CallTarget interopCallAdapter ;
78
75
79
76
/**
80
77
* Represents a call target that is a WebAssembly function or an imported function.
@@ -89,7 +86,6 @@ public WasmFunctionInstance(WasmContext context, WasmInstance moduleInstance, Wa
89
86
this .function = Objects .requireNonNull (function , "function must be non-null" );
90
87
this .target = Objects .requireNonNull (target , "Call target must be non-null" );
91
88
this .truffleContext = context .environment ().getContext ();
92
- this .interopCallAdapter = context .language ().interopCallAdapterFor (function .type ());
93
89
assert ((RootCallTarget ) target ).getRootNode ().getLanguage (WasmLanguage .class ) == context .language ();
94
90
}
95
91
@@ -147,11 +143,25 @@ Object execute(Object[] arguments,
147
143
TruffleContext c = getTruffleContext ();
148
144
Object prev = c .enter (self );
149
145
try {
150
- CallTarget callAdapter = Objects .requireNonNull (this .interopCallAdapter );
146
+ CallTarget callAdapter = this .function .getInteropCallAdapter ();
147
+ if (callAdapter == null ) {
148
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
149
+ callAdapter = createInteropCallAdapter ();
150
+ }
151
151
return callNode .execute (callAdapter , WasmArguments .create (this , arguments ));
152
152
// throws ArityException, UnsupportedTypeException
153
153
} finally {
154
154
c .leave (self , prev );
155
155
}
156
156
}
157
+
158
+ @ TruffleBoundary
159
+ private CallTarget createInteropCallAdapter () {
160
+ CallTarget callAdapter = this .function .getInteropCallAdapter ();
161
+ if (callAdapter == null ) {
162
+ callAdapter = context .language ().interopCallAdapterFor (function .type ());
163
+ this .function .setInteropCallAdapter (callAdapter );
164
+ }
165
+ return callAdapter ;
166
+ }
157
167
}
0 commit comments