diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 647b0bfb18..bbc5547cac 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,9 +9,9 @@ --> - + https://github.com/aspnet/Blazor - d1f3a3db8a379cc887cd6dde0acf77dcd5e16c36 + 9ff01af4257317a90b64959fe1c87aef3da4a36f https://github.com/aspnet/AspNetCore-Tooling diff --git a/eng/Versions.props b/eng/Versions.props index ad3237db70..59d5afadfa 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -95,7 +95,7 @@ 5.0.0-alpha.1.19556.7 - 3.1.0-preview4.19576.1 + 3.1.0-preview4.19578.1 5.0.0-alpha.1.19626.1 5.0.0-alpha.1.19626.1 diff --git a/src/Components/Blazor/Blazor/src/Hosting/EntrypointInvoker.cs b/src/Components/Blazor/Blazor/src/Hosting/EntrypointInvoker.cs index bce063bcf5..40a5d07de4 100644 --- a/src/Components/Blazor/Blazor/src/Hosting/EntrypointInvoker.cs +++ b/src/Components/Blazor/Blazor/src/Hosting/EntrypointInvoker.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Blazor.Hosting { var assembly = Assembly.Load(assemblyName); var entrypoint = FindUnderlyingEntrypoint(assembly); - var @params = entrypoint.GetParameters().Length == 1 ? new object[] { args } : new object[] { }; + var @params = entrypoint.GetParameters().Length == 1 ? new object[] { args ?? Array.Empty() } : new object[] { }; entrypointResult = entrypoint.Invoke(null, @params); } catch (Exception syncException) diff --git a/src/Components/Web.JS/dist/Release/blazor.webassembly.js b/src/Components/Web.JS/dist/Release/blazor.webassembly.js index 50714fd113..66bcb15fc5 100644 --- a/src/Components/Web.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Web.JS/dist/Release/blazor.webassembly.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=45)}([,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(25),n(19);var r=n(26),o=n(13),a={},i=!1;function l(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=l,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");l(n||0,o.toLogicalElement(r,!0),t)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),l=r.values(o),u=r.count(o),s=t.referenceFrames(),c=r.values(s),f=t.diffReader,d=0;d0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function l(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===c(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=u(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):d(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=c},,,,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function l(e,t,n,r){var o=s();if(o.invokeDotNetFromJS){var a=JSON.stringify(r,h),i=o.invokeDotNetFromJS(e,t,n,a);return i?f(i):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function u(e,t,r,a){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var i=o++,l=new Promise(function(e,t){n[i]={resolve:e,reject:t}});try{var u=JSON.stringify(a,h);s().beginInvokeDotNetFromJS(i,e,t,r,u)}catch(e){c(i,!1,e)}return l}function s(){if(null!==a)return a;throw new Error("No .NET call dispatcher has been set.")}function c(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function f(e){return e?JSON.parse(e,function(e,n){return t.reduce(function(t,n){return n(e,t)},n)}):null}function d(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach(function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e}),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){a=e},e.attachReviver=i,e.invokeMethod=function(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),l=Module.stackAlloc(4),u=0;u>2,r=Module.HEAPU32[n+1];if(r>g)throw new Error("Cannot read uint64 with high order part "+r+", because the result would exceed Number.MAX_SAFE_INTEGER.");return r*y+Module.HEAPU32[n]},readFloatField:function(e,t){return Module.getValue(e+(t||0),"float")},readObjectField:function(e,t){return Module.getValue(e+(t||0),"i32")},readStringField:function(e,n){var r=Module.getValue(e+(n||0),"i32");return 0===r?null:t.monoPlatform.toJavaScriptString(r)},readStructField:function(e,t){return e+(t||0)}};var E=document.createElement("a");function _(e){return e+12}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(35),o=window.chrome&&navigator.userAgent.indexOf("Edge")<0,a=!1;function i(){return a&&o}t.hasDebuggingEnabled=i,t.attachDebuggerHotkey=function(e){a=e.some(function(e){return/\.pdb$/.test(r.getFileNameFromUrl(e))});var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";i()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),document.addEventListener("keydown",function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(a?o?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Edge(Chromium) or Chrome is supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(19),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=a,this.arrayBuilderSegmentReader=i,this.diffReader=l,this.editReader=u,this.frameReader=s}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,a.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*a.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*a.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return c(e,t,l.structLength)},e.prototype.referenceFramesEntry=function(e,t){return c(e,t,s.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=c(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=c(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var a={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},i={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},l={structLength:4+i.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return c(e,t,u.structLength)}},u={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},s={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function c(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}}]); \ No newline at end of file +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=45)}([,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(25),n(19);var r=n(26),o=n(13),a={},i=!1;function u(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=u,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");u(n||0,o.toLogicalElement(r,!0),t)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),u=r.values(o),l=r.count(o),s=t.referenceFrames(),c=r.values(s),d=t.diffReader,f=0;f0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===c(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=d(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=c},,,,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t,n,r){var o=s();if(o.invokeDotNetFromJS){var a=JSON.stringify(r,h),i=o.invokeDotNetFromJS(e,t,n,a);return i?d(i):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function l(e,t,r,a){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var i=o++,u=new Promise(function(e,t){n[i]={resolve:e,reject:t}});try{var l=JSON.stringify(a,h);s().beginInvokeDotNetFromJS(i,e,t,r,l)}catch(e){c(i,!1,e)}return u}function s(){if(null!==a)return a;throw new Error("No .NET call dispatcher has been set.")}function c(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function d(e){return e?JSON.parse(e,function(e,n){return t.reduce(function(t,n){return n(e,t)},n)}):null}function f(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach(function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e}),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){a=e},e.attachReviver=i,e.invokeMethod=function(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]>2,r=Module.HEAPU32[n+1];if(r>s)throw new Error("Cannot read uint64 with high order part "+r+", because the result would exceed Number.MAX_SAFE_INTEGER.");return r*l+Module.HEAPU32[n]},readFloatField:function(e,t){return Module.getValue(e+(t||0),"float")},readObjectField:function(e,t){return Module.getValue(e+(t||0),"i32")},readStringField:function(e,n){var r=Module.getValue(e+(n||0),"i32");return 0===r?null:t.monoPlatform.toJavaScriptString(r)},readStructField:function(e,t){return e+(t||0)}};var c=document.createElement("a");function d(e){return e+12}function f(e,t,n){var r="["+e+"] "+t+":"+n;return Module.mono_bind_static_method(r)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(35),o=window.chrome&&navigator.userAgent.indexOf("Edge")<0,a=!1;function i(){return a&&o}t.hasDebuggingEnabled=i,t.attachDebuggerHotkey=function(e){a=e.some(function(e){return/\.pdb$/.test(r.getFileNameFromUrl(e))});var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";i()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),document.addEventListener("keydown",function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(a?o?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Edge(Chromium) or Chrome is supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(19),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=a,this.arrayBuilderSegmentReader=i,this.diffReader=u,this.editReader=l,this.frameReader=s}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,a.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*a.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*a.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return c(e,t,u.structLength)},e.prototype.referenceFramesEntry=function(e,t){return c(e,t,s.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=c(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=c(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var a={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},i={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},u={structLength:4+i.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return c(e,t,l.structLength)}},l={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},s={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function c(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}}]); \ No newline at end of file diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index 527dcd5ab8..cf637d8444 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -1,19 +1,9 @@ -import { MethodHandle, System_Object, System_String, System_Array, Pointer, Platform } from '../Platform'; +import { System_Object, System_String, System_Array, Pointer, Platform } from '../Platform'; import { getFileNameFromUrl } from '../Url'; import { attachDebuggerHotkey, hasDebuggingEnabled } from './MonoDebugger'; import { showErrorNotification } from '../../BootErrors'; -const assemblyHandleCache: { [assemblyName: string]: number } = {}; -const typeHandleCache: { [fullyQualifiedTypeName: string]: number } = {}; -const methodHandleCache: { [fullyQualifiedMethodName: string]: MethodHandle } = {}; - -let assembly_load: (assemblyName: string) => number; -let find_class: (assemblyHandle: number, namespace: string, className: string) => number; -let find_method: (typeHandle: number, methodName: string, unknownArg: number) => MethodHandle; -let invoke_method: (method: MethodHandle, target: System_Object, argsArrayPtr: number, exceptionFlagIntPtr: number) => System_Object; -let mono_string_array_new: (length: number) => System_Array; let mono_string_get_utf8: (managedString: System_String) => Mono.Utf8Ptr; -let mono_string: (jsString: string) => System_String; const appBinDirName = 'appBinDir'; const uint64HighOrderShift = Math.pow(2, 32); const maxSafeNumberHighPart = Math.pow(2, 21) - 1; // The high-order int32 from Number.MAX_SAFE_INTEGER @@ -38,8 +28,6 @@ export const monoPlatform: Platform = { }); }, - findMethod: findMethod, - callEntryPoint: function callEntryPoint(assemblyName: string) { // Instead of using Module.mono_call_assembly_entry_point, we have our own logic for invoking // the entrypoint which adds support for async main. @@ -47,40 +35,9 @@ export const monoPlatform: Platform = { // In the future, we might want Blazor.start to return a Promise>, where the // outer promise reflects the startup process, and the inner one reflects the possibly-async // .NET entrypoint method. - const invokeEntrypoint = findMethod('Microsoft.AspNetCore.Blazor', 'Microsoft.AspNetCore.Blazor.Hosting', 'EntrypointInvoker', 'InvokeEntrypoint'); - this.callMethod(invokeEntrypoint, null, [ - this.toDotNetString(assemblyName), - 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[]. - ]); - }, - - callMethod: function callMethod(method: MethodHandle, target: System_Object, args: System_Object[]): System_Object { - if (args.length > 4) { - // Hopefully this restriction can be eased soon, but for now make it clear what's going on - throw new Error(`Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass ${args.length}.`); - } - - const stack = Module.stackSave(); - - try { - const argsBuffer = Module.stackAlloc(args.length); - const exceptionFlagManagedInt = Module.stackAlloc(4); - for (let i = 0; i < args.length; ++i) { - Module.setValue(argsBuffer + i * 4, args[i], 'i32'); - } - Module.setValue(exceptionFlagManagedInt, 0, 'i32'); - - const res = invoke_method(method, target, argsBuffer, exceptionFlagManagedInt); - - if (Module.getValue(exceptionFlagManagedInt, 'i32') !== 0) { - // If the exception flag is set, the returned value is exception.ToString() - throw new Error(monoPlatform.toJavaScriptString(res)); - } - - return res; - } finally { - Module.stackRestore(stack); - } + const invokeEntrypoint = bindStaticMethod('Microsoft.AspNetCore.Blazor', 'Microsoft.AspNetCore.Blazor.Hosting.EntrypointInvoker', 'InvokeEntrypoint'); + // Note we're passing in null because passing arrays is problematic until https://github.com/mono/mono/issues/18245 is resolved. + invokeEntrypoint(assemblyName, null); }, toJavaScriptString: function toJavaScriptString(managedString: System_String) { @@ -94,10 +51,6 @@ export const monoPlatform: Platform = { return res; }, - toDotNetString: function toDotNetString(jsString: string): System_String { - return mono_string(jsString); - }, - toUint8Array: function toUint8Array(array: System_Array): Uint8Array { const dataPtr = getArrayDataPointer(array); const length = Module.getValue(dataPtr, 'i32'); @@ -158,44 +111,6 @@ export const monoPlatform: Platform = { }, }; -function findAssembly(assemblyName: string): number { - let assemblyHandle = assemblyHandleCache[assemblyName]; - if (!assemblyHandle) { - assemblyHandle = assembly_load(assemblyName); - if (!assemblyHandle) { - throw new Error(`Could not find assembly "${assemblyName}"`); - } - assemblyHandleCache[assemblyName] = assemblyHandle; - } - return assemblyHandle; -} - -function findType(assemblyName: string, namespace: string, className: string): number { - const fullyQualifiedTypeName = `[${assemblyName}]${namespace}.${className}`; - let typeHandle = typeHandleCache[fullyQualifiedTypeName]; - if (!typeHandle) { - typeHandle = find_class(findAssembly(assemblyName), namespace, className); - if (!typeHandle) { - throw new Error(`Could not find type "${className}" in namespace "${namespace}" in assembly "${assemblyName}"`); - } - typeHandleCache[fullyQualifiedTypeName] = typeHandle; - } - return typeHandle; -} - -function findMethod(assemblyName: string, namespace: string, className: string, methodName: string): MethodHandle { - const fullyQualifiedMethodName = `[${assemblyName}]${namespace}.${className}::${methodName}`; - let methodHandle = methodHandleCache[fullyQualifiedMethodName]; - if (!methodHandle) { - methodHandle = find_method(findType(assemblyName, namespace, className), methodName, -1); - if (!methodHandle) { - throw new Error(`Could not find method "${methodName}" on type "${namespace}.${className}"`); - } - methodHandleCache[fullyQualifiedMethodName] = methodHandle; - } - return methodHandle; -} - function addScriptTagsToDocument() { const browserSupportsNativeWebAssembly = typeof WebAssembly !== 'undefined' && WebAssembly.validate; if (!browserSupportsNativeWebAssembly) { @@ -254,26 +169,8 @@ function createEmscriptenModuleInstance(loadAssemblyUrls: string[], onReady: () 'number', 'number', ]); - assembly_load = Module.cwrap('mono_wasm_assembly_load', 'number', ['string']); - find_class = Module.cwrap('mono_wasm_assembly_find_class', 'number', [ - 'number', - 'string', - 'string', - ]); - find_method = Module.cwrap('mono_wasm_assembly_find_method', 'number', [ - 'number', - 'string', - 'number', - ]); - invoke_method = Module.cwrap('mono_wasm_invoke_method', 'number', [ - 'number', - 'number', - 'number', - ]); mono_string_get_utf8 = Module.cwrap('mono_wasm_string_get_utf8', 'number', ['number']); - mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']); - mono_string_array_new = Module.cwrap('mono_wasm_string_array_new', 'number', ['number']); MONO.loaded_files = []; @@ -346,10 +243,16 @@ function getArrayDataPointer(array: System_Array): number { return array + 12; // First byte from here is length, then following bytes are entries } +function bindStaticMethod(assembly: string, typeName: string, method: string) : (...args: any[]) => any { + // Fully qualified name looks like this: "[debugger-test] Math:IntAdd" + const fqn = `[${assembly}] ${typeName}:${method}`; + return Module.mono_bind_static_method(fqn); +} + function attachInteropInvoker(): void { - const dotNetDispatcherInvokeMethodHandle = findMethod('Mono.WebAssembly.Interop', 'Mono.WebAssembly.Interop', 'MonoWebAssemblyJSRuntime', 'InvokeDotNet'); - const dotNetDispatcherBeginInvokeMethodHandle = findMethod('Mono.WebAssembly.Interop', 'Mono.WebAssembly.Interop', 'MonoWebAssemblyJSRuntime', 'BeginInvokeDotNet'); - const dotNetDispatcherEndInvokeJSMethodHandle = findMethod('Mono.WebAssembly.Interop', 'Mono.WebAssembly.Interop', 'MonoWebAssemblyJSRuntime', 'EndInvokeJS'); + const dotNetDispatcherInvokeMethodHandle = bindStaticMethod('Mono.WebAssembly.Interop', 'Mono.WebAssembly.Interop.MonoWebAssemblyJSRuntime', 'InvokeDotNet'); + const dotNetDispatcherBeginInvokeMethodHandle = bindStaticMethod('Mono.WebAssembly.Interop', 'Mono.WebAssembly.Interop.MonoWebAssemblyJSRuntime', 'BeginInvokeDotNet'); + const dotNetDispatcherEndInvokeJSMethodHandle = bindStaticMethod('Mono.WebAssembly.Interop', 'Mono.WebAssembly.Interop.MonoWebAssemblyJSRuntime', 'EndInvokeJS'); DotNet.attachDispatcher({ beginInvokeDotNetFromJS: (callId: number, assemblyName: string | null, methodIdentifier: string, dotNetObjectId: any | null, argsJson: string): void => { @@ -362,30 +265,25 @@ function attachInteropInvoker(): void { ? dotNetObjectId.toString() : assemblyName; - monoPlatform.callMethod(dotNetDispatcherBeginInvokeMethodHandle, null, [ - callId ? monoPlatform.toDotNetString(callId.toString()) : null, - monoPlatform.toDotNetString(assemblyNameOrDotNetObjectId), - monoPlatform.toDotNetString(methodIdentifier), - monoPlatform.toDotNetString(argsJson), - ]); + dotNetDispatcherBeginInvokeMethodHandle( + callId ? callId.toString() : null, + assemblyNameOrDotNetObjectId, + methodIdentifier, + argsJson, + ); }, endInvokeJSFromDotNet: (asyncHandle, succeeded, serializedArgs): void => { - monoPlatform.callMethod( - dotNetDispatcherEndInvokeJSMethodHandle, - null, - [monoPlatform.toDotNetString(serializedArgs)] + dotNetDispatcherEndInvokeJSMethodHandle( + serializedArgs ); }, invokeDotNetFromJS: (assemblyName, methodIdentifier, dotNetObjectId, argsJson) => { - const resultJsonStringPtr = monoPlatform.callMethod(dotNetDispatcherInvokeMethodHandle, null, [ - assemblyName ? monoPlatform.toDotNetString(assemblyName) : null, - monoPlatform.toDotNetString(methodIdentifier), - dotNetObjectId ? monoPlatform.toDotNetString(dotNetObjectId.toString()) : null, - monoPlatform.toDotNetString(argsJson), - ]) as System_String; - return resultJsonStringPtr - ? monoPlatform.toJavaScriptString(resultJsonStringPtr) - : null; + return dotNetDispatcherInvokeMethodHandle( + assemblyName ? assemblyName : null, + methodIdentifier, + dotNetObjectId ? dotNetObjectId.toString() : null, + argsJson, + ) as string; }, }); } diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoTypes.d.ts b/src/Components/Web.JS/src/Platform/Mono/MonoTypes.d.ts index 0fc613915b..7d2f5c23bf 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoTypes.d.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoTypes.d.ts @@ -10,7 +10,7 @@ declare namespace Module { function FS_createPath(parent, path, canRead, canWrite); function FS_createDataFile(parent, name, data, canRead, canWrite, canOwn); - function mono_call_assembly_entry_point(assemblyName: string, args: any[]): any; + function mono_bind_static_method(fqn: string): BoundStaticMethod; } // Emscripten declares these globals @@ -28,3 +28,7 @@ declare namespace MONO { var mono_wasm_runtime_is_ready: boolean; function mono_wasm_setenv (name: string, value: string): void; } + +// mono_bind_static_method allows arbitrary JS data types to be sent over the wire. However we are +// artifically limiting it to a subset of types that we actually use. +declare type BoundStaticMethod = (...args: (string | number | null)[]) => (string | number | null); diff --git a/src/Components/Web.JS/src/Platform/Platform.ts b/src/Components/Web.JS/src/Platform/Platform.ts index 29eb04609e..8d5daf454a 100644 --- a/src/Components/Web.JS/src/Platform/Platform.ts +++ b/src/Components/Web.JS/src/Platform/Platform.ts @@ -2,12 +2,8 @@ export interface Platform { start(loadAssemblyUrls: string[]): Promise; callEntryPoint(assemblyName: string): void; - findMethod(assemblyName: string, namespace: string, className: string, methodName: string): MethodHandle; - callMethod(method: MethodHandle, target: System_Object | null, args: (System_Object | null)[]): System_Object; toJavaScriptString(dotNetString: System_String): string; - toDotNetString(javaScriptString: string): System_String; - toUint8Array(array: System_Array): Uint8Array; getArrayLength(array: System_Array): number;