42
42
43
43
import java .util .Objects ;
44
44
45
- import org .graalvm .wasm .api .InteropArray ;
46
- import org .graalvm .wasm .api .Vector128 ;
47
- import org .graalvm .wasm .exception .Failure ;
48
- import org .graalvm .wasm .exception .WasmException ;
45
+ import org .graalvm .wasm .nodes .WasmCallNode ;
49
46
import org .graalvm .wasm .nodes .WasmIndirectCallNode ;
50
47
51
48
import com .oracle .truffle .api .CallTarget ;
52
49
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
53
50
import com .oracle .truffle .api .RootCallTarget ;
54
51
import com .oracle .truffle .api .TruffleContext ;
55
52
import com .oracle .truffle .api .dsl .Cached ;
56
- import com .oracle .truffle .api .interop . ArityException ;
53
+ import com .oracle .truffle .api .dsl . ImportStatic ;
57
54
import com .oracle .truffle .api .interop .InteropLibrary ;
58
55
import com .oracle .truffle .api .interop .TruffleObject ;
59
- import com .oracle .truffle .api .interop .UnsupportedTypeException ;
60
56
import com .oracle .truffle .api .library .CachedLibrary ;
61
57
import com .oracle .truffle .api .library .ExportLibrary ;
62
58
import com .oracle .truffle .api .library .ExportMessage ;
63
59
60
+ @ ImportStatic (WasmCallNode .class )
64
61
@ ExportLibrary (InteropLibrary .class )
65
62
public final class WasmFunctionInstance extends EmbedderDataHolder implements TruffleObject {
66
63
@@ -69,7 +66,15 @@ public final class WasmFunctionInstance extends EmbedderDataHolder implements Tr
69
66
private final WasmFunction function ;
70
67
private final CallTarget target ;
71
68
private final TruffleContext truffleContext ;
69
+ /**
70
+ * Stores the imported function object for {@link org.graalvm.wasm.api.ExecuteHostFunctionNode}.
71
+ * Initialized during linking.
72
+ */
72
73
private Object importedFunction ;
74
+ /**
75
+ * Interop call adapter for exported functions, converting parameter and result values.
76
+ */
77
+ private final CallTarget interopCallAdapter ;
73
78
74
79
/**
75
80
* Represents a call target that is a WebAssembly function or an imported function.
@@ -84,6 +89,7 @@ public WasmFunctionInstance(WasmContext context, WasmInstance moduleInstance, Wa
84
89
this .function = Objects .requireNonNull (function , "function must be non-null" );
85
90
this .target = Objects .requireNonNull (target , "Call target must be non-null" );
86
91
this .truffleContext = context .environment ().getContext ();
92
+ this .interopCallAdapter = context .language ().interopCallAdapterFor (function .type ());
87
93
assert ((RootCallTarget ) target ).getRootNode ().getLanguage (WasmLanguage .class ) == context .language ();
88
94
}
89
95
@@ -137,102 +143,15 @@ boolean isExecutable() {
137
143
@ ExportMessage
138
144
Object execute (Object [] arguments ,
139
145
@ CachedLibrary ("this" ) InteropLibrary self ,
140
- @ Cached WasmIndirectCallNode callNode ) throws ArityException , UnsupportedTypeException {
146
+ @ Cached WasmIndirectCallNode callNode ) {
141
147
TruffleContext c = getTruffleContext ();
142
148
Object prev = c .enter (self );
143
149
try {
144
- Object result = callNode .execute (target , WasmArguments .create (moduleInstance , validateArguments (arguments )));
145
-
146
- // For external calls of a WebAssembly function we have to materialize the multi-value
147
- // stack.
148
- // At this point the multi-value stack has already been populated, therefore, we don't
149
- // have to check the size of the multi-value stack.
150
- if (result == WasmConstant .MULTI_VALUE ) {
151
- WasmLanguage language = context .language ();
152
- assert language == WasmLanguage .get (null );
153
- return multiValueStackAsArray (language );
154
- }
155
- return result ;
150
+ CallTarget callAdapter = Objects .requireNonNull (this .interopCallAdapter );
151
+ return callNode .execute (callAdapter , WasmArguments .create (this , arguments ));
152
+ // throws ArityException, UnsupportedTypeException
156
153
} finally {
157
154
c .leave (self , prev );
158
155
}
159
156
}
160
-
161
- private Object [] validateArguments (Object [] arguments ) throws ArityException , UnsupportedTypeException {
162
- if (function == null ) {
163
- return arguments ;
164
- }
165
- final int paramCount = function .paramCount ();
166
- if (arguments .length != paramCount ) {
167
- throw ArityException .create (paramCount , paramCount , arguments .length );
168
- }
169
- for (int i = 0 ; i < paramCount ; i ++) {
170
- byte paramType = function .paramTypeAt (i );
171
- Object value = arguments [i ];
172
- switch (paramType ) {
173
- case WasmType .I32_TYPE -> {
174
- if (value instanceof Integer ) {
175
- continue ;
176
- }
177
- }
178
- case WasmType .I64_TYPE -> {
179
- if (value instanceof Long ) {
180
- continue ;
181
- }
182
- }
183
- case WasmType .F32_TYPE -> {
184
- if (value instanceof Float ) {
185
- continue ;
186
- }
187
- }
188
- case WasmType .F64_TYPE -> {
189
- if (value instanceof Double ) {
190
- continue ;
191
- }
192
- }
193
- case WasmType .V128_TYPE -> {
194
- if (value instanceof Vector128 ) {
195
- continue ;
196
- }
197
- }
198
- case WasmType .FUNCREF_TYPE -> {
199
- if (value instanceof WasmFunctionInstance || value == WasmConstant .NULL ) {
200
- continue ;
201
- }
202
- }
203
- case WasmType .EXTERNREF_TYPE -> {
204
- continue ;
205
- }
206
- default -> throw WasmException .create (Failure .UNKNOWN_TYPE );
207
- }
208
- throw UnsupportedTypeException .create (arguments );
209
- }
210
- return arguments ;
211
- }
212
-
213
- private Object multiValueStackAsArray (WasmLanguage language ) {
214
- final var multiValueStack = language .multiValueStack ();
215
- final long [] primitiveMultiValueStack = multiValueStack .primitiveStack ();
216
- final Object [] objectMultiValueStack = multiValueStack .objectStack ();
217
- final int resultCount = function .resultCount ();
218
- assert primitiveMultiValueStack .length >= resultCount ;
219
- assert objectMultiValueStack .length >= resultCount ;
220
- final Object [] values = new Object [resultCount ];
221
- for (int i = 0 ; i < resultCount ; i ++) {
222
- byte resultType = function .resultTypeAt (i );
223
- values [i ] = switch (resultType ) {
224
- case WasmType .I32_TYPE -> (int ) primitiveMultiValueStack [i ];
225
- case WasmType .I64_TYPE -> primitiveMultiValueStack [i ];
226
- case WasmType .F32_TYPE -> Float .intBitsToFloat ((int ) primitiveMultiValueStack [i ]);
227
- case WasmType .F64_TYPE -> Double .longBitsToDouble (primitiveMultiValueStack [i ]);
228
- case WasmType .V128_TYPE , WasmType .FUNCREF_TYPE , WasmType .EXTERNREF_TYPE -> {
229
- Object obj = objectMultiValueStack [i ];
230
- objectMultiValueStack [i ] = null ;
231
- yield obj ;
232
- }
233
- default -> throw WasmException .create (Failure .UNSPECIFIED_INTERNAL );
234
- };
235
- }
236
- return InteropArray .create (values );
237
- }
238
157
}
0 commit comments