Skip to content

Commit a02a01f

Browse files
Version 7.4.2: Enhanced support for parameterless value type constructors (mentioned in GitHub Issue #444); fixed COM-related memory leak on .NET Framework (GitHub Issue #510); enabled multidimensional array manipulation via VBScript indexing syntax (GitHub Issue #511); improved stability on Apple Silicon devices. Tested with V8 11.4.183.17.
1 parent d9a58a6 commit a02a01f

32 files changed

+686
-185
lines changed

ClearScript/Exports/VersionSymbols.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#pragma once
77

8-
#define CLEARSCRIPT_VERSION_STRING "7.4.1"
9-
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,4,1
10-
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.4.1"
8+
#define CLEARSCRIPT_VERSION_STRING "7.4.2"
9+
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,4,2
10+
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.4.2"
1111
#define CLEARSCRIPT_FILE_FLAGS 0L

ClearScript/HostItem.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,30 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
14081408
return GetHostProperty(signature, defaultProperty, invokeFlags, args);
14091409
}
14101410

1411+
if (Target.Type.IsArray && (Target.Type.GetArrayRank() == args.Length))
1412+
{
1413+
// special case to enable VBScript "x(a, b, ...)" syntax when x is a multidimensional array
1414+
1415+
var indices = new long[args.Length];
1416+
var failed = false;
1417+
1418+
for (var position = 0; position < args.Length; position++)
1419+
{
1420+
if (!MiscHelpers.TryGetNumericIndex(args[position], out long index))
1421+
{
1422+
failed = true;
1423+
break;
1424+
}
1425+
1426+
indices[position] = index;
1427+
}
1428+
1429+
if (!failed)
1430+
{
1431+
return ((Array)Target.InvokeTarget).GetValue(indices);
1432+
}
1433+
}
1434+
14111435
if (TargetDynamicMetaObject != null)
14121436
{
14131437
if (TargetDynamicMetaObject.TryGetIndex(args, out var result))
@@ -1641,6 +1665,32 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
16411665
throw new InvalidOperationException("Invalid argument count");
16421666
}
16431667

1668+
if (Target.Type.IsArray && (Target.Type.GetArrayRank() == (args.Length - 1)))
1669+
{
1670+
// special case to enable VBScript "x(a, b, ...) = value" syntax when x is a multidimensional array
1671+
1672+
var indices = new long[args.Length - 1];
1673+
var failed = false;
1674+
1675+
for (var position = 0; position < (args.Length - 1); position++)
1676+
{
1677+
if (!MiscHelpers.TryGetNumericIndex(args[position], out long index))
1678+
{
1679+
failed = true;
1680+
break;
1681+
}
1682+
1683+
indices[position] = index;
1684+
}
1685+
1686+
if (!failed)
1687+
{
1688+
var value = args[args.Length - 1];
1689+
((Array)Target.InvokeTarget).SetValue(value, indices);
1690+
return value;
1691+
}
1692+
}
1693+
16441694
if (TargetDynamicMetaObject != null)
16451695
{
16461696
if (TargetDynamicMetaObject.TrySetIndex(args.Take(args.Length - 1).ToArray(), args[args.Length - 1], out result))

ClearScript/Properties/AssemblyInfo.Core.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
[assembly: InternalsVisibleTo("ClearScriptTest")]
1919

2020
[assembly: ComVisible(false)]
21-
[assembly: AssemblyVersion("7.4.1")]
22-
[assembly: AssemblyFileVersion("7.4.1")]
23-
[assembly: AssemblyInformationalVersion("7.4.1")]
21+
[assembly: AssemblyVersion("7.4.2")]
22+
[assembly: AssemblyFileVersion("7.4.2")]
23+
[assembly: AssemblyInformationalVersion("7.4.2")]
2424

2525
namespace Microsoft.ClearScript.Properties
2626
{
2727
internal static class ClearScriptVersion
2828
{
29-
public const string Triad = "7.4.1";
30-
public const string Informational = "7.4.1";
29+
public const string Triad = "7.4.2";
30+
public const string Informational = "7.4.2";
3131
}
3232
}

ClearScript/Properties/AssemblyInfo.V8.ICUData.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
[assembly: InternalsVisibleTo("ClearScript.V8")]
1616

1717
[assembly: ComVisible(false)]
18-
[assembly: AssemblyVersion("7.4.1")]
19-
[assembly: AssemblyFileVersion("7.4.1")]
20-
[assembly: AssemblyInformationalVersion("7.4.1")]
18+
[assembly: AssemblyVersion("7.4.2")]
19+
[assembly: AssemblyFileVersion("7.4.2")]
20+
[assembly: AssemblyInformationalVersion("7.4.2")]

ClearScript/Properties/AssemblyInfo.V8.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
[assembly: InternalsVisibleTo("ClearScriptTest")]
1616

1717
[assembly: ComVisible(false)]
18-
[assembly: AssemblyVersion("7.4.1")]
19-
[assembly: AssemblyFileVersion("7.4.1")]
20-
[assembly: AssemblyInformationalVersion("7.4.1")]
18+
[assembly: AssemblyVersion("7.4.2")]
19+
[assembly: AssemblyFileVersion("7.4.2")]
20+
[assembly: AssemblyInformationalVersion("7.4.2")]

ClearScript/Properties/AssemblyInfo.Windows.Core.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
[assembly: InternalsVisibleTo("ClearScriptTest")]
1717

1818
[assembly: ComVisible(false)]
19-
[assembly: AssemblyVersion("7.4.1")]
20-
[assembly: AssemblyFileVersion("7.4.1")]
21-
[assembly: AssemblyInformationalVersion("7.4.1")]
19+
[assembly: AssemblyVersion("7.4.2")]
20+
[assembly: AssemblyFileVersion("7.4.2")]
21+
[assembly: AssemblyInformationalVersion("7.4.2")]

ClearScript/Properties/AssemblyInfo.Windows.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
[assembly: InternalsVisibleTo("ClearScriptTest")]
1616

1717
[assembly: ComVisible(false)]
18-
[assembly: AssemblyVersion("7.4.1")]
19-
[assembly: AssemblyFileVersion("7.4.1")]
20-
[assembly: AssemblyInformationalVersion("7.4.1")]
18+
[assembly: AssemblyVersion("7.4.2")]
19+
[assembly: AssemblyFileVersion("7.4.2")]
20+
[assembly: AssemblyInformationalVersion("7.4.2")]

ClearScript/Util/COM/TypeInfoHelpers.NetFramework.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,31 @@
22
// Licensed under the MIT license.
33

44
using System;
5+
using System.Collections.Concurrent;
56
using System.Runtime.InteropServices;
67
using System.Runtime.InteropServices.ComTypes;
78

89
namespace Microsoft.ClearScript.Util.COM
910
{
1011
internal static partial class TypeInfoHelpers
1112
{
13+
private static readonly ConcurrentDictionary<Guid, Type> managedTypeMap = new ConcurrentDictionary<Guid, Type>();
14+
1215
public static Type GetManagedType(this ITypeInfo typeInfo)
1316
{
14-
var pTypeInfo = Marshal.GetComInterfaceForObject(typeInfo, typeof(ITypeInfo));
15-
try
16-
{
17-
return Marshal.GetTypeForITypeInfo(pTypeInfo);
18-
}
19-
finally
17+
var guid = typeInfo.GetGuid();
18+
return (guid == Guid.Empty) ? null : managedTypeMap.GetOrAdd(guid, _ =>
2019
{
21-
Marshal.Release(pTypeInfo);
22-
}
20+
var pTypeInfo = Marshal.GetComInterfaceForObject(typeInfo, typeof(ITypeInfo));
21+
try
22+
{
23+
return Marshal.GetTypeForITypeInfo(pTypeInfo);
24+
}
25+
finally
26+
{
27+
Marshal.Release(pTypeInfo);
28+
}
29+
});
2330
}
2431
}
2532
}

ClearScript/Util/TypeHelpers.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ public static object CreateInstance(this Type type, BindingFlags flags, params o
487487

488488
public static object CreateInstance(this Type type, IHostInvokeContext invokeContext, HostTarget target, object[] args, object[] bindArgs)
489489
{
490-
if (type.IsCOMObject || (type.IsValueType && (args.Length < 1)))
490+
if (type.IsCOMObject)
491491
{
492492
return type.CreateInstance(args);
493493
}
@@ -500,7 +500,13 @@ public static object CreateInstance(this Type type, IHostInvokeContext invokeCon
500500
return InvokeHelpers.InvokeConstructor(invokeContext, boundConstructor, args);
501501
}
502502

503-
var candidates = type.GetConstructors(flags).Where(testConstructor => testConstructor.IsAccessible(invokeContext.AccessContext) && !testConstructor.IsBlockedFromScript(invokeContext.DefaultAccess)).ToArray();
503+
var constructors = type.GetConstructors(flags);
504+
if (type.IsValueType && (args.Length < 1) && !constructors.Any(testConstructor => testConstructor.GetParameters().Length < 1))
505+
{
506+
return type.CreateInstance();
507+
}
508+
509+
var candidates = constructors.Where(testConstructor => testConstructor.IsAccessible(invokeContext.AccessContext) && !testConstructor.IsBlockedFromScript(invokeContext.DefaultAccess)).ToArray();
504510
if (candidates.Length < 1)
505511
{
506512
throw new MissingMethodException(MiscHelpers.FormatInvariant("Type '{0}' has no constructor that matches the specified arguments", type.GetFullFriendlyName()));
@@ -1271,14 +1277,16 @@ public int CompareTo(BindArgCost other)
12711277

12721278
private sealed class BindCandidate<T> : IComparable<BindCandidate<T>> where T : MemberInfo
12731279
{
1280+
private readonly int defaultArgCount;
12741281
private readonly bool paramArray;
12751282
private readonly List<BindArgCost> argCosts;
12761283

12771284
public T Candidate { get; }
12781285

1279-
private BindCandidate(T candidate, bool paramArray, List<BindArgCost> argCosts)
1286+
private BindCandidate(T candidate, int defaultArgCount, bool paramArray, List<BindArgCost> argCosts)
12801287
{
12811288
Candidate = candidate;
1289+
this.defaultArgCount = defaultArgCount;
12821290
this.paramArray = paramArray;
12831291
this.argCosts = argCosts;
12841292
}
@@ -1297,6 +1305,12 @@ public int CompareTo(BindCandidate<T> other)
12971305
}
12981306
}
12991307

1308+
result = defaultArgCount.CompareTo(other.defaultArgCount);
1309+
if (result != 0)
1310+
{
1311+
return result;
1312+
}
1313+
13001314
result = paramArray.CompareTo(other.paramArray);
13011315
if (result != 0)
13021316
{
@@ -1316,6 +1330,7 @@ public int CompareTo(BindCandidate<T> other)
13161330

13171331
public static BindCandidate<T> TryCreateInstance(T candidate, ParameterInfo[] parameters, object[] args, Type[] argTypes)
13181332
{
1333+
var defaultArgCount = 0;
13191334
var paramArray = false;
13201335
var argCosts = new List<BindArgCost>();
13211336

@@ -1343,6 +1358,7 @@ public static BindCandidate<T> TryCreateInstance(T candidate, ParameterInfo[] pa
13431358
return null;
13441359
}
13451360

1361+
defaultArgCount += 1;
13461362
continue;
13471363
}
13481364

@@ -1359,13 +1375,13 @@ public static BindCandidate<T> TryCreateInstance(T candidate, ParameterInfo[] pa
13591375
{
13601376
if (argIndex >= args.Length)
13611377
{
1362-
return new BindCandidate<T>(candidate, true, argCosts);
1378+
return new BindCandidate<T>(candidate, defaultArgCount, true, argCosts);
13631379
}
13641380

13651381
if ((argIndex == (args.Length - 1)) && paramType.IsBindableFromArg(args[argIndex], argTypes[argIndex], out cost))
13661382
{
13671383
argCosts.Add(cost);
1368-
return new BindCandidate<T>(candidate, true, argCosts);
1384+
return new BindCandidate<T>(candidate, defaultArgCount, true, argCosts);
13691385
}
13701386

13711387
paramType = paramType.GetElementType();
@@ -1385,7 +1401,7 @@ public static BindCandidate<T> TryCreateInstance(T candidate, ParameterInfo[] pa
13851401
return null;
13861402
}
13871403

1388-
return new BindCandidate<T>(candidate, paramArray, argCosts);
1404+
return new BindCandidate<T>(candidate, defaultArgCount, paramArray, argCosts);
13891405
}
13901406
}
13911407

ClearScriptBenchmarks/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
1212

1313
[assembly: ComVisible(false)]
14-
[assembly: AssemblyVersion("7.4.1")]
15-
[assembly: AssemblyFileVersion("7.4.1")]
16-
[assembly: AssemblyInformationalVersion("7.4.1")]
14+
[assembly: AssemblyVersion("7.4.2")]
15+
[assembly: AssemblyFileVersion("7.4.2")]
16+
[assembly: AssemblyInformationalVersion("7.4.2")]

0 commit comments

Comments
 (0)