-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[wasm]: JavaScript interop with [JSImport] and [JSExport] attributes and Roslyn #66304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[wasm]: JavaScript interop with [JSImport] and [JSExport] attributes and Roslyn #66304
Conversation
|
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
|
Tagging subscribers to 'arch-wasm': @lewing Issue Detailsjust prototyping
|
45b7531 to
3c1632a
Compare
df06213 to
b44b2e0
Compare
57f7c36 to
b0964c3
Compare
45eb979 to
6fb4f63
Compare
|
/azp run runtime-wasm |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run runtime-wasm |
|
Azure Pipelines successfully started running 1 pipeline(s). |
9c09df4 to
9d81c87
Compare
|
/azp run runtime-wasm |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run runtime-wasm |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Test failure |
This comment was marked as outdated.
This comment was marked as outdated.
|
# Conflicts: # src/mono/wasm/runtime/exports.ts
src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/timers.mjs
Show resolved
Hide resolved
| System.Net.WebSockets; | ||
| System.Net.WebSockets.Client; | ||
| System.Numerics.Vectors; | ||
| System.ObjectModel; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that you are only removing code from this section. Should the newly added library not be exposed in the shared framework?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new ones are System.Runtime.InteropServices.JavaScript and JSImportGenerator.
Both of them should be visible and compile on any platform.
I don't fully understand the question nor the necessary action. Could you please elaborate ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new assembly System.Runtime.InteropServices.JavaScript is currently not exposed in the shared framework because the entry is missing from here:
runtime/src/libraries/NetCoreAppLibrary.props
Lines 28 to 176 in cf83273
| <NetCoreAppLibrary> | |
| $(NetFxReference) | |
| netstandard; | |
| Microsoft.CSharp; | |
| Microsoft.VisualBasic.Core; | |
| Microsoft.Win32.Primitives; | |
| Microsoft.Win32.Registry; | |
| System.AppContext; | |
| System.Buffers; | |
| System.Collections; | |
| System.Collections.Concurrent; | |
| System.Collections.Immutable; | |
| System.Collections.NonGeneric; | |
| System.Collections.Specialized; | |
| System.ComponentModel; | |
| System.ComponentModel.Annotations; | |
| System.ComponentModel.EventBasedAsync; | |
| System.ComponentModel.Primitives; | |
| System.ComponentModel.TypeConverter; | |
| System.Console; | |
| System.Data.Common; | |
| System.Data.DataSetExtensions; | |
| System.Diagnostics.Contracts; | |
| System.Diagnostics.Debug; | |
| System.Diagnostics.DiagnosticSource; | |
| System.Diagnostics.FileVersionInfo; | |
| System.Diagnostics.Process; | |
| System.Diagnostics.StackTrace; | |
| System.Diagnostics.TextWriterTraceListener; | |
| System.Diagnostics.Tools; | |
| System.Diagnostics.TraceSource; | |
| System.Diagnostics.Tracing; | |
| System.Drawing.Primitives; | |
| System.Dynamic.Runtime; | |
| System.Formats.Asn1; | |
| System.Formats.Tar; | |
| System.Globalization; | |
| System.Globalization.Calendars; | |
| System.Globalization.Extensions; | |
| System.IO; | |
| System.IO.Compression; | |
| System.IO.Compression.Brotli; | |
| System.IO.Compression.ZipFile; | |
| System.IO.FileSystem; | |
| System.IO.FileSystem.AccessControl; | |
| System.IO.FileSystem.DriveInfo; | |
| System.IO.FileSystem.Primitives; | |
| System.IO.FileSystem.Watcher; | |
| System.IO.IsolatedStorage; | |
| System.IO.MemoryMappedFiles; | |
| System.IO.Pipes; | |
| System.IO.Pipes.AccessControl; | |
| System.IO.UnmanagedMemoryStream; | |
| System.Linq; | |
| System.Linq.Expressions; | |
| System.Linq.Parallel; | |
| System.Linq.Queryable; | |
| System.Memory; | |
| System.Net.Http; | |
| System.Net.Http.Json; | |
| System.Net.HttpListener; | |
| System.Net.Mail; | |
| System.Net.NameResolution; | |
| System.Net.NetworkInformation; | |
| System.Net.Ping; | |
| System.Net.Primitives; | |
| System.Net.Quic; | |
| System.Net.Requests; | |
| System.Net.Security; | |
| System.Net.ServicePoint; | |
| System.Net.Sockets; | |
| System.Net.WebClient; | |
| System.Net.WebHeaderCollection; | |
| System.Net.WebProxy; | |
| System.Net.WebSockets; | |
| System.Net.WebSockets.Client; | |
| System.Numerics.Vectors; | |
| System.ObjectModel; | |
| System.Private.CoreLib; | |
| System.Private.DataContractSerialization; | |
| System.Private.Uri; | |
| System.Private.Xml; | |
| System.Private.Xml.Linq; | |
| System.Reflection; | |
| System.Reflection.DispatchProxy; | |
| System.Reflection.Emit; | |
| System.Reflection.Emit.ILGeneration; | |
| System.Reflection.Emit.Lightweight; | |
| System.Reflection.Extensions; | |
| System.Reflection.Metadata; | |
| System.Reflection.Primitives; | |
| System.Reflection.TypeExtensions; | |
| System.Resources.Reader; | |
| System.Resources.ResourceManager; | |
| System.Resources.Writer; | |
| System.Runtime; | |
| System.Runtime.CompilerServices.Unsafe; | |
| System.Runtime.CompilerServices.VisualC; | |
| System.Runtime.Extensions; | |
| System.Runtime.Handles; | |
| System.Runtime.InteropServices; | |
| System.Runtime.InteropServices.JavaScript; | |
| System.Runtime.InteropServices.RuntimeInformation; | |
| System.Runtime.Intrinsics; | |
| System.Runtime.Loader; | |
| System.Runtime.Numerics; | |
| System.Runtime.Serialization.Formatters; | |
| System.Runtime.Serialization.Json; | |
| System.Runtime.Serialization.Primitives; | |
| System.Runtime.Serialization.Xml; | |
| System.Security.AccessControl; | |
| System.Security.Claims; | |
| System.Security.Cryptography; | |
| System.Security.Cryptography.Algorithms; | |
| System.Security.Cryptography.Cng; | |
| System.Security.Cryptography.Csp; | |
| System.Security.Cryptography.Encoding; | |
| System.Security.Cryptography.OpenSsl; | |
| System.Security.Cryptography.Primitives; | |
| System.Security.Cryptography.X509Certificates; | |
| System.Security.Principal; | |
| System.Security.Principal.Windows; | |
| System.Security.SecureString; | |
| System.Text.Encoding; | |
| System.Text.Encoding.CodePages; | |
| System.Text.Encoding.Extensions; | |
| System.Text.Encodings.Web; | |
| System.Text.Json; | |
| System.Text.RegularExpressions; | |
| System.Threading; | |
| System.Threading.Channels; | |
| System.Threading.Overlapped; | |
| System.Threading.Tasks; | |
| System.Threading.Tasks.Dataflow; | |
| System.Threading.Tasks.Extensions; | |
| System.Threading.Tasks.Parallel; | |
| System.Threading.Thread; | |
| System.Threading.ThreadPool; | |
| System.Threading.Timer; | |
| System.Transactions.Local; | |
| System.ValueTuple; | |
| System.Web.HttpUtility; | |
| System.Xml.ReaderWriter; | |
| System.Xml.XDocument; | |
| System.Xml.XmlDocument; | |
| System.Xml.XmlSerializer; | |
| System.Xml.XPath; | |
| System.Xml.XPath.XDocument; | |
| </NetCoreAppLibrary> |
The source generator is already exposed, so no action necessary for that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's already there from previous PR
runtime/src/libraries/NetCoreAppLibrary.props
Line 129 in cf83273
| System.Runtime.InteropServices.JavaScript; |
is that OK ?
Design
This evolved from #64493 and steals many ideas from #60765 and also from conversations with @kg
Related API proposal is #70133
Contributes to #46378
Contributes to #47909
Fixes #65959
Fixes #69394
JSImportJSExportcode is always retained as we don't have linker visibility to JavaScript usage.stackallocfor call arguments, both directionsMonoString*MonoObject*to user javaScriptMonoString*is still used for strings and exception Message[JSExport]marked methods are accessible from JS side.[JSMarshalAs]attribute.JSTypecould be used.Examples
In scope
JSImportAttribute,JSExportAttributeFunction.New(string code, out Action function)and few otherFunc<>signaturesJSObject.GetPropertyAsXXXJSObject.SetPropertyas extension methodJSMarshalAsAttributeandJSTypeJSType.Bool- C#boolas JS boolean as opposed to possible but unusualNumberin JS.Nullable<>JSType.Number- it's actually likedoubleinsideboolandchar,decimal,float,doubleIntPtr,void*for people who know what they are doing with itNullable<>JSType.BigIntInt64andNullable<Int64>JSType.String-System.StringJSType.Date-System.DateTime,System.DateTimeOffsetNullable<>JSType.Promise-Task,Task<>JSType.Function-Func<>andAction<>JSType.MemoryView-ArraySegment<byte>,ArraySegment<int>,ArraySegment<double>Uint8Array-like view, with API protecting user from wasm memory resizePinnedGCHandle until the JS view is collectedJSType.MemoryView-Span<byte>,Span<int>,Span<double>JSType.Error-System.ExceptionandJSExceptionJSType.Arraystring[]as JavaScriptArray_RegisterGCRoot/mono_wasm_register_rooton the list bufferobject[]as JavaScriptArrayJSObject[]as JavaScriptArraybyte[]as JavaScriptUint8Arrayint[]as JavaScriptInt32Arraydouble[]as JavaScriptFloat64ArrayJSType.ObjectforJSObjectproxyJSType.Discard,JSType.VoidJSType.AnyforSystem.Object- by dynamic type of parameter instancestring,double,bool,DateTime,JSObject,Exception, and C# proxy back get default mappingJSObjectproxy would be createdstring,bool,byte,char,short,int,float,double,DateTime,DateTimeOffset,JSObject,Exception,DateTime,Nullable<>get default mappingManagedObjectproxy would be createdTask<object>signaturebyte[],int[],double[]<->Uint8Array,Int32Array,Float64Arrayand backstring[],object[]->ArrayArray->object[]long, functions,Span,ArraySegment, will throwNotImplementedExceptionJSMarshalAsAttributeon generic parameters with multiple params.void Foo([JSMarshalAs<JSType.Promise<JSType.BigInt>>] Task<long> value)GetArgumentSignature[JSImport]to[JSImport]`Int64values could throw overflow when passed asSystem.Object, instead we throwNotImplementedExceptionwhen we seeInt64. Same forbigint.Consider
Wasm.BrowserProfile.SamplePossible Future
bind_static_methodto consume[JSExport][JSMarshalAs(JSType.XXX)]ccalls.jsoptional file, get rid of private interop DLLJSType.Array-[MarshalUsing]for with P/Invoke native custom marshalerJSImportonlyUriasstringas custom marshalerJSMarshalAsAttributewithJSType.CustomandJSCustomTypeMarshaller,JSMarshallingAttributeJSMarshalAsAttributewithJSType.MemoryView[MarshalUsing]Memory<byte>JSMarshalAsAttributewithJSType.BigIntUInt64JSMarshalAsAttributewithJSType.StringDateTime,DateTimeOffsetJSMarshalAsAttributewithJSType.NumberSByte,UInt16,UInt32,UInt64,UIntPtrBoolean,CharDateTime,DateTimeOffset[MarshalUsing]forJSExportJSMarshalAsAttributeandJSTypeJSType.Int32ArrayforSpan<int>JSType.Int16ArrayforSpan<short>MonoString*MonoObject*InFlightSystem.Private.Runtime.InteropServices.JavaScriptassemblyOut of scope
DelegateMarshalAsAttributeandUnmanagedTypebehavior on method paramsUnmanagedType.LPArray&UnmanagedType.LPStructis not supported by generated marshalersUnmanagedType.FunctionPtr- maybe for another wasm C function via JS ? What marshaler would be used to marshal the parameters of the function.UnmanagedType.Bool,VariantBool- we could represent System.Boolean asnumberor asbooleanin JS.UnmanagedType.I1, I2, I4, I8, U1, U2, U4, U8, Currency, SysInt, SysUInt- all of that is alwaysnumberorBigIntin JSUnmanagedType.BStr, LPStr, LPWStr, LPTStr, ByValTStr, VBByRefStr, AnsiBStr, TBStr, HString, LPUTF8Str- all of this isstringin JS.UnmanagedType.IUnknown, IDispatch, Interface, SafeArray, AsAny, Error, IInspectable- not relevantUnmanagedType.Struct, ByValArray- we could not map struct to JS call stackUnmanagedType.IUnknown, IDispatch, Interface, SafeArray, AsAny, Error, IInspectable