Skip to content
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] Redesign of JS objects marshaling and lifecycle #57098

Merged
merged 33 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8ce637c
thenable and datetime cleanup
pavelsavara Aug 9, 2021
d8326dd
removed ownsHandle for readability, removed AnyRef from hierarchy, re…
pavelsavara Aug 9, 2021
4b96785
rename _csOwnedObjects
pavelsavara Aug 9, 2021
0a4c611
rename _csOwnedObjects
pavelsavara Aug 9, 2021
99b05bb
redirect to Inflight counter
pavelsavara Aug 9, 2021
0d218f9
renames
pavelsavara Aug 9, 2021
151a059
rename and move
pavelsavara Aug 9, 2021
0f3d6d0
rename
pavelsavara Aug 9, 2021
dca5d5e
New+BindCoreObject -> CreateCsOwnedObject single call
pavelsavara Aug 9, 2021
4783438
remove refcount frames
pavelsavara Aug 9, 2021
c2fd18e
differentiate gcHandles
pavelsavara Aug 9, 2021
d30c4a8
get rid of weak GCHandle
pavelsavara Aug 9, 2021
53e2eb9
feedback
pavelsavara Aug 10, 2021
36e864a
added MappedType enum
pavelsavara Aug 10, 2021
e0b3b53
naming consistency
pavelsavara Aug 10, 2021
7c743b1
feedback
pavelsavara Aug 10, 2021
efcd1a9
rename _cs_owned_objects_by_js_handle
pavelsavara Aug 10, 2021
a9212b7
split and rename files
pavelsavara Aug 10, 2021
4f24a9d
shouldAddInflight to more methods
pavelsavara Aug 10, 2021
c5f22be
improved in-flight references
pavelsavara Aug 10, 2021
7d23f76
assert for JSObject not disposed
pavelsavara Aug 10, 2021
cce3ccc
introduce in-flight assert
pavelsavara Aug 10, 2021
e29416a
move should_add_in_flight arg to fisrt position, so that we could bin…
pavelsavara Aug 10, 2021
e4dd539
doc
pavelsavara Aug 10, 2021
3897513
cleanup
pavelsavara Aug 10, 2021
d7345bc
doc
pavelsavara Aug 10, 2021
6ee696a
implement fallback for missing support of FInalizationRegistry/WeakRe…
pavelsavara Aug 16, 2021
92b9a3b
feedback
pavelsavara Aug 16, 2021
685d2a5
no polyfill feedback
pavelsavara Aug 16, 2021
a6f7eda
feedback
pavelsavara Aug 16, 2021
4a388ed
name consistency feedback
pavelsavara Aug 16, 2021
f5cede0
use symbols for helper fields
pavelsavara Aug 16, 2021
b8ad165
feedback
pavelsavara Aug 16, 2021
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
34 changes: 6 additions & 28 deletions src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

using JSObject = System.Runtime.InteropServices.JavaScript.JSObject;
using JSException = System.Runtime.InteropServices.JavaScript.JSException;
Expand Down Expand Up @@ -34,11 +30,9 @@ internal static partial class Runtime
internal static extern object GetGlobalObject(string? globalName, out int exceptionalResult);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object ReleaseHandle(int jsHandle, out int exceptionalResult);
internal static extern object ReleaseCSOwnedObject(int jsHandle);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object BindCoreObject(int jsHandle, int gcHandle, out int exceptionalResult);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object New(string className, object[] parms, out int exceptionalResult);
internal static extern object CreateCSOwnedObject(string className, object[] parms, out int exceptionalResult);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object TypedArrayToArray(int jsHandle, out int exceptionalResult);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
Expand Down Expand Up @@ -75,32 +69,16 @@ public static string InvokeJS(string str)
return res as System.Runtime.InteropServices.JavaScript.Function;
}

public static int New<T>(params object[] parms)
{
object res = New(typeof(T).Name, parms, out int exception);
if (exception != 0)
throw new JSException((string)res);
return (int)res;
}

public static int New(string hostClassName, params object[] parms)
{
object res = New(hostClassName, parms, out int exception);
if (exception != 0)
throw new JSException((string)res);
return (int)res;
}

public static object GetGlobalObject(string? str = null)
{
int exception;
object globalHandle = Runtime.GetGlobalObject(str, out exception);
object jsObj = GetGlobalObject(str, out exception);

if (exception != 0)
throw new JSException($"Error obtaining a handle to global {str}");

ReleaseInFlight(globalHandle);
return globalHandle;
ReleaseInFlight(jsObj);
return jsObj;
}

[MethodImplAttribute(MethodImplOptions.NoInlining)]
Expand All @@ -125,7 +103,7 @@ public static unsafe void DumpAotProfileData(ref byte buf, int len, string extra
}
}

public static void ReleaseInFlight(object? obj)
internal static void ReleaseInFlight(object? obj)
{
JSObject? jsObj = obj as JSObject;
jsObj?.ReleaseInFlight();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<ItemGroup Condition="'$(TargetsBrowser)' == 'true'">
<Compile Include="$(CommonPath)Interop\Browser\Interop.Runtime.cs" Link="Common\Interop\Browser\Interop.Runtime.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\Runtime.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\Runtime.CS.Owned.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\Runtime.JS.Owned.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\JSException.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\JSObject.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\DataView.cs" />
Expand All @@ -28,7 +30,7 @@
<Compile Include="System\Runtime\InteropServices\JavaScript\CoreObject.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\HostObject.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\Function.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\AnyRef.cs" />
<Compile Include="System\Runtime\InteropServices\JavaScript\JSObject.References.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Runtime" />
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ public class Array : CoreObject
/// Initializes a new instance of the Array class.
/// </summary>
/// <param name="_params">Parameters.</param>
public Array(params object[] _params) : base(Interop.Runtime.New<Array>(_params))
public Array(params object[] _params) : base(nameof(Array), _params)
{ }

/// <summary>
/// Initializes a new instance of the Array/> class.
/// </summary>
/// <param name="jsHandle">Js handle.</param>
/// <param name="ownsHandle">Whether or not the handle is owned by the clr or not.</param>
internal Array(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
internal Array(IntPtr jsHandle) : base(jsHandle)
{ }

/// <summary>
Expand Down Expand Up @@ -82,6 +81,8 @@ public object this[int i]
{
get
{
AssertNotDisposed();

object indexValue = Interop.Runtime.GetByIndex(JSHandle, i, out int exception);

if (exception != 0)
Expand All @@ -91,6 +92,8 @@ public object this[int i]
}
set
{
AssertNotDisposed();

object res = Interop.Runtime.SetByIndex(JSHandle, i, value, out int exception);

if (exception != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@ public class ArrayBuffer : CoreObject
/// <summary>
/// Initializes a new instance of the JavaScript Core ArrayBuffer class.
/// </summary>
public ArrayBuffer() : base(Interop.Runtime.New<ArrayBuffer>())
public ArrayBuffer() : base(nameof(ArrayBuffer))
{ }

/// <summary>
/// Initializes a new instance of the JavaScript Core ArrayBuffer class.
/// </summary>
/// <param name="length">Length.</param>
public ArrayBuffer(int length) : base(Interop.Runtime.New<ArrayBuffer>(length))
public ArrayBuffer(int length) : base(nameof(ArrayBuffer), length)
{ }

/// <summary>
/// Initializes a new instance of the JavaScript Core ArrayBuffer class.
/// </summary>
/// <param name="jsHandle">Js handle.</param>
/// <param name="ownsHandle">Whether or not the handle is owned by the clr or not.</param>
internal ArrayBuffer(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
internal ArrayBuffer(IntPtr jsHandle) : base(jsHandle)
{ }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ namespace System.Runtime.InteropServices.JavaScript
/// </remarks>
public abstract class CoreObject : JSObject
{
protected CoreObject(int jsHandle) : base(jsHandle, true)
internal CoreObject(IntPtr jsHandle) : base(jsHandle)
{
object result = Interop.Runtime.BindCoreObject(jsHandle, GCHandleValue, out int exception);
if (exception != 0)
throw new JSException(SR.Format(SR.CoreObjectErrorBinding, result));
}

internal CoreObject(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
{ }
protected CoreObject(string typeName, params object[] _params) : base(typeName, _params)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public class DataView : CoreObject
/// Initializes a new instance of the DataView class.
/// </summary>
/// <param name="buffer">ArrayBuffer to use as the storage backing the new DataView object.</param>
public DataView(ArrayBuffer buffer) : base(Runtime.New<DataView>(buffer))
public DataView(ArrayBuffer buffer) : base(nameof(DataView), buffer)
{ }

/// <summary>
/// Initializes a new instance of the DataView class.
/// </summary>
/// <param name="buffer">ArrayBuffer to use as the storage backing the new DataView object.</param>
/// <param name="byteOffset">The offset, in bytes, to the first byte in the above buffer for the new view to reference. If unspecified, the buffer view starts with the first byte.</param>
public DataView(ArrayBuffer buffer, int byteOffset) : base(Runtime.New<DataView>(buffer, byteOffset))
public DataView(ArrayBuffer buffer, int byteOffset) : base(nameof(DataView), buffer, byteOffset)
{ }

/// <summary>
Expand All @@ -32,22 +32,22 @@ public DataView(ArrayBuffer buffer, int byteOffset) : base(Runtime.New<DataView>
/// <param name="buffer">ArrayBuffer to use as the storage backing the new DataView object.</param>
/// <param name="byteOffset">The offset, in bytes, to the first byte in the above buffer for the new view to reference. If unspecified, the buffer view starts with the first byte.</param>
/// <param name="byteLength">The number of elements in the byte array. If unspecified, the view's length will match the buffer's length.</param>
public DataView(ArrayBuffer buffer, int byteOffset, int byteLength) : base(Runtime.New<DataView>(buffer, byteOffset, byteLength))
public DataView(ArrayBuffer buffer, int byteOffset, int byteLength) : base(nameof(DataView), buffer, byteOffset, byteLength)
{ }

/// <summary>
/// Initializes a new instance of the DataView class.
/// </summary>
/// <param name="buffer">SharedArrayBuffer to use as the storage backing the new DataView object.</param>
public DataView(SharedArrayBuffer buffer) : base(Runtime.New<DataView>(buffer))
public DataView(SharedArrayBuffer buffer) : base(nameof(DataView), buffer)
{ }

/// <summary>
/// Initializes a new instance of the DataView class.
/// </summary>
/// <param name="buffer">SharedArrayBuffer to use as the storage backing the new DataView object.</param>
/// <param name="byteOffset">The offset, in bytes, to the first byte in the above buffer for the new view to reference. If unspecified, the buffer view starts with the first byte.</param>
public DataView(SharedArrayBuffer buffer, int byteOffset) : base(Runtime.New<DataView>(buffer, byteOffset))
public DataView(SharedArrayBuffer buffer, int byteOffset) : base(nameof(DataView), buffer, byteOffset)
{ }

/// <summary>
Expand All @@ -56,15 +56,14 @@ public DataView(SharedArrayBuffer buffer, int byteOffset) : base(Runtime.New<Dat
/// <param name="buffer">SharedArrayBuffer to use as the storage backing the new DataView object.</param>
/// <param name="byteOffset">The offset, in bytes, to the first byte in the above buffer for the new view to reference. If unspecified, the buffer view starts with the first byte.</param>
/// <param name="byteLength">The number of elements in the byte array. If unspecified, the view's length will match the buffer's length.</param>
public DataView(SharedArrayBuffer buffer, int byteOffset, int byteLength) : base(Runtime.New<DataView>(buffer, byteOffset, byteLength))
public DataView(SharedArrayBuffer buffer, int byteOffset, int byteLength) : base(nameof(DataView), buffer, byteOffset, byteLength)
{ }

/// <summary>
/// Initializes a new instance of the DataView class.
/// </summary>
/// <param name="jsHandle">Js handle.</param>
/// <param name="ownsHandle">Managed owned</param>
internal DataView(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
internal DataView(IntPtr jsHandle) : base(jsHandle)
{ }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public Float32Array(SharedArrayBuffer buffer, int byteOffset) : base(buffer, byt

public Float32Array(SharedArrayBuffer buffer, int byteOffset, int length) : base(buffer, byteOffset, length) { }

internal Float32Array(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
internal Float32Array(IntPtr jsHandle) : base(jsHandle)
{ }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public Float64Array(SharedArrayBuffer buffer, int byteOffset) : base(buffer, byt

public Float64Array(SharedArrayBuffer buffer, int byteOffset, int length) : base(buffer, byteOffset, length) { }

internal Float64Array(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
internal Float64Array(IntPtr jsHandle) : base(jsHandle)
{ }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ namespace System.Runtime.InteropServices.JavaScript
/// </remarks>
public class Function : CoreObject
{
public Function(params object[] args) : base(Interop.Runtime.New<Function>(args))
public Function(params object[] args) : base(nameof(Function), args)
{ }

internal Function(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
internal Function(IntPtr jsHandle) : base(jsHandle)
{ }

/// <summary>
Expand All @@ -28,28 +28,34 @@ internal Function(IntPtr jsHandle, bool ownsHandle) : base(jsHandle, ownsHandle)
/// <returns>The apply.</returns>
/// <param name="thisArg">This argument.</param>
/// <param name="argsArray">Arguments.</param>
public object Apply(object? thisArg = null, object[]? argsArray = null) => Invoke("apply", thisArg, argsArray);
public object Apply(object? thisArg, object[]? argsArray = null) => Invoke("apply", thisArg, argsArray);

/// <summary>
/// Creates a new Function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
/// </summary>
/// <returns>The bind.</returns>
/// <param name="thisArg">This argument.</param>
/// <param name="argsArray">Arguments.</param>
public Function Bind(object? thisArg = null, object[]? argsArray = null) => (Function)Invoke("bind", thisArg, argsArray);
public Function Bind(object? thisArg, object[]? argsArray = null) => (Function)Invoke("bind", thisArg, argsArray);

/// <summary>
/// Calls a function with a given `this` value and arguments provided individually.
/// </summary>
/// <returns>The result of calling the function with the specified `this` value and arguments.</returns>
/// <param name="thisArg">Optional (null value). The value of this provided for the call to a function. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode, null and undefined will be replaced with the global object and primitive values will be converted to objects.</param>
/// <param name="argsArray">Optional. Arguments for the function.</param>
public object Call(object? thisArg = null, params object[] argsArray)
public object Call(object? thisArg, params object[] argsArray)
{
object?[] argsList = new object[argsArray.Length + 1];
argsList[0] = thisArg;
System.Array.Copy(argsArray, 0, argsList, 1, argsArray.Length);
return Invoke("call", argsList);
}

/// <summary>
/// Calls a function with a null `this` value.
/// </summary>
/// <returns>The result of calling the function.</returns>
public object Call() => Call(null);
}
}
Loading