Skip to content

Commit

Permalink
Version 7.3.1: Added script indexing support for IReadOnlyList<T> (Gi…
Browse files Browse the repository at this point in the history
…tHub Issue #393); added ScriptEngine.NullExportValue; added V8RuntimeHeapInfo.TotalAvailableSize and TotalExternalSize (GitHub Issue #391); added partial workaround for VT_BSTR/NULL bug in COM interop (GitHub Issue #390); updated API documentation. Tested with V8 10.3.174.17.
  • Loading branch information
ClearScriptLib committed Jun 29, 2022
1 parent 2812f30 commit f764372
Show file tree
Hide file tree
Showing 674 changed files with 1,504 additions and 1,071 deletions.
6 changes: 3 additions & 3 deletions ClearScript/Exports/VersionSymbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#pragma once

#define CLEARSCRIPT_VERSION_STRING "7.3.0"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,3,0
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.3.0"
#define CLEARSCRIPT_VERSION_STRING "7.3.1"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,3,1
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.3.1"
#define CLEARSCRIPT_FILE_FLAGS 0L
14 changes: 10 additions & 4 deletions ClearScript/HostItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,12 @@ private bool BindSpecialTarget<T>(out T specialTarget) where T : class
return specialTarget != null;
}

if (Target.Type.IsAssignableToGenericType(typeof(IReadOnlyList<>), out typeArgs))
{
specialTarget = typeof(ReadOnlyHostList<>).MakeGenericType(typeArgs).CreateInstance(Engine, Target.InvokeTarget) as T;
return specialTarget != null;
}

specialTarget = null;
return false;
}
Expand Down Expand Up @@ -1542,7 +1548,7 @@ private object GetHostProperty(PropertyInfo property, BindingFlags invokeFlags,
var getMethod = property.GetMethod;
if ((getMethod == null) || !getMethod.IsAccessible(AccessContext) || getMethod.IsBlockedFromScript(DefaultAccess, false))
{
throw new UnauthorizedAccessException("Property get method is unavailable or inaccessible");
throw new UnauthorizedAccessException("The property get method is unavailable or inaccessible");
}

var result = property.GetValue(Target.InvokeTarget, invokeFlags, Type.DefaultBinder, args, culture);
Expand Down Expand Up @@ -1628,7 +1634,7 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
{
if (field.IsLiteral || field.IsInitOnly || field.IsReadOnlyForScript(DefaultAccess))
{
throw new UnauthorizedAccessException("Field is read-only");
throw new UnauthorizedAccessException("The field is read-only");
}

var value = args[0];
Expand All @@ -1651,13 +1657,13 @@ private object SetHostProperty(PropertyInfo property, BindingFlags invokeFlags,
{
if (property.IsReadOnlyForScript(DefaultAccess))
{
throw new UnauthorizedAccessException("Property is read-only");
throw new UnauthorizedAccessException("The property is read-only");
}

var setMethod = property.SetMethod;
if ((setMethod == null) || !setMethod.IsAccessible(AccessContext) || setMethod.IsBlockedFromScript(DefaultAccess, false))
{
throw new UnauthorizedAccessException("Property set method is unavailable or inaccessible");
throw new UnauthorizedAccessException("The property set method is unavailable or inaccessible");
}

var value = args[args.Length - 1];
Expand Down
25 changes: 25 additions & 0 deletions ClearScript/HostList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,29 @@ public object this[int index]

#endregion
}

internal sealed class ReadOnlyHostList<T> : IHostList
{
private readonly ScriptEngine engine;
private readonly IReadOnlyList<T> list;

public ReadOnlyHostList(ScriptEngine engine, IReadOnlyList<T> list)
{
this.engine = engine;
this.list = list;
}

#region IHostList implementation

public int Count => list.Count;

public object this[int index]
{
get => engine.PrepareResult(list[index], ScriptMemberFlags.None, true);

set => throw new UnauthorizedAccessException("The object is read-only");
}

#endregion
}
}
3 changes: 1 addition & 2 deletions ClearScript/HostTypeCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.ClearScript.Util;
using Microsoft.ClearScript.Util.COM;
Expand Down Expand Up @@ -232,7 +231,7 @@ private PropertyBag AddEnumTypeInfoInternal(ITypeInfo typeInfo)
if (varDescScope.Value.varkind == VARKIND.VAR_CONST)
{
var name = typeInfo.GetMemberName(varDescScope.Value.memid);
node.SetPropertyNoCheck(name, Marshal.GetObjectForNativeVariant(varDescScope.Value.desc.lpvarValue));
node.SetPropertyNoCheck(name, MiscHelpers.GetObjectForVariant(varDescScope.Value.desc.lpvarValue));
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions ClearScript/Properties/AssemblyInfo.Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
[assembly: InternalsVisibleTo("ClearScriptTest")]

[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.3.0")]
[assembly: AssemblyFileVersion("7.3.0")]
[assembly: AssemblyInformationalVersion("7.3.0")]
[assembly: AssemblyVersion("7.3.1")]
[assembly: AssemblyFileVersion("7.3.1")]
[assembly: AssemblyInformationalVersion("7.3.1")]

namespace Microsoft.ClearScript.Properties
{
internal static class ClearScriptVersion
{
public const string Triad = "7.3.0";
public const string Informational = "7.3.0";
public const string Triad = "7.3.1";
public const string Informational = "7.3.1";
}
}
6 changes: 3 additions & 3 deletions ClearScript/Properties/AssemblyInfo.V8.ICUData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
[assembly: InternalsVisibleTo("ClearScript.V8")]

[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.3.0")]
[assembly: AssemblyFileVersion("7.3.0")]
[assembly: AssemblyInformationalVersion("7.3.0")]
[assembly: AssemblyVersion("7.3.1")]
[assembly: AssemblyFileVersion("7.3.1")]
[assembly: AssemblyInformationalVersion("7.3.1")]
6 changes: 3 additions & 3 deletions ClearScript/Properties/AssemblyInfo.V8.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
[assembly: InternalsVisibleTo("ClearScriptTest")]

[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.3.0")]
[assembly: AssemblyFileVersion("7.3.0")]
[assembly: AssemblyInformationalVersion("7.3.0")]
[assembly: AssemblyVersion("7.3.1")]
[assembly: AssemblyFileVersion("7.3.1")]
[assembly: AssemblyInformationalVersion("7.3.1")]
6 changes: 3 additions & 3 deletions ClearScript/Properties/AssemblyInfo.Windows.Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@
[assembly: InternalsVisibleTo("ClearScriptTest")]

[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.3.0")]
[assembly: AssemblyFileVersion("7.3.0")]
[assembly: AssemblyInformationalVersion("7.3.0")]
[assembly: AssemblyVersion("7.3.1")]
[assembly: AssemblyFileVersion("7.3.1")]
[assembly: AssemblyInformationalVersion("7.3.1")]
6 changes: 3 additions & 3 deletions ClearScript/Properties/AssemblyInfo.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
[assembly: InternalsVisibleTo("ClearScriptTest")]

[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.3.0")]
[assembly: AssemblyFileVersion("7.3.0")]
[assembly: AssemblyInformationalVersion("7.3.0")]
[assembly: AssemblyVersion("7.3.1")]
[assembly: AssemblyFileVersion("7.3.1")]
[assembly: AssemblyInformationalVersion("7.3.1")]
25 changes: 23 additions & 2 deletions ClearScript/ScriptEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,31 @@ public bool DisableExtensionMethods
/// Some script languages support one or more special non-<c>null</c> values that represent
/// nonexistent, missing, unknown, or undefined data. When such a value is marshaled to the
/// host, the script engine maps it to the value of this property. The default value is
/// <c><see cref="Undefined.Value"/></c>.
/// <c><see cref="Undefined.Value">Undefined.Value</see></c>.
/// </remarks>
public object UndefinedImportValue { get; set; } = Undefined.Value;

/// <summary>
/// Gets or sets the engine's null export value.
/// </summary>
/// <remarks>
/// <para>
/// When a null object reference is marshaled to script code, the script engine maps it to
/// the value of this property. The default value is simply <c>null</c>, which corresponds
/// to <c>null</c> or its closest equivalent in the script language. Other useful
/// possibilities include
/// <c><see cref="Undefined.Value">Undefined.Value</see></c> and
/// <c><see href="https://microsoft.github.io/ClearScript/Reference/html/F_Microsoft_ClearScript_Windows_Nothing_Value.htm">Nothing.Value</see></c>.
/// </para>
/// <para>
/// Note that <see cref="ScriptMemberFlags.WrapNullResult"/>,
/// <see cref="EnableNullResultWrapping"/>, and
/// <see href="https://microsoft.github.io/ClearScript/Reference/html/T_Microsoft_ClearScript_Windows_WindowsScriptEngineFlags.htm">MarshalNullAsDispatch</see>
/// all take precedence over this property.
/// </para>
/// </remarks>
public object NullExportValue { get; set; }

/// <summary>
/// Gets or sets the engine's void result export value.
/// </summary>
Expand All @@ -306,7 +327,7 @@ public bool DisableExtensionMethods
/// as a C#
/// <c><see href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/void">void</see></c>
/// method), the script engine returns the value of this property as a dummy result. The
/// default value is <c><see cref="VoidResult.Value"/></c>.
/// default value is <c><see cref="VoidResult.Value">VoidResult.Value</see></c>.
/// </remarks>
public object VoidResultValue { get; set; } = VoidResult.Value;

Expand Down
12 changes: 6 additions & 6 deletions ClearScript/Util/COM/DispatchHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static object GetProperty(this IDispatch dispatch, string name, params ob
{
var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero };
HResult.Check(dispatch.Invoke(dispid, ref iid, 0, DispatchFlags.PropertyGet, ref dispArgs, resultVariantBlock.Addr, out _, out _));
return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr);
return MiscHelpers.GetObjectForVariant(resultVariantBlock.Addr);
}
}
}
Expand Down Expand Up @@ -92,7 +92,7 @@ public static object Invoke(this IDispatch dispatch, params object[] args)
{
var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero };
HResult.Check(dispatch.Invoke(SpecialDispIDs.Default, ref iid, 0, DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out _, out _));
return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr);
return MiscHelpers.GetObjectForVariant(resultVariantBlock.Addr);
}
}
}
Expand All @@ -111,7 +111,7 @@ public static object InvokeMethod(this IDispatch dispatch, string name, params o
{
var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero };
HResult.Check(dispatch.Invoke(dispid, iid, 0, DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out _, out _));
return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr);
return MiscHelpers.GetObjectForVariant(resultVariantBlock.Addr);
}
}
}
Expand Down Expand Up @@ -185,7 +185,7 @@ public static object GetProperty(this IDispatchEx dispatchEx, string name, bool
{
var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero };
HResult.Check(dispatchEx.InvokeEx(dispid, 0, DispatchFlags.PropertyGet, ref dispArgs, resultVariantBlock.Addr, out _));
return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr);
return MiscHelpers.GetObjectForVariant(resultVariantBlock.Addr);
}
}
}
Expand Down Expand Up @@ -240,7 +240,7 @@ public static object Invoke(this IDispatchEx dispatchEx, bool asConstructor, par
{
var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero };
HResult.Check(dispatchEx.InvokeEx(SpecialDispIDs.Default, 0, asConstructor ? DispatchFlags.Construct : DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out _));
return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr);
return MiscHelpers.GetObjectForVariant(resultVariantBlock.Addr);
}
}
}
Expand All @@ -259,7 +259,7 @@ public static object InvokeMethod(this IDispatchEx dispatchEx, string name, bool
{
var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero };
HResult.Check(dispatchEx.InvokeEx(dispid, 0, DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out _));
return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr);
return MiscHelpers.GetObjectForVariant(resultVariantBlock.Addr);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion ClearScript/Util/CoTaskMemBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ protected override void Dispose(bool disposing)
for (var index = 0; index < args.Length; index++)
{
var pArg = GetAddrInternal(args.Length + index);
args[index] = Marshal.GetObjectForNativeVariant(pArg);
args[index] = MiscHelpers.GetObjectForVariant(pArg);
NativeMethods.VariantClear(pArg);
}
}
Expand Down
12 changes: 12 additions & 0 deletions ClearScript/Util/MiscHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,18 @@ public static bool ProcessorArchitectureIsArm()
}
}

public static object GetObjectForVariant(IntPtr pVariant)
{
var result = Marshal.GetObjectForNativeVariant(pVariant);

if ((result == null) && (Marshal.ReadInt16(pVariant) == (short)VarEnum.VT_BSTR))
{
return string.Empty;
}

return result;
}

#endregion
}
}
6 changes: 3 additions & 3 deletions ClearScript/Util/TypeHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Microsoft.ClearScript.Util
{
internal static partial class TypeHelpers
{
private static readonly string[] importBlackList =
private static readonly string[] importDenyList =
{
// ReSharper disable StringLiteralTypo

Expand Down Expand Up @@ -75,7 +75,7 @@ public static bool IsImportable(this Type type)
if (!type.IsNested && !type.IsSpecialName && !type.IsCompilerGenerated())
{
var locator = type.GetLocator();
return !importBlackList.Contains(locator) && IsValidLocator(locator);
return !importDenyList.Contains(locator) && IsValidLocator(locator);
}

return false;
Expand Down Expand Up @@ -785,7 +785,7 @@ private static Type GetPropertyIndexType(object bindArg)
return bindArg.GetType();
}

throw new InvalidOperationException("Property index value must not be null");
throw new InvalidOperationException("The property index value must not be null");
}

private static PropertyInfo SelectProperty(PropertyInfo[] candidates, BindingFlags bindFlags, object[] bindArgs)
Expand Down
4 changes: 2 additions & 2 deletions ClearScript/V8/SplitProxy/IV8SplitProxyNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ internal interface IV8SplitProxyNative
void V8Isolate_SetEnableInterruptPropagation(V8Isolate.Handle hIsolate, bool value);
bool V8Isolate_GetDisableHeapSizeViolationInterrupt(V8Isolate.Handle hIsolate);
void V8Isolate_SetDisableHeapSizeViolationInterrupt(V8Isolate.Handle hIsolate, bool value);
void V8Isolate_GetHeapStatistics(V8Isolate.Handle hIsolate, out ulong totalHeapSize, out ulong totalHeapSizeExecutable, out ulong totalPhysicalSize, out ulong usedHeapSize, out ulong heapSizeLimit);
void V8Isolate_GetHeapStatistics(V8Isolate.Handle hIsolate, out ulong totalHeapSize, out ulong totalHeapSizeExecutable, out ulong totalPhysicalSize, out ulong totalAvailableSize, out ulong usedHeapSize, out ulong heapSizeLimit, out ulong totalExternalSize);
void V8Isolate_GetStatistics(V8Isolate.Handle hIsolate, out ulong scriptCount, out ulong scriptCacheSize, out ulong moduleCount, out ulong[] postedTaskCounts, out ulong[] invokedTaskCounts);
void V8Isolate_CollectGarbage(V8Isolate.Handle hIsolate, bool exhaustive);
bool V8Isolate_BeginCpuProfile(V8Isolate.Handle hIsolate, string name, bool recordSamples);
Expand Down Expand Up @@ -180,7 +180,7 @@ internal interface IV8SplitProxyNative
void V8Context_SetEnableIsolateInterruptPropagation(V8Context.Handle hContext, bool value);
bool V8Context_GetDisableIsolateHeapSizeViolationInterrupt(V8Context.Handle hContext);
void V8Context_SetDisableIsolateHeapSizeViolationInterrupt(V8Context.Handle hContext, bool value);
void V8Context_GetIsolateHeapStatistics(V8Context.Handle hContext, out ulong totalHeapSize, out ulong totalHeapSizeExecutable, out ulong totalPhysicalSize, out ulong usedHeapSize, out ulong heapSizeLimit);
void V8Context_GetIsolateHeapStatistics(V8Context.Handle hContext, out ulong totalHeapSize, out ulong totalHeapSizeExecutable, out ulong totalPhysicalSize, out ulong totalAvailableSize, out ulong usedHeapSize, out ulong heapSizeLimit, out ulong totalExternalSize);
void V8Context_GetIsolateStatistics(V8Context.Handle hContext, out ulong scriptCount, out ulong scriptCacheSize, out ulong moduleCount, out ulong[] postedTaskCounts, out ulong[] invokedTaskCounts);
void V8Context_GetStatistics(V8Context.Handle hContext, out ulong scriptCount, out ulong moduleCount, out ulong moduleCacheSize);
void V8Context_CollectGarbage(V8Context.Handle hContext, bool exhaustive);
Expand Down
8 changes: 6 additions & 2 deletions ClearScript/V8/SplitProxy/V8ContextProxyImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,17 +194,21 @@ public override V8RuntimeHeapInfo GetIsolateHeapInfo()
var totalHeapSize = 0UL;
var totalHeapSizeExecutable = 0UL;
var totalPhysicalSize = 0UL;
var totalAvailableSize = 0UL;
var usedHeapSize = 0UL;
var heapSizeLimit = 0UL;
V8SplitProxyNative.Invoke(instance => instance.V8Context_GetIsolateHeapStatistics(Handle, out totalHeapSize, out totalHeapSizeExecutable, out totalPhysicalSize, out usedHeapSize, out heapSizeLimit));
var totalExternalSize = 0UL;
V8SplitProxyNative.Invoke(instance => instance.V8Context_GetIsolateHeapStatistics(Handle, out totalHeapSize, out totalHeapSizeExecutable, out totalPhysicalSize, out totalAvailableSize, out usedHeapSize, out heapSizeLimit, out totalExternalSize));

return new V8RuntimeHeapInfo
{
TotalHeapSize = totalHeapSize,
TotalHeapSizeExecutable = totalHeapSizeExecutable,
TotalPhysicalSize = totalPhysicalSize,
TotalAvailableSize = totalAvailableSize,
UsedHeapSize = usedHeapSize,
HeapSizeLimit = heapSizeLimit
HeapSizeLimit = heapSizeLimit,
TotalExternalSize = totalExternalSize
};
}

Expand Down
8 changes: 6 additions & 2 deletions ClearScript/V8/SplitProxy/V8IsolateProxyImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,21 @@ public override V8RuntimeHeapInfo GetHeapInfo()
var totalHeapSize = 0UL;
var totalHeapSizeExecutable = 0UL;
var totalPhysicalSize = 0UL;
var totalAvailableSize = 0UL;
var usedHeapSize = 0UL;
var heapSizeLimit = 0UL;
V8SplitProxyNative.Invoke(instance => instance.V8Isolate_GetHeapStatistics(Handle, out totalHeapSize, out totalHeapSizeExecutable, out totalPhysicalSize, out usedHeapSize, out heapSizeLimit));
var totalExternalSize = 0UL;
V8SplitProxyNative.Invoke(instance => instance.V8Isolate_GetHeapStatistics(Handle, out totalHeapSize, out totalHeapSizeExecutable, out totalPhysicalSize, out totalAvailableSize, out usedHeapSize, out heapSizeLimit, out totalExternalSize));

return new V8RuntimeHeapInfo
{
TotalHeapSize = totalHeapSize,
TotalHeapSizeExecutable = totalHeapSizeExecutable,
TotalPhysicalSize = totalPhysicalSize,
TotalAvailableSize = totalAvailableSize,
UsedHeapSize = usedHeapSize,
HeapSizeLimit = heapSizeLimit
HeapSizeLimit = heapSizeLimit,
TotalExternalSize = totalExternalSize
};
}

Expand Down
Loading

0 comments on commit f764372

Please sign in to comment.