public bool Equals(JsDynamicObject other) { if (other is null) { return(false); } if (Handle.Type != other.Handle.Type) { return(false); } System.Diagnostics.Debug.Assert(Handle.Type == JsType.Object || Handle.Type == JsType.Function, "Only objects are supported by JsDynamicObject atm."); CheckDisposed(); // TODO: Do this using a native method, which would be more efficient. var gObj = _host.GetMember(JsValue.Global, "Object"); try { var result = _host.InvokeByName("is", gObj, 2, new DotNetValue[] { DotNetValue.FromJsValue(Handle), DotNetValue.FromJsValue(other.Handle) }); return(result.TryGetObject(_host, typeof(bool), out object resultObj) && (bool)resultObj); } finally { _host.Release(gObj); } }
public NodeBridge(IHostInProcess host) { _host = host; Global = new JsDynamicObject(JsValue.Global, _host); }
public void SetMember(JsDynamicObject ownerHandle, string name, DotNetValue value) { _host.SetMember(ownerHandle.Handle, name, value); }
internal bool TryGetObject(IHostInProcess host, Type targetType, out object result) { var releaseHandle = true; try { switch (Type) { case JsType.Null: releaseHandle = false; result = null; return(true); case JsType.Object: case JsType.Function: releaseHandle = false; var asDynamic = new JsDynamicObject(this, host); var wasConverted = asDynamic.TryConvertIntern(targetType, out result); if (wasConverted) { // Prevent GC release of `asDynamic` by disposing it now // TODO DM 17.05.2020: The check for ArrayBuffer shows deeper design problems (conversion should be externalized?) if (!ReferenceEquals(asDynamic, result) && targetType != typeof(ArrayBuffer)) { asDynamic.Dispose(); } return(true); } result = asDynamic; return(true); case JsType.String: result = Marshal.PtrToStringUni(Value); return(true); case JsType.Number: // TODO: This will break on 32 bit systems! releaseHandle = false; var numberValue = BitConverter.Int64BitsToDouble((long)Value); if (targetType == typeof(int)) { result = (int)numberValue; } else if (targetType == typeof(long)) { result = (long)numberValue; } else { result = numberValue; } return(true); case JsType.Boolean: releaseHandle = false; result = Value != IntPtr.Zero; return(true); case JsType.Error: // This is not for error objects. This is whenever js code threw an exception! throw new InvalidOperationException(host.StringFromNativeUtf8(Value)); case JsType.Undefined: releaseHandle = false; result = null; return(false); default: throw new InvalidOperationException($"Unsupported JsType '{Type}'"); } } finally { if (releaseHandle) { host.Release(this); } } }