Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions sdks/wasm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ debug/:
release/:
mkdir -p $@

debug/.stamp-build: driver.o library_mono.js binding_support.js $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a | debug/
$(EMCC) -g4 -Os -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s "BINARYEN_TRAP_MODE='clamp'" -s TOTAL_MEMORY=134217728 -s ALIASING_FUNCTION_POINTERS=0 -s ASSERTIONS=2 --js-library library_mono.js --js-library binding_support.js driver.o $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a -o debug/mono.js -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString']"
debug/.stamp-build: driver.o library_mono.js binding_support.js dotnet_support.js $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a | debug/
$(EMCC) -g4 -Os -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s "BINARYEN_TRAP_MODE='clamp'" -s TOTAL_MEMORY=134217728 -s ALIASING_FUNCTION_POINTERS=0 -s ASSERTIONS=2 --js-library library_mono.js --js-library binding_support.js --js-library dotnet_support.js driver.o $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a -o debug/mono.js -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString']"
touch $@

# Notice that release/.stamp-build depends on debug/.stamp-build. This is the case as emcc is believed to not work well with parallel builds.
release/.stamp-build: driver.o library_mono.js binding_support.js $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a debug/.stamp-build | release/
$(EMCC) -Oz --llvm-opts 2 --llvm-lto 1 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s "BINARYEN_TRAP_MODE='clamp'" -s TOTAL_MEMORY=134217728 -s ALIASING_FUNCTION_POINTERS=0 --js-library library_mono.js --js-library binding_support.js driver.o $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a -o release/mono.js -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString']"
release/.stamp-build: driver.o library_mono.js binding_support.js dotnet_support.js $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a debug/.stamp-build | release/
$(EMCC) -Oz --llvm-opts 2 --llvm-lto 1 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s "BINARYEN_TRAP_MODE='clamp'" -s TOTAL_MEMORY=134217728 -s ALIASING_FUNCTION_POINTERS=0 --js-library library_mono.js --js-library binding_support.js --js-library dotnet_support.js driver.o $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a -o release/mono.js -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString']"
touch $@

mono.js: $(DRIVER_CONF)/.stamp-build
Expand Down Expand Up @@ -181,6 +181,7 @@ package: build
cp $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a tmp/
cp library_mono.js tmp/
cp binding_support.js tmp/
cp dotnet_support.js tmp/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dotnet_suppport.js file is missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the backing support file. Thanks Rodrigo.

cp -r debug tmp/
cp -r release tmp/
rm tmp/debug/.stamp-build
Expand Down
105 changes: 105 additions & 0 deletions sdks/wasm/dotnet_support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

var DotNetSupportLib = {
$DOTNET: {
_dotnet_get_global: function() {
function testGlobal(obj) {
obj['___dotnet_global___'] = obj;
var success = typeof ___dotnet_global___ === 'object' && obj['___dotnet_global___'] === obj;
if (!success) {
delete obj['___dotnet_global___'];
}
return success;
}
if (typeof ___dotnet_global___ === 'object') {
return ___dotnet_global___;
}
if (typeof global === 'object' && testGlobal(global)) {
___dotnet_global___ = global;
} else if (typeof window === 'object' && testGlobal(window)) {
___dotnet_global___ = window;
}
if (typeof ___dotnet_global___ === 'object') {
return ___dotnet_global___;
}
throw Error('unable to get DotNet global object.');
},
//FIXME this is wastefull, we could remove the temp malloc by going the UTF16 route
//FIXME this is unsafe, cuz raw objects could be GC'd.
conv_string: function (mono_obj) {
if (mono_obj == 0)
return null;

if (!this.mono_string_get_utf8)
this.mono_string_get_utf8 = Module.cwrap ('mono_wasm_string_get_utf8', 'number', ['number']);

var raw = this.mono_string_get_utf8 (mono_obj);
var res = Module.UTF8ToString (raw);
Module._free (raw);

return res;
},
},
mono_wasm_invoke_js_marshalled: function(exceptionMessage, asyncHandleLongPtr, functionName, argsJson) {

var mono_string = DOTNET._dotnet_get_global()._mono_string_cached
|| (DOTNET._dotnet_get_global()._mono_string_cached = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']));

try {
// Passing a .NET long into JS via Emscripten is tricky. The method here is to pass
// as pointer to the long, then combine two reads from the HEAPU32 array.
// Even though JS numbers can't represent the full range of a .NET long, it's OK
// because we'll never exceed Number.MAX_SAFE_INTEGER (2^53 - 1) in this case.
//var u32Index = $1 >> 2;
var u32Index = asyncHandleLongPtr >> 2;
var asyncHandleJsNumber = Module.HEAPU32[u32Index + 1]*4294967296 + Module.HEAPU32[u32Index];

// var funcNameJsString = UTF8ToString (functionName);
// var argsJsonJsString = argsJson && UTF8ToString (argsJson);
var funcNameJsString = DOTNET.conv_string(functionName);
var argsJsonJsString = argsJson && DOTNET.conv_string (argsJson);

var dotNetExports = DOTNET._dotnet_get_global().DotNet;
if (!dotNetExports) {
throw new Error('The Microsoft.JSInterop.js library is not loaded.');
}

if (asyncHandleJsNumber) {
dotNetExports.jsCallDispatcher.beginInvokeJSFromDotNet(asyncHandleJsNumber, funcNameJsString, argsJsonJsString);
return 0;
} else {
var resultJson = dotNetExports.jsCallDispatcher.invokeJSFromDotNet(funcNameJsString, argsJsonJsString);
return resultJson === null ? 0 : mono_string(resultJson);
}
} catch (ex) {
var exceptionJsString = ex.message + '\n' + ex.stack;
var exceptionSystemString = mono_string(exceptionJsString);
setValue (exceptionMessage, exceptionSystemString, 'i32'); // *exceptionMessage = exceptionSystemString;
return 0;
}
},
mono_wasm_invoke_js_unmarshalled: function(exceptionMessage, funcName, arg0, arg1, arg2) {
try {
// Get the function you're trying to invoke
var funcNameJsString = DOTNET.conv_string(funcName);
var dotNetExports = DOTNET._dotnet_get_global().DotNet;
if (!dotNetExports) {
throw new Error('The Microsoft.JSInterop.js library is not loaded.');
}
var funcInstance = dotNetExports.jsCallDispatcher.findJSFunction(funcNameJsString);

return funcInstance.call(null, arg0, arg1, arg2);
} catch (ex) {
var exceptionJsString = ex.message + '\n' + ex.stack;
var mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']); // TODO: Cache
var exceptionSystemString = mono_string(exceptionJsString);
setValue (exceptionMessage, exceptionSystemString, 'i32'); // *exceptionMessage = exceptionSystemString;
return 0;
}
}


};

autoAddDeps(DotNetSupportLib, '$DOTNET')
mergeInto(LibraryManager.library, DotNetSupportLib)

9 changes: 9 additions & 0 deletions sdks/wasm/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ typedef struct _MonoAssemblyName MonoAssemblyName;
//JS funcs
extern MonoObject* mono_wasm_invoke_js_with_args (int js_handle, MonoString *method, MonoArray *args, int *is_exception);

// Blazor specific custom routines - see dotnet_support.js for backing code
extern void* mono_wasm_invoke_js_marshalled (MonoString **exceptionMessage, void *asyncHandleLongPtr, MonoString *funcName, MonoString *argsJson);
extern void* mono_wasm_invoke_js_unmarshalled (MonoString **exceptionMessage, MonoString *funcName, void* arg0, void* arg1, void* arg2);

void mono_jit_set_aot_mode (MonoAotMode mode);
MonoDomain* mono_jit_init_version (const char *root_domain_name, const char *runtime_version);
MonoAssembly* mono_assembly_open (const char *filename, MonoImageOpenStatus *status);
Expand Down Expand Up @@ -206,6 +210,11 @@ mono_wasm_load_runtime (const char *managed_path, int enable_debugging)

mono_add_internal_call ("WebAssembly.Runtime::InvokeJS", mono_wasm_invoke_js);
mono_add_internal_call ("WebAssembly.Runtime::InvokeJSWithArgs", mono_wasm_invoke_js_with_args);

// Blazor specific custom routines - see dotnet_support.js for backing code
mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSMarshalled", mono_wasm_invoke_js_marshalled);
mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSUnmarshalled", mono_wasm_invoke_js_unmarshalled);

}

EMSCRIPTEN_KEEPALIVE MonoAssembly*
Expand Down