Skip to content

Commit c217047

Browse files
Version 7.5.1-preview: [V8] Added support for JavaScript explicit resource management and script-side host object disposal (GitHub Issue #533); [V8] added support for JavaScript object disposal from the host; added JavaScriptObjectFlags: Iterable, AsyncIterable, Disposable, AsyncDisposable; added IJavaScriptObject.Update; made HostItemFlags.DirectAccess apply to all fully public classes by default (GitHub Discussion #626); added HostSettings.DisableInteropAssemblyConstruction (GitHub Issue #645); added ScriptEngine.MarshalEnumAsUnderlyingType and AcceptEnumAsUnderlyingType (GitHub Discussion #693); [V8] updated V8FastArgs to use ArrayPool; removed initialization script minimization to ease debugging; updated API documentation. Tested with V8 14.3.127.17.
1 parent 88b084e commit c217047

File tree

1,468 files changed

+6120
-3678
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,468 files changed

+6120
-3678
lines changed

ClearScript/ByRefArg.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ namespace Microsoft.ClearScript
1010
internal interface IByRefArg
1111
{
1212
Type Type { get; }
13-
object Value { get; set; }
13+
object Value { get; }
14+
object SetValue(IHostContext context, object value);
1415
}
1516

1617
internal interface IOutArg : IByRefArg
@@ -80,11 +81,9 @@ public override Invocability GetInvocability(IHostContext context, BindingFlags
8081

8182
#region IByRefArg implementation
8283

83-
object IByRefArg.Value
84-
{
85-
get => target.Value;
86-
set => ((IHostVariable)target).Value = value;
87-
}
84+
object IByRefArg.Value => target.Value;
85+
86+
object IByRefArg.SetValue(IHostContext context, object value) => ((IHostVariable)target).SetValue(context, value);
8887

8988
#endregion
9089
}

ClearScript/DefaultDocumentLoader.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ public class DefaultDocumentLoader : DocumentLoader, DocumentLoader.IStatistics
2727
".." + Path.AltDirectorySeparatorChar,
2828
};
2929

30+
private static readonly Func<HttpClientHandler> defaultHttpClientHandlerFactory = static () => new HttpClientHandler();
31+
3032
private readonly List<Document> cache = new();
3133
private long fileCheckCount;
3234
private long webCheckCount;
35+
private Func<HttpClientHandler> httpClientHandlerFactory;
3336

3437
// ReSharper disable EmptyConstructor
3538

@@ -43,6 +46,12 @@ public DefaultDocumentLoader()
4346

4447
// ReSharper restore EmptyConstructor
4548

49+
internal Func<HttpClientHandler> HttpClientHandlerFactory
50+
{
51+
get => httpClientHandlerFactory ?? defaultHttpClientHandlerFactory;
52+
set => httpClientHandlerFactory = value;
53+
}
54+
4655
private Task<(Document, List<Uri>)> GetCachedDocumentOrCandidateUrisAsync(DocumentSettings settings, DocumentInfo? sourceInfo, Uri uri)
4756
{
4857
return GetCachedDocumentOrCandidateUrisWorkerAsync(settings, sourceInfo, uri.ToEnumerable());
@@ -229,7 +238,7 @@ private Task<bool> FileDocumentExistsAsync(string path)
229238
private async Task<bool> WebDocumentExistsAsync(Uri uri)
230239
{
231240
Interlocked.Increment(ref webCheckCount);
232-
using (var client = new HttpClient())
241+
using (var client = new HttpClient(HttpClientHandlerFactory()))
233242
{
234243
using (var request = new HttpRequestMessage(HttpMethod.Head, uri))
235244
{
@@ -282,7 +291,7 @@ private async Task<Document> LoadDocumentAsync(DocumentSettings settings, Uri ur
282291
}
283292
else
284293
{
285-
using (var client = new HttpClient())
294+
using (var client = new HttpClient(HttpClientHandlerFactory()))
286295
{
287296
contents = await client.GetStringAsync(uri).ConfigureAwait(false);
288297
}

ClearScript/DelegateFactory.Generated.cs

Lines changed: 34 additions & 34 deletions
Large diffs are not rendered by default.

ClearScript/DelegateFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,11 @@ protected static object GetArgValue(object arg)
185185
return (arg is IByRefArg byRefArg) ? byRefArg.Value : arg;
186186
}
187187

188-
protected static void SetArgValue(object arg, object value)
188+
protected void SetArgValue(object arg, object value)
189189
{
190190
if (arg is IByRefArg byRefArg)
191191
{
192-
byRefArg.Value = value;
192+
byRefArg.SetValue(Engine, value);
193193
}
194194
}
195195

ClearScript/DelegateFactory.tt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace Microsoft.ClearScript
3232
#>
3333

3434
[ExcludeFromCodeCoverage]
35-
private class ProcShim<#= typeParamList #> : ProcShim
35+
private sealed class ProcShim<#= typeParamList #> : ProcShim
3636
{
3737
private static readonly MethodInfo method = typeof(ProcShim<#= typeParamList #>).GetMethod("InvokeTarget");
3838
private static readonly bool allByValue = <#= allByValueExpr #>;
@@ -103,7 +103,7 @@ namespace Microsoft.ClearScript
103103
#>
104104

105105
[ExcludeFromCodeCoverage]
106-
private class FuncShim<#= typeParamList #> : FuncShim<TResult>
106+
private sealed class FuncShim<#= typeParamList #> : FuncShim<TResult>
107107
{
108108
private static readonly MethodInfo method = typeof(FuncShim<#= typeParamList #>).GetMethod("InvokeTarget");
109109
private static readonly bool allByValue = <#= allByValueExpr #>;

ClearScript/DocumentSettings.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ public void AddSystemDocument(string identifier, DocumentCategory category, stri
140140
AddSystemDocument(identifier, new StringDocument(info, contents));
141141
}
142142

143-
144143
/// <summary>
145144
/// Adds the specified document as a system document to the configuration.
146145
/// </summary>

ClearScript/Exports/VersionSymbols.h

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

66
#pragma once
77

8-
#define CLEARSCRIPT_VERSION_STRING "7.5.0"
9-
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,5,0
10-
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.5.0"
11-
#define CLEARSCRIPT_FILE_FLAGS 0L
8+
#define CLEARSCRIPT_VERSION_STRING "7.5.1"
9+
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,5,1
10+
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.5.1-preview"
11+
#define CLEARSCRIPT_FILE_FLAGS VS_FF_PRERELEASE

ClearScript/HostItem.cs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
using System.Runtime.InteropServices;
1414
using System.Runtime.InteropServices.ComTypes;
1515
using System.Runtime.InteropServices.Expando;
16+
using System.Threading.Tasks;
17+
using Microsoft.ClearScript.JavaScript;
1618
using Microsoft.ClearScript.Util;
1719
using Microsoft.ClearScript.Util.COM;
1820

1921
namespace Microsoft.ClearScript
2022
{
21-
internal partial class HostItem : DynamicObject, IReflect, IDynamic, IEnumVARIANT, ICustomQueryInterface, IHostItem, IHostTargetContext
23+
internal partial class HostItem : DynamicObject, IReflect, IDynamic, IEnumVARIANT, ICustomQueryInterface, IDisposableHostItem, IHostTargetContext
2224
{
2325
#region data
2426

@@ -821,6 +823,12 @@ protected virtual void RemoveExpandoMemberName(string name)
821823

822824
private StringComparer MemberNameComparer => UseCaseInsensitiveMemberBinding ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal;
823825

826+
private void HostInvoke<TArg>(Action<TArg> action, in TArg arg)
827+
{
828+
BindTargetMemberData();
829+
Engine.HostInvoke(action, arg);
830+
}
831+
824832
private TResult HostInvoke<TArg, TResult>(Func<TArg, TResult> func, in TArg arg)
825833
{
826834
BindTargetMemberData();
@@ -1784,8 +1792,8 @@ private object SetHostPropertyWorker(PropertyInfo property, MethodInfo setMethod
17841792
if (argCount < paramCount)
17851793
{
17861794
var missingArgs = Enumerable.Repeat(Missing.Value, paramCount - argCount).ToArray();
1787-
args = args.Take(argCount).Concat(missingArgs).Concat(value.ToEnumerable()).ToArray();
1788-
bindArgs = bindArgs.Take(argCount).Concat(missingArgs).Concat(bindArgs[bindArgs.Length - 1].ToEnumerable()).ToArray();
1795+
args = args.Take(argCount).Concat(missingArgs).Concat(EnumerableHelpers.ToEnumerable(value)).ToArray();
1796+
bindArgs = bindArgs.Take(argCount).Concat(missingArgs).Concat(EnumerableHelpers.ToEnumerable(bindArgs[bindArgs.Length - 1])).ToArray();
17891797
}
17901798

17911799
// ReSharper disable once SuspiciousTypeConversion.Global
@@ -1813,7 +1821,7 @@ private object SetHostPropertyWorker(PropertyInfo property, MethodInfo setMethod
18131821
}
18141822
}
18151823

1816-
if (property.PropertyType.IsAssignableFromValue(ref value))
1824+
if (property.PropertyType.IsAssignableFromValue(this, ref value))
18171825
{
18181826
args[args.Length - 1] = value;
18191827
InvokeHelpers.InvokeMethod(this, setMethod, Target.InvokeTarget, args, property.GetScriptMemberFlags(this));
@@ -1824,7 +1832,7 @@ private object SetHostPropertyWorker(PropertyInfo property, MethodInfo setMethod
18241832
// the property type. The latter has failed, so let's try the former.
18251833

18261834
var setParams = setMethod.GetParameters();
1827-
if ((setParams.Length >= args.Length) && (setParams[args.Length - 1].ParameterType.IsAssignableFromValue(ref value)))
1835+
if ((setParams.Length >= args.Length) && (setParams[args.Length - 1].ParameterType.IsAssignableFromValue(this, ref value)))
18281836
{
18291837
args[args.Length - 1] = value;
18301838
InvokeHelpers.InvokeMethod(this, setMethod, Target.InvokeTarget, args, property.GetScriptMemberFlags(this));
@@ -1853,7 +1861,7 @@ private object SetHostField(BindSignature signature, FieldInfo field, object[] a
18531861
private object SetHostFieldWorker(FieldInfo field, object[] args)
18541862
{
18551863
var value = args[0];
1856-
if (field.FieldType.IsAssignableFromValue(ref value))
1864+
if (field.FieldType.IsAssignableFromValue(this, ref value))
18571865
{
18581866
field.SetValue(Target.InvokeTarget, value);
18591867
return value;
@@ -2003,7 +2011,7 @@ public override bool TrySetIndex(SetIndexBinder binder, object[] indices, object
20032011

20042012
if (indices.Length > 1)
20052013
{
2006-
ThisDynamic.SetProperty(SpecialMemberNames.Default, indices.Concat(value.ToEnumerable()).ToArray());
2014+
ThisDynamic.SetProperty(SpecialMemberNames.Default, indices.Concat(EnumerableHelpers.ToEnumerable(value)).ToArray());
20072015
}
20082016

20092017
throw new InvalidOperationException("Invalid argument or index count");
@@ -2442,6 +2450,40 @@ public object Unwrap()
24422450

24432451
#endregion
24442452

2453+
#region IDisposableHostItem implementation
2454+
2455+
void IDisposableHostItem.Dispose()
2456+
{
2457+
HostInvoke(
2458+
static self =>
2459+
{
2460+
if (self.BindSpecialTarget(out IDisposable disposable))
2461+
{
2462+
disposable.Dispose();
2463+
}
2464+
},
2465+
this
2466+
);
2467+
}
2468+
2469+
object IDisposableHostItem.DisposeAsync()
2470+
{
2471+
return Engine.MarshalToScript(HostInvoke(
2472+
static self =>
2473+
{
2474+
if (self.BindSpecialTarget(out IAsyncDisposable asyncDisposable))
2475+
{
2476+
return asyncDisposable.DisposeAsync().ToPromise(self.Engine);
2477+
}
2478+
2479+
return Task.CompletedTask.ToPromise(self.Engine);
2480+
},
2481+
this
2482+
));
2483+
}
2484+
2485+
#endregion
2486+
24452487
#region IHostTargetContext implementation
24462488

24472489
public CustomAttributeLoader CustomAttributeLoader => CachedCustomAttributeLoader;

ClearScript/HostList.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public object this[int index]
6161

6262
set
6363
{
64-
if (!typeof(T).IsAssignableFromValue(ref value))
64+
if (!typeof(T).IsAssignableFromValue(engine, ref value))
6565
{
6666
throw new InvalidOperationException("Assignment invalid due to type mismatch");
6767
}

ClearScript/HostSettings.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,14 @@ public static CustomAttributeLoader CustomAttributeLoader
4949
get => customAttributeLoader ?? CustomAttributeLoader.Default;
5050
set => customAttributeLoader = value;
5151
}
52+
53+
/// <summary>
54+
/// Enables or disables interop assembly construction.
55+
/// </summary>
56+
/// <remarks>
57+
/// Setting this property to <c>true</c> disables the construction of interop assemblies
58+
/// at runtime. It is effective only on .NET Framework.
59+
/// </remarks>
60+
public static bool DisableInteropAssemblyConstruction { get; set; }
5261
}
5362
}

0 commit comments

Comments
 (0)