-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[browser] JS interop fix marshalling of completed task of long #123366
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
[browser] JS interop fix marshalling of completed task of long #123366
Conversation
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.
Pull request overview
This PR fixes a bug in the marshalling of completed Task<long> to JavaScript through the JSExport/JSImport API. When a Task<long> was already completed, a shortcut path in the marshalling code would call a generic ToJS(object) method instead of the proper type-specific marshaler delegate. Since the ToJS(object) method explicitly throws a NotSupportedException for long types (because longs can be marshaled as either JS number or bigint), this caused runtime errors.
Changes:
- Fixed the marshaller to use the proper delegate (
marshaler(ref this, result)) instead of the generic object marshaller for completed tasks - Added comprehensive test coverage for both incomplete and completed
Task<long>scenarios - Added supporting JSImport and JSExport methods to facilitate the new tests
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| JSMarshalerArgument.Task.cs | Fixed line 360 to use the marshaler delegate instead of ToJS(object) for completed task results |
| JavaScriptTestHelper.cs | Added JSImport invoke1_TaskOfLong and JSExport AwaitTaskOfInt64 for testing Task marshalling with BigInt |
| JSExportTest.cs | Added two test methods: JsExportTaskOfLong (incomplete task) and JsExportCompletedTaskOfLong (completed task - the bug scenario) |
...teropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSExportTest.cs
Outdated
Show resolved
Hide resolved
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
A 'shortcut' is taken in the marshalling process to JS when a
Task<T>is already completed to just marshall the value directy. I found that the task result marshaller would differ from the one used in the path where the task is not yet completed. For most types this is fine, however forTask<long>there are options (number vs bigint) and the marshaller used in the shortcut path (the ToJS(object) function) couldnt decide which js type should be used. If this path was hit the end user would get an error likeToJSNotSupported, Int64.The changes include two new tests that marshall
Task<long>, one completing after crossing the interop boundary and one before crossing. The latter test would fail before the fix. The fix is using the marshaller delegate (provided by codegen) which indeed is able to marshall as the type configured by the user.