1
- import { MethodHandle , System_Object , System_String , System_Array , Pointer , Platform } from '../Platform' ;
1
+ import { System_Object , System_String , System_Array , Pointer , Platform } from '../Platform' ;
2
2
import { getFileNameFromUrl } from '../Url' ;
3
3
import { attachDebuggerHotkey , hasDebuggingEnabled } from './MonoDebugger' ;
4
4
import { showErrorNotification } from '../../BootErrors' ;
5
5
6
- const assemblyHandleCache : { [ assemblyName : string ] : number } = { } ;
7
- const typeHandleCache : { [ fullyQualifiedTypeName : string ] : number } = { } ;
8
- const methodHandleCache : { [ fullyQualifiedMethodName : string ] : MethodHandle } = { } ;
9
-
10
- let assembly_load : ( assemblyName : string ) => number ;
11
- let find_class : ( assemblyHandle : number , namespace : string , className : string ) => number ;
12
- let find_method : ( typeHandle : number , methodName : string , unknownArg : number ) => MethodHandle ;
13
- let invoke_method : ( method : MethodHandle , target : System_Object , argsArrayPtr : number , exceptionFlagIntPtr : number ) => System_Object ;
14
- let mono_string_array_new : ( length : number ) => System_Array < System_String > ;
15
6
let mono_string_get_utf8 : ( managedString : System_String ) => Mono . Utf8Ptr ;
16
- let mono_string : ( jsString : string ) => System_String ;
17
7
const appBinDirName = 'appBinDir' ;
18
8
const uint64HighOrderShift = Math . pow ( 2 , 32 ) ;
19
9
const maxSafeNumberHighPart = Math . pow ( 2 , 21 ) - 1 ; // The high-order int32 from Number.MAX_SAFE_INTEGER
@@ -38,49 +28,16 @@ export const monoPlatform: Platform = {
38
28
} ) ;
39
29
} ,
40
30
41
- findMethod : findMethod ,
42
-
43
31
callEntryPoint : function callEntryPoint ( assemblyName : string ) {
44
32
// Instead of using Module.mono_call_assembly_entry_point, we have our own logic for invoking
45
33
// the entrypoint which adds support for async main.
46
34
// Currently we disregard the return value from the entrypoint, whether it's sync or async.
47
35
// In the future, we might want Blazor.start to return a Promise<Promise<value>>, where the
48
36
// outer promise reflects the startup process, and the inner one reflects the possibly-async
49
37
// .NET entrypoint method.
50
- const invokeEntrypoint = findMethod ( 'Microsoft.AspNetCore.Blazor' , 'Microsoft.AspNetCore.Blazor.Hosting' , 'EntrypointInvoker' , 'InvokeEntrypoint' ) ;
51
- this . callMethod ( invokeEntrypoint , null , [
52
- this . toDotNetString ( assemblyName ) ,
53
- mono_string_array_new ( 0 ) // In the future, we may have a way of supplying arg strings. For now, we always supply an empty string[].
54
- ] ) ;
55
- } ,
56
-
57
- callMethod : function callMethod ( method : MethodHandle , target : System_Object , args : System_Object [ ] ) : System_Object {
58
- if ( args . length > 4 ) {
59
- // Hopefully this restriction can be eased soon, but for now make it clear what's going on
60
- throw new Error ( `Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass ${ args . length } .` ) ;
61
- }
62
-
63
- const stack = Module . stackSave ( ) ;
64
-
65
- try {
66
- const argsBuffer = Module . stackAlloc ( args . length ) ;
67
- const exceptionFlagManagedInt = Module . stackAlloc ( 4 ) ;
68
- for ( let i = 0 ; i < args . length ; ++ i ) {
69
- Module . setValue ( argsBuffer + i * 4 , args [ i ] , 'i32' ) ;
70
- }
71
- Module . setValue ( exceptionFlagManagedInt , 0 , 'i32' ) ;
72
-
73
- const res = invoke_method ( method , target , argsBuffer , exceptionFlagManagedInt ) ;
74
-
75
- if ( Module . getValue ( exceptionFlagManagedInt , 'i32' ) !== 0 ) {
76
- // If the exception flag is set, the returned value is exception.ToString()
77
- throw new Error ( monoPlatform . toJavaScriptString ( < System_String > res ) ) ;
78
- }
79
-
80
- return res ;
81
- } finally {
82
- Module . stackRestore ( stack ) ;
83
- }
38
+ const invokeEntrypoint = bindStaticMethod ( 'Microsoft.AspNetCore.Blazor' , 'Microsoft.AspNetCore.Blazor.Hosting.EntrypointInvoker' , 'InvokeEntrypoint' ) ;
39
+ // Note we're passing in null because passing arrays is problematic until https://github.com/mono/mono/issues/18245 is resolved.
40
+ invokeEntrypoint ( assemblyName , null ) ;
84
41
} ,
85
42
86
43
toJavaScriptString : function toJavaScriptString ( managedString : System_String ) {
@@ -94,10 +51,6 @@ export const monoPlatform: Platform = {
94
51
return res ;
95
52
} ,
96
53
97
- toDotNetString : function toDotNetString ( jsString : string ) : System_String {
98
- return mono_string ( jsString ) ;
99
- } ,
100
-
101
54
toUint8Array : function toUint8Array ( array : System_Array < any > ) : Uint8Array {
102
55
const dataPtr = getArrayDataPointer ( array ) ;
103
56
const length = Module . getValue ( dataPtr , 'i32' ) ;
@@ -158,44 +111,6 @@ export const monoPlatform: Platform = {
158
111
} ,
159
112
} ;
160
113
161
- function findAssembly ( assemblyName : string ) : number {
162
- let assemblyHandle = assemblyHandleCache [ assemblyName ] ;
163
- if ( ! assemblyHandle ) {
164
- assemblyHandle = assembly_load ( assemblyName ) ;
165
- if ( ! assemblyHandle ) {
166
- throw new Error ( `Could not find assembly "${ assemblyName } "` ) ;
167
- }
168
- assemblyHandleCache [ assemblyName ] = assemblyHandle ;
169
- }
170
- return assemblyHandle ;
171
- }
172
-
173
- function findType ( assemblyName : string , namespace : string , className : string ) : number {
174
- const fullyQualifiedTypeName = `[${ assemblyName } ]${ namespace } .${ className } ` ;
175
- let typeHandle = typeHandleCache [ fullyQualifiedTypeName ] ;
176
- if ( ! typeHandle ) {
177
- typeHandle = find_class ( findAssembly ( assemblyName ) , namespace , className ) ;
178
- if ( ! typeHandle ) {
179
- throw new Error ( `Could not find type "${ className } " in namespace "${ namespace } " in assembly "${ assemblyName } "` ) ;
180
- }
181
- typeHandleCache [ fullyQualifiedTypeName ] = typeHandle ;
182
- }
183
- return typeHandle ;
184
- }
185
-
186
- function findMethod ( assemblyName : string , namespace : string , className : string , methodName : string ) : MethodHandle {
187
- const fullyQualifiedMethodName = `[${ assemblyName } ]${ namespace } .${ className } ::${ methodName } ` ;
188
- let methodHandle = methodHandleCache [ fullyQualifiedMethodName ] ;
189
- if ( ! methodHandle ) {
190
- methodHandle = find_method ( findType ( assemblyName , namespace , className ) , methodName , - 1 ) ;
191
- if ( ! methodHandle ) {
192
- throw new Error ( `Could not find method "${ methodName } " on type "${ namespace } .${ className } "` ) ;
193
- }
194
- methodHandleCache [ fullyQualifiedMethodName ] = methodHandle ;
195
- }
196
- return methodHandle ;
197
- }
198
-
199
114
function addScriptTagsToDocument ( ) {
200
115
const browserSupportsNativeWebAssembly = typeof WebAssembly !== 'undefined' && WebAssembly . validate ;
201
116
if ( ! browserSupportsNativeWebAssembly ) {
@@ -254,26 +169,8 @@ function createEmscriptenModuleInstance(loadAssemblyUrls: string[], onReady: ()
254
169
'number' ,
255
170
'number' ,
256
171
] ) ;
257
- assembly_load = Module . cwrap ( 'mono_wasm_assembly_load' , 'number' , [ 'string' ] ) ;
258
- find_class = Module . cwrap ( 'mono_wasm_assembly_find_class' , 'number' , [
259
- 'number' ,
260
- 'string' ,
261
- 'string' ,
262
- ] ) ;
263
- find_method = Module . cwrap ( 'mono_wasm_assembly_find_method' , 'number' , [
264
- 'number' ,
265
- 'string' ,
266
- 'number' ,
267
- ] ) ;
268
- invoke_method = Module . cwrap ( 'mono_wasm_invoke_method' , 'number' , [
269
- 'number' ,
270
- 'number' ,
271
- 'number' ,
272
- ] ) ;
273
172
274
173
mono_string_get_utf8 = Module . cwrap ( 'mono_wasm_string_get_utf8' , 'number' , [ 'number' ] ) ;
275
- mono_string = Module . cwrap ( 'mono_wasm_string_from_js' , 'number' , [ 'string' ] ) ;
276
- mono_string_array_new = Module . cwrap ( 'mono_wasm_string_array_new' , 'number' , [ 'number' ] ) ;
277
174
278
175
MONO . loaded_files = [ ] ;
279
176
@@ -346,10 +243,16 @@ function getArrayDataPointer<T>(array: System_Array<T>): number {
346
243
return < number > < any > array + 12 ; // First byte from here is length, then following bytes are entries
347
244
}
348
245
246
+ function bindStaticMethod ( assembly : string , typeName : string , method : string ) : ( ...args : any [ ] ) => any {
247
+ // Fully qualified name looks like this: "[debugger-test] Math:IntAdd"
248
+ const fqn = `[${ assembly } ] ${ typeName } :${ method } ` ;
249
+ return Module . mono_bind_static_method ( fqn ) ;
250
+ }
251
+
349
252
function attachInteropInvoker ( ) : void {
350
- const dotNetDispatcherInvokeMethodHandle = findMethod ( 'Mono.WebAssembly.Interop' , 'Mono.WebAssembly.Interop' , ' MonoWebAssemblyJSRuntime', 'InvokeDotNet' ) ;
351
- const dotNetDispatcherBeginInvokeMethodHandle = findMethod ( 'Mono.WebAssembly.Interop' , 'Mono.WebAssembly.Interop' , ' MonoWebAssemblyJSRuntime', 'BeginInvokeDotNet' ) ;
352
- const dotNetDispatcherEndInvokeJSMethodHandle = findMethod ( 'Mono.WebAssembly.Interop' , 'Mono.WebAssembly.Interop' , ' MonoWebAssemblyJSRuntime', 'EndInvokeJS' ) ;
253
+ const dotNetDispatcherInvokeMethodHandle = bindStaticMethod ( 'Mono.WebAssembly.Interop' , 'Mono.WebAssembly.Interop. MonoWebAssemblyJSRuntime' , 'InvokeDotNet' ) ;
254
+ const dotNetDispatcherBeginInvokeMethodHandle = bindStaticMethod ( 'Mono.WebAssembly.Interop' , 'Mono.WebAssembly.Interop. MonoWebAssemblyJSRuntime' , 'BeginInvokeDotNet' ) ;
255
+ const dotNetDispatcherEndInvokeJSMethodHandle = bindStaticMethod ( 'Mono.WebAssembly.Interop' , 'Mono.WebAssembly.Interop. MonoWebAssemblyJSRuntime' , 'EndInvokeJS' ) ;
353
256
354
257
DotNet . attachDispatcher ( {
355
258
beginInvokeDotNetFromJS : ( callId : number , assemblyName : string | null , methodIdentifier : string , dotNetObjectId : any | null , argsJson : string ) : void => {
@@ -362,30 +265,25 @@ function attachInteropInvoker(): void {
362
265
? dotNetObjectId . toString ( )
363
266
: assemblyName ;
364
267
365
- monoPlatform . callMethod ( dotNetDispatcherBeginInvokeMethodHandle , null , [
366
- callId ? monoPlatform . toDotNetString ( callId . toString ( ) ) : null ,
367
- monoPlatform . toDotNetString ( assemblyNameOrDotNetObjectId ) ,
368
- monoPlatform . toDotNetString ( methodIdentifier ) ,
369
- monoPlatform . toDotNetString ( argsJson ) ,
370
- ] ) ;
268
+ dotNetDispatcherBeginInvokeMethodHandle (
269
+ callId ? callId . toString ( ) : null ,
270
+ assemblyNameOrDotNetObjectId ,
271
+ methodIdentifier ,
272
+ argsJson ,
273
+ ) ;
371
274
} ,
372
275
endInvokeJSFromDotNet : ( asyncHandle , succeeded , serializedArgs ) : void => {
373
- monoPlatform . callMethod (
374
- dotNetDispatcherEndInvokeJSMethodHandle ,
375
- null ,
376
- [ monoPlatform . toDotNetString ( serializedArgs ) ]
276
+ dotNetDispatcherEndInvokeJSMethodHandle (
277
+ serializedArgs
377
278
) ;
378
279
} ,
379
280
invokeDotNetFromJS : ( assemblyName , methodIdentifier , dotNetObjectId , argsJson ) => {
380
- const resultJsonStringPtr = monoPlatform . callMethod ( dotNetDispatcherInvokeMethodHandle , null , [
381
- assemblyName ? monoPlatform . toDotNetString ( assemblyName ) : null ,
382
- monoPlatform . toDotNetString ( methodIdentifier ) ,
383
- dotNetObjectId ? monoPlatform . toDotNetString ( dotNetObjectId . toString ( ) ) : null ,
384
- monoPlatform . toDotNetString ( argsJson ) ,
385
- ] ) as System_String ;
386
- return resultJsonStringPtr
387
- ? monoPlatform . toJavaScriptString ( resultJsonStringPtr )
388
- : null ;
281
+ return dotNetDispatcherInvokeMethodHandle (
282
+ assemblyName ? assemblyName : null ,
283
+ methodIdentifier ,
284
+ dotNetObjectId ? dotNetObjectId . toString ( ) : null ,
285
+ argsJson ,
286
+ ) as string ;
389
287
} ,
390
288
} ) ;
391
289
}
0 commit comments