Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
New+BindCoreObject -> CreateCsOwnedObject single call
  • Loading branch information
pavelsavara committed Aug 16, 2021
commit dca5d5ee415b818471e517265ee954ae796d7cf5
16 changes: 3 additions & 13 deletions src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ internal static partial class Runtime
[MethodImplAttribute(MethodImplOptions.InternalCall)]
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(int gcHandle, 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,17 +73,9 @@ public static string InvokeJS(string str)
return res as System.Runtime.InteropServices.JavaScript.Function;
}

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

public static IntPtr New(string hostClassName, params object[] parms)
internal static IntPtr CreateCsOwnedObject(int gcHandle, string typeName, params object[] parms)
{
object res = New(hostClassName, parms, out int exception);
object res = CreateCsOwnedObject(gcHandle, typeName, parms, out int exception);
if (exception != 0)
throw new JSException((string)res);
return (IntPtr)(int)res;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,26 @@ public partial class JSObject : SafeHandleMinusOneIsInvalid
internal int GCHandleValue => (int)(IntPtr)WeakRefHandle;
public bool IsDisposed { get; private set; }

public JSObject() : this(Interop.Runtime.New<object>())
public JSObject() : base(true)
{
object result = Interop.Runtime.BindCoreObject(JSHandle, GCHandleValue, out int exception);
if (exception != 0)
throw new JSException(SR.Format(SR.JSObjectErrorBinding, result));
// this is weak C# reference to the JSObject, it has same lifetime as the JSObject
WeakRefHandle = GCHandle.Alloc(this, GCHandleType.Weak);
InFlight = null;
InFlightCounter = 0;

var jsHandle = Interop.Runtime.CreateCsOwnedObject(GCHandleValue, nameof(Object));
SetHandle(jsHandle);
}

protected JSObject(string typeName, object[] _params) : base(true)
{
// this is weak C# reference to the JSObject, it has same lifetime as the JSObject
WeakRefHandle = GCHandle.Alloc(this, GCHandleType.Weak);
InFlight = null;
InFlightCounter = 0;

var jsHandle = Interop.Runtime.CreateCsOwnedObject(GCHandleValue, typeName, _params);
SetHandle(jsHandle);
}

internal JSObject(IntPtr jsHandle) : base(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ 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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ 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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ namespace System.Runtime.InteropServices.JavaScript
/// </remarks>
public abstract class CoreObject : JSObject
{
protected CoreObject(IntPtr jsHandle) : base(jsHandle)
internal CoreObject(IntPtr jsHandle) : base(jsHandle)
{
}

protected CoreObject(string typeName, params object[] _params) : base(typeName, _params)
{
object result = Interop.Runtime.BindCoreObject((int)jsHandle, GCHandleValue, out int exception);
if (exception != 0)
throw new JSException(SR.Format(SR.CoreObjectErrorBinding, result));
}
}
}
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,7 +56,7 @@ 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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ 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) : base(jsHandle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,9 @@ namespace System.Runtime.InteropServices.JavaScript
public interface IHostObject
{ }

public class HostObject : HostObjectBase
public class HostObject : JSObject, IHostObject
{
public HostObject(string hostName, params object[] _params) : base(Interop.Runtime.New(hostName, _params))
public HostObject(string typeName, params object[] _params) : base(typeName, _params)
{ }
}

public abstract class HostObjectBase : JSObject, IHostObject
{
protected HostObjectBase(IntPtr jsHandle) : base(jsHandle)
{
object result = Interop.Runtime.BindCoreObject((int)jsHandle, GCHandleValue, out int exception);
if (exception != 0)
throw new JSException(SR.Format(SR.HostObjectErrorBinding, result));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Map : CoreObject, IDictionary
/// <summary>
/// Initializes a new instance of the Map class.
/// </summary>
public Map() : base(Runtime.New<Map>())
public Map() : base(nameof(Map))
{ }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@ public static string InvokeJS(string str)
return Interop.Runtime.CompileFunction(snippet);
}

public static IntPtr New<T>(params object[] parms)
{
return Interop.Runtime.New(typeof(T).Name, parms);
}

public static IntPtr New(string hostClassName, params object[] parms)
{
return Interop.Runtime.New(hostClassName, parms);
}

public static object GetGlobalObject(string? str = null)
{
return Interop.Runtime.GetGlobalObject(str);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class SharedArrayBuffer : CoreObject
/// Initializes a new instance of the JavaScript Core SharedArrayBuffer class.
/// </summary>
/// <param name="length">The size, in bytes, of the array buffer to create.</param>
public SharedArrayBuffer(int length) : base(Interop.Runtime.New<SharedArrayBuffer>(length))
public SharedArrayBuffer(int length) : base(nameof(SharedArrayBuffer), length)
{ }

internal SharedArrayBuffer(IntPtr jsHandle) : base(jsHandle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,28 @@ public enum TypedArrayTypeCode
/// </summary>
public abstract class TypedArray<T, U> : CoreObject, ITypedArray, ITypedArray<T, U> where U : struct
{
protected TypedArray() : base(Interop.Runtime.New<T>())
protected TypedArray() : base(typeof(T).Name)
{ }

protected TypedArray(int length) : base(Interop.Runtime.New<T>(length))
protected TypedArray(int length) : base(typeof(T).Name, length)
{ }

protected TypedArray(ArrayBuffer buffer) : base(Interop.Runtime.New<T>(buffer))
protected TypedArray(ArrayBuffer buffer) : base(typeof(T).Name, buffer)
{ }

protected TypedArray(ArrayBuffer buffer, int byteOffset) : base(Interop.Runtime.New<T>(buffer, byteOffset))
protected TypedArray(ArrayBuffer buffer, int byteOffset) : base(typeof(T).Name, buffer, byteOffset)
{ }

protected TypedArray(ArrayBuffer buffer, int byteOffset, int length) : base(Interop.Runtime.New<T>(buffer, byteOffset, length))
protected TypedArray(ArrayBuffer buffer, int byteOffset, int length) : base(typeof(T).Name, buffer, byteOffset, length)
{ }

protected TypedArray(SharedArrayBuffer buffer) : base(Interop.Runtime.New<T>(buffer))
protected TypedArray(SharedArrayBuffer buffer) : base(typeof(T).Name, buffer)
{ }

protected TypedArray(SharedArrayBuffer buffer, int byteOffset) : base(Interop.Runtime.New<T>(buffer, byteOffset))
protected TypedArray(SharedArrayBuffer buffer, int byteOffset) : base(typeof(T).Name, buffer, byteOffset)
{ }

protected TypedArray(SharedArrayBuffer buffer, int byteOffset, int length) : base(Interop.Runtime.New<T>(buffer, byteOffset, length))
protected TypedArray(SharedArrayBuffer buffer, int byteOffset, int length) : base(typeof(T).Name, buffer, byteOffset, length)
{ }

internal TypedArray(IntPtr jsHandle) : base(jsHandle)
Expand Down
46 changes: 17 additions & 29 deletions src/mono/wasm/runtime/binding_support.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,36 +123,37 @@ var BindingSupportLib = {
// that any code relying on the old get_method/call_method pattern will
// break in a more understandable way.

this._create_cs_owned_object = bind_runtime_method ("CreateCSOwnedObject", "ii");
this._bind_core_clr_obj = bind_runtime_method ("BindCoreCLRObject", "ii");
this._get_js_owned_object_gc_handle = bind_runtime_method ("GetJSOwnedObjectGCHandle", "m");
this._try_get_cs_owned_object_js_handle = bind_runtime_method ("TryGetCsOwnedObjectJsHandle", "m");
this._get_raw_mono_obj = bind_runtime_method ("GetDotNetObject", "ii!");

this._create_cs_owned_object = bind_runtime_method ("CreateCSOwnedObject", "ii");
this._try_get_cs_owned_object_js_handle = bind_runtime_method ("TryGetCsOwnedObjectJsHandle", "m");
this._cs_owned_object_get_js_handle = bind_runtime_method ("CsOwnedObjectGetJsHandle", 'mi');
this._release_cs_owned_object_by_handle = bind_runtime_method ("ReleaseCsOwnedObjectByHandle", 'i');

this._get_js_owned_object_gc_handle = bind_runtime_method ("GetJSOwnedObjectGCHandle", "m");
this._release_js_owned_object_by_handle = bind_runtime_method ("ReleaseJSOwnedObjectByHandle", "i");

this._is_simple_array = bind_runtime_method ("IsSimpleArray", "m");
this._setup_js_cont = bind_runtime_method ("SetupJSContinuation", "mo");

this._create_tcs = bind_runtime_method ("CreateTaskSource","");
this._set_tcs_result = bind_runtime_method ("SetTaskSourceResult","io");
this._set_tcs_failure = bind_runtime_method ("SetTaskSourceFailure","is");
this._get_tcs_task = bind_runtime_method ("GetTaskSourceTask","i!");
this._setup_js_cont = bind_runtime_method ("SetupJSContinuation", "mo");

this._object_to_string = bind_runtime_method ("ObjectToString", "m");
this._get_date_value = bind_runtime_method ("GetDateValue", "m");
this._create_date_time = bind_runtime_method ("CreateDateTime", "d!");
this._create_uri = bind_runtime_method ("CreateUri","s!");

this._cs_owned_object_get_js_handle = bind_runtime_method ("CsOwnedObjectGetJsHandle", 'mi');
this._release_cs_owned_object_by_handle = bind_runtime_method ("ReleaseCsOwnedObjectByHandle", 'i');
this._release_js_owned_object_by_handle = bind_runtime_method ("ReleaseJSOwnedObjectByHandle", "i");

this._are_promises_supported = ((typeof Promise === "object") || (typeof Promise === "function")) && (typeof Promise.resolve === "function");
this.isThenable = (js_obj) => {
// When using an external Promise library like Bluebird the Promise.resolve may not be sufficient
// to identify the object as a Promise.
return Promise.resolve(js_obj) === js_obj ||
((typeof js_obj === "object" || typeof js_obj === "function") && typeof js_obj.then === "function")
}
};

this._empty_string = "";
this._empty_string_ptr = 0;
Expand Down Expand Up @@ -1889,21 +1890,7 @@ var BindingSupportLib = {
BINDING.bindings_lazy_init ();
BINDING._mono_wasm_release_js_handle(js_handle);
},
mono_wasm_bind_core_object: function(js_handle, gc_handle, is_exception) {
BINDING.bindings_lazy_init ();

var js_obj = BINDING.mono_wasm_get_jsobj_from_js_handle (js_handle);
if (!js_obj) {
setValue (is_exception, 1, "i32");
return BINDING.js_string_to_mono_string ("ERR05: Invalid JS object handle '" + js_handle + "'");
}

BINDING.wasm_bind_core_clr_obj(js_handle, gc_handle );
js_obj.__mono_gc_handle__ = gc_handle;
js_obj.__mono_js_handle__ = js_handle;
return gc_handle;
},
mono_wasm_new: function (core_name, args, is_exception) {
mono_wasm_create_cs_owned_object: function (gc_handle, core_name, args, is_exception) {
var argsRoot = MONO.mono_wasm_new_root (args), nameRoot = MONO.mono_wasm_new_root (core_name);
try {
BINDING.bindings_lazy_init ();
Expand Down Expand Up @@ -1934,13 +1921,14 @@ var BindingSupportLib = {
if (js_args)
argsList = argsList.concat (js_args);
var tempCtor = constructor.bind.apply (constructor, argsList);
var obj = new tempCtor ();
return obj;
var js_obj = new tempCtor ();
return js_obj;
};

var res = allocator(coreObj, js_args);
var js_handle = BINDING.mono_wasm_get_js_handle(res);
// yes, convert int
var js_obj = allocator(coreObj, js_args);
js_obj.__mono_gc_handle__ = gc_handle;
var js_handle = BINDING.mono_wasm_get_js_handle(js_obj);
// yes, convert int, because on error we need to return String on same method signature
return BINDING.mono_wasm_convert_return_value(js_handle);
} catch (e) {
var res = e.toString ();
Expand Down
6 changes: 2 additions & 4 deletions src/mono/wasm/runtime/corebindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ extern MonoObject* mono_wasm_set_object_property (int js_handle, MonoString *pro
extern MonoObject* mono_wasm_set_by_index (int js_handle, int property_index, MonoObject *value, int *is_exception);
extern MonoObject* mono_wasm_get_global_object (MonoString *global_name, int *is_exception);
extern void* mono_wasm_release_cs_owned_object (int js_handle);
extern MonoObject* mono_wasm_new (MonoString *core_name, MonoArray *args, int *is_exception);
extern int mono_wasm_bind_core_object (int js_handle, int gc_handle, int *is_exception);
extern MonoObject* mono_wasm_create_cs_owned_object (int gc_handle, MonoString *core_name, MonoArray *args, int *is_exception);
extern MonoObject* mono_wasm_typed_array_to_array (int js_handle, int *is_exception);
extern MonoObject* mono_wasm_typed_array_copy_to (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception);
extern MonoObject* mono_wasm_typed_array_from (int ptr, int begin, int end, int bytes_per_element, int type, int *is_exception);
Expand Down Expand Up @@ -75,9 +74,8 @@ void core_initialize_internals ()
mono_add_internal_call ("Interop/Runtime::SetObjectProperty", mono_wasm_set_object_property);
mono_add_internal_call ("Interop/Runtime::SetByIndex", mono_wasm_set_by_index);
mono_add_internal_call ("Interop/Runtime::GetGlobalObject", mono_wasm_get_global_object);
mono_add_internal_call ("Interop/Runtime::CreateCsOwnedObject", mono_wasm_create_cs_owned_object);
mono_add_internal_call ("Interop/Runtime::ReleaseCsOwnedObject", mono_wasm_release_cs_owned_object);
mono_add_internal_call ("Interop/Runtime::BindCoreObject", mono_wasm_bind_core_object);
mono_add_internal_call ("Interop/Runtime::New", mono_wasm_new);
mono_add_internal_call ("Interop/Runtime::TypedArrayToArray", mono_wasm_typed_array_to_array);
mono_add_internal_call ("Interop/Runtime::TypedArrayCopyTo", mono_wasm_typed_array_copy_to);
mono_add_internal_call ("Interop/Runtime::TypedArrayFrom", mono_wasm_typed_array_from);
Expand Down