public unsafe void ToManaged(out Exception?value) { if (slot.Type == MarshalerType.None) { value = null; return; } if (slot.Type == MarshalerType.Exception) { // this is managed exception round-trip #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. value = (Exception)((GCHandle)slot.GCHandle).Target; #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. return; } JSObject?jsException = null; if (slot.JSHandle != IntPtr.Zero) { // this is JSException round-trip jsException = JSHostImplementation.CreateCSOwnedProxy(slot.JSHandle); } string?message; ToManaged(out message); value = new JSException(message !, jsException); }
public static JSObject CreateCSOwnedProxy(IntPtr jsHandle, MappedType mappedType, int shouldAddInflight) { JSObject?jsObject = null; lock (_csOwnedObjects) { if (!_csOwnedObjects.TryGetValue((int)jsHandle, out WeakReference <JSObject>?reference) || !reference.TryGetTarget(out jsObject) || jsObject.IsDisposed) { jsObject = mappedType switch { MappedType.JSObject => new JSObject(jsHandle), MappedType.Array => new Array(jsHandle), MappedType.ArrayBuffer => new ArrayBuffer(jsHandle), MappedType.DataView => new DataView(jsHandle), MappedType.Function => new Function(jsHandle), MappedType.Uint8Array => new Uint8Array(jsHandle), _ => throw new ArgumentOutOfRangeException(nameof(mappedType)) }; _csOwnedObjects[(int)jsHandle] = new WeakReference <JSObject>(jsObject, trackResurrection: true); } } if (shouldAddInflight != 0) { jsObject.AddInFlight(); } return(jsObject); }
public static int BindCoreCLRObject(int jsId, int gcHandle) { GCHandle h = (GCHandle)(IntPtr)gcHandle; JSObject?obj = null; lock (_boundObjects) { if (_boundObjects.TryGetValue(jsId, out WeakReference <JSObject>?wr)) { if (!wr.TryGetTarget(out JSObject? instance) || (instance.Int32Handle != (int)(IntPtr)h && h.IsAllocated)) { throw new JSException(SR.Format(SR.MultipleHandlesPointingJsId, jsId)); } obj = instance; } else if (h.Target is JSObject instance) { _boundObjects.Add(jsId, new WeakReference <JSObject>(instance, trackResurrection: true)); obj = instance; } } return(obj?.Int32Handle ?? 0); }
public static object?GetDotNetObject(int gcHandle) { GCHandle h = (GCHandle)(IntPtr)gcHandle; JSObject?o = h.Target as JSObject; return(o?.RawObject ?? null); }
public static void UnBindRawJSObjectAndFree(int gcHandle) { GCHandle h = (GCHandle)(IntPtr)gcHandle; JSObject?obj = h.Target as JSObject; lock (_rawToJS) { if (obj?.RawObject != null) { _rawToJS.Remove(obj.RawObject); int exception; Interop.Runtime.ReleaseHandle(obj.JSHandle, out exception); if (exception != 0) { throw new JSException($"Error releasing handle on (js-obj js '{obj.JSHandle}' .NET '{(IntPtr)obj.Handle} raw '{obj.RawObject != null})"); } // Calling Release Handle above only removes the reference from the JavaScript side but does not // release the bridged JSObject associated with the raw object so we have to do that ourselves. obj.JSHandle = -1; obj.IsDisposed = true; obj.RawObject = null; obj.Handle.Free(); } } }
private bool _disposedValue = false; // To detect redundant calls private void Dispose(bool disposing) { if (!_disposedValue) { _mapIterator?.Dispose(); _mapIterator = null; _disposedValue = true; } }
public unsafe void ToManaged(out JSObject?value) { if (slot.Type == MarshalerType.None) { value = null; return; } value = JSHostImplementation.CreateCSOwnedProxy(slot.JSHandle); }
public unsafe void ToManaged(out JSObject?value) { if (slot.Type == MarshalerType.None) { value = null; return; } value = JavaScriptExports.CreateCSOwnedProxy(slot.JSHandle); }
public static string?GetProtocol(JSObject?webSocket) { if (webSocket == null || webSocket.IsDisposed) { return(null); } string?protocol = webSocket.GetPropertyAsString("protocol"); return(protocol); }
public static int TryGetCSOwnedObjectJSHandle(object rawObj, int shouldAddInflight) { JSObject?jsObject = rawObj as JSObject; if (jsObject != null && shouldAddInflight != 0) { jsObject.AddInFlight(); } return(jsObject?.JSHandle ?? 0); }
public static JSObject?NewJSObject(JSObject?jsFuncPtr = null, params object[] parms) { object res = NewObjectJS(jsFuncPtr?.JSHandle ?? 0, parms, out int exception); if (exception != 0) { throw new JSException((string)res); } return(res as JSObject); }
public static int GetReadyState(JSObject?webSocket) { if (webSocket == null || webSocket.IsDisposed) { return(-1); } int?readyState = webSocket.GetPropertyAsInt32("readyState"); if (!readyState.HasValue) { return(-1); } return(readyState.Value); }
public static int GetJSObjectId(object rawObj) { JSObject?obj = rawObj as JSObject; lock (_rawToJS) { if (obj == null && !_rawToJS.TryGetValue(rawObj, out obj)) { return(-1); } return(obj?.JSHandle ?? -1); } }
public static int BindExistingObject(object rawObj, int jsId) { JSObject?obj = rawObj as JSObject; lock (_rawToJS) { if (obj == null && !_rawToJS.TryGetValue(rawObj, out obj)) { _rawToJS[rawObj] = obj = new JSObject(jsId, rawObj); } return(obj == null ? 0 : (int)(IntPtr)obj.Handle); } }
public static JSObject CreateCSOwnedProxy(IntPtr jsHandle) { JSObject?res = null; lock (s_csOwnedObjects) { if (!s_csOwnedObjects.TryGetValue((int)jsHandle, out WeakReference <JSObject>?reference) || !reference.TryGetTarget(out res) || res.IsDisposed) { res = new JSObject(jsHandle); s_csOwnedObjects[(int)jsHandle] = new WeakReference <JSObject>(res, trackResurrection: true); } } return(res); }
private bool _disposedValue = false; // To detect redundant calls private void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects). } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. _mapItemIterator?.Dispose(); _mapItemIterator = null; _disposedValue = true; } }
public bool MoveNext() { if (_mapItemIterator == null) { _mapItemIterator = (JSObject)_mapItemCollection._map.Invoke(_mapItemCollection._iterator); } using (var result = (JSObject)_mapItemIterator.Invoke("next")) { bool done = (bool)result.GetObjectProperty("done"); if (!done) { Current = result.GetObjectProperty("value"); } return(!done); } }
private async Task ConnectAsyncCore(Uri uri, List <string>?requestedSubProtocols, CancellationToken cancellationToken) { try { string[]? subProtocols = requestedSubProtocols?.ToArray(); var onClose = (int code, string reason) => { _closeStatus = (WebSocketCloseStatus)code; _closeStatusDescription = reason; WebSocketState state = State; if (state == WebSocketState.Connecting || state == WebSocketState.Open || state == WebSocketState.CloseSent) { _state = WebSocketState.Closed; } }; Memory <int> responseMemory = new Memory <int>(responseStatus); responseStatusHandle = responseMemory.Pin(); _innerWebSocket = BrowserInterop.UnsafeCreate(uri.ToString(), subProtocols, responseStatusHandle.Value, onClose); var openTask = BrowserInterop.WebSocketOpen(_innerWebSocket); var wrappedTask = CancelationHelper(openTask !, cancellationToken, _state); await wrappedTask.ConfigureAwait(true); if (State == WebSocketState.Connecting) { _state = WebSocketState.Open; } } catch (OperationCanceledException ex) { _state = WebSocketState.Closed; if (_aborted) { throw new WebSocketException(WebSocketError.Faulted, SR.net_webstatus_ConnectFailure, ex); } throw; } catch (Exception) { Dispose(); throw; } }
public unsafe void ToManaged(out JSObject?[]?value) { if (slot.Type == MarshalerType.None) { value = null; return; } value = new JSObject?[slot.Length]; JSMarshalerArgument *payload = (JSMarshalerArgument *)slot.IntPtrValue; for (int i = 0; i < slot.Length; i++) { ref JSMarshalerArgument arg = ref payload[i]; JSObject?val; arg.ToManaged(out val); value[i] = val; }
public static int BindJSObject(int jsId, bool ownsHandle, int mappedType) { JSObject?target = null; lock (_boundObjects) { if (!_boundObjects.TryGetValue(jsId, out WeakReference <JSObject>?reference) || !reference.TryGetTarget(out target) || target.IsDisposed) { IntPtr jsIntPtr = (IntPtr)jsId; target = mappedType > 0 ? BindJSType(jsIntPtr, ownsHandle, mappedType) : new JSObject(jsIntPtr, ownsHandle); _boundObjects[jsId] = new WeakReference <JSObject>(target, trackResurrection: true); } } return(target.Int32Handle); }
public override void Dispose() { if (!_disposed) { var state = State; _disposed = true; if (state < WebSocketState.Aborted && state != WebSocketState.None) { Abort(); } if (state != WebSocketState.Aborted) { _state = WebSocketState.Closed; } _innerWebSocket?.Dispose(); _innerWebSocket = null; } }
public void ToJS(JSObject?value) { if (value == null) { slot.Type = MarshalerType.None; } else { if (value.IsDisposed) { throw new ObjectDisposedException(nameof(value)); } slot.Type = MarshalerType.JSObject; slot.JSHandle = value.JSHandle; if (slot.JSHandle == IntPtr.Zero) { throw new ObjectDisposedException(nameof(value)); } } }
// Advance to the next item. public bool MoveNext() { if (_mapIterator == null) { _mapIterator = (JSObject)_map.Invoke("entries"); } using (var result = (JSObject)_mapIterator.Invoke("next")) { using (var resultValue = (Array)result.GetObjectProperty("value")) { if (resultValue != null) { Key = resultValue[0]; Value = resultValue[1]; } else { Value = null; } } return(!(bool)result.GetObjectProperty("done")); } }
public static void ReleaseInFlight(object?obj) { JSObject?jsObj = obj as JSObject; jsObj?.ReleaseInFlight(); }
public static void GetCSOwnedObjectByJSHandleRef(IntPtr jsHandle, int shouldAddInflight, out JSObject?result) { lock (_csOwnedObjects) { if (_csOwnedObjects.TryGetValue((int)jsHandle, out WeakReference <JSObject>?reference)) { reference.TryGetTarget(out JSObject? jsObject); if (shouldAddInflight != 0 && jsObject != null) { jsObject.AddInFlight(); } result = jsObject; return; } } result = null; }
public void Reset() { _mapItemIterator?.Dispose(); _mapItemIterator = null; }
public DOMObject(JSObject?jsobject) { ManagedJSObject = jsobject ?? throw new ArgumentNullException(nameof(jsobject)); }
internal JSException(string msg, JSObject?jsException) : base(msg) { this.jsException = jsException; }
/// <summary> /// Initializes a new instance of the JSException class with a specified error message. /// </summary> /// <param name="msg">The message that describes the error.</param> public JSException(string msg) : base(msg) { jsException = null; }
public static async ValueTask <T> CancelationHelper <T>(Task <T> promise, CancellationToken cancellationToken, JSObject?abortController = null, JSObject?fetchResponse = null) { if (promise.IsCompletedSuccessfully) { return(promise.Result); } try { using (var operationRegistration = cancellationToken.Register(() => { CancelablePromise.CancelPromise(promise); if (abortController != null) { AbortRequest(abortController); } if (fetchResponse != null) { AbortResponse(fetchResponse); } })) { return(await promise.ConfigureAwait(true)); } } catch (OperationCanceledException oce) when(cancellationToken.IsCancellationRequested) { throw CancellationHelper.CreateOperationCanceledException(oce, cancellationToken); } catch (JSException jse) { if (jse.Message.StartsWith("AbortError", StringComparison.Ordinal)) { throw CancellationHelper.CreateOperationCanceledException(jse, CancellationToken.None); } if (cancellationToken.IsCancellationRequested) { throw CancellationHelper.CreateOperationCanceledException(jse, cancellationToken); } throw new HttpRequestException(jse.Message, jse); } }