Skip to content

Commit

Permalink
Version 6.0.2: Fixed error handling in JavaScriptExtensions.ToPromise…
Browse files Browse the repository at this point in the history
…; added JavaScriptExtensions.ToTask (GitHub Issue #182); added DocumentLoader.MaxCacheSize and DocumentCategory.MaxCacheSize; added code to break event connections on engine disposal (GitHub Issue #183); improved ES6 module support, fixing cycle crash (GitHub Issue #181); added DynamicHostObject (GitHub Issue #180); added BigInt / BigInteger support for V8 (GitHub Issue #176); hardened Assembly.Load call in V8Proxy.cs (GitHub Issue #175); improved V8Update environment isolation to fix some V8 build issues (GitHub Issue #185); updated API documentation. Tested with V8 8.3.110.9.
  • Loading branch information
ClearScriptLib committed May 28, 2020
1 parent 18478cb commit ee1a5e3
Show file tree
Hide file tree
Showing 642 changed files with 2,916 additions and 1,057 deletions.
4 changes: 2 additions & 2 deletions ClearScript.NoV8.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp50</s:String>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Ecpp/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Eh/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/CalculateUnusedTypeMembers/@EntryValue">False</s:Boolean>
Expand All @@ -17,7 +16,6 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VBStringEndsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VBStringStartsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/JsInspections/LanguageLevel/@EntryValue">Experimental</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_PREPROCESSOR_IF/@EntryValue">DO_NOT_CHANGE</s:String>
Expand Down Expand Up @@ -136,6 +134,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=HRESULT/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=hwnd/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ijwhost/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=instanceof/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=INVALIDARG/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Invocability/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=invocable/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -146,6 +145,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=memid/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NETFRAMEWORK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NOINTERFACE/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Numerics/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=nupkg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=oleaut/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plex/@EntryIndexedValue">True</s:Boolean>
Expand Down
4 changes: 2 additions & 2 deletions ClearScript.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp50</s:String>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Ecpp/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Eh/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/CalculateUnusedTypeMembers/@EntryValue">False</s:Boolean>
Expand All @@ -17,7 +16,6 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VBStringEndsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VBStringStartsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/JsInspections/LanguageLevel/@EntryValue">Experimental</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_PREPROCESSOR_IF/@EntryValue">DO_NOT_CHANGE</s:String>
Expand Down Expand Up @@ -136,6 +134,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=HRESULT/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=hwnd/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ijwhost/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=instanceof/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=INVALIDARG/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Invocability/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=invocable/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -146,6 +145,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=memid/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NETFRAMEWORK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NOINTERFACE/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Numerics/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=nupkg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=oleaut/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plex/@EntryIndexedValue">True</s:Boolean>
Expand Down
6 changes: 2 additions & 4 deletions ClearScript/CanonicalRefTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Microsoft.ClearScript
{
internal static class CanonicalRefTable
{
private static readonly object tableLock = new object();
private static readonly Dictionary<Type, ICanonicalRefMap> table = new Dictionary<Type, ICanonicalRefMap>();

public static object GetCanonicalRef(object obj)
Expand All @@ -30,7 +29,7 @@ public static object GetCanonicalRef(object obj)
private static ICanonicalRefMap GetMap(object obj)
{
var type = obj.GetType();
lock (tableLock)
lock (table)
{
ICanonicalRefMap map;
if (!table.TryGetValue(type, out map))
Expand Down Expand Up @@ -81,7 +80,6 @@ private abstract class CanonicalRefMapBase : ICanonicalRefMap

private sealed class CanonicalRefMap<T> : CanonicalRefMapBase
{
private readonly object mapLock = new object();
private readonly Dictionary<T, WeakReference> map = new Dictionary<T, WeakReference>();
private DateTime lastCompactionTime = DateTime.MinValue;

Expand Down Expand Up @@ -126,7 +124,7 @@ private void CompactIfNecessary()

public override object GetRef(object obj)
{
lock (mapLock)
lock (map)
{
var result = GetRefInternal(obj);
CompactIfNecessary();
Expand Down
5 changes: 3 additions & 2 deletions ClearScript/ClearScript.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>5</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand All @@ -47,7 +46,6 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>5</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(SolutionDir)ClearScript.snk')">
<SignAssembly>true</SignAssembly>
Expand All @@ -64,10 +62,12 @@
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Numerics" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="CanonicalRefTable.cs" />
<Compile Include="DynamicHostMetaObject.cs" />
<Compile Include="HostItem.NetFramework.cs" />
<Compile Include="HostSettings.cs" />
<Compile Include="Document.cs" />
Expand Down Expand Up @@ -107,6 +107,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>AssemblyInfo.tt</DependentUpon>
</Compile>
<Compile Include="DynamicHostObject.cs" />
<Compile Include="ScriptAccess.cs" />
<Compile Include="ScriptEngineException.cs" />
<Compile Include="ScriptInterruptedException.cs" />
Expand Down
3 changes: 2 additions & 1 deletion ClearScript/DelegateFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ private static Delegate CreateSimpleDelegate(ScriptEngine engine, object target,
}
else
{
var typeArgs = paramTypes.Concat(new[] { method.ReturnType, delegateType }).ToArray();
// ReSharper disable once RedundantExplicitArrayCreation
var typeArgs = paramTypes.Concat(new Type[] { method.ReturnType, delegateType }).ToArray();
shimType = funcShimTemplates[paramTypes.Length].MakeSpecificType(typeArgs);
}

Expand Down
17 changes: 17 additions & 0 deletions ClearScript/DocumentCategory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,25 @@ public abstract class DocumentCategory
{
internal DocumentCategory()
{
MaxCacheSize = 1024;
}

/// <summary>
/// Gets or sets the maximum cache size for the document category.
/// </summary>
/// <remarks>
/// <para>
/// This property specifies the maximum number of prepared or compiled documents of the
/// current category to be cached by script engines. Its initial value is 1024.
/// </para>
/// <para>
/// Each script engine or runtime maintains private caches for supported document
/// categories. These are distinct from the caches used by document loaders.
/// </para>
/// </remarks>
/// <seealso cref="DocumentLoader.MaxCacheSize"/>
public uint MaxCacheSize { get; set; }

/// <summary>
/// Gets the document category for normal scripts.
/// </summary>
Expand Down
34 changes: 25 additions & 9 deletions ClearScript/DocumentLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ public static DocumentLoader Default
get { return DefaultImpl.Instance; }
}

/// <summary>
/// Gets or sets the maximum size of the document loader's cache.
/// </summary>
/// <remarks>
/// This property specifies the maximum number of documents to be cached by the document
/// loader. For the default document loader, its initial value is 1024.
/// </remarks>
/// <seealso cref="Default"/>
public virtual uint MaxCacheSize
{
get { return 0; }
set { throw new NotSupportedException("Loader does not support caching"); }
}

/// <summary>
/// Loads a document.
/// </summary>
Expand Down Expand Up @@ -99,7 +113,7 @@ public virtual void DiscardCachedDocuments()

#region Nested type: DefaultImpl

private class DefaultImpl : DocumentLoader
private sealed class DefaultImpl : DocumentLoader
{
public static readonly DefaultImpl Instance = new DefaultImpl();

Expand All @@ -111,12 +125,11 @@ private class DefaultImpl : DocumentLoader
".." + Path.AltDirectorySeparatorChar,
};

private readonly object cacheLock = new object();
private readonly List<Document> cache = new List<Document>();
private const int maxCacheSize = 1024;

private DefaultImpl()
{
MaxCacheSize = 1024;
}

private static async Task<List<Uri>> GetCandidateUrisAsync(DocumentSettings settings, DocumentInfo? sourceInfo, Uri uri)
Expand Down Expand Up @@ -310,7 +323,7 @@ private async Task<Document> LoadDocumentAsync(DocumentSettings settings, Uri ur
{
if (!flags.HasFlag(DocumentAccessFlags.EnableFileLoading))
{
throw new UnauthorizedAccessException("This script engine is not configured for loading documents from the file system");
throw new UnauthorizedAccessException("The script engine is not configured for loading documents from the file system");
}

using (var reader = new StreamReader(uri.LocalPath))
Expand All @@ -322,7 +335,7 @@ private async Task<Document> LoadDocumentAsync(DocumentSettings settings, Uri ur
{
if (!flags.HasFlag(DocumentAccessFlags.EnableWebLoading))
{
throw new UnauthorizedAccessException("This script engine is not configured for downloading documents from the Web");
throw new UnauthorizedAccessException("The script engine is not configured for downloading documents from the Web");
}

using (var client = new WebClient())
Expand All @@ -344,7 +357,7 @@ private async Task<Document> LoadDocumentAsync(DocumentSettings settings, Uri ur

private Document GetCachedDocument(Uri uri)
{
lock (cacheLock)
lock (cache)
{
for (var index = 0; index < cache.Count; index++)
{
Expand All @@ -363,7 +376,7 @@ private Document GetCachedDocument(Uri uri)

private Document CacheDocument(Document document)
{
lock (cacheLock)
lock (cache)
{
var cachedDocument = cache.FirstOrDefault(testDocument => testDocument.Info.Uri == document.Info.Uri);
if (cachedDocument != null)
Expand All @@ -372,6 +385,7 @@ private Document CacheDocument(Document document)
return cachedDocument;
}

var maxCacheSize = Math.Max(16, Convert.ToInt32(Math.Min(MaxCacheSize, int.MaxValue)));
while (cache.Count >= maxCacheSize)
{
cache.RemoveAt(cache.Count - 1);
Expand All @@ -384,14 +398,16 @@ private Document CacheDocument(Document document)

#region DocumentLoader overrides

public override uint MaxCacheSize { get; set; }

public override async Task<Document> LoadDocumentAsync(DocumentSettings settings, DocumentInfo? sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback)
{
MiscHelpers.VerifyNonNullArgument(settings, "settings");
MiscHelpers.VerifyNonBlankArgument(specifier, "specifier", "Invalid document specifier");

if ((settings.AccessFlags & DocumentAccessFlags.EnableAllLoading) == DocumentAccessFlags.None)
{
throw new UnauthorizedAccessException("This script engine is not configured for loading documents");
throw new UnauthorizedAccessException("The script engine is not configured for loading documents");
}

if (category == null)
Expand Down Expand Up @@ -461,7 +477,7 @@ public override async Task<Document> LoadDocumentAsync(DocumentSettings settings

public override void DiscardCachedDocuments()
{
lock (cacheLock)
lock (cache)
{
cache.Clear();
}
Expand Down
95 changes: 95 additions & 0 deletions ClearScript/DynamicHostMetaObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Collections.Generic;
using System.Dynamic;

namespace Microsoft.ClearScript
{
internal sealed class DynamicHostMetaObject : DynamicMetaObject
{
private readonly IDynamicMetaObjectProvider metaObjectProvider;
private readonly DynamicMetaObject metaObject;

public DynamicHostMetaObject(IDynamicMetaObjectProvider metaObjectProvider, DynamicMetaObject metaObject)
: base(metaObject.Expression, metaObject.Restrictions, metaObject.Value)
{
this.metaObjectProvider = metaObjectProvider;
this.metaObject = metaObject;
}

public bool HasMember(string name, bool ignoreCase)
{
return DynamicHostObject.HasMember(metaObjectProvider, metaObject, name, ignoreCase);
}

#region DynamicMetaObject overrides

public override IEnumerable<string> GetDynamicMemberNames()
{
return metaObject.GetDynamicMemberNames();
}

public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
{
return metaObject.BindBinaryOperation(binder, arg);
}

public override DynamicMetaObject BindConvert(ConvertBinder binder)
{
return metaObject.BindConvert(binder);
}

public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args)
{
return metaObject.BindCreateInstance(binder, args);
}

public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes)
{
return metaObject.BindDeleteIndex(binder, indexes);
}

public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
{
return metaObject.BindDeleteMember(binder);
}

public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
{
return metaObject.BindGetIndex(binder, indexes);
}

public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
{
return metaObject.BindGetMember(binder);
}

public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
{
return metaObject.BindInvoke(binder, args);
}

public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
return metaObject.BindInvokeMember(binder, args);
}

public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
{
return metaObject.BindSetIndex(binder, indexes, value);
}

public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
{
return metaObject.BindSetMember(binder, value);
}

public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder)
{
return metaObject.BindUnaryOperation(binder);
}

#endregion
}
}
Loading

0 comments on commit ee1a5e3

Please sign in to comment.