Version 6.0.1: Improved support for IIS least-privilege accounts (GitHub Issue #160); fixed 64-bit V8 initialization on Azure App Service (GitHub Issue #166); enabled DirectAccess for ComVisible .NET objects (GitHub Issue #161); added ScriptEngine.ExposeHostObjectStaticMembers (GitHub Issue #152); added ScriptEngine.UndefinedImportValue and made Undefined.Value public (GitHub Issue #154); enhanced ExtendedHostFunctions.typeLibEnums to pull in external enumerations; added thread affinity enforcement in WindowsScriptEngine.Dispose; eliminated KeyNotFoundException when checking for system documents (GitHub Issue #169); enabled the use of the application's root folder as a backup for its local data folder (GitHub Issue #171); reduced minimum CPU profile and heap size sampling intervals to 125 ms; updated deployment and API documentation, resolving GitHub Issues #158 and #159. Tested with V8 8.1.307.28.

This commit is contained in:
ClearScript 2020-04-13 11:29:36 -04:00
Родитель d2ff7caa1f
Коммит 19ca67c7a3
739 изменённых файлов: 4153 добавлений и 3102 удалений

Просмотреть файл

@ -123,6 +123,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=dispid/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dispids/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=DISPPARAMS/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ELEMDESC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=excep/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=EXCEPINFO/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Exprs/@EntryIndexedValue">True</s:Boolean>
@ -162,6 +163,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Steptype/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=sunspider/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEATTR/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEDESC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEFLAGS/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEKIND/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPELIBATTR/@EntryIndexedValue">True</s:Boolean>

Просмотреть файл

@ -123,6 +123,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=dispid/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dispids/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=DISPPARAMS/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ELEMDESC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=excep/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=EXCEPINFO/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Exprs/@EntryIndexedValue">True</s:Boolean>
@ -162,6 +163,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Steptype/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=sunspider/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEATTR/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEDESC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEFLAGS/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEKIND/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPELIBATTR/@EntryIndexedValue">True</s:Boolean>

Просмотреть файл

@ -58,9 +58,9 @@ namespace Microsoft.ClearScript
get { return target.DynamicInvokeTarget; }
}
public override HostTargetFlags Flags
public override HostTargetFlags GetFlags(IHostInvokeContext context)
{
get { return target.Flags; }
return target.GetFlags(context);
}
public override string[] GetAuxMethodNames(IHostInvokeContext context, BindingFlags bindFlags)

Просмотреть файл

@ -126,6 +126,7 @@
<Compile Include="Util\COM\DispatchMember.cs" />
<Compile Include="Util\COM\DispatchWrappers.cs" />
<Compile Include="Util\COM\HResult.cs" />
<Compile Include="Util\COM\StructHelpers.cs" />
<Compile Include="Util\COM\TypeInfoHelpers.cs" />
<Compile Include="Util\COM\TypeInfoHelpers.NetFramework.cs" />
<Compile Include="Util\COM\TypeLibHelpers.cs" />

Просмотреть файл

@ -136,7 +136,7 @@ namespace Microsoft.ClearScript
}
var uniqueName = manager.GetUniqueName(Name, Category.DefaultName);
if (Flags.GetValueOrDefault().HasFlag(DocumentFlags.IsTransient))
if (info.Flags.GetValueOrDefault().HasFlag(DocumentFlags.IsTransient))
{
uniqueName += " [temp]";
}

Просмотреть файл

@ -3,7 +3,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Microsoft.ClearScript.JavaScript;
@ -190,14 +189,13 @@ namespace Microsoft.ClearScript
private Document FindSystemDocument(string identifier, DocumentCategory category)
{
try
Document document;
if (systemDocumentMap.TryGetValue(Tuple.Create(identifier, category ?? DocumentCategory.Script), out document))
{
return systemDocumentMap[Tuple.Create(identifier, category ?? DocumentCategory.Script)];
}
catch (KeyNotFoundException)
{
return null;
return document;
}
return null;
}
}
}

Просмотреть файл

@ -5,5 +5,5 @@
#pragma once
#define CLEARSCRIPT_VERSION_STRING "6.0.0.0"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 6,0,0,0
#define CLEARSCRIPT_VERSION_STRING "6.0.1.0"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 6,0,1,0

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT license.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
@ -1647,13 +1646,20 @@ namespace Microsoft.ClearScript
}
/// <summary>
/// Imports enumerations from a type library.
/// Imports enumerations defined within or referenced from a COM/ActiveX type library.
/// </summary>
/// <typeparam name="T">The imported type whose parent library is to be searched for enumerations.</typeparam>
/// <typeparam name="T">The imported type whose parent library is to be searched for relevant enumerations.</typeparam>
/// <param name="obj">An instance of the representative type.</param>
/// <returns>A collection of imported enumerations.</returns>
public IPropertyBag typeLibEnums<T>(T obj) where T : class
/// <param name="collection">An optional host type collection with which to merge the imported enumerations.</param>
/// <returns>A host type collection: <paramref name="collection"/> if it is not <c>null</c>, a new host type collection otherwise.</returns>
public HostTypeCollection typeLibEnums<T>(T obj, HostTypeCollection collection = null) where T : class
{
MiscHelpers.VerifyNonNullArgument(obj, "obj");
if (collection == null)
{
collection = new HostTypeCollection();
}
var type = typeof(T);
if (type.IsUnknownCOMObject())
{
@ -1663,31 +1669,18 @@ namespace Microsoft.ClearScript
var typeInfo = dispatch.GetTypeInfo();
if (typeInfo != null)
{
return typeInfo.GetTypeLibEnums();
typeInfo.GetContainingTypeLib().GetReferencedEnums().ForEach(collection.AddEnumTypeInfo);
return collection;
}
}
throw new ArgumentException("Object type is not imported", "obj");
}
if (!type.IsImport)
else if (type.IsImport && (type.Assembly.GetCustomAttribute(typeof(ImportedFromTypeLibAttribute)) != null))
{
throw new ArgumentException("Object type is not imported", "obj");
type.Assembly.GetReferencedEnums().ForEach(collection.AddType);
return collection;
}
var typeCollection = new HostTypeCollection();
var assembly = type.Assembly;
Debug.Assert(assembly.GetCustomAttribute(typeof(ImportedFromTypeLibAttribute)) != null);
foreach (var assemblyType in assembly.GetTypes())
{
if (assemblyType.IsPublic && assemblyType.IsEnum)
{
typeCollection.AddType(assemblyType);
}
}
return typeCollection;
throw new ArgumentException("Object type is not imported", "obj");
}
// ReSharper restore InconsistentNaming

Просмотреть файл

@ -51,9 +51,9 @@ namespace Microsoft.ClearScript
get { return null; }
}
public override HostTargetFlags Flags
public override HostTargetFlags GetFlags(IHostInvokeContext context)
{
get { return HostTargetFlags.None; }
return HostTargetFlags.None;
}
public override string[] GetAuxMethodNames(IHostInvokeContext context, BindingFlags bindFlags)

Просмотреть файл

@ -53,7 +53,7 @@ namespace Microsoft.ClearScript
private object InvokeMethod(string name, Type[] typeArgs, object[] args, object[] bindArgs)
{
var bindResult = BindMethod(name, typeArgs, args, bindArgs);
if ((bindResult is MethodBindFailure) && target.Flags.HasFlag(HostTargetFlags.AllowExtensionMethods))
if ((bindResult is MethodBindFailure) && target.GetFlags(this).HasFlag(HostTargetFlags.AllowExtensionMethods))
{
var targetArg = target.Target.ToEnumerable();
var extensionArgs = targetArg.Concat(args).ToArray();
@ -108,17 +108,17 @@ namespace Microsoft.ClearScript
// WARNING: BindSignature holds on to the specified typeArgs; subsequent modification
// will result in bugs that are difficult to diagnose. Create a copy if necessary.
var signature = new BindSignature(accessContext, bindFlags, target, name, typeArgs, bindArgs);
var signature = new BindSignature(AccessContext, bindFlags, target, name, typeArgs, bindArgs);
MethodBindResult result;
object rawResult;
if (engine.TryGetCachedBindResult(signature, out rawResult))
{
result = MethodBindResult.Create(name, rawResult, target, args);
result = MethodBindResult.Create(name, bindFlags, rawResult, target, args);
}
else
{
result = BindMethodInternal(accessContext, bindFlags, target, name, typeArgs, args, bindArgs);
result = BindMethodInternal(AccessContext, bindFlags, target, name, typeArgs, args, bindArgs);
if (!result.IsPreferredMethod(this, name))
{
if (result is MethodBindSuccess)
@ -128,7 +128,7 @@ namespace Microsoft.ClearScript
foreach (var altName in GetAltMethodNames(name, bindFlags))
{
var altResult = BindMethodInternal(accessContext, bindFlags, target, altName, typeArgs, args, bindArgs);
var altResult = BindMethodInternal(AccessContext, bindFlags, target, altName, typeArgs, args, bindArgs);
if (altResult.IsUnblockedMethod(this))
{
result = altResult;
@ -163,7 +163,7 @@ namespace Microsoft.ClearScript
object rawResult;
if (coreBindCache.TryGetValue(signature, out rawResult))
{
result = MethodBindResult.Create(name, rawResult, target, args);
result = MethodBindResult.Create(name, bindFlags, rawResult, target, args);
}
else
{
@ -185,7 +185,7 @@ namespace Microsoft.ClearScript
// perform default binding
var rawResult = BindMethodRaw(bindFlags, binder, target, bindArgs);
var result = MethodBindResult.Create(name, rawResult, target, args);
var result = MethodBindResult.Create(name, bindFlags, rawResult, target, args);
if ((result is MethodBindFailure) && !(target is HostType) && target.Type.IsInterface)
{
// binding through interface failed; try base interfaces
@ -194,7 +194,7 @@ namespace Microsoft.ClearScript
var baseInterfaceTarget = HostObject.Wrap(target.InvokeTarget, interfaceType);
rawResult = BindMethodRaw(bindFlags, binder, baseInterfaceTarget, bindArgs);
var baseInterfaceResult = MethodBindResult.Create(name, rawResult, target, args);
var baseInterfaceResult = MethodBindResult.Create(name, bindFlags, rawResult, target, args);
if (baseInterfaceResult is MethodBindSuccess)
{
return baseInterfaceResult;
@ -205,7 +205,7 @@ namespace Microsoft.ClearScript
var objectTarget = HostObject.Wrap(target.InvokeTarget, typeof(object));
rawResult = BindMethodRaw(bindFlags, binder, objectTarget, bindArgs);
var objectResult = MethodBindResult.Create(name, rawResult, target, args);
var objectResult = MethodBindResult.Create(name, bindFlags, rawResult, target, args);
if (objectResult is MethodBindSuccess)
{
return objectResult;
@ -259,7 +259,7 @@ namespace Microsoft.ClearScript
private IEnumerable<string> GetAltMethodNamesInternal(string name, BindingFlags bindFlags)
{
foreach (var method in target.Type.GetScriptableMethods(name, bindFlags, accessContext, defaultAccess))
foreach (var method in target.Type.GetScriptableMethods(name, bindFlags, AccessContext, DefaultAccess))
{
var methodName = method.GetShortName();
if (methodName != name)
@ -326,7 +326,7 @@ namespace Microsoft.ClearScript
{
object state;
var rawResult = Type.DefaultBinder.BindToMethod(bindFlags, candidates, ref args, null, null, null, out state);
return MethodBindResult.Create(name, rawResult, hostTarget, args);
return MethodBindResult.Create(name, bindFlags, rawResult, hostTarget, args);
}
catch (MissingMethodException)
{
@ -368,7 +368,7 @@ namespace Microsoft.ClearScript
private IEnumerable<MethodInfo> GetReflectionCandidates(BindingFlags bindFlags, Type type, string name, Type[] typeArgs)
{
foreach (var method in type.GetScriptableMethods(name, bindFlags, accessContext, defaultAccess))
foreach (var method in type.GetScriptableMethods(name, bindFlags, AccessContext, DefaultAccess))
{
MethodInfo tempMethod = null;
@ -420,12 +420,12 @@ namespace Microsoft.ClearScript
private abstract class MethodBindResult
{
public static MethodBindResult Create(string name, object rawResult, HostTarget hostTarget, object[] args)
public static MethodBindResult Create(string name, BindingFlags bindFlags, object rawResult, HostTarget hostTarget, object[] args)
{
var method = rawResult as MethodInfo;
if (method != null)
{
if ((method.IsStatic) && !hostTarget.Flags.HasFlag(HostTargetFlags.AllowStaticMembers))
if (method.IsStatic && !bindFlags.HasFlag(BindingFlags.Static))
{
return new MethodBindFailure(() => new InvalidOperationException(MiscHelpers.FormatInvariant("Cannot access static method '{0}' in non-static context", method.Name)));
}

Просмотреть файл

@ -25,9 +25,6 @@ namespace Microsoft.ClearScript
private readonly ScriptEngine engine;
private readonly HostTarget target;
private readonly HostItemFlags flags;
private Type accessContext;
private ScriptAccess defaultAccess;
private HostTargetMemberData targetMemberData;
internal static bool EnableVTablePatching;
@ -141,7 +138,7 @@ namespace Microsoft.ClearScript
{
if (TargetInvocability == null)
{
TargetInvocability = target.GetInvocability(GetCommonBindFlags(), accessContext, defaultAccess, flags.HasFlag(HostItemFlags.HideDynamicMembers));
TargetInvocability = target.GetInvocability(GetCommonBindFlags(), AccessContext, DefaultAccess, flags.HasFlag(HostItemFlags.HideDynamicMembers));
}
return TargetInvocability.GetValueOrDefault();
@ -404,6 +401,48 @@ namespace Microsoft.ClearScript
set { targetMemberData.TargetInvocability = value; }
}
private Type CurrentAccessContext
{
get { return (flags.HasFlag(HostItemFlags.PrivateAccess) || (target.Type.IsAnonymous() && !engine.EnforceAnonymousTypeAccess)) ? target.Type : engine.AccessContext; }
}
private ScriptAccess CurrentDefaultAccess
{
get { return engine.DefaultAccess; }
}
private HostTargetFlags CurrentTargetFlags
{
get { return target.GetFlags(this); }
}
private Type CachedAccessContext
{
get
{
var targetMemberDataWithContext = targetMemberData as HostTargetMemberDataWithContext;
return (targetMemberDataWithContext != null) ? targetMemberDataWithContext.AccessContext : CurrentAccessContext;
}
}
private ScriptAccess CachedDefaultAccess
{
get
{
var targetMemberDataWithContext = targetMemberData as HostTargetMemberDataWithContext;
return (targetMemberDataWithContext) != null ? targetMemberDataWithContext.DefaultAccess : CurrentDefaultAccess;
}
}
private HostTargetFlags CachedTargetFlags
{
get
{
var targetMemberDataWithContext = targetMemberData as HostTargetMemberDataWithContext;
return (targetMemberDataWithContext) != null ? targetMemberDataWithContext.TargetFlags : CurrentTargetFlags;
}
}
#endregion
#region initialization
@ -531,14 +570,8 @@ namespace Microsoft.ClearScript
private void BindTargetMemberData()
{
var newAccessContext = flags.HasFlag(HostItemFlags.PrivateAccess) || (target.Type.IsAnonymous() && !engine.EnforceAnonymousTypeAccess) ? target.Type : engine.AccessContext;
var newDefaultAccess = engine.DefaultAccess;
if ((targetMemberData == null) || (accessContext != newAccessContext) || (defaultAccess != newDefaultAccess))
if ((targetMemberData == null) || (AccessContext != CurrentAccessContext) || (DefaultAccess != CurrentDefaultAccess) || (TargetFlags != CurrentTargetFlags))
{
accessContext = newAccessContext;
defaultAccess = newDefaultAccess;
if (target is HostMethod)
{
// host methods can share their (dummy) member data
@ -566,13 +599,13 @@ namespace Microsoft.ClearScript
if ((TargetDynamic == null) && (TargetPropertyBag == null) && (TargetList == null) && (TargetDynamicMetaObject == null))
{
// host objects without dynamic members can share their member data
targetMemberData = engine.GetSharedHostObjectMemberData(hostObject, accessContext, defaultAccess);
targetMemberData = engine.GetSharedHostObjectMemberData(hostObject, CurrentAccessContext, CurrentDefaultAccess, CurrentTargetFlags);
return;
}
}
// all other targets use unique member data
targetMemberData = new HostTargetMemberData();
targetMemberData = new HostTargetMemberDataWithContext(CurrentAccessContext, CurrentDefaultAccess, CurrentTargetFlags);
}
}
@ -635,7 +668,7 @@ namespace Microsoft.ClearScript
{
if (TypeEventNames == null)
{
var localEvents = target.Type.GetScriptableEvents(GetCommonBindFlags(), accessContext, defaultAccess);
var localEvents = target.Type.GetScriptableEvents(GetCommonBindFlags(), AccessContext, DefaultAccess);
TypeEventNames = localEvents.Select(eventInfo => eventInfo.GetScriptName()).ToArray();
}
@ -646,7 +679,7 @@ namespace Microsoft.ClearScript
{
if (TypeFieldNames == null)
{
var localFields = target.Type.GetScriptableFields(GetCommonBindFlags(), accessContext, defaultAccess);
var localFields = target.Type.GetScriptableFields(GetCommonBindFlags(), AccessContext, DefaultAccess);
TypeFieldNames = localFields.Select(field => field.GetScriptName()).ToArray();
}
@ -657,7 +690,7 @@ namespace Microsoft.ClearScript
{
if (TypeMethodNames == null)
{
var localMethods = target.Type.GetScriptableMethods(GetMethodBindFlags(), accessContext, defaultAccess);
var localMethods = target.Type.GetScriptableMethods(GetMethodBindFlags(), AccessContext, DefaultAccess);
TypeMethodNames = localMethods.Select(method => method.GetScriptName()).ToArray();
}
@ -668,7 +701,7 @@ namespace Microsoft.ClearScript
{
if (TypePropertyNames == null)
{
var localProperties = target.Type.GetScriptableProperties(GetCommonBindFlags(), accessContext, defaultAccess);
var localProperties = target.Type.GetScriptableProperties(GetCommonBindFlags(), AccessContext, DefaultAccess);
TypePropertyNames = localProperties.Select(property => property.GetScriptName()).ToArray();
}
@ -689,11 +722,11 @@ namespace Microsoft.ClearScript
{
ownMethodNames = null;
var names = target.GetAuxMethodNames(this, GetMethodBindFlags()).AsEnumerable();
var names = target.GetAuxMethodNames(this, GetMethodBindFlags()).AsEnumerable() ?? Enumerable.Empty<string>();
if ((TargetDynamic == null) && (TargetPropertyBag == null))
{
names = names.Concat(GetLocalMethodNames());
if (target.Flags.HasFlag(HostTargetFlags.AllowExtensionMethods))
if (TargetFlags.HasFlag(HostTargetFlags.AllowExtensionMethods))
{
var extensionMethodSummary = engine.ExtensionMethodSummary;
ExtensionMethodSummary = extensionMethodSummary;
@ -718,7 +751,7 @@ namespace Microsoft.ClearScript
private string[] GetAllPropertyNames()
{
var names = target.GetAuxPropertyNames(this, GetCommonBindFlags()).AsEnumerable();
var names = target.GetAuxPropertyNames(this, GetCommonBindFlags()).AsEnumerable() ?? Enumerable.Empty<string>();
if (TargetDynamic != null)
{
names = names.Concat(TargetDynamic.GetPropertyNames());
@ -771,7 +804,7 @@ namespace Microsoft.ClearScript
private void UpdateMethodNames(out bool updated)
{
if ((AllMethodNames == null) ||
(target.Flags.HasFlag(HostTargetFlags.AllowExtensionMethods) && (ExtensionMethodSummary != engine.ExtensionMethodSummary)))
(TargetFlags.HasFlag(HostTargetFlags.AllowExtensionMethods) && (ExtensionMethodSummary != engine.ExtensionMethodSummary)))
{
string[] ownMethodNames;
AllMethodNames = GetAllMethodNames(out ownMethodNames);
@ -847,12 +880,12 @@ namespace Microsoft.ClearScript
{
var bindFlags = BindingFlags.Public | BindingFlags.NonPublic;
if (target.Flags.HasFlag(HostTargetFlags.AllowStaticMembers))
if (TargetFlags.HasFlag(HostTargetFlags.AllowStaticMembers))
{
bindFlags |= BindingFlags.Static;
bindFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy;
}
if (target.Flags.HasFlag(HostTargetFlags.AllowInstanceMembers))
if (TargetFlags.HasFlag(HostTargetFlags.AllowInstanceMembers))
{
bindFlags |= BindingFlags.Instance;
}
@ -890,16 +923,16 @@ namespace Microsoft.ClearScript
invokeFlags |= onFlags;
invokeFlags &= ~offFlags;
if (target.Flags.HasFlag(HostTargetFlags.AllowStaticMembers))
if (TargetFlags.HasFlag(HostTargetFlags.AllowStaticMembers))
{
invokeFlags |= BindingFlags.Static;
invokeFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy;
}
else
{
invokeFlags &= ~BindingFlags.Static;
}
if (target.Flags.HasFlag(HostTargetFlags.AllowInstanceMembers))
if (TargetFlags.HasFlag(HostTargetFlags.AllowInstanceMembers))
{
invokeFlags |= BindingFlags.Instance;
}
@ -1237,7 +1270,7 @@ namespace Microsoft.ClearScript
return DelegateFactory.CreateDelegate(engine, args[0], specificType);
}
return specificType.CreateInstance(accessContext, defaultAccess, args);
return specificType.CreateInstance(AccessContext, DefaultAccess, args);
}
}
@ -1257,7 +1290,7 @@ namespace Microsoft.ClearScript
return DelegateFactory.CreateDelegate(engine, args[0], type);
}
return type.CreateInstance(accessContext, defaultAccess, args);
return type.CreateInstance(AccessContext, DefaultAccess, args);
}
if (TargetDynamicMetaObject != null)
@ -1399,7 +1432,7 @@ namespace Microsoft.ClearScript
if (name == SpecialMemberNames.Default)
{
var defaultProperty = target.Type.GetScriptableDefaultProperty(invokeFlags, bindArgs, accessContext, defaultAccess);
var defaultProperty = target.Type.GetScriptableDefaultProperty(invokeFlags, bindArgs, AccessContext, DefaultAccess);
if (defaultProperty != null)
{
return GetHostProperty(defaultProperty, invokeFlags, args, culture);
@ -1495,7 +1528,7 @@ namespace Microsoft.ClearScript
}
}
var property = target.Type.GetScriptableProperty(name, invokeFlags, bindArgs, accessContext, defaultAccess);
var property = target.Type.GetScriptableProperty(name, invokeFlags, bindArgs, AccessContext, DefaultAccess);
if (property != null)
{
return GetHostProperty(property, invokeFlags, args, culture);
@ -1506,7 +1539,7 @@ namespace Microsoft.ClearScript
throw new MissingMemberException(MiscHelpers.FormatInvariant("Object has no suitable property named '{0}'", name));
}
var eventInfo = target.Type.GetScriptableEvent(name, invokeFlags, accessContext, defaultAccess);
var eventInfo = target.Type.GetScriptableEvent(name, invokeFlags, AccessContext, DefaultAccess);
if (eventInfo != null)
{
var type = typeof(EventSource<>).MakeSpecificType(eventInfo.EventHandlerType);
@ -1514,7 +1547,7 @@ namespace Microsoft.ClearScript
return type.CreateInstance(BindingFlags.NonPublic, engine, target.InvokeTarget, eventInfo);
}
var field = target.Type.GetScriptableField(name, invokeFlags, accessContext, defaultAccess);
var field = target.Type.GetScriptableField(name, invokeFlags, AccessContext, DefaultAccess);
if (field != null)
{
var result = field.GetValue(target.InvokeTarget);
@ -1524,7 +1557,7 @@ namespace Microsoft.ClearScript
if (includeBoundMembers)
{
if (target.Type.GetScriptableProperties(name, invokeFlags, accessContext, defaultAccess).Any())
if (target.Type.GetScriptableProperties(name, invokeFlags, AccessContext, DefaultAccess).Any())
{
if (HostIndexedPropertyMap == null)
{
@ -1572,7 +1605,7 @@ namespace Microsoft.ClearScript
}
var getMethod = property.GetMethod;
if ((getMethod == null) || !getMethod.IsAccessible(accessContext) || getMethod.IsBlockedFromScript(defaultAccess, false))
if ((getMethod == null) || !getMethod.IsAccessible(AccessContext) || getMethod.IsBlockedFromScript(DefaultAccess, false))
{
throw new UnauthorizedAccessException("Property get method is unavailable or inaccessible");
}
@ -1592,7 +1625,7 @@ namespace Microsoft.ClearScript
object result;
var defaultProperty = target.Type.GetScriptableDefaultProperty(invokeFlags, bindArgs.Take(bindArgs.Length - 1).ToArray(), accessContext, defaultAccess);
var defaultProperty = target.Type.GetScriptableDefaultProperty(invokeFlags, bindArgs.Take(bindArgs.Length - 1).ToArray(), AccessContext, DefaultAccess);
if (defaultProperty != null)
{
return SetHostProperty(defaultProperty, invokeFlags, args, culture);
@ -1645,18 +1678,18 @@ namespace Microsoft.ClearScript
throw new InvalidOperationException("Invalid argument count");
}
var property = target.Type.GetScriptableProperty(name, invokeFlags, bindArgs.Take(bindArgs.Length - 1).ToArray(), accessContext, defaultAccess);
var property = target.Type.GetScriptableProperty(name, invokeFlags, bindArgs.Take(bindArgs.Length - 1).ToArray(), AccessContext, DefaultAccess);
if (property != null)
{
return SetHostProperty(property, invokeFlags, args, culture);
}
var field = target.Type.GetScriptableField(name, invokeFlags, accessContext, defaultAccess);
var field = target.Type.GetScriptableField(name, invokeFlags, AccessContext, DefaultAccess);
if (field != null)
{
if (args.Length == 1)
{
if (field.IsLiteral || field.IsInitOnly || field.IsReadOnlyForScript(defaultAccess))
if (field.IsLiteral || field.IsInitOnly || field.IsReadOnlyForScript(DefaultAccess))
{
throw new UnauthorizedAccessException("Field is read-only");
}
@ -1679,13 +1712,13 @@ namespace Microsoft.ClearScript
private object SetHostProperty(PropertyInfo property, BindingFlags invokeFlags, object[] args, CultureInfo culture)
{
if (property.IsReadOnlyForScript(defaultAccess))
if (property.IsReadOnlyForScript(DefaultAccess))
{
throw new UnauthorizedAccessException("Property is read-only");
}
var setMethod = property.SetMethod;
if ((setMethod == null) || !setMethod.IsAccessible(accessContext) || setMethod.IsBlockedFromScript(defaultAccess, false))
if ((setMethod == null) || !setMethod.IsAccessible(AccessContext) || setMethod.IsBlockedFromScript(DefaultAccess, false))
{
throw new UnauthorizedAccessException("Property set method is unavailable or inaccessible");
}
@ -2206,11 +2239,6 @@ namespace Microsoft.ClearScript
get { return engine; }
}
public Type AccessContext
{
get { return accessContext; }
}
public object Unwrap()
{
return target.Target;
@ -2220,9 +2248,19 @@ namespace Microsoft.ClearScript
#region IHostInvokeContext implementation
public Type AccessContext
{
get { return CachedAccessContext; }
}
public ScriptAccess DefaultAccess
{
get { return defaultAccess; }
get { return CachedDefaultAccess; }
}
public HostTargetFlags TargetFlags
{
get { return CachedTargetFlags; }
}
#endregion

Просмотреть файл

@ -38,7 +38,8 @@ namespace Microsoft.ClearScript
/// Specifies that the script engine is to be given direct access to the exposed object if
/// possible. This option, when supported, suppresses marshaling and hands off the object
/// for script access without the host's involvement. It is currently supported only for
/// COM objects exposed in Windows Script engines.
/// COM and <see href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.comvisibleattribute">COM-visible</see>
/// objects exposed in Windows Script engines.
/// </summary>
DirectAccess = 0x00000008
}

Просмотреть файл

@ -49,9 +49,9 @@ namespace Microsoft.ClearScript
get { return null; }
}
public override HostTargetFlags Flags
public override HostTargetFlags GetFlags(IHostInvokeContext context)
{
get { return HostTargetFlags.None; }
return HostTargetFlags.None;
}
public override bool TryInvoke(IHostInvokeContext context, BindingFlags invokeFlags, object[] args, object[] bindArgs, out object result)

Просмотреть файл

@ -139,9 +139,15 @@ namespace Microsoft.ClearScript
get { return target; }
}
public override HostTargetFlags Flags
public override HostTargetFlags GetFlags(IHostInvokeContext context)
{
get { return HostTargetFlags.AllowInstanceMembers | HostTargetFlags.AllowExtensionMethods; }
var flags = HostTargetFlags.AllowInstanceMembers | HostTargetFlags.AllowExtensionMethods;
if (context.Engine.ExposeHostObjectStaticMembers)
{
flags |= HostTargetFlags.AllowStaticMembers;
}
return flags;
}
public override Invocability GetInvocability(BindingFlags bindFlags, Type accessContext, ScriptAccess defaultAccess, bool ignoreDynamic)

Просмотреть файл

@ -17,7 +17,7 @@ namespace Microsoft.ClearScript
public abstract object DynamicInvokeTarget { get; }
public abstract HostTargetFlags Flags { get; }
public abstract HostTargetFlags GetFlags(IHostInvokeContext context);
public virtual string[] GetAuxMethodNames(IHostInvokeContext context, BindingFlags bindFlags)
{

Просмотреть файл

@ -28,15 +28,17 @@ namespace Microsoft.ClearScript
public Invocability? TargetInvocability;
}
internal sealed class SharedHostObjectMemberData : HostTargetMemberData
internal class HostTargetMemberDataWithContext : HostTargetMemberData
{
public readonly Type AccessContext;
public readonly ScriptAccess DefaultAccess;
public readonly HostTargetFlags TargetFlags;
public SharedHostObjectMemberData(Type accessContext, ScriptAccess defaultAccess)
public HostTargetMemberDataWithContext(Type accessContext, ScriptAccess defaultAccess, HostTargetFlags targetFlags)
{
AccessContext = accessContext;
DefaultAccess = defaultAccess;
TargetFlags = targetFlags;
}
}
}

Просмотреть файл

@ -156,13 +156,10 @@ namespace Microsoft.ClearScript
get { return GetSpecificType(); }
}
public override HostTargetFlags Flags
public override HostTargetFlags GetFlags(IHostInvokeContext context)
{
get
{
var type = GetSpecificTypeNoThrow();
return (type != null) ? HostTargetFlags.AllowStaticMembers : HostTargetFlags.None;
}
var type = GetSpecificTypeNoThrow();
return (type != null) ? HostTargetFlags.AllowStaticMembers : HostTargetFlags.None;
}
public override string[] GetAuxPropertyNames(IHostInvokeContext context, BindingFlags bindFlags)

Просмотреть файл

@ -5,7 +5,11 @@ using System;
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;
using TYPEKIND = System.Runtime.InteropServices.ComTypes.TYPEKIND;
namespace Microsoft.ClearScript
{
@ -185,12 +189,105 @@ namespace Microsoft.ClearScript
return namespaceNode;
}
internal void AddEnumTypeInfo(ITypeInfo typeInfo)
{
AddEnumTypeInfoInternal(typeInfo);
}
private PropertyBag AddEnumTypeInfoInternal(ITypeInfo typeInfo)
{
using (var attrScope = typeInfo.CreateAttrScope())
{
if (attrScope.Value.typekind == TYPEKIND.TKIND_ALIAS)
{
ITypeInfo refTypeInfo;
typeInfo.GetRefTypeInfo(unchecked((int)attrScope.Value.tdescAlias.lpValue.ToInt64()), out refTypeInfo);
var node = AddEnumTypeInfoInternal(refTypeInfo);
if (node != null)
{
var locator = typeInfo.GetManagedName();
var segments = locator.Split('.');
if (segments.Length > 0)
{
var namespaceNode = GetOrCreateNamespaceNode(locator);
if (namespaceNode != null)
{
namespaceNode.SetPropertyNoCheck(segments.Last(), node);
return node;
}
}
}
}
else if (attrScope.Value.typekind == TYPEKIND.TKIND_ENUM)
{
var node = GetOrCreateEnumTypeInfoNode(typeInfo);
if (node != null)
{
var count = attrScope.Value.cVars;
for (var index = 0; index < count; index++)
{
using (var varDescScope = typeInfo.CreateVarDescScope(index))
{
if (varDescScope.Value.varkind == VARKIND.VAR_CONST)
{
var name = typeInfo.GetMemberName(varDescScope.Value.memid);
node.SetPropertyNoCheck(name, Marshal.GetObjectForNativeVariant(varDescScope.Value.desc.lpvarValue));
}
}
}
return node;
}
}
}
return null;
}
private PropertyBag GetOrCreateEnumTypeInfoNode(ITypeInfo typeInfo)
{
var locator = typeInfo.GetManagedName();
var segments = locator.Split('.');
if (segments.Length < 1)
{
return null;
}
PropertyBag enumTypeInfoNode = this;
foreach (var segment in segments)
{
PropertyBag innerNode;
object node;
if (!enumTypeInfoNode.TryGetValue(segment, out node))
{
innerNode = new PropertyBag(true);
enumTypeInfoNode.SetPropertyNoCheck(segment, innerNode);
}
else
{
innerNode = node as PropertyBag;
if (innerNode == null)
{
throw new OperationCanceledException(MiscHelpers.FormatInvariant("Enumeration conflicts with '{0}' at '{1}'", node.GetFriendlyName(), locator));
}
}
enumTypeInfoNode = innerNode;
}
return enumTypeInfoNode;
}
private void AddType(HostType hostType)
{
MiscHelpers.VerifyNonNullArgument(hostType, "hostType");
foreach (var type in hostType.Types)
{
var namespaceNode = GetNamespaceNode(type);
var namespaceNode = GetOrCreateNamespaceNode(type);
if (namespaceNode != null)
{
AddTypeToNamespaceNode(namespaceNode, type);
@ -198,10 +295,13 @@ namespace Microsoft.ClearScript
}
}
private PropertyBag GetNamespaceNode(Type type)
private PropertyBag GetOrCreateNamespaceNode(Type type)
{
var locator = type.GetLocator();
return GetOrCreateNamespaceNode(type.GetLocator());
}
private PropertyBag GetOrCreateNamespaceNode(string locator)
{
var segments = locator.Split('.');
if (segments.Length < 1)
{

Просмотреть файл

@ -89,9 +89,15 @@ namespace Microsoft.ClearScript
get { return value; }
}
public override HostTargetFlags Flags
public override HostTargetFlags GetFlags(IHostInvokeContext context)
{
get { return HostTargetFlags.AllowInstanceMembers | HostTargetFlags.AllowExtensionMethods; }
var flags = HostTargetFlags.AllowInstanceMembers | HostTargetFlags.AllowExtensionMethods;
if (context.Engine.ExposeHostObjectStaticMembers)
{
flags |= HostTargetFlags.AllowStaticMembers;
}
return flags;
}
public override bool TryInvokeAuxMember(IHostInvokeContext context, string name, BindingFlags invokeFlags, object[] args, object[] bindArgs, out object result)

Просмотреть файл

@ -17,14 +17,14 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ClearScriptTest")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.0.0")]
[assembly: AssemblyVersion("6.0.1.0")]
[assembly: AssemblyFileVersion("6.0.1.0")]
namespace Microsoft.ClearScript.Properties
{
internal static class ClearScriptVersion
{
public const string Value = "6.0.0.0";
public const string Triad = "6.0.0";
public const string Value = "6.0.1.0";
public const string Triad = "6.0.1";
}
}

Просмотреть файл

@ -22,6 +22,8 @@ namespace Microsoft.ClearScript
private Type accessContext;
private ScriptAccess defaultAccess;
private bool enforceAnonymousTypeAccess;
private bool exposeHostObjectStaticMembers;
private object undefinedImportValue = Undefined.Value;
private DocumentSettings documentSettings;
private readonly DocumentSettings defaultDocumentSettings = new DocumentSettings();
@ -148,6 +150,19 @@ namespace Microsoft.ClearScript
}
}
/// <summary>
/// Controls whether host objects provide access to the static members of their exposed types to script code.
/// </summary>
public bool ExposeHostObjectStaticMembers
{
get { return exposeHostObjectStaticMembers; }
set
{
exposeHostObjectStaticMembers = value;
OnAccessSettingsChanged();
}
}
/// <summary>
/// Enables or disables script code formatting.
/// </summary>
@ -237,6 +252,21 @@ namespace Microsoft.ClearScript
/// <seealso cref="HostFunctions.newVar{T}(T)"/>
public bool EnableAutoHostVariables { get; set; }
/// <summary>
/// Gets or sets the engine's undefined import value.
/// </summary>
/// <remarks>
/// 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
/// <see cref="Undefined.Value"/>.
/// </remarks>
public object UndefinedImportValue
{
get { return undefinedImportValue; }
set { undefinedImportValue = value; }
}
/// <summary>
/// Gets or sets a callback that can be used to halt script execution.
/// </summary>
@ -969,7 +999,8 @@ namespace Microsoft.ClearScript
/// <para>
/// If a debugger is attached, it will present the specified script code to the user as a
/// document with the specified name. Discarding this document removes it from view but
/// has no effect on the script engine.
/// has no effect on the script engine. Only Windows Script engines honor
/// <paramref name="discard"/>.
/// </para>
/// </remarks>
public void Execute(string documentName, bool discard, string code)
@ -1124,7 +1155,8 @@ namespace Microsoft.ClearScript
/// <para>
/// If a debugger is attached, it will present the specified script code to the user as a
/// document with the specified name. Discarding this document removes it from view but
/// has no effect on the script engine.
/// has no effect on the script engine. Only Windows Script engines honor
/// <paramref name="discard"/>.
/// </para>
/// <para>
/// The following table summarizes the types of result values that script code can return.
@ -1786,7 +1818,7 @@ namespace Microsoft.ClearScript
private readonly ConditionalWeakTable<Type, List<WeakReference>> sharedHostObjectMemberDataCache = new ConditionalWeakTable<Type, List<WeakReference>>();
internal HostTargetMemberData GetSharedHostObjectMemberData(HostObject target, Type targetAccessContext, ScriptAccess targetDefaultAccess)
internal HostTargetMemberData GetSharedHostObjectMemberData(HostObject target, Type targetAccessContext, ScriptAccess targetDefaultAccess, HostTargetFlags targetFlags)
{
var cacheEntry = sharedHostObjectMemberDataCache.GetOrCreateValue(target.Type);
@ -1795,14 +1827,14 @@ namespace Microsoft.ClearScript
foreach (var weakRef in cacheEntry)
{
var memberData = weakRef.Target as SharedHostObjectMemberData;
var memberData = weakRef.Target as HostTargetMemberDataWithContext;
if (memberData == null)
{
staleWeakRefCount++;
}
else
{
if ((memberData.AccessContext == targetAccessContext) && (memberData.DefaultAccess == targetDefaultAccess))
if ((memberData.AccessContext == targetAccessContext) && (memberData.DefaultAccess == targetDefaultAccess) && (memberData.TargetFlags == targetFlags))
{
return memberData;
}
@ -1826,7 +1858,7 @@ namespace Microsoft.ClearScript
}
}
var newMemberData = new SharedHostObjectMemberData(targetAccessContext, targetDefaultAccess);
var newMemberData = new HostTargetMemberDataWithContext(targetAccessContext, targetDefaultAccess, targetFlags);
cacheEntry.Add(new WeakReference(newMemberData));
return newMemberData;
}

Просмотреть файл

@ -55,9 +55,9 @@ namespace Microsoft.ClearScript
get { return null; }
}
public override HostTargetFlags Flags
public override HostTargetFlags GetFlags(IHostInvokeContext context)
{
get { return HostTargetFlags.None; }
return HostTargetFlags.None;
}
public override bool TryInvoke(IHostInvokeContext context, BindingFlags invokeFlags, object[] args, object[] bindArgs, out object result)

Просмотреть файл

@ -7,13 +7,16 @@ namespace Microsoft.ClearScript
/// Represents an undefined value.
/// </summary>
/// <remarks>
/// Most script languages support one or more special values that represent nonexistent,
/// missing, unknown, or undefined data. The ClearScript library maps some such values to
/// <c>null</c>, and others to instances of this class.
/// Some script languages support one or more special non-<c>null</c> values that represent
/// nonexistent, missing, unknown, or undefined data. The ClearScript library maps such values
/// to instances of this class.
/// </remarks>
public class Undefined
{
internal static readonly Undefined Value = new Undefined();
/// <summary>
/// The sole instance of the <see cref="Undefined"/> class.
/// </summary>
public static readonly Undefined Value = new Undefined();
private Undefined()
{

Просмотреть файл

@ -47,6 +47,19 @@ namespace Microsoft.ClearScript.Util
{
return assemblyName.FullName;
}
IEnumerable<string> subDirPaths;
if (MiscHelpers.Try(out subDirPaths, () => Directory.EnumerateDirectories(dirPath, "*", SearchOption.AllDirectories)))
{
foreach (var subDirPath in subDirPaths)
{
path = Path.Combine(subDirPath, fileName);
if (File.Exists(path) && MiscHelpers.Try(out assemblyName, () => AssemblyName.GetAssemblyName(path)))
{
return assemblyName.FullName;
}
}
}
}
return name;
@ -94,5 +107,146 @@ namespace Microsoft.ClearScript.Util
return false;
}
public static IEnumerable<Type> GetReferencedEnums(this Assembly assembly)
{
var processedTypes = new HashSet<Type>();
return assembly.GetAllTypes().SelectMany(type => GetReferencedEnums(assembly, type, processedTypes));
}
private static IEnumerable<Type> GetReferencedEnums(Assembly assembly, Type type, HashSet<Type> processedTypes)
{
if ((type == null) || !type.IsVisible || type.ContainsGenericParameters || processedTypes.Contains(type))
{
yield break;
}
processedTypes.Add(type);
if (type.IsEnum)
{
yield return type;
yield break;
}
foreach (var enumType in GetReferencedEnums(assembly, type.GetElementType(), processedTypes))
{
yield return enumType;
}
foreach (var enumType in type.GetGenericArguments().SelectMany(argType => GetReferencedEnums(assembly, argType, processedTypes)))
{
yield return enumType;
}
foreach (var enumType in GetReferencedEnums(assembly, type.BaseType, processedTypes))
{
yield return enumType;
}
foreach (var enumType in type.GetInterfaces().SelectMany(interfaceType => GetReferencedEnums(assembly, interfaceType, processedTypes)))
{
yield return enumType;
}
if (type.Assembly == assembly)
{
foreach (var enumType in type.GetMembers().SelectMany(member => GetReferencedEnums(assembly, member, processedTypes)))
{
yield return enumType;
}
}
}
private static IEnumerable<Type> GetReferencedEnums(Assembly assembly, MemberInfo member, HashSet<Type> processedTypes)
{
if (member == null)
{
return Enumerable.Empty<Type>();
}
if (member.MemberType == MemberTypes.Field)
{
return GetReferencedEnums(assembly, (FieldInfo)member, processedTypes);
}
if (member.MemberType == MemberTypes.Property)
{
return GetReferencedEnums(assembly, (PropertyInfo)member, processedTypes);
}
if (member.MemberType == MemberTypes.Method)
{
return GetReferencedEnums(assembly, (MethodInfo)member, processedTypes);
}
if (member.MemberType == MemberTypes.NestedType)
{
return GetReferencedEnums(assembly, (Type)member, processedTypes);
}
return Enumerable.Empty<Type>();
}
private static IEnumerable<Type> GetReferencedEnums(Assembly assembly, FieldInfo field, HashSet<Type> processedTypes)
{
if (field == null)
{
return Enumerable.Empty<Type>();
}
return GetReferencedEnums(assembly, field.FieldType, processedTypes);
}
private static IEnumerable<Type> GetReferencedEnums(Assembly assembly, PropertyInfo property, HashSet<Type> processedTypes)
{
if (property == null)
{
yield break;
}
foreach (var enumType in GetReferencedEnums(assembly, property.PropertyType, processedTypes))
{
yield return enumType;
}
foreach (var enumType in GetReferencedEnums(assembly, property.GetMethod, processedTypes))
{
yield return enumType;
}
foreach (var enumType in GetReferencedEnums(assembly, property.SetMethod, processedTypes))
{
yield return enumType;
}
}
private static IEnumerable<Type> GetReferencedEnums(Assembly assembly, MethodInfo method, HashSet<Type> processedTypes)
{
if (method == null)
{
yield break;
}
foreach (var enumType in GetReferencedEnums(assembly, method.ReturnParameter, processedTypes))
{
yield return enumType;
}
foreach (var enumType in method.GetParameters().SelectMany(param => GetReferencedEnums(assembly, param, processedTypes)))
{
yield return enumType;
}
}
private static IEnumerable<Type> GetReferencedEnums(Assembly assembly, ParameterInfo param, HashSet<Type> processedTypes)
{
if (param == null)
{
return Enumerable.Empty<Type>();
}
return GetReferencedEnums(assembly, param.ParameterType, processedTypes);
}
}
}

Просмотреть файл

@ -36,66 +36,49 @@ namespace Microsoft.ClearScript.Util
public static string GetFullAssemblyNameImpl(string name)
{
string fullName;
return ((table != null) && table.TryGetValue(name, out fullName)) ? fullName : name;
return ((table != null) && table.TryGetValue(name, out fullName)) ? fullName : AssemblyHelpers.GetFullAssemblyName(name);
}
private static void LoadAssemblyTable()
{
// ReSharper disable EmptyGeneralCatchClause
string filePath = null;
try
if (!ReadAssemblyTable() && BuildAssemblyTable())
{
var dirPath = Path.Combine(MiscHelpers.GetLocalDataRootPath(), GetRuntimeVersionDirectoryName());
Directory.CreateDirectory(dirPath);
filePath = Path.Combine(dirPath, "AssemblyTable.bin");
if (File.Exists(filePath))
{
try
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var formatter = new BinaryFormatter();
table = (ConcurrentDictionary<string, string>)formatter.Deserialize(stream);
}
}
catch (Exception)
{
}
}
WriteAssemblyTable();
}
catch (Exception)
{
}
if (table == null)
{
BuildAssemblyTable();
if ((table != null) && (filePath != null))
{
try
{
using (var stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, table);
}
}
catch (Exception)
{
}
}
}
// ReSharper restore EmptyGeneralCatchClause
}
private static void BuildAssemblyTable()
private static bool ReadAssemblyTable()
{
// ReSharper disable EmptyGeneralCatchClause
bool usingAppPath;
if (ReadAssemblyTable(MiscHelpers.GetLocalDataRootPath(out usingAppPath)))
{
return true;
}
try
return !usingAppPath && ReadAssemblyTable(MiscHelpers.GetLocalDataRootPath(AppDomain.CurrentDomain.BaseDirectory));
}
private static bool ReadAssemblyTable(string rootPath)
{
var succeeded = MiscHelpers.Try(() =>
{
var filePath = GetFilePath(rootPath);
if (File.Exists(filePath))
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var formatter = new BinaryFormatter();
table = (ConcurrentDictionary<string, string>)formatter.Deserialize(stream);
}
}
});
return succeeded && (table != null);
}
private static bool BuildAssemblyTable()
{
var succeeded = MiscHelpers.Try(() =>
{
var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\.NETFramework");
if (key != null)
@ -105,22 +88,47 @@ namespace Microsoft.ClearScript.Util
table = new ConcurrentDictionary<string, string>();
foreach (var filePath in Directory.EnumerateFiles(dirPath, "*.dll", SearchOption.AllDirectories))
{
try
var path = filePath;
MiscHelpers.Try(() =>
{
var assemblyName = Assembly.ReflectionOnlyLoadFrom(filePath).GetName();
var assemblyName = Assembly.ReflectionOnlyLoadFrom(path).GetName();
table.TryAdd(assemblyName.Name, assemblyName.FullName);
}
catch (Exception)
{
}
});
}
}
}
catch (Exception)
{
}
});
// ReSharper restore EmptyGeneralCatchClause
return succeeded && (table != null);
}
private static void WriteAssemblyTable()
{
bool usingAppPath;
if (!WriteAssemblyTable(MiscHelpers.GetLocalDataRootPath(out usingAppPath)) && !usingAppPath)
{
WriteAssemblyTable(MiscHelpers.GetLocalDataRootPath(AppDomain.CurrentDomain.BaseDirectory));
}
}
private static bool WriteAssemblyTable(string rootPath)
{
return MiscHelpers.Try(() =>
{
var filePath = GetFilePath(rootPath);
using (var stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, table);
}
});
}
private static string GetFilePath(string rootPath)
{
var dirPath = Path.Combine(rootPath, GetRuntimeVersionDirectoryName());
Directory.CreateDirectory(dirPath);
return Path.Combine(dirPath, "AssemblyTable.bin");
}
private static string GetRuntimeVersionDirectoryName()

Просмотреть файл

@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Microsoft.ClearScript.Util.COM
{
internal static class StructHelpers
{
public delegate void GetStruct(out IntPtr pStruct);
public delegate void ReleaseStruct(IntPtr pStruct);
public static IScope<T> CreateScope<T>(GetStruct get, ReleaseStruct release)
{
IntPtr pStruct;
get(out pStruct);
return Scope.Create(() => (T)Marshal.PtrToStructure(pStruct, typeof(T)), value => release(pStruct));
}
public static IEnumerable<T> GetStructsFromArray<T>(IntPtr pStructs, int count)
{
var size = Marshal.SizeOf(typeof(T));
for (var pStruct = pStructs; count > 0; count--)
{
yield return (T)Marshal.PtrToStructure(pStruct, typeof(T));
pStruct += size;
}
}
}
}

Просмотреть файл

@ -17,6 +17,9 @@ namespace Microsoft.ClearScript.Util.COM
{
internal static partial class TypeInfoHelpers
{
// GUID_ManagedName (um\cor.h)
private static readonly Guid managedNameGuid = new Guid("{0f21f359-ab84-41e8-9a78-36d110e6d2f9}");
public static ITypeLib GetContainingTypeLib(this ITypeInfo typeInfo)
{
int index;
@ -35,6 +38,35 @@ namespace Microsoft.ClearScript.Util.COM
return typeInfo.GetMemberName(-1);
}
public static string GetManagedName(this ITypeInfo typeInfo)
{
var typeInfo2 = typeInfo as ITypeInfo2;
if (typeInfo2 != null)
{
// ReSharper disable EmptyGeneralCatchClause
try
{
var guid = managedNameGuid;
object data;
typeInfo2.GetCustData(ref guid, out data);
var name = data as string;
if (name != null)
{
return name.Trim();
}
}
catch (Exception)
{
}
// ReSharper restore EmptyGeneralCatchClause
}
return typeInfo.GetContainingTypeLib().GetManagedName() + "." + Marshal.GetTypeInfoName(typeInfo);
}
public static string GetMemberName(this ITypeInfo typeInfo, int memid)
{
string name;
@ -47,140 +79,118 @@ namespace Microsoft.ClearScript.Util.COM
public static Guid GetGuid(this ITypeInfo typeInfo)
{
return typeInfo.GetTypeAttr().guid;
using (var attrScope = typeInfo.CreateAttrScope())
{
return attrScope.Value.guid;
}
}
public static Guid GetOrCreateGuid(this ITypeInfo typeInfo)
{
var guid = typeInfo.GetGuid();
if (guid != Guid.Empty)
{
return guid;
}
var guidBytes = typeInfo.GetContainingTypeLib().GetGuid().ToByteArray();
var nameBytes = BitConverter.GetBytes(typeInfo.GetName().GetDigestAsUInt64());
for (var index = 0; index < guidBytes.Length; index++)
{
guidBytes[index] ^= nameBytes[index % nameBytes.Length];
}
return new Guid(guidBytes);
}
public static TYPEFLAGS GetFlags(this ITypeInfo typeInfo)
{
return typeInfo.GetTypeAttr().wTypeFlags;
using (var attrScope = typeInfo.CreateAttrScope())
{
return attrScope.Value.wTypeFlags;
}
}
public static TYPEKIND GetKind(this ITypeInfo typeInfo)
{
return typeInfo.GetTypeAttr().typekind;
using (var attrScope = typeInfo.CreateAttrScope())
{
return attrScope.Value.typekind;
}
}
public static IEnumerable<DispatchMember> GetDispatchMembers(this ITypeInfo typeInfo)
{
var funcCount = typeInfo.GetTypeAttr().cFuncs;
var isEnumerable = false;
var names = new string[1];
for (var index = 0; index < funcCount; index++)
using (var attrScope = typeInfo.CreateAttrScope())
{
IntPtr pDesc;
typeInfo.GetFuncDesc(index, out pDesc);
try
{
var desc = (FUNCDESC)Marshal.PtrToStructure(pDesc, typeof(FUNCDESC));
if (desc.memid == SpecialDispIDs.NewEnum)
{
isEnumerable = true;
}
var count = attrScope.Value.cFuncs;
var isEnumerable = false;
if ((desc.wFuncFlags & (short)FUNCFLAGS.FUNCFLAG_FRESTRICTED) != 0)
{
continue;
}
int nameCount;
typeInfo.GetNames(desc.memid, names, 1, out nameCount);
if (nameCount > 0)
{
yield return new DispatchMember(names[0], desc.memid, desc.invkind);
}
}
finally
var names = new string[1];
for (var index = 0; index < count; index++)
{
typeInfo.ReleaseFuncDesc(pDesc);
}
using (var funcDescScope = typeInfo.CreateFuncDescScope(index))
{
if (funcDescScope.Value.memid == SpecialDispIDs.NewEnum)
{
isEnumerable = true;
}
if (isEnumerable)
{
yield return new DispatchMember("GetEnumerator", SpecialDispIDs.GetEnumerator, INVOKEKIND.INVOKE_FUNC);
if ((funcDescScope.Value.wFuncFlags & (short)FUNCFLAGS.FUNCFLAG_FRESTRICTED) != 0)
{
continue;
}
int nameCount;
typeInfo.GetNames(funcDescScope.Value.memid, names, 1, out nameCount);
if (nameCount > 0)
{
yield return new DispatchMember(names[0], funcDescScope.Value.memid, funcDescScope.Value.invkind);
}
if (isEnumerable)
{
yield return new DispatchMember("GetEnumerator", SpecialDispIDs.GetEnumerator, INVOKEKIND.INVOKE_FUNC);
}
}
}
}
}
public static IPropertyBag GetTypeLibEnums(this ITypeInfo typeInfo)
public static bool IsEnum(this ITypeInfo typeInfo)
{
var typeLib = typeInfo.GetContainingTypeLib();
var typeLibName = typeLib.GetName();
var rootNode = new PropertyBag(true);
var typeInfoCount = typeLib.GetTypeInfoCount();
for (var typeInfoIndex = 0; typeInfoIndex < typeInfoCount; typeInfoIndex++)
using (var attrScope = typeInfo.CreateAttrScope())
{
typeLib.GetTypeInfo(typeInfoIndex, out typeInfo);
var typeInfoName = typeInfo.GetName();
if (attrScope.Value.typekind == TYPEKIND.TKIND_ENUM)
{
return true;
}
var typeAttr = typeInfo.GetTypeAttr();
if (typeAttr.typekind == TYPEKIND.TKIND_ALIAS)
if (attrScope.Value.typekind == TYPEKIND.TKIND_ALIAS)
{
ITypeInfo refTypeInfo;
typeInfo.GetRefTypeInfo(unchecked((int)(long)typeAttr.tdescAlias.lpValue), out refTypeInfo);
typeInfo = refTypeInfo;
typeAttr = typeInfo.GetTypeAttr();
typeInfo.GetRefTypeInfo(unchecked((int)attrScope.Value.tdescAlias.lpValue.ToInt64()), out refTypeInfo);
return refTypeInfo.IsEnum();
}
if (typeAttr.typekind == TYPEKIND.TKIND_ENUM)
{
var varCount = typeAttr.cVars;
for (var varIndex = 0; varIndex < varCount; varIndex++)
{
IntPtr pVarDesc;
typeInfo.GetVarDesc(varIndex, out pVarDesc);
try
{
var varDesc = (VARDESC)Marshal.PtrToStructure(pVarDesc, typeof(VARDESC));
if (varDesc.varkind == VARKIND.VAR_CONST)
{
var varName = typeInfo.GetMemberName(varDesc.memid);
object typeLibNodeObj;
if (!rootNode.TryGetValue(typeLibName, out typeLibNodeObj) || !(typeLibNodeObj is PropertyBag))
{
typeLibNodeObj = new PropertyBag(true);
rootNode.SetPropertyNoCheck(typeLibName, typeLibNodeObj);
}
object typeInfoNodeObj;
var typeLibNode = (PropertyBag)typeLibNodeObj;
if (!typeLibNode.TryGetValue(typeInfoName, out typeInfoNodeObj) || !(typeInfoNodeObj is PropertyBag))
{
typeInfoNodeObj = new PropertyBag(true);
typeLibNode.SetPropertyNoCheck(typeInfoName, typeInfoNodeObj);
}
var typeInfoNode = (PropertyBag)typeInfoNodeObj;
typeInfoNode.SetPropertyNoCheck(varName, Marshal.GetObjectForNativeVariant(varDesc.desc.lpvarValue));
}
}
finally
{
typeInfo.ReleaseVarDesc(pVarDesc);
}
}
}
return false;
}
return rootNode;
}
private static TYPEATTR GetTypeAttr(this ITypeInfo typeInfo)
public static IScope<TYPEATTR> CreateAttrScope(this ITypeInfo typeInfo)
{
IntPtr pTypeAttr;
typeInfo.GetTypeAttr(out pTypeAttr);
try
{
return (TYPEATTR)Marshal.PtrToStructure(pTypeAttr, typeof(TYPEATTR));
}
finally
{
typeInfo.ReleaseTypeAttr(pTypeAttr);
}
return StructHelpers.CreateScope<TYPEATTR>(typeInfo.GetTypeAttr, typeInfo.ReleaseTypeAttr);
}
public static IScope<VARDESC> CreateVarDescScope(this ITypeInfo typeInfo, int index)
{
return StructHelpers.CreateScope<VARDESC>((out IntPtr pVarDesc) => typeInfo.GetVarDesc(index, out pVarDesc), typeInfo.ReleaseVarDesc);
}
public static IScope<FUNCDESC> CreateFuncDescScope(this ITypeInfo typeInfo, int index)
{
return StructHelpers.CreateScope<FUNCDESC>((out IntPtr pFuncDesc) => typeInfo.GetFuncDesc(index, out pFuncDesc), typeInfo.ReleaseFuncDesc);
}
}
}

Просмотреть файл

@ -1,12 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using ELEMDESC = System.Runtime.InteropServices.ComTypes.ELEMDESC;
using FUNCDESC = System.Runtime.InteropServices.ComTypes.FUNCDESC;
using TYPEDESC = System.Runtime.InteropServices.ComTypes.TYPEDESC;
using TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR;
using VARDESC = System.Runtime.InteropServices.ComTypes.VARDESC;
namespace Microsoft.ClearScript.Util.COM
{
internal static class TypeLibHelpers
{
// GUID_ManagedName (um\cor.h)
private static readonly Guid managedNameGuid = new Guid("{0f21f359-ab84-41e8-9a78-36d110e6d2f9}");
public static string GetName(this ITypeLib typeLib)
{
return typeLib.GetMemberName(-1);
@ -21,5 +33,186 @@ namespace Microsoft.ClearScript.Util.COM
typeLib.GetDocumentation(index, out name, out docString, out helpContext, out helpFile);
return name;
}
public static string GetManagedName(this ITypeLib typeLib)
{
var typeLib2 = typeLib as ITypeLib2;
if (typeLib2 != null)
{
// ReSharper disable EmptyGeneralCatchClause
try
{
var guid = managedNameGuid;
object data;
typeLib2.GetCustData(ref guid, out data);
var name = data as string;
if (name != null)
{
name = name.Trim();
if (name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
{
return name.Substring(0, name.Length - 4);
}
return name;
}
}
catch (Exception)
{
}
// ReSharper restore EmptyGeneralCatchClause
}
return typeLib.GetName();
}
public static Guid GetGuid(this ITypeLib typeLib)
{
using (var attrScope = typeLib.CreateAttrScope())
{
return attrScope.Value.guid;
}
}
public static IScope<TYPELIBATTR> CreateAttrScope(this ITypeLib typeLib)
{
return StructHelpers.CreateScope<TYPELIBATTR>(typeLib.GetLibAttr, typeLib.ReleaseTLibAttr);
}
public static IEnumerable<ITypeInfo> GetReferencedEnums(this ITypeLib typeLib)
{
var processedTypeInfo = new Dictionary<Guid, ITypeInfo>();
var count = typeLib.GetTypeInfoCount();
for (var index = 0; index < count; index++)
{
ITypeInfo typeInfo;
typeLib.GetTypeInfo(index, out typeInfo);
foreach (var enumTypeInfo in GetReferencedEnums(typeLib, typeInfo, processedTypeInfo))
{
yield return enumTypeInfo;
}
}
}
private static IEnumerable<ITypeInfo> GetReferencedEnums(ITypeLib typeLib, ITypeInfo typeInfo, Dictionary<Guid, ITypeInfo> processedTypeInfo)
{
if (typeInfo == null)
{
yield break;
}
var guid = typeInfo.GetOrCreateGuid();
if (processedTypeInfo.ContainsKey(guid))
{
yield break;
}
processedTypeInfo.Add(guid, typeInfo);
if (typeInfo.IsEnum())
{
yield return typeInfo;
yield break;
}
if (typeInfo.GetContainingTypeLib().GetGuid() != typeLib.GetGuid())
{
yield break;
}
using (var typeAttrScope = typeInfo.CreateAttrScope())
{
for (var funcIndex = 0; funcIndex < typeAttrScope.Value.cFuncs; funcIndex++)
{
using (var funcDescScope = typeInfo.CreateFuncDescScope(funcIndex))
{
foreach (var enumTypeInfo in GetReferencedEnums(typeLib, typeInfo, funcDescScope.Value, processedTypeInfo))
{
yield return enumTypeInfo;
}
}
}
for (var varIndex = 0; varIndex < typeAttrScope.Value.cVars; varIndex++)
{
using (var varDescScope = typeInfo.CreateVarDescScope(varIndex))
{
foreach (var enumTypeInfo in GetReferencedEnums(typeLib, typeInfo, varDescScope.Value, processedTypeInfo))
{
yield return enumTypeInfo;
}
}
}
for (var implTypeIndex = 0; implTypeIndex < typeAttrScope.Value.cImplTypes; implTypeIndex++)
{
int href;
typeInfo.GetRefTypeOfImplType(implTypeIndex, out href);
ITypeInfo refTypeInfo;
typeInfo.GetRefTypeInfo(href, out refTypeInfo);
var refGuid = refTypeInfo.GetGuid();
if ((refGuid == typeof(IDispatch).GUID) || (refGuid == typeof(IDispatchEx).GUID))
{
continue;
}
foreach (var enumTypeInfo in GetReferencedEnums(typeLib, refTypeInfo, processedTypeInfo))
{
yield return enumTypeInfo;
}
}
}
}
private static IEnumerable<ITypeInfo> GetReferencedEnums(ITypeLib typeLib, ITypeInfo typeInfo, FUNCDESC funcDesc, Dictionary<Guid, ITypeInfo> processedTypeInfo)
{
foreach (var enumTypeInfo in GetReferencedEnums(typeLib, typeInfo, funcDesc.elemdescFunc, processedTypeInfo))
{
yield return enumTypeInfo;
}
foreach (var elemDesc in StructHelpers.GetStructsFromArray<ELEMDESC>(funcDesc.lprgelemdescParam, funcDesc.cParams))
{
foreach (var enumTypeInfo in GetReferencedEnums(typeLib, typeInfo, elemDesc, processedTypeInfo))
{
yield return enumTypeInfo;
}
}
}
private static IEnumerable<ITypeInfo> GetReferencedEnums(ITypeLib typeLib, ITypeInfo typeInfo, VARDESC varDesc, Dictionary<Guid, ITypeInfo> processedTypeInfo)
{
return GetReferencedEnums(typeLib, typeInfo, varDesc.elemdescVar, processedTypeInfo);
}
private static IEnumerable<ITypeInfo> GetReferencedEnums(ITypeLib typeLib, ITypeInfo typeInfo, ELEMDESC elemDesc, Dictionary<Guid, ITypeInfo> processedTypeInfo)
{
return GetReferencedEnums(typeLib, typeInfo, elemDesc.tdesc, processedTypeInfo);
}
private static IEnumerable<ITypeInfo> GetReferencedEnums(ITypeLib typeLib, ITypeInfo typeInfo, TYPEDESC typeDesc, Dictionary<Guid, ITypeInfo> processedTypeInfo)
{
if ((typeDesc.vt == (short)VarEnum.VT_PTR) || (typeDesc.vt == (short)VarEnum.VT_CARRAY))
{
return GetReferencedEnums(typeLib, typeInfo, (TYPEDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(TYPEDESC)), processedTypeInfo);
}
if (typeDesc.vt == (short)VarEnum.VT_USERDEFINED)
{
ITypeInfo refTypeInfo;
typeInfo.GetRefTypeInfo(unchecked((int)typeDesc.lpValue.ToInt64()), out refTypeInfo);
return GetReferencedEnums(typeLib, refTypeInfo, processedTypeInfo);
}
return Enumerable.Empty<ITypeInfo>();
}
}
}

Просмотреть файл

@ -10,5 +10,6 @@ namespace Microsoft.ClearScript.Util
ScriptEngine Engine { get; }
Type AccessContext { get; }
ScriptAccess DefaultAccess { get; }
HostTargetFlags TargetFlags { get; }
}
}

Просмотреть файл

@ -10,7 +10,20 @@ namespace Microsoft.ClearScript.Util.IJW
{
public static IntPtr Load()
{
var dirPath = Path.Combine(MiscHelpers.GetLocalDataRootPath(), "IJW");
IntPtr hLibrary;
var usingAppPath = false;
if (!MiscHelpers.Try(out hLibrary, () => Load(MiscHelpers.GetLocalDataRootPath(out usingAppPath))) && !usingAppPath)
{
hLibrary = Load(MiscHelpers.GetLocalDataRootPath(AppDomain.CurrentDomain.BaseDirectory));
}
return hLibrary;
}
private static IntPtr Load(string rootPath)
{
var dirPath = Path.Combine(rootPath, "IJW");
var filePath = Path.Combine(dirPath, "ijwhost.dll");
if (!File.Exists(filePath))

Просмотреть файл

@ -305,12 +305,7 @@ namespace Microsoft.ClearScript.Util
return (index >= 0) ? name.Substring(index + 1) : name;
}
private static bool IsExplicitImplementation(this MemberInfo member)
{
return member.Name.IndexOf('.') >= 0;
}
private static T GetAttribute<T>(this MemberInfo member, bool inherit) where T : Attribute
public static T GetAttribute<T>(this MemberInfo member, bool inherit) where T : Attribute
{
try
{
@ -329,5 +324,10 @@ namespace Microsoft.ClearScript.Util
throw;
}
}
private static bool IsExplicitImplementation(this MemberInfo member)
{
return member.Name.IndexOf('.') >= 0;
}
}
}

Просмотреть файл

@ -514,9 +514,33 @@ namespace Microsoft.ClearScript.Util
Debug.Assert(false, "Entered code block presumed unreachable.");
}
public static string GetLocalDataRootPath()
public static string GetLocalDataRootPath(out bool usingAppPath)
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "ClearScript", ClearScriptVersion.Triad, Environment.Is64BitProcess ? "x64" : "x86");
var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (string.IsNullOrWhiteSpace(basePath))
{
basePath = AppDomain.CurrentDomain.BaseDirectory;
usingAppPath = true;
}
else
{
usingAppPath = false;
}
return GetLocalDataRootPath(basePath);
}
public static string GetLocalDataRootPath(string basePath)
{
var path = Path.Combine(basePath, "Microsoft", "ClearScript", ClearScriptVersion.Triad, Environment.Is64BitProcess ? "x64" : "x86");
string fullPath;
if (Try(out fullPath, () => Path.GetFullPath(path)))
{
return fullPath;
}
return path;
}
#endregion

Просмотреть файл

@ -11,15 +11,11 @@ using Microsoft.ClearScript.Util.COM;
using Microsoft.Win32;
using TYPEFLAGS = System.Runtime.InteropServices.ComTypes.TYPEFLAGS;
using TYPEKIND = System.Runtime.InteropServices.ComTypes.TYPEKIND;
using TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR;
namespace Microsoft.ClearScript.Util
{
internal static class ObjectHelpers
{
// GUID_ManagedName (um\cor.h)
private static readonly Guid managedNameGuid = new Guid("{0f21f359-ab84-41e8-9a78-36d110e6d2f9}");
public static Type GetTypeOrTypeInfo(this object value)
{
var type = value.GetType();
@ -176,7 +172,7 @@ namespace Microsoft.ClearScript.Util
var assembly = LoadPrimaryInteropAssembly(typeLib);
if (assembly != null)
{
var name = GetManagedTypeInfoName(typeInfo, typeLib);
var name = typeInfo.GetManagedName();
var guid = typeInfo.GetGuid();
var type = assembly.GetType(name, false, true);
@ -185,7 +181,7 @@ namespace Microsoft.ClearScript.Util
return type;
}
var types = assembly.GetTypes();
var types = assembly.GetAllTypes().ToArray();
if ((index >= 0) && (index < types.Length))
{
type = types[index];
@ -225,23 +221,15 @@ namespace Microsoft.ClearScript.Util
try
{
IntPtr pLibAttr;
typeLib.GetLibAttr(out pLibAttr);
try
using (var attrScope = typeLib.CreateAttrScope())
{
var typeLibAttr = (TYPELIBATTR)Marshal.PtrToStructure(pLibAttr, typeof(TYPELIBATTR));
string name;
string codeBase;
if (GetPrimaryInteropAssembly(typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, out name, out codeBase))
if (GetPrimaryInteropAssembly(attrScope.Value.guid, attrScope.Value.wMajorVerNum, attrScope.Value.wMinorVerNum, out name, out codeBase))
{
return Assembly.Load(new AssemblyName(name) { CodeBase = codeBase });
}
}
finally
{
typeLib.ReleaseTLibAttr(pLibAttr);
}
}
catch (Exception)
{
@ -283,70 +271,6 @@ namespace Microsoft.ClearScript.Util
return name != null;
}
private static string GetManagedTypeInfoName(ITypeInfo typeInfo, ITypeLib typeLib)
{
var typeInfo2 = typeInfo as ITypeInfo2;
if (typeInfo2 != null)
{
// ReSharper disable EmptyGeneralCatchClause
try
{
var guid = managedNameGuid;
object data;
typeInfo2.GetCustData(ref guid, out data);
var name = data as string;
if (name != null)
{
return name.Trim();
}
}
catch (Exception)
{
}
// ReSharper restore EmptyGeneralCatchClause
}
return GetManagedTypeLibName(typeLib) + "." + Marshal.GetTypeInfoName(typeInfo);
}
private static string GetManagedTypeLibName(ITypeLib typeLib)
{
var typeLib2 = typeLib as ITypeLib2;
if (typeLib2 != null)
{
// ReSharper disable EmptyGeneralCatchClause
try
{
var guid = managedNameGuid;
object data;
typeLib2.GetCustData(ref guid, out data);
var name = data as string;
if (name != null)
{
name = name.Trim();
if (name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
{
return name.Substring(0, name.Length - 4);
}
return name;
}
}
catch (Exception)
{
}
// ReSharper restore EmptyGeneralCatchClause
}
return typeLib.GetName();
}
#region Nested type: IProvideClassInfo
[ComImport]

Просмотреть файл

@ -11,11 +11,11 @@ namespace Microsoft.ClearScript.Util.Test
// ReSharper disable EventNeverSubscribedTo.Local
// ReSharper disable UnusedType.Local
public AccessContextTestBase() { }
internal AccessContextTestBase(int arg) { }
protected AccessContextTestBase(string arg) { }
protected internal AccessContextTestBase(DateTime arg) { }
private AccessContextTestBase(TimeSpan arg) { }
public AccessContextTestBase() {}
internal AccessContextTestBase(int arg) {}
protected AccessContextTestBase(string arg) {}
protected internal AccessContextTestBase(DateTime arg) {}
private AccessContextTestBase(TimeSpan arg) {}
public event EventHandler PublicEvent;
internal event EventHandler InternalEvent;
@ -29,11 +29,11 @@ namespace Microsoft.ClearScript.Util.Test
protected internal string ProtectedInternalField;
private string privateField;
public void PublicMethod() { }
internal void InternalMethod() { }
protected void ProtectedMethod() { }
protected internal void ProtectedInternalMethod() { }
private void PrivateMethod() { }
public void PublicMethod() {}
internal void InternalMethod() {}
protected void ProtectedMethod() {}
protected internal void ProtectedInternalMethod() {}
private void PrivateMethod() {}
public string PublicProperty { get; set; }
internal string InternalProperty { get; set; }
@ -41,11 +41,11 @@ namespace Microsoft.ClearScript.Util.Test
protected internal string ProtectedInternalProperty { get; set; }
private string PrivateProperty { get; set; }
public class PublicNestedType { }
internal sealed class InternalNestedType { }
protected class ProtectedNestedType { }
protected internal sealed class ProtectedInternalNestedType { }
private sealed class PrivateNestedType { }
public class PublicNestedType {}
internal sealed class InternalNestedType {}
protected class ProtectedNestedType {}
protected internal sealed class ProtectedInternalNestedType {}
private sealed class PrivateNestedType {}
// ReSharper restore UnusedType.Local
// ReSharper restore EventNeverSubscribedTo.Local

Просмотреть файл

@ -3,7 +3,6 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
namespace Microsoft.ClearScript.Util
{
@ -40,14 +39,9 @@ namespace Microsoft.ClearScript.Util
return fullTypeName;
}
public static IntPtr GetITypeInfo(this Type type)
public static IntPtr GetTypeInfo(this Type type)
{
return IntPtr.Zero;
}
public static Type GetManagedType(this ITypeInfo typeInfo)
{
return null;
}
}
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.ClearScript.Util
return fullTypeName;
}
public static IntPtr GetITypeInfo(this Type type)
public static IntPtr GetTypeInfo(this Type type)
{
return Marshal.GetITypeInfoForType(type);
}

Просмотреть файл

@ -324,6 +324,23 @@ namespace Microsoft.ClearScript.Util
return type.Assembly.IsFriendOf(thatType.Assembly);
}
public static bool IsCOMVisible(this Type type)
{
var attribute = type.GetAttribute<ComVisibleAttribute>(false);
if (attribute != null)
{
return attribute.Value;
}
attribute = type.Assembly.GetAttribute<ComVisibleAttribute>(false);
if (attribute != null)
{
return attribute.Value;
}
return false;
}
public static string GetRootName(this Type type)
{
return StripGenericSuffix(type.Name);

Просмотреть файл

@ -293,7 +293,7 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-ia32.dll">
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-ia32.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" "$(OutDir)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" "$(OutDir)"</Command>
@ -302,7 +302,7 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)%(Filename)%(Extension)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)%(Filename)%(Extension)</Outputs>
</CopyFileToFolders>
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-ia32.dll.pdb">
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-ia32.dll.pdb">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" "$(OutDir)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" "$(OutDir)"</Command>

Просмотреть файл

@ -210,7 +210,7 @@
<CopyFileToFolders Include="..\..\V8\lib\v8-ia32.dll.pdb" />
<CopyFileToFolders Include="..\..\V8\lib\v8-base-ia32.dll" />
<CopyFileToFolders Include="..\..\V8\lib\v8-base-ia32.dll.pdb" />
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-ia32.dll" />
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-ia32.dll.pdb" />
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-ia32.dll" />
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-ia32.dll.pdb" />
</ItemGroup>
</Project>

Просмотреть файл

@ -88,11 +88,13 @@
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<OmitFramePointers>false</OmitFramePointers>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation Condition="'$(VisualStudioVersion)'=='15.0'">DebugFull</GenerateDebugInformation>
<GenerateDebugInformation Condition="'$(VisualStudioVersion)'=='14.0'">true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)ClearScript\V8\V8\lib\v8-x64.dll.lib</AdditionalDependencies>
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>$(SolutionDir)\ClearScript\Exports</AdditionalIncludeDirectories>
@ -119,6 +121,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation Condition="'$(VisualStudioVersion)'=='15.0'">DebugFull</GenerateDebugInformation>
@ -127,6 +130,7 @@
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>$(SolutionDir)\ClearScript\Exports</AdditionalIncludeDirectories>
@ -294,7 +298,7 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-x64.dll">
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-x64.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" "$(OutDir)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" "$(OutDir)"</Command>
@ -303,7 +307,7 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)%(Filename)%(Extension)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)%(Filename)%(Extension)</Outputs>
</CopyFileToFolders>
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-x64.dll.pdb">
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-x64.dll.pdb">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" "$(OutDir)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" "$(OutDir)"</Command>

Просмотреть файл

@ -210,7 +210,7 @@
<CopyFileToFolders Include="..\..\V8\lib\v8-x64.dll.pdb" />
<CopyFileToFolders Include="..\..\V8\lib\v8-base-x64.dll" />
<CopyFileToFolders Include="..\..\V8\lib\v8-base-x64.dll.pdb" />
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-x64.dll" />
<CopyFileToFolders Include="..\..\V8\lib\v8-libcpp-x64.dll.pdb" />
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-x64.dll" />
<CopyFileToFolders Include="..\..\V8\lib\v8-zlib-x64.dll.pdb" />
</ItemGroup>
</Project>

Просмотреть файл

@ -31,4 +31,3 @@
#include "V8ObjectHolderImpl.h"
#include "V8ScriptHolderImpl.h"
#include "HighResolutionClock.h"
#include "CallbackManager.h"

Просмотреть файл

@ -8,6 +8,7 @@
//-----------------------------------------------------------------------------
#include <algorithm>
#include <array>
#include <codecvt>
#include <cstdint>
#include <functional>

Просмотреть файл

@ -95,6 +95,9 @@ public:
template <typename T>
class SharedPtr final
{
template <typename TOther>
friend class SharedPtr;
public:
SharedPtr<T>()
@ -179,14 +182,56 @@ public:
return m_pTarget;
}
operator T*() const
T& operator*() const
{
return m_pTarget;
_ASSERTE(m_pTarget != nullptr);
return *m_pTarget;
}
T* GetRawPtr() const
template <typename TOther>
TOther& DerefAs() const
{
return m_pTarget;
_ASSERTE(m_pTarget != nullptr);
return *static_cast<TOther*>(m_pTarget);
}
bool operator==(nullptr_t) const
{
return IsEmpty();
}
bool operator==(T* pThat) const
{
return m_pTarget == pThat;
}
template <typename TOther>
bool operator==(const SharedPtr<TOther>& that) const
{
return m_pTarget == that.m_pTarget;
}
bool operator!=(nullptr_t) const
{
return !operator==(nullptr);
}
bool operator!=(T* pThat) const
{
return !operator==(pThat);
}
template <typename TOther>
bool operator!=(const SharedPtr<TOther>& that) const
{
return !operator==(that);
}
template <typename TOther>
SharedPtr<TOther> CastTo() const
{
AddRef();
return SharedPtr<TOther>(static_cast<TOther*>(m_pTarget), m_pRefCount);
}
bool IsEmpty() const
@ -257,7 +302,7 @@ private:
MoveInitialize(that);
}
void AddRef()
void AddRef() const
{
if (m_pTarget != nullptr)
{

Просмотреть файл

@ -9,7 +9,7 @@
V8Context* V8Context::Create(const SharedPtr<V8Isolate>& spIsolate, const StdString& name, const Options& options)
{
return new V8ContextImpl(static_cast<V8IsolateImpl*>(spIsolate.GetRawPtr()), name, options);
return new V8ContextImpl(spIsolate.CastTo<V8IsolateImpl>(), name, options);
}
//-----------------------------------------------------------------------------

Просмотреть файл

@ -51,8 +51,8 @@ public:
virtual V8ScriptHolder* Compile(const V8DocumentInfo& documentInfo, StdString&& code) = 0;
virtual V8ScriptHolder* Compile(const V8DocumentInfo& documentInfo, StdString&& code, V8CacheType cacheType, std::vector<uint8_t>& cacheBytes) = 0;
virtual V8ScriptHolder* Compile(const V8DocumentInfo& documentInfo, StdString&& code, V8CacheType cacheType, const std::vector<uint8_t>& cacheBytes, bool& cacheAccepted) = 0;
virtual bool CanExecute(V8ScriptHolder* pHolder) = 0;
virtual V8Value Execute(V8ScriptHolder* pHolder, bool evaluate) = 0;
virtual bool CanExecute(const SharedPtr<V8ScriptHolder>& spHolder) = 0;
virtual V8Value Execute(const SharedPtr<V8ScriptHolder>& spHolder, bool evaluate) = 0;
virtual void Interrupt() = 0;
virtual void GetIsolateHeapStatistics(v8::HeapStatistics& heapStatistics) = 0;

Просмотреть файл

@ -120,7 +120,7 @@ static V8ContextImpl* GetContextImplFromData(const TInfo& info)
#define BEGIN_ISOLATE_SCOPE \
{ \
__pragma(warning(disable:4456)) /* declaration hides previous local declaration */ \
V8IsolateImpl::Scope t_IsolateScope(m_spIsolateImpl); \
V8IsolateImpl::Scope t_IsolateScope(*m_spIsolateImpl); \
__pragma(warning(default:4456))
#define END_ISOLATE_SCOPE \
@ -169,8 +169,8 @@ static V8ContextImpl* GetContextImplFromData(const TInfo& info)
#define BEGIN_EXECUTION_SCOPE \
{ \
__pragma(warning(disable:4456)) /* declaration hides previous local declaration */ \
V8IsolateImpl::ExecutionScope t_ExecutionScope(m_spIsolateImpl); \
V8IsolateImpl::TryCatch t_TryCatch(m_spIsolateImpl); \
V8IsolateImpl::ExecutionScope t_ExecutionScope(*m_spIsolateImpl); \
V8IsolateImpl::TryCatch t_TryCatch(*m_spIsolateImpl); \
__pragma(warning(default:4456))
#define END_EXECUTION_SCOPE \
@ -184,7 +184,7 @@ static V8ContextImpl* GetContextImplFromData(const TInfo& info)
#define BEGIN_DOCUMENT_SCOPE(DOCUMENT_INFO) \
{ \
__pragma(warning(disable:4456)) /* declaration hides previous local declaration */ \
V8IsolateImpl::DocumentScope t_DocumentScope(m_spIsolateImpl, DOCUMENT_INFO); \
V8IsolateImpl::DocumentScope t_DocumentScope(*m_spIsolateImpl, DOCUMENT_INFO); \
__pragma(warning(default:4456))
#define END_DOCUMENT_SCOPE \
@ -214,15 +214,15 @@ static const size_t s_MaxModuleCacheSize = 1024;
//-----------------------------------------------------------------------------
V8ContextImpl::V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name):
V8ContextImpl(pIsolateImpl, name, Options())
V8ContextImpl(SharedPtr<V8IsolateImpl>(pIsolateImpl), name, Options())
{
}
//-----------------------------------------------------------------------------
V8ContextImpl::V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name, const Options& options):
V8ContextImpl::V8ContextImpl(SharedPtr<V8IsolateImpl>&& spIsolateImpl, const StdString& name, const Options& options):
m_Name(name),
m_spIsolateImpl(pIsolateImpl),
m_spIsolateImpl(std::move(spIsolateImpl)),
m_DateTimeConversionEnabled(options.EnableDateTimeConversion),
m_pvV8ObjectCache(nullptr),
m_AllowHostObjectConstructorCall(false)
@ -539,7 +539,7 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
auto codeDigest = code.GetDigest();
v8::ScriptCompiler::Source source(FROM_MAYBE(CreateString(code)), CreateScriptOrigin(documentInfo));
std::unique_ptr<V8ScriptHolder> spScriptHolder;
std::unique_ptr<V8ScriptHolder> upScriptHolder;
if (documentInfo.IsModule())
{
@ -555,7 +555,7 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
CacheModule(documentInfo, codeDigest, hModule);
}
spScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hModule)), documentInfo, codeDigest, std::move(code)));
upScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hModule)), documentInfo, codeDigest, std::move(code)));
}
else
{
@ -571,10 +571,10 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
CacheScript(documentInfo, codeDigest, hScript);
}
spScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hScript)), documentInfo, codeDigest));
upScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hScript)), documentInfo, codeDigest));
}
return spScriptHolder.release();
return upScriptHolder.release();
FROM_MAYBE_CATCH
@ -603,8 +603,8 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
auto codeDigest = code.GetDigest();
v8::ScriptCompiler::Source source(FROM_MAYBE(CreateString(code)), CreateScriptOrigin(documentInfo));
std::unique_ptr<V8ScriptHolder> spScriptHolder;
UniqueDeletePtr<v8::ScriptCompiler::CachedData> spCachedData;
std::unique_ptr<V8ScriptHolder> upScriptHolder;
UniqueDeletePtr<v8::ScriptCompiler::CachedData> upCachedData;
if (documentInfo.IsModule())
{
@ -620,8 +620,8 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
CacheModule(documentInfo, codeDigest, hModule);
}
spScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hModule)), documentInfo, codeDigest, std::move(code)));
spCachedData.reset(v8::ScriptCompiler::CreateCodeCache(hModule->GetUnboundModuleScript()));
upScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hModule)), documentInfo, codeDigest, std::move(code)));
upCachedData.reset(v8::ScriptCompiler::CreateCodeCache(hModule->GetUnboundModuleScript()));
}
else
{
@ -637,23 +637,23 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
CacheScript(documentInfo, codeDigest, hScript);
}
spScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hScript)), documentInfo, codeDigest));
spCachedData.reset(v8::ScriptCompiler::CreateCodeCache(hScript));
upScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hScript)), documentInfo, codeDigest));
upCachedData.reset(v8::ScriptCompiler::CreateCodeCache(hScript));
}
cacheBytes.clear();
if (spCachedData && (spCachedData->length > 0) && (spCachedData->data != nullptr))
if (upCachedData && (upCachedData->length > 0) && (upCachedData->data != nullptr))
{
cacheBytes.resize(spCachedData->length);
memcpy_s(&cacheBytes[0], cacheBytes.size(), spCachedData->data, spCachedData->length);
cacheBytes.resize(upCachedData->length);
memcpy_s(&cacheBytes[0], cacheBytes.size(), upCachedData->data, upCachedData->length);
if (documentInfo.IsModule())
{
spScriptHolder->SetCacheBytes(cacheBytes);
upScriptHolder->SetCacheBytes(cacheBytes);
}
}
return spScriptHolder.release();
return upScriptHolder.release();
FROM_MAYBE_CATCH
@ -683,7 +683,7 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
auto codeDigest = code.GetDigest();
auto pCachedData = new v8::ScriptCompiler::CachedData(&cacheBytes[0], static_cast<int>(cacheBytes.size()), v8::ScriptCompiler::CachedData::BufferNotOwned);
v8::ScriptCompiler::Source source(FROM_MAYBE(CreateString(code)), CreateScriptOrigin(documentInfo), pCachedData);
std::unique_ptr<V8ScriptHolder> spScriptHolder;
std::unique_ptr<V8ScriptHolder> upScriptHolder;
if (documentInfo.IsModule())
{
@ -699,7 +699,7 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
CacheModule(documentInfo, codeDigest, hModule);
}
spScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hModule)), documentInfo, codeDigest, std::move(code)));
upScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hModule)), documentInfo, codeDigest, std::move(code)));
}
else
{
@ -715,16 +715,16 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
CacheScript(documentInfo, codeDigest, hScript);
}
spScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hScript)), documentInfo, codeDigest));
upScriptHolder.reset(new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hScript)), documentInfo, codeDigest));
}
cacheAccepted = !pCachedData->rejected;
if (cacheAccepted && documentInfo.IsModule())
{
spScriptHolder->SetCacheBytes(cacheBytes);
upScriptHolder->SetCacheBytes(cacheBytes);
}
return spScriptHolder.release();
return upScriptHolder.release();
FROM_MAYBE_CATCH
@ -738,38 +738,38 @@ V8ScriptHolder* V8ContextImpl::Compile(const V8DocumentInfo& documentInfo, StdSt
//-----------------------------------------------------------------------------
bool V8ContextImpl::CanExecute(V8ScriptHolder* pHolder)
bool V8ContextImpl::CanExecute(const SharedPtr<V8ScriptHolder>& spHolder)
{
return pHolder->IsSameIsolate(m_spIsolateImpl.GetRawPtr());
return spHolder->IsSameIsolate(m_spIsolateImpl);
}
//-----------------------------------------------------------------------------
V8Value V8ContextImpl::Execute(V8ScriptHolder* pHolder, bool evaluate)
V8Value V8ContextImpl::Execute(const SharedPtr<V8ScriptHolder>& spHolder, bool evaluate)
{
BEGIN_CONTEXT_SCOPE
BEGIN_DOCUMENT_SCOPE(pHolder->GetDocumentInfo())
BEGIN_DOCUMENT_SCOPE(spHolder->GetDocumentInfo())
BEGIN_EXECUTION_SCOPE
FROM_MAYBE_TRY
v8::Local<v8::Value> hResult;
if (pHolder->GetDocumentInfo().IsModule())
if (spHolder->GetDocumentInfo().IsModule())
{
auto codeDigest = pHolder->GetCode().GetDigest();
auto hModule = GetCachedModule(pHolder->GetDocumentInfo(), codeDigest);
auto codeDigest = spHolder->GetCode().GetDigest();
auto hModule = GetCachedModule(spHolder->GetDocumentInfo(), codeDigest);
if (hModule.IsEmpty())
{
if (pHolder->GetCacheBytes().size() > 0)
if (spHolder->GetCacheBytes().size() > 0)
{
auto pCachedData = new v8::ScriptCompiler::CachedData(&pHolder->GetCacheBytes()[0], static_cast<int>(pHolder->GetCacheBytes().size()), v8::ScriptCompiler::CachedData::BufferNotOwned);
v8::ScriptCompiler::Source source(FROM_MAYBE(CreateString(pHolder->GetCode())), CreateScriptOrigin(pHolder->GetDocumentInfo()), pCachedData);
auto pCachedData = new v8::ScriptCompiler::CachedData(&spHolder->GetCacheBytes()[0], static_cast<int>(spHolder->GetCacheBytes().size()), v8::ScriptCompiler::CachedData::BufferNotOwned);
v8::ScriptCompiler::Source source(FROM_MAYBE(CreateString(spHolder->GetCode())), CreateScriptOrigin(spHolder->GetDocumentInfo()), pCachedData);
hModule = VERIFY_MAYBE(CompileModule(&source));
_ASSERTE(!pCachedData->rejected);
}
else
{
v8::ScriptCompiler::Source source(FROM_MAYBE(CreateString(pHolder->GetCode())), CreateScriptOrigin(pHolder->GetDocumentInfo()));
v8::ScriptCompiler::Source source(FROM_MAYBE(CreateString(spHolder->GetCode())), CreateScriptOrigin(spHolder->GetDocumentInfo()));
hModule = VERIFY_MAYBE(CompileModule(&source));
}
@ -778,7 +778,7 @@ V8Value V8ContextImpl::Execute(V8ScriptHolder* pHolder, bool evaluate)
throw V8Exception(V8Exception::Type::General, m_Name, StdString(L"Module compilation failed; no additional information was provided by the V8 runtime"), false /*executionStarted*/);
}
CacheModule(pHolder->GetDocumentInfo(), codeDigest, hModule);
CacheModule(spHolder->GetDocumentInfo(), codeDigest, hModule);
}
if (hModule->GetStatus() < v8::Module::kInstantiated)
@ -797,7 +797,7 @@ V8Value V8ContextImpl::Execute(V8ScriptHolder* pHolder, bool evaluate)
}
else
{
auto hScript = ::HandleFromPtr<v8::UnboundScript>(pHolder->GetScript());
auto hScript = ::HandleFromPtr<v8::UnboundScript>(spHolder->GetScript());
hResult = VERIFY_MAYBE(hScript->BindToCurrentContext()->Run(m_hContext));
}
@ -922,7 +922,7 @@ void V8ContextImpl::Flush()
void V8ContextImpl::Destroy()
{
m_spIsolateImpl->CallWithLockNoWait([this] (V8IsolateImpl* /*pIsolateImpl*/)
m_spIsolateImpl->CallWithLockNoWait(true /*allowNesting*/, [this] (V8IsolateImpl* /*pIsolateImpl*/)
{
delete this;
});
@ -1259,13 +1259,13 @@ void V8ContextImpl::InitializeImportMeta(v8::Local<v8::Context> /*hContext*/, v8
v8::MaybeLocal<v8::Promise> V8ContextImpl::ImportModule(v8::Local<v8::ScriptOrModule> /*hReferrer*/, v8::Local<v8::String> hSpecifier)
{
V8IsolateImpl::TryCatch outerTryCatch(m_spIsolateImpl);
V8IsolateImpl::TryCatch outerTryCatch(*m_spIsolateImpl);
FROM_MAYBE_TRY
auto hResolver = FROM_MAYBE(v8::Promise::Resolver::New(m_hContext));
V8IsolateImpl::TryCatch innerTryCatch(m_spIsolateImpl);
V8IsolateImpl::TryCatch innerTryCatch(*m_spIsolateImpl);
FROM_MAYBE_TRY
@ -1302,7 +1302,7 @@ v8::MaybeLocal<v8::Promise> V8ContextImpl::ImportModule(v8::Local<v8::ScriptOrMo
v8::MaybeLocal<v8::Module> V8ContextImpl::ResolveModule(v8::Local<v8::String> hSpecifier, v8::Local<v8::Module> /*hReferrer*/)
{
V8IsolateImpl::TryCatch tryCatch(m_spIsolateImpl);
V8IsolateImpl::TryCatch tryCatch(*m_spIsolateImpl);
FROM_MAYBE_TRY

Просмотреть файл

@ -20,7 +20,7 @@ class V8ContextImpl final: public V8Context
public:
V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name);
V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name, const Options& options);
V8ContextImpl(SharedPtr<V8IsolateImpl>&& spIsolateImpl, const StdString& name, const Options& options);
static size_t GetInstanceCount();
const StdString& GetName() const { return m_Name; }
@ -45,8 +45,8 @@ public:
virtual V8ScriptHolder* Compile(const V8DocumentInfo& documentInfo, StdString&& code) override;
virtual V8ScriptHolder* Compile(const V8DocumentInfo& documentInfo, StdString&& code, V8CacheType cacheType, std::vector<uint8_t>& cacheBytes) override;
virtual V8ScriptHolder* Compile(const V8DocumentInfo& documentInfo, StdString&& code, V8CacheType cacheType, const std::vector<uint8_t>& cacheBytes, bool& cacheAccepted) override;
virtual bool CanExecute(V8ScriptHolder* pHolder) override;
virtual V8Value Execute(V8ScriptHolder* pHolder, bool evaluate) override;
virtual bool CanExecute(const SharedPtr<V8ScriptHolder>& spHolder) override;
virtual V8Value Execute(const SharedPtr<V8ScriptHolder>& spHolder, bool evaluate) override;
virtual void Interrupt() override;
virtual void GetIsolateHeapStatistics(v8::HeapStatistics& heapStatistics) override;

Просмотреть файл

@ -299,9 +299,25 @@ namespace V8 {
auto statistics = GetContext()->GetIsolateStatistics();
auto gcStatistics = gcnew V8Runtime::Statistics;
gcStatistics->ScriptCount = statistics.ScriptCount;
gcStatistics->ScriptCacheSize = statistics.ScriptCacheSize;
gcStatistics->ModuleCount = statistics.ModuleCount;
auto size = static_cast<int>(statistics.PostedTaskCounts.size());
gcStatistics->PostedTaskCounts = gcnew array<uint64_t>(size);
for (auto index = 0; index < size; index++)
{
gcStatistics->PostedTaskCounts[index] = statistics.PostedTaskCounts[index];
}
size = static_cast<int>(statistics.InvokedTaskCounts.size());
gcStatistics->InvokedTaskCounts = gcnew array<uint64_t>(size);
for (auto index = 0; index < size; index++)
{
gcStatistics->InvokedTaskCounts[index] = statistics.InvokedTaskCounts[index];
}
return gcStatistics;
}

Просмотреть файл

@ -11,6 +11,17 @@ class V8Isolate: public WeakRefTarget<V8Isolate>, public IV8Entity
{
public:
enum class TaskKind: uint16_t
{
Worker,
DelayedWorker,
Foreground,
DelayedForeground,
NonNestableForeground,
NonNestableDelayedForeground,
Count
};
struct Options final
{
bool EnableDebugging = false;
@ -21,9 +32,23 @@ public:
struct Statistics final
{
using TaskCounts = std::array<size_t, static_cast<size_t>(TaskKind::Count)>;
void BumpPostedTaskCount(TaskKind kind)
{
++PostedTaskCounts[static_cast<size_t>(kind)];
}
void BumpInvokedTaskCount(TaskKind kind)
{
++InvokedTaskCounts[static_cast<size_t>(kind)];
}
size_t ScriptCount = 0;
size_t ScriptCacheSize = 0;
size_t ModuleCount = 0;
TaskCounts PostedTaskCounts = {};
TaskCounts InvokedTaskCounts = {};
};
static V8Isolate* Create(const StdString& name, const v8::ResourceConstraints* pConstraints, const Options& options);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -24,23 +24,23 @@ class V8IsolateImpl final: public V8Isolate, public v8_inspector::V8InspectorCli
public:
explicit NativeScope(V8IsolateImpl* pIsolateImpl):
m_pIsolateImpl(pIsolateImpl),
m_LockScope(m_pIsolateImpl->m_spIsolate.get()),
m_IsolateScope(m_pIsolateImpl->m_spIsolate.get()),
m_HandleScope(m_pIsolateImpl->m_spIsolate.get())
explicit NativeScope(V8IsolateImpl& isolateImpl):
m_IsolateImpl(isolateImpl),
m_LockScope(m_IsolateImpl.m_upIsolate.get()),
m_IsolateScope(m_IsolateImpl.m_upIsolate.get()),
m_HandleScope(m_IsolateImpl.m_upIsolate.get())
{
m_pIsolateImpl->ProcessCallWithLockQueue();
m_IsolateImpl.ProcessCallWithLockQueue();
}
~NativeScope()
{
m_pIsolateImpl->ProcessCallWithLockQueue();
m_IsolateImpl.ProcessCallWithLockQueue();
}
private:
V8IsolateImpl* m_pIsolateImpl;
V8IsolateImpl& m_IsolateImpl;
v8::Locker m_LockScope;
v8::Isolate::Scope m_IsolateScope;
v8::HandleScope m_HandleScope;
@ -48,6 +48,8 @@ class V8IsolateImpl final: public V8Isolate, public v8_inspector::V8InspectorCli
public:
using CallWithLockCallback = std::function<void(V8IsolateImpl*)>;
class Scope final
{
PROHIBIT_COPY(Scope)
@ -55,9 +57,9 @@ public:
public:
explicit Scope(V8IsolateImpl* pIsolateImpl):
m_MutexLock(pIsolateImpl->m_Mutex),
m_NativeScope(pIsolateImpl)
explicit Scope(V8IsolateImpl& isolateImpl):
m_MutexLock(isolateImpl.m_Mutex),
m_NativeScope(isolateImpl)
{
}
@ -74,11 +76,11 @@ public:
public:
explicit ExecutionScope(V8IsolateImpl* pIsolateImpl):
m_pIsolateImpl(pIsolateImpl),
explicit ExecutionScope(V8IsolateImpl& isolateImpl):
m_IsolateImpl(isolateImpl),
m_ExecutionStarted(false)
{
m_pPreviousExecutionScope = m_pIsolateImpl->EnterExecutionScope(this, reinterpret_cast<size_t*>(&pIsolateImpl));
m_pPreviousExecutionScope = m_IsolateImpl.EnterExecutionScope(this, reinterpret_cast<size_t*>(this));
}
void OnExecutionStarted()
@ -93,12 +95,12 @@ public:
~ExecutionScope()
{
m_pIsolateImpl->ExitExecutionScope(m_pPreviousExecutionScope);
m_IsolateImpl.ExitExecutionScope(m_pPreviousExecutionScope);
}
private:
V8IsolateImpl* m_pIsolateImpl;
V8IsolateImpl& m_IsolateImpl;
ExecutionScope* m_pPreviousExecutionScope;
bool m_ExecutionStarted;
};
@ -110,21 +112,21 @@ public:
public:
DocumentScope(V8IsolateImpl* pIsolateImpl, const V8DocumentInfo& documentInfo):
m_pIsolateImpl(pIsolateImpl)
DocumentScope(V8IsolateImpl& isolateImpl, const V8DocumentInfo& documentInfo):
m_IsolateImpl(isolateImpl)
{
m_pPreviousDocumentInfo = m_pIsolateImpl->m_pDocumentInfo;
m_pIsolateImpl->m_pDocumentInfo = &documentInfo;
m_pPreviousDocumentInfo = m_IsolateImpl.m_pDocumentInfo;
m_IsolateImpl.m_pDocumentInfo = &documentInfo;
}
~DocumentScope()
{
m_pIsolateImpl->m_pDocumentInfo = m_pPreviousDocumentInfo;
m_IsolateImpl.m_pDocumentInfo = m_pPreviousDocumentInfo;
}
private:
V8IsolateImpl* m_pIsolateImpl;
V8IsolateImpl& m_IsolateImpl;
const V8DocumentInfo* m_pPreviousDocumentInfo;
};
@ -135,8 +137,8 @@ public:
public:
explicit TryCatch(V8IsolateImpl* pIsolateImpl):
v8::TryCatch(pIsolateImpl->m_spIsolate.get())
explicit TryCatch(V8IsolateImpl& isolateImpl):
v8::TryCatch(isolateImpl.m_upIsolate.get())
{
}
};
@ -152,102 +154,102 @@ public:
v8::Local<v8::Context> CreateContext(v8::ExtensionConfiguration* pExtensionConfiguation = nullptr, v8::Local<v8::ObjectTemplate> hGlobalTemplate = v8::Local<v8::ObjectTemplate>(), v8::Local<v8::Value> hGlobalObject = v8::Local<v8::Value>())
{
return v8::Context::New(m_spIsolate.get(), pExtensionConfiguation, hGlobalTemplate, hGlobalObject);
return v8::Context::New(m_upIsolate.get(), pExtensionConfiguation, hGlobalTemplate, hGlobalObject);
}
v8::Local<v8::Primitive> GetUndefined()
{
return v8::Undefined(m_spIsolate.get());
return v8::Undefined(m_upIsolate.get());
}
v8::Local<v8::Primitive> GetNull()
{
return v8::Null(m_spIsolate.get());
return v8::Null(m_upIsolate.get());
}
v8::Local<v8::Boolean> GetTrue()
{
return v8::True(m_spIsolate.get());
return v8::True(m_upIsolate.get());
}
v8::Local<v8::Boolean> GetFalse()
{
return v8::False(m_spIsolate.get());
return v8::False(m_upIsolate.get());
}
bool BooleanValue(v8::Local<v8::Value> hValue)
{
return hValue->BooleanValue(m_spIsolate.get());
return hValue->BooleanValue(m_upIsolate.get());
}
v8::Local<v8::Symbol> GetIteratorSymbol()
{
return v8::Symbol::GetIterator(m_spIsolate.get());
return v8::Symbol::GetIterator(m_upIsolate.get());
}
v8::Local<v8::Object> CreateObject()
{
return v8::Object::New(m_spIsolate.get());
return v8::Object::New(m_upIsolate.get());
}
v8::Local<v8::Number> CreateNumber(double value)
{
return v8::Number::New(m_spIsolate.get(), value);
return v8::Number::New(m_upIsolate.get(), value);
}
v8::Local<v8::Integer> CreateInteger(int32_t value)
{
return v8::Int32::New(m_spIsolate.get(), value);
return v8::Int32::New(m_upIsolate.get(), value);
}
v8::Local<v8::Integer> CreateInteger(uint32_t value)
{
return v8::Uint32::NewFromUnsigned(m_spIsolate.get(), value);
return v8::Uint32::NewFromUnsigned(m_upIsolate.get(), value);
}
v8::MaybeLocal<v8::String> CreateString(const StdString& value, v8::NewStringType type = v8::NewStringType::kNormal)
{
return value.ToV8String(m_spIsolate.get(), type);
return value.ToV8String(m_upIsolate.get(), type);
}
StdString CreateStdString(v8::Local<v8::Value> hValue)
{
return StdString(m_spIsolate.get(), hValue);
return StdString(m_upIsolate.get(), hValue);
}
v8::Local<v8::Symbol> CreateSymbol(v8::Local<v8::String> hName = v8::Local<v8::String>())
{
return v8::Symbol::New(m_spIsolate.get(), hName);
return v8::Symbol::New(m_upIsolate.get(), hName);
}
v8::Local<v8::Private> CreatePrivate(v8::Local<v8::String> hName = v8::Local<v8::String>())
{
return v8::Private::New(m_spIsolate.get(), hName);
return v8::Private::New(m_upIsolate.get(), hName);
}
v8::Local<v8::Array> CreateArray(int length = 0)
{
return v8::Array::New(m_spIsolate.get(), length);
return v8::Array::New(m_upIsolate.get(), length);
}
v8::Local<v8::External> CreateExternal(void* pvValue)
{
return v8::External::New(m_spIsolate.get(), pvValue);
return v8::External::New(m_upIsolate.get(), pvValue);
}
v8::Local<v8::ObjectTemplate> CreateObjectTemplate()
{
return v8::ObjectTemplate::New(m_spIsolate.get());
return v8::ObjectTemplate::New(m_upIsolate.get());
}
v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(v8::FunctionCallback callback = 0, v8::Local<v8::Value> data = v8::Local<v8::Value>(), v8::Local<v8::Signature> signature = v8::Local<v8::Signature>(), int length = 0)
{
return v8::FunctionTemplate::New(m_spIsolate.get(), callback, data, signature, length);
return v8::FunctionTemplate::New(m_upIsolate.get(), callback, data, signature, length);
}
v8::MaybeLocal<v8::UnboundScript> CompileUnboundScript(v8::ScriptCompiler::Source* pSource, v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileOptions, v8::ScriptCompiler::NoCacheReason noCacheReason = v8::ScriptCompiler::kNoCacheNoReason)
{
auto result = v8::ScriptCompiler::CompileUnboundScript(m_spIsolate.get(), pSource, options, noCacheReason);
auto result = v8::ScriptCompiler::CompileUnboundScript(m_upIsolate.get(), pSource, options, noCacheReason);
if (!result.IsEmpty())
{
@ -259,7 +261,7 @@ public:
v8::MaybeLocal<v8::Module> CompileModule(v8::ScriptCompiler::Source* pSource, v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileOptions, v8::ScriptCompiler::NoCacheReason noCacheReason = v8::ScriptCompiler::kNoCacheNoReason)
{
auto result = v8::ScriptCompiler::CompileModule(m_spIsolate.get(), pSource, options, noCacheReason);
auto result = v8::ScriptCompiler::CompileModule(m_upIsolate.get(), pSource, options, noCacheReason);
if (!result.IsEmpty())
{
@ -272,31 +274,31 @@ public:
template <typename T>
v8::Local<T> CreateLocal(v8::Local<T> hTarget)
{
return v8::Local<T>::New(m_spIsolate.get(), hTarget);
return v8::Local<T>::New(m_upIsolate.get(), hTarget);
}
template <typename T>
v8::Local<T> CreateLocal(Persistent<T> hTarget)
{
return hTarget.CreateLocal(m_spIsolate.get());
return hTarget.CreateLocal(m_upIsolate.get());
}
template <typename T>
Persistent<T> CreatePersistent(v8::Local<T> hTarget)
{
return Persistent<T>::New(m_spIsolate.get(), hTarget);
return Persistent<T>::New(m_upIsolate.get(), hTarget);
}
template <typename T>
Persistent<T> CreatePersistent(Persistent<T> hTarget)
{
return Persistent<T>::New(m_spIsolate.get(), hTarget);
return Persistent<T>::New(m_upIsolate.get(), hTarget);
}
template <typename T, typename TArg1, typename TArg2>
Persistent<T> MakeWeak(Persistent<T> hTarget, TArg1* pArg1, TArg2* pArg2, void (*pCallback)(v8::Isolate*, Persistent<T>*, TArg1*, TArg2*))
{
return hTarget.MakeWeak(m_spIsolate.get(), pArg1, pArg2, pCallback);
return hTarget.MakeWeak(m_upIsolate.get(), pArg1, pArg2, pCallback);
}
template <typename T>
@ -313,7 +315,7 @@ public:
v8::Local<v8::Value> ThrowException(v8::Local<v8::Value> hException)
{
return m_spIsolate->ThrowException(hException);
return m_upIsolate->ThrowException(hException);
}
bool IsDebuggingEnabled()
@ -334,59 +336,59 @@ public:
END_MUTEX_SCOPE
m_spIsolate->TerminateExecution();
m_upIsolate->TerminateExecution();
m_IsExecutionTerminating = true;
}
bool IsExecutionTerminating()
{
return m_spIsolate->IsExecutionTerminating() || m_IsExecutionTerminating;
return m_upIsolate->IsExecutionTerminating() || m_IsExecutionTerminating;
}
void CancelTerminateExecution()
{
m_spIsolate->CancelTerminateExecution();
m_upIsolate->CancelTerminateExecution();
m_IsExecutionTerminating = false;
}
int ContextDisposedNotification()
{
return m_spIsolate->ContextDisposedNotification();
return m_upIsolate->ContextDisposedNotification();
}
bool IdleNotificationDeadline(double deadlineInSeconds)
{
return m_spIsolate->IdleNotificationDeadline(deadlineInSeconds);
return m_upIsolate->IdleNotificationDeadline(deadlineInSeconds);
}
void LowMemoryNotification()
{
m_spIsolate->LowMemoryNotification();
m_upIsolate->LowMemoryNotification();
}
v8::Local<v8::StackFrame> GetStackFrame(v8::Local<v8::StackTrace> hStackTrace, uint32_t index)
{
return hStackTrace->GetFrame(m_spIsolate.get(), index);
return hStackTrace->GetFrame(m_upIsolate.get(), index);
}
void RequestInterrupt(v8::InterruptCallback callback, void* pvData)
{
m_spIsolate->RequestInterrupt(callback, pvData);
m_upIsolate->RequestInterrupt(callback, pvData);
}
bool IsCurrent() const
{
return m_spIsolate.get() == v8::Isolate::GetCurrent();
return m_upIsolate.get() == v8::Isolate::GetCurrent();
}
bool IsLocked() const
{
return v8::Locker::IsLocked(m_spIsolate.get());
return v8::Locker::IsLocked(m_upIsolate.get());
}
v8::Local<v8::String> GetTypeOf(v8::Local<v8::Value> hValue)
{
return !hValue.IsEmpty() ? hValue->TypeOf(m_spIsolate.get()) : GetUndefined()->TypeOf(m_spIsolate.get());
return !hValue.IsEmpty() ? hValue->TypeOf(m_upIsolate.get()) : GetUndefined()->TypeOf(m_upIsolate.get());
}
bool IsOutOfMemory() const
@ -429,8 +431,8 @@ public:
virtual v8::Local<v8::Context> ensureDefaultContextInGroup(int contextGroupId) override;
virtual double currentTimeMS() override;
virtual void sendResponse(int callId, std::unique_ptr<v8_inspector::StringBuffer> spMessage) override;
virtual void sendNotification(std::unique_ptr<v8_inspector::StringBuffer> spMessage) override;
virtual void sendResponse(int callId, std::unique_ptr<v8_inspector::StringBuffer> upMessage) override;
virtual void sendNotification(std::unique_ptr<v8_inspector::StringBuffer> upMessage) override;
virtual void flushProtocolNotifications() override;
void* AddRefV8Object(void* pvObject);
@ -439,13 +441,13 @@ public:
void* AddRefV8Script(void* pvScript);
void ReleaseV8Script(void* pvScript);
void RunTaskAsync(v8::Task* pTask);
void RunTaskDelayed(v8::Task* pTask, double delayInSeconds);
void RunTaskWithLockAsync(v8::Task* pTask);
void RunTaskWithLockDelayed(v8::Task* pTask, double delayInSeconds);
v8::TaskRunner* CreateForegroundTaskRunner();
void RunTaskAsync(std::unique_ptr<v8::Task> upTask);
void RunTaskDelayed(std::unique_ptr<v8::Task> upTask, double delayInSeconds);
void RunTaskWithLockAsync(bool allowNesting, std::unique_ptr<v8::Task> upTask);
void RunTaskWithLockDelayed(bool allowNesting, std::unique_ptr<v8::Task> upTask, double delayInSeconds);
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner();
void CallWithLockNoWait(std::function<void(V8IsolateImpl*)>&& callback);
void CallWithLockNoWait(bool allowNesting, CallWithLockCallback&& callback);
void DECLSPEC_NORETURN ThrowOutOfMemoryException();
static void ImportMetaInitializeCallback(v8::Local<v8::Context> hContext, v8::Local<v8::Module> hModule, v8::Local<v8::Object> hMeta);
@ -464,6 +466,9 @@ public:
private:
using CallWithLockEntry = std::pair<bool /*allowNesting*/, CallWithLockCallback>;
using CallWithLockQueue = std::queue<CallWithLockEntry>;
struct ContextEntry final
{
V8ContextImpl* pContextImpl;
@ -485,11 +490,12 @@ private:
bool RunMessageLoop(bool awaitingDebugger);
void CallWithLockAsync(std::function<void(V8IsolateImpl*)>&& callback);
void CallWithLockAsync(bool allowNesting, CallWithLockCallback&& callback);
static void ProcessCallWithLockQueue(v8::Isolate* pIsolate, void* pvIsolateImpl);
void ProcessCallWithLockQueue();
void ProcessCallWithLockQueue(std::unique_lock<std::mutex>& lock);
void ProcessCallWithLockQueue(std::queue<std::function<void(V8IsolateImpl*)>>& callWithLockQueue);
void ProcessCallWithLockQueue(CallWithLockQueue& callWithLockQueue);
CallWithLockQueue PopCallWithLockQueue(const std::unique_lock<std::mutex>& lock);
void ConnectDebugClient();
void SendDebugCommand(const StdString& command);
@ -508,25 +514,27 @@ private:
void FlushContextAsync(v8::Local<v8::Context> hContext);
void FlushContextAsync(ContextEntry& contextEntry);
void FlushContext(V8ContextImpl* pContextImpl);
void FlushContext(V8ContextImpl& contextImpl);
StdString m_Name;
UniqueDisposePtr<v8::Isolate> m_spIsolate;
UniqueDisposePtr<v8::CpuProfiler> m_spCpuProfiler;
UniqueDisposePtr<v8::Isolate> m_upIsolate;
UniqueDisposePtr<v8::CpuProfiler> m_upCpuProfiler;
Persistent<v8::Private> m_hHostObjectHolderKey;
RecursiveMutex m_Mutex;
std::list<ContextEntry> m_ContextEntries;
SimpleMutex m_DataMutex;
std::shared_ptr<v8::TaskRunner> m_spForegroundTaskRunner;
std::vector<std::shared_ptr<v8::Task>> m_AsyncTasks;
std::queue<std::function<void(V8IsolateImpl*)>> m_CallWithLockQueue;
CallWithLockQueue m_CallWithLockQueue;
std::condition_variable m_CallWithLockQueueChanged;
size_t m_CallWithLockLevel;
std::vector<SharedPtr<Timer>> m_TaskTimers;
std::list<ScriptCacheEntry> m_ScriptCache;
bool m_DebuggingEnabled;
int m_DebugPort;
void* m_pvDebugAgent;
std::unique_ptr<v8_inspector::V8Inspector> m_spInspector;
std::unique_ptr<v8_inspector::V8InspectorSession> m_spInspectorSession;
std::unique_ptr<v8_inspector::V8Inspector> m_upInspector;
std::unique_ptr<v8_inspector::V8InspectorSession> m_upInspectorSession;
bool m_AwaitingDebugger;
bool m_InMessageLoop;
bool m_QuitMessageLoop;

Просмотреть файл

@ -340,9 +340,25 @@ namespace V8 {
auto statistics = GetIsolate()->GetStatistics();
auto gcStatistics = gcnew V8Runtime::Statistics;
gcStatistics->ScriptCount = statistics.ScriptCount;
gcStatistics->ScriptCacheSize = statistics.ScriptCacheSize;
gcStatistics->ModuleCount = statistics.ModuleCount;
auto size = static_cast<int>(statistics.PostedTaskCounts.size());
gcStatistics->PostedTaskCounts = gcnew array<uint64_t>(size);
for (auto index = 0; index < size; index++)
{
gcStatistics->PostedTaskCounts[index] = statistics.PostedTaskCounts[index];
}
size = static_cast<int>(statistics.InvokedTaskCounts.size());
gcStatistics->InvokedTaskCounts = gcnew array<uint64_t>(size);
for (auto index = 0; index < size; index++)
{
gcStatistics->InvokedTaskCounts[index] = statistics.InvokedTaskCounts[index];
}
return gcStatistics;
}

Просмотреть файл

@ -3,97 +3,88 @@
#include "ClearScriptV8Native.h"
//-----------------------------------------------------------------------------
// local helper functions
//-----------------------------------------------------------------------------
V8ObjectHolderImpl* GetHolderImpl(V8ObjectHolder* pHolder)
{
return static_cast<V8ObjectHolderImpl*>(pHolder);
}
//-----------------------------------------------------------------------------
// V8ObjectHelpers implementation
//-----------------------------------------------------------------------------
V8Value V8ObjectHelpers::GetProperty(V8ObjectHolder* pHolder, const StdString& name)
V8Value V8ObjectHelpers::GetProperty(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name)
{
return GetHolderImpl(pHolder)->GetProperty(name);
return spHolder.DerefAs<V8ObjectHolderImpl>().GetProperty(name);
}
//-----------------------------------------------------------------------------
void V8ObjectHelpers::SetProperty(V8ObjectHolder* pHolder, const StdString& name, const V8Value& value)
void V8ObjectHelpers::SetProperty(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name, const V8Value& value)
{
GetHolderImpl(pHolder)->SetProperty(name, value);
spHolder.DerefAs<V8ObjectHolderImpl>().SetProperty(name, value);
}
//-----------------------------------------------------------------------------
bool V8ObjectHelpers::DeleteProperty(V8ObjectHolder* pHolder, const StdString& name)
bool V8ObjectHelpers::DeleteProperty(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name)
{
return GetHolderImpl(pHolder)->DeleteProperty(name);
return spHolder.DerefAs<V8ObjectHolderImpl>().DeleteProperty(name);
}
//-----------------------------------------------------------------------------
void V8ObjectHelpers::GetPropertyNames(V8ObjectHolder* pHolder, std::vector<StdString>& names)
void V8ObjectHelpers::GetPropertyNames(const SharedPtr<V8ObjectHolder>& spHolder, std::vector<StdString>& names)
{
GetHolderImpl(pHolder)->GetPropertyNames(names);
spHolder.DerefAs<V8ObjectHolderImpl>().GetPropertyNames(names);
}
//-----------------------------------------------------------------------------
V8Value V8ObjectHelpers::GetProperty(V8ObjectHolder* pHolder, int index)
V8Value V8ObjectHelpers::GetProperty(const SharedPtr<V8ObjectHolder>& spHolder, int index)
{
return GetHolderImpl(pHolder)->GetProperty(index);
return spHolder.DerefAs<V8ObjectHolderImpl>().GetProperty(index);
}
//-----------------------------------------------------------------------------
void V8ObjectHelpers::SetProperty(V8ObjectHolder* pHolder, int index, const V8Value& value)
void V8ObjectHelpers::SetProperty(const SharedPtr<V8ObjectHolder>& spHolder, int index, const V8Value& value)
{
GetHolderImpl(pHolder)->SetProperty(index, value);
spHolder.DerefAs<V8ObjectHolderImpl>().SetProperty(index, value);
}
//-----------------------------------------------------------------------------
bool V8ObjectHelpers::DeleteProperty(V8ObjectHolder* pHolder, int index)
bool V8ObjectHelpers::DeleteProperty(const SharedPtr<V8ObjectHolder>& spHolder, int index)
{
return GetHolderImpl(pHolder)->DeleteProperty(index);
return spHolder.DerefAs<V8ObjectHolderImpl>().DeleteProperty(index);
}
//-----------------------------------------------------------------------------
void V8ObjectHelpers::GetPropertyIndices(V8ObjectHolder* pHolder, std::vector<int>& indices)
void V8ObjectHelpers::GetPropertyIndices(const SharedPtr<V8ObjectHolder>& spHolder, std::vector<int>& indices)
{
GetHolderImpl(pHolder)->GetPropertyIndices(indices);
spHolder.DerefAs<V8ObjectHolderImpl>().GetPropertyIndices(indices);
}
//-----------------------------------------------------------------------------
V8Value V8ObjectHelpers::Invoke(V8ObjectHolder* pHolder, bool asConstructor, const std::vector<V8Value>& args)
V8Value V8ObjectHelpers::Invoke(const SharedPtr<V8ObjectHolder>& spHolder, bool asConstructor, const std::vector<V8Value>& args)
{
return GetHolderImpl(pHolder)->Invoke(asConstructor, args);
return spHolder.DerefAs<V8ObjectHolderImpl>().Invoke(asConstructor, args);
}
//-----------------------------------------------------------------------------
V8Value V8ObjectHelpers::InvokeMethod(V8ObjectHolder* pHolder, const StdString& name, const std::vector<V8Value>& args)
V8Value V8ObjectHelpers::InvokeMethod(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name, const std::vector<V8Value>& args)
{
return GetHolderImpl(pHolder)->InvokeMethod(name, args);
return spHolder.DerefAs<V8ObjectHolderImpl>().InvokeMethod(name, args);
}
//-----------------------------------------------------------------------------
void V8ObjectHelpers::GetArrayBufferOrViewInfo(V8ObjectHolder* pHolder, V8Value& arrayBuffer, size_t& offset, size_t& size, size_t& length)
void V8ObjectHelpers::GetArrayBufferOrViewInfo(const SharedPtr<V8ObjectHolder>& spHolder, V8Value& arrayBuffer, size_t& offset, size_t& size, size_t& length)
{
return GetHolderImpl(pHolder)->GetArrayBufferOrViewInfo(arrayBuffer, offset, size, length);
return spHolder.DerefAs<V8ObjectHolderImpl>().GetArrayBufferOrViewInfo(arrayBuffer, offset, size, length);
}
//-----------------------------------------------------------------------------
void V8ObjectHelpers::InvokeWithArrayBufferOrViewData(V8ObjectHolder* pHolder, ArrayBufferOrViewDataCallbackT* pCallback, void* pvArg)
void V8ObjectHelpers::InvokeWithArrayBufferOrViewData(const SharedPtr<V8ObjectHolder>& spHolder, ArrayBufferOrViewDataCallbackT* pCallback, void* pvArg)
{
return GetHolderImpl(pHolder)->InvokeWithArrayBufferOrViewData(pCallback, pvArg);
return spHolder.DerefAs<V8ObjectHolderImpl>().InvokeWithArrayBufferOrViewData(pCallback, pvArg);
}

Просмотреть файл

@ -13,20 +13,20 @@ class V8ObjectHelpers final
public:
static V8Value GetProperty(V8ObjectHolder* pHolder, const StdString& name);
static void SetProperty(V8ObjectHolder* pHolder, const StdString& name, const V8Value& value);
static bool DeleteProperty(V8ObjectHolder* pHolder, const StdString& name);
static void GetPropertyNames(V8ObjectHolder* pHolder, std::vector<StdString>& names);
static V8Value GetProperty(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name);
static void SetProperty(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name, const V8Value& value);
static bool DeleteProperty(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name);
static void GetPropertyNames(const SharedPtr<V8ObjectHolder>& spHolder, std::vector<StdString>& names);
static V8Value GetProperty(V8ObjectHolder* pHolder, int index);
static void SetProperty(V8ObjectHolder* pHolder, int index, const V8Value& value);
static bool DeleteProperty(V8ObjectHolder* pHolder, int index);
static void GetPropertyIndices(V8ObjectHolder* pHolder, std::vector<int>& indices);
static V8Value GetProperty(const SharedPtr<V8ObjectHolder>& spHolder, int index);
static void SetProperty(const SharedPtr<V8ObjectHolder>& spHolder, int index, const V8Value& value);
static bool DeleteProperty(const SharedPtr<V8ObjectHolder>& spHolder, int index);
static void GetPropertyIndices(const SharedPtr<V8ObjectHolder>& spHolder, std::vector<int>& indices);
static V8Value Invoke(V8ObjectHolder* pHolder, bool asConstructor, const std::vector<V8Value>& args);
static V8Value InvokeMethod(V8ObjectHolder* pHolder, const StdString& name, const std::vector<V8Value>& args);
static V8Value Invoke(const SharedPtr<V8ObjectHolder>& spHolder, bool asConstructor, const std::vector<V8Value>& args);
static V8Value InvokeMethod(const SharedPtr<V8ObjectHolder>& spHolder, const StdString& name, const std::vector<V8Value>& args);
typedef void ArrayBufferOrViewDataCallbackT(void* pvData, void* pvArg);
static void GetArrayBufferOrViewInfo(V8ObjectHolder* pHolder, V8Value& arrayBuffer, size_t& offset, size_t& size, size_t& length);
static void InvokeWithArrayBufferOrViewData(V8ObjectHolder* pHolder, ArrayBufferOrViewDataCallbackT* pCallback, void* pvArg);
static void GetArrayBufferOrViewInfo(const SharedPtr<V8ObjectHolder>& spHolder, V8Value& arrayBuffer, size_t& offset, size_t& size, size_t& length);
static void InvokeWithArrayBufferOrViewData(const SharedPtr<V8ObjectHolder>& spHolder, ArrayBufferOrViewDataCallbackT* pCallback, void* pvArg);
};

Просмотреть файл

@ -7,7 +7,7 @@
// V8ObjectHolder
//-----------------------------------------------------------------------------
class V8ObjectHolder
class V8ObjectHolder: public SharedPtrTarget
{
public:

Просмотреть файл

@ -7,7 +7,7 @@
// V8ObjectHolderImpl implementation
//-----------------------------------------------------------------------------
V8ObjectHolderImpl::V8ObjectHolderImpl(V8WeakContextBinding* pBinding, void* pvObject):
V8ObjectHolderImpl::V8ObjectHolderImpl(const SharedPtr<V8WeakContextBinding>& pBinding, void* pvObject):
m_spBinding(pBinding),
m_pvObject(pvObject)
{

Просмотреть файл

@ -13,7 +13,7 @@ class V8ObjectHolderImpl final: public V8ObjectHolder
public:
V8ObjectHolderImpl(V8WeakContextBinding* pBinding, void* pvObject);
V8ObjectHolderImpl(const SharedPtr<V8WeakContextBinding>& spBinding, void* pvObject);
virtual V8ObjectHolderImpl* Clone() const override;
virtual void* GetObject() const override;

Просмотреть файл

@ -9,9 +9,14 @@
#pragma warning(push, 3)
//#define V8_DEPRECATION_WARNINGS
#define V8_DEPRECATION_WARNINGS
//#define V8_IMMINENT_DEPRECATION_WARNINGS
#ifdef _M_X64
//#define V8_COMPRESS_POINTERS
//#define V8_31BIT_SMIS_ON_64BIT_ARCH
#endif //_M_X64
#include "v8.h"
#include "v8-platform.h"
#include "v8-inspector.h"

Просмотреть файл

@ -3,16 +3,22 @@
#pragma once
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
class V8IsolateImpl;
//-----------------------------------------------------------------------------
// V8ScriptHolder
//-----------------------------------------------------------------------------
class V8ScriptHolder
class V8ScriptHolder: public SharedPtrTarget
{
public:
virtual V8ScriptHolder* Clone() const = 0;
virtual bool IsSameIsolate(void* pvIsolate) const = 0;
virtual bool IsSameIsolate(const SharedPtr<V8IsolateImpl>& spThat) const = 0;
virtual void* GetScript() const = 0;
virtual const V8DocumentInfo& GetDocumentInfo() const = 0;
virtual size_t GetCodeDigest() const = 0;

Просмотреть файл

@ -7,8 +7,8 @@
// V8ScriptHolderImpl implementation
//-----------------------------------------------------------------------------
V8ScriptHolderImpl::V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest):
m_spBinding(pBinding),
V8ScriptHolderImpl::V8ScriptHolderImpl(const SharedPtr<V8WeakContextBinding>& spBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest):
m_spBinding(spBinding),
m_pvScript(pvScript),
m_DocumentInfo(documentInfo),
m_CodeDigest(codeDigest)
@ -17,8 +17,8 @@ V8ScriptHolderImpl::V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvS
//-----------------------------------------------------------------------------
V8ScriptHolderImpl::V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, StdString&& code):
m_spBinding(pBinding),
V8ScriptHolderImpl::V8ScriptHolderImpl(const SharedPtr<V8WeakContextBinding>& spBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, StdString&& code):
m_spBinding(spBinding),
m_pvScript(pvScript),
m_DocumentInfo(documentInfo),
m_Code(std::move(code)),
@ -28,8 +28,8 @@ V8ScriptHolderImpl::V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvS
//-----------------------------------------------------------------------------
V8ScriptHolderImpl::V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, const StdString& code, const std::vector<uint8_t>& cacheBytes):
m_spBinding(pBinding),
V8ScriptHolderImpl::V8ScriptHolderImpl(const SharedPtr<V8WeakContextBinding>& spBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, const StdString& code, const std::vector<uint8_t>& cacheBytes):
m_spBinding(spBinding),
m_pvScript(pvScript),
m_DocumentInfo(documentInfo),
m_CodeDigest(codeDigest),
@ -47,12 +47,12 @@ V8ScriptHolderImpl* V8ScriptHolderImpl::Clone() const
//-----------------------------------------------------------------------------
bool V8ScriptHolderImpl::IsSameIsolate(void* pvIsolate) const
bool V8ScriptHolderImpl::IsSameIsolate(const SharedPtr<V8IsolateImpl>& spThat) const
{
SharedPtr<V8IsolateImpl> spIsolateImpl;
if (m_spBinding->TryGetIsolateImpl(spIsolateImpl))
{
return spIsolateImpl.GetRawPtr() == pvIsolate;
return spIsolateImpl == spThat;
}
return false;

Просмотреть файл

@ -13,11 +13,11 @@ class V8ScriptHolderImpl final: public V8ScriptHolder
public:
V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest);
V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, StdString&& code);
V8ScriptHolderImpl(const SharedPtr<V8WeakContextBinding>& spBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest);
V8ScriptHolderImpl(const SharedPtr<V8WeakContextBinding>& spBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, StdString&& code);
virtual V8ScriptHolderImpl* Clone() const override;
virtual bool IsSameIsolate(void* pvIsolate) const override;
virtual bool IsSameIsolate(const SharedPtr<V8IsolateImpl>& spThat) const override;
virtual void* GetScript() const override;
virtual const V8DocumentInfo& GetDocumentInfo() const override;
virtual size_t GetCodeDigest() const override;
@ -30,7 +30,7 @@ public:
private:
V8ScriptHolderImpl(V8WeakContextBinding* pBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, const StdString& code, const std::vector<uint8_t>& cacheBytes);
V8ScriptHolderImpl(const SharedPtr<V8WeakContextBinding>& spBinding, void* pvScript, const V8DocumentInfo& documentInfo, size_t codeDigest, const StdString& code, const std::vector<uint8_t>& cacheBytes);
SharedPtr<V8WeakContextBinding> m_spBinding;
void* m_pvScript;

Просмотреть файл

@ -11,9 +11,9 @@ class V8WeakContextBinding final: public SharedPtrTarget
{
public:
V8WeakContextBinding(V8IsolateImpl* pIsolateImpl, V8ContextImpl* pContextImpl):
m_wrIsolate(pIsolateImpl->CreateWeakRef()),
m_IsolateName(pIsolateImpl->GetName()),
V8WeakContextBinding(const SharedPtr<V8IsolateImpl>& spIsolateImpl, V8ContextImpl* pContextImpl):
m_wrIsolate(spIsolateImpl->CreateWeakRef()),
m_IsolateName(spIsolateImpl->GetName()),
m_wrContext(pContextImpl->CreateWeakRef()),
m_ContextName(pContextImpl->GetName())
{
@ -35,7 +35,7 @@ public:
auto spIsolate = m_wrIsolate.GetTarget();
if (!spIsolate.IsEmpty())
{
spIsolateImpl = static_cast<V8IsolateImpl*>(spIsolate.GetRawPtr());
spIsolateImpl = spIsolate.CastTo<V8IsolateImpl>();
return true;
}
@ -58,7 +58,7 @@ public:
auto spContext = m_wrContext.GetTarget();
if (!spContext.IsEmpty())
{
spContextImpl = static_cast<V8ContextImpl*>(spContext.GetRawPtr());
spContextImpl = spContext.CastTo<V8ContextImpl>();
return true;
}

Просмотреть файл

@ -53,8 +53,8 @@ public:
private:
explicit WeakRef(WeakRefImpl<T>* pImpl):
m_spImpl(pImpl)
explicit WeakRef(const SharedPtr<WeakRefImpl<T>>& spImpl):
m_spImpl(spImpl)
{
}
@ -75,7 +75,7 @@ public:
{
}
WeakRef<T> CreateWeakRef()
WeakRef<T> CreateWeakRef() const
{
return WeakRef<T>(m_spWeakRefImpl);
}

Просмотреть файл

@ -1,25 +0,0 @@
diff --git a/third_party/libc++/BUILD.gn b/third_party/libc++/BUILD.gn
index c082724..bbfc92e 100644
--- a/third_party/libc++/BUILD.gn
+++ b/third_party/libc++/BUILD.gn
@@ -29,6 +29,12 @@ config("winver") {
]
}
+if (current_cpu == "x86") {
+ clearscript_v8_platform = "ia32"
+} else {
+ clearscript_v8_platform = current_cpu
+}
+
if (libcxx_is_shared) {
_libcxx_target_type = "shared_library"
} else {
@@ -51,6 +57,7 @@ target(_libcxx_target_type, "libc++") {
if (libcxx_is_shared) {
no_default_deps = true
}
+ output_name = "v8-libcpp-${clearscript_v8_platform}"
sources = [
"trunk/src/algorithm.cpp",
"trunk/src/any.cpp",

Просмотреть файл

@ -1,9 +1,18 @@
diff --git a/BUILD.gn b/BUILD.gn
index 5df0619b1d..66e318705e 100644
index 0ffa2b794d..ac34786897 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -211,6 +211,12 @@ if (v8_multi_arch_build &&
v8_enable_pointer_compression = !v8_enable_pointer_compression
@@ -507,7 +507,7 @@ config("toolchain") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
defines = []
- cflags = []
+ cflags = [ "-Wno-invalid-offsetof" ]
ldflags = []
if (v8_current_cpu == "arm") {
@@ -3509,7 +3509,14 @@ v8_source_set("torque_ls_base") {
}
}
+if (v8_current_cpu == "x86") {
@ -12,18 +21,12 @@ index 5df0619b1d..66e318705e 100644
+ clearscript_v8_platform = v8_current_cpu
+}
+
# Derived defaults.
if (v8_enable_verify_heap == "") {
v8_enable_verify_heap = v8_enable_debugging_features
@@ -3533,6 +3539,7 @@ v8_source_set("torque_ls_base") {
}
v8_component("v8_libbase") {
+ output_name = "v8-base-${clearscript_v8_platform}"
sources = [
"src/base/address-region.h",
"src/base/atomic-utils.h",
@@ -3733,6 +3740,7 @@ v8_component("v8_libbase") {
@@ -3710,6 +3717,7 @@ v8_component("v8_libbase") {
}
v8_component("v8_libplatform") {
@ -31,55 +34,19 @@ index 5df0619b1d..66e318705e 100644
sources = [
"//base/trace_event/common/trace_event_common.h",
"include/libplatform/libplatform-export.h",
@@ -4147,6 +4155,7 @@ group("v8_fuzzers") {
@@ -4104,6 +4112,7 @@ group("v8_fuzzers") {
if (is_component_build) {
v8_component("v8") {
+ output_name = "v8-${clearscript_v8_platform}"
sources = [
"src/utils/v8dll-main.cc",
]
diff --git a/include/v8-inspector.h b/include/v8-inspector.h
index 5f53f21d55..1e575d2abe 100644
--- a/include/v8-inspector.h
+++ b/include/v8-inspector.h
@@ -249,6 +249,7 @@ struct V8_EXPORT V8StackTraceId {
class V8_EXPORT V8Inspector {
public:
static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*);
+ static V8Inspector* createPtr(v8::Isolate*, V8InspectorClient*);
virtual ~V8Inspector() = default;
sources = [ "src/utils/v8dll-main.cc" ]
// Contexts instrumentation.
diff --git a/include/v8-platform.h b/include/v8-platform.h
index c6e78f2381..217e2bff08 100644
--- a/include/v8-platform.h
+++ b/include/v8-platform.h
@@ -444,6 +444,19 @@ class Platform {
V8_EXPORT static double SystemClockTimeMillis();
};
+class SafePlatform {
+ public:
+ virtual int NumberOfWorkerThreads() = 0;
+ virtual TaskRunner* CreateForegroundTaskRunner(Isolate* isolate) = 0;
+ virtual void CallOnWorkerThread(std::unique_ptr<Task> task) = 0;
+ virtual void CallDelayedOnWorkerThread(std::unique_ptr<Task> task, double delay_in_seconds) = 0;
+ virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0;
+ virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, double delay_in_seconds) = 0;
+ virtual double MonotonicallyIncreasingTime() = 0;
+ virtual double CurrentClockTimeMillis() = 0;
+ virtual TracingController* GetTracingController() = 0;
+ V8_EXPORT static void Initialize(SafePlatform& impl);
+};
} // namespace v8
#endif // V8_V8_PLATFORM_H_
public_deps = [
diff --git a/include/v8.h b/include/v8.h
index 1387f74715..8a03fc9320 100644
index d6f60c2562..622e10f80b 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1624,6 +1624,7 @@ class V8_EXPORT ScriptCompiler {
@@ -1659,6 +1659,7 @@ class V8_EXPORT ScriptCompiler {
// (with delete[]) when the CachedData object is destroyed.
CachedData(const uint8_t* data, int length,
BufferPolicy buffer_policy = BufferNotOwned);
@ -88,10 +55,10 @@ index 1387f74715..8a03fc9320 100644
// TODO(marja): Async compilation; add constructors which take a callback
// which will be called when V8 no longer needs the data.
diff --git a/src/api/api.cc b/src/api/api.cc
index 0d80f986f1..e1ac3ead27 100644
index 7fe974de24..50408a4f78 100644
--- a/src/api/api.cc
+++ b/src/api/api.cc
@@ -2047,6 +2047,10 @@ ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
@@ -2049,6 +2049,10 @@ ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
rejected(false),
buffer_policy(buffer_policy_) {}
@ -103,21 +70,21 @@ index 0d80f986f1..e1ac3ead27 100644
if (buffer_policy == BufferOwned) {
delete[] data;
diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc
index 3051ce3662..713ba80688 100644
index 702a64d091..63463fb477 100644
--- a/src/codegen/code-stub-assembler.cc
+++ b/src/codegen/code-stub-assembler.cc
@@ -12460,6 +12460,11 @@ TNode<String> CodeStubAssembler::Typeof(SloppyTNode<Object> value) {
@@ -11960,6 +11960,11 @@ TNode<String> CodeStubAssembler::Typeof(SloppyTNode<Object> value) {
GotoIf(InstanceTypeEqual(instance_type, ODDBALL_TYPE), &if_oddball);
+ Label resume_default(this);
+ GotoIfNot(Word32And(LoadMapBitField(map), Int32Constant(Map::HasNamedInterceptorBit::kMask)), &resume_default);
+ Branch(Word32And(LoadMapBitField2(map), Int32Constant(Map::IsImmutablePrototypeBit::kMask)), &return_function, &return_object);
+ GotoIfNot(Word32And(LoadMapBitField(map), Int32Constant(Map::Bits1::HasNamedInterceptorBit::kMask)), &resume_default);
+ Branch(Word32And(LoadMapBitField2(map), Int32Constant(Map::Bits2::IsImmutablePrototypeBit::kMask)), &return_function, &return_object);
+ BIND(&resume_default);
+
TNode<Int32T> callable_or_undetectable_mask = Word32And(
LoadMapBitField(map),
Int32Constant(Map::IsCallableBit::kMask | Map::IsUndetectableBit::kMask));
TNode<Int32T> callable_or_undetectable_mask =
Word32And(LoadMapBitField(map),
Int32Constant(Map::Bits1::IsCallableBit::kMask |
diff --git a/src/execution/stack-guard.cc b/src/execution/stack-guard.cc
index d37327f1c3..4f063b7bab 100644
--- a/src/execution/stack-guard.cc
@ -135,10 +102,10 @@ index d37327f1c3..4f063b7bab 100644
set_jslimit(SimulatorStack::JsLimitFromCLimit(isolate, limit));
real_climit_ = limit;
diff --git a/src/init/v8.cc b/src/init/v8.cc
index fd26c60848..a2081f5211 100644
index edcc399f95..119839bebb 100644
--- a/src/init/v8.cc
+++ b/src/init/v8.cc
@@ -124,7 +124,6 @@ void V8::InitializeOncePerProcess() {
@@ -123,7 +123,6 @@ void V8::InitializeOncePerProcess() {
}
void V8::InitializePlatform(v8::Platform* platform) {
@ -146,76 +113,11 @@ index fd26c60848..a2081f5211 100644
CHECK(platform);
platform_ = platform;
v8::base::SetPrintStackTrace(platform_->GetStackTracePrinter());
@@ -171,4 +170,49 @@ void V8::SetSnapshotBlob(StartupData* snapshot_blob) {
double Platform::SystemClockTimeMillis() {
return base::OS::TimeCurrentMillis();
}
+
+class SafePlatformImpl final: public Platform {
+ public:
+ void SetImpl(SafePlatform& impl) {
+ impl_.store(&impl);
+ }
+ virtual int NumberOfWorkerThreads() override {
+ return impl_.load()->NumberOfWorkerThreads();
+ }
+ virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(Isolate* isolate) override {
+ return std::shared_ptr<v8::TaskRunner>(impl_.load()->CreateForegroundTaskRunner(isolate));
+ }
+ virtual void CallOnWorkerThread(std::unique_ptr<Task> task) override {
+ impl_.load()->CallOnWorkerThread(std::move(task));
+ }
+ virtual void CallDelayedOnWorkerThread(std::unique_ptr<Task> task, double delay_in_seconds) override {
+ impl_.load()->CallDelayedOnWorkerThread(std::move(task), delay_in_seconds);
+ }
+ virtual void CallOnForegroundThread(Isolate* isolate, Task* task) override {
+ impl_.load()->CallOnForegroundThread(isolate, task);
+ }
+ virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, double delay_in_seconds) override {
+ impl_.load()->CallDelayedOnForegroundThread(isolate, task, delay_in_seconds);
+ }
+ virtual double MonotonicallyIncreasingTime() override {
+ return impl_.load()->MonotonicallyIncreasingTime();
+ }
+ virtual double CurrentClockTimeMillis() override {
+ return impl_.load()->CurrentClockTimeMillis();
+ }
+ virtual TracingController* GetTracingController() override {
+ return impl_.load()->GetTracingController();
+ }
+ private:
+ std::atomic<SafePlatform*> impl_;
+};
+
+void SafePlatform::Initialize(SafePlatform& impl) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+ static SafePlatformImpl platform;
+#pragma clang diagnostic pop
+ platform.SetImpl(impl);
+ V8::InitializePlatform(&platform);
+}
} // namespace v8
diff --git a/src/inspector/v8-inspector-impl.cc b/src/inspector/v8-inspector-impl.cc
index e91dd7f7f4..762b050add 100644
--- a/src/inspector/v8-inspector-impl.cc
+++ b/src/inspector/v8-inspector-impl.cc
@@ -54,6 +54,10 @@ std::unique_ptr<V8Inspector> V8Inspector::create(v8::Isolate* isolate,
return std::unique_ptr<V8Inspector>(new V8InspectorImpl(isolate, client));
}
+V8Inspector* V8Inspector::createPtr(v8::Isolate* isolate, V8InspectorClient* client) {
+ return create(isolate, client).release();
+}
+
V8InspectorImpl::V8InspectorImpl(v8::Isolate* isolate,
V8InspectorClient* client)
: m_isolate(isolate),
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 227cff8da4..828bf57e31 100644
index 9b53019297..3ca00b9e0e 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -811,6 +811,12 @@ Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
@@ -818,6 +818,12 @@ Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
if (object->IsString()) return isolate->factory()->string_string();
if (object->IsSymbol()) return isolate->factory()->symbol_string();
if (object->IsBigInt()) return isolate->factory()->bigint_string();

Просмотреть файл

@ -0,0 +1,23 @@
diff --git a/BUILD.gn b/BUILD.gn
index 2414c88..0e0e2bf 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -225,10 +225,18 @@ config("zlib_warnings") {
}
}
+if (current_cpu == "x86") {
+ clearscript_v8_platform = "ia32"
+} else {
+ clearscript_v8_platform = current_cpu
+}
+
component("zlib") {
if (!is_win) {
# Don't stomp on "libzlib" on other platforms.
output_name = "chrome_zlib"
+ } else {
+ output_name = "v8-zlib-${clearscript_v8_platform}"
}
sources = [

Просмотреть файл

@ -58,7 +58,7 @@ namespace Microsoft.ClearScript.V8
{
}
var hCppLibrary = LoadNativeLibrary("v8-libcpp");
var hZlibLibrary = LoadNativeLibrary("v8-zlib");
try
{
var hBaseLibrary = LoadNativeLibrary("v8-base");
@ -117,7 +117,7 @@ namespace Microsoft.ClearScript.V8
}
finally
{
NativeMethods.FreeLibrary(hCppLibrary);
NativeMethods.FreeLibrary(hZlibLibrary);
}
}

Просмотреть файл

@ -877,6 +877,21 @@ namespace Microsoft.ClearScript.V8
#endregion
#region Nested type: TaskKind
internal enum TaskKind : ushort
{
Worker,
DelayedWorker,
Foreground,
DelayedForeground,
NonNestableForeground,
NonNestableDelayedForeground,
Count
}
#endregion
#region Nested type: Statistics
internal sealed class Statistics
@ -884,6 +899,8 @@ namespace Microsoft.ClearScript.V8
public ulong ScriptCount;
public ulong ScriptCacheSize;
public ulong ModuleCount;
public ulong[] PostedTaskCounts;
public ulong[] InvokedTaskCounts;
}
#endregion

Просмотреть файл

@ -1271,7 +1271,7 @@ namespace Microsoft.ClearScript.V8
{
if (obj == null)
{
return Undefined.Value;
return UndefinedImportValue;
}
if (obj is DBNull)

Просмотреть файл

@ -140,7 +140,7 @@ namespace Microsoft.ClearScript.Windows
if (mask.HasFlag(ScriptInfoFlags.ITypeInfo))
{
pTypeInfo = item.GetType().GetITypeInfo();
pTypeInfo = item.GetType().GetTypeInfo();
}
}

Просмотреть файл

@ -314,7 +314,7 @@ namespace Microsoft.ClearScript.Windows
continue;
}
if ((item != null) && item.GetType().IsCOMObject)
if ((item != null) && (item.GetType().IsCOMObject || item.GetType().IsCOMVisible()))
{
directAccessItem = item;
return true;
@ -427,7 +427,7 @@ namespace Microsoft.ClearScript.Windows
{
if (obj == null)
{
return Undefined.Value;
return UndefinedImportValue;
}
if (obj is DBNull)
@ -802,6 +802,7 @@ namespace Microsoft.ClearScript.Windows
/// </remarks>
protected override void Dispose(bool disposing)
{
VerifyAccess();
if (disposedFlag.Set())
{
if (disposing)

Двоичные данные
ClearScript/doc/Build.docx

Двоичный файл не отображается.

Двоичные данные
ClearScript/doc/Reference.chm

Двоичный файл не отображается.

Просмотреть файл

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.ClearScript.Test</RootNamespace>
<AssemblyName>ClearScriptBenchmarks</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>

Просмотреть файл

@ -11,5 +11,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.0.0")]
[assembly: AssemblyVersion("6.0.1.0")]
[assembly: AssemblyFileVersion("6.0.1.0")]

Просмотреть файл

@ -14,6 +14,8 @@ namespace Microsoft.ClearScript.Test
{
public static void Main(string[] args)
{
HostSettings.UseAssemblyTable = true;
if ((args.Length == 2) && (args[0] == "-t"))
{
RunTest(args[1]);

Просмотреть файл

@ -11,5 +11,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.0.0")]
[assembly: AssemblyVersion("6.0.1.0")]
[assembly: AssemblyFileVersion("6.0.1.0")]

Просмотреть файл

@ -16,8 +16,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class AccessContextTest : ClearScriptTest
{

Просмотреть файл

@ -47,8 +47,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll", "BadV8Deployment_NoManagedAssembly")]
[DeploymentItem("v8-base-x64.dll", "BadV8Deployment_NoManagedAssembly")]
[DeploymentItem("v8-base-ia32.dll", "BadV8Deployment_NoManagedAssembly")]
[DeploymentItem("v8-libcpp-x64.dll", "BadV8Deployment_NoManagedAssembly")]
[DeploymentItem("v8-libcpp-ia32.dll", "BadV8Deployment_NoManagedAssembly")]
[DeploymentItem("v8-zlib-x64.dll", "BadV8Deployment_NoManagedAssembly")]
[DeploymentItem("v8-zlib-ia32.dll", "BadV8Deployment_NoManagedAssembly")]
public void BadV8Deployment_NoManagedAssembly()
{
V8Proxy.RunWithDeploymentDir("BadV8Deployment_NoManagedAssembly", () =>

Просмотреть файл

@ -17,8 +17,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class BaseMemberAccessTest : ClearScriptTest
{

Просмотреть файл

@ -32,8 +32,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[DeploymentItem("ClearScriptConsole.exe")]
[DeploymentItem("Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]

Просмотреть файл

@ -18,8 +18,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class CrossEngineTest : ClearScriptTest
{

Просмотреть файл

@ -15,8 +15,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
[SuppressMessage("ReSharper", "StringLiteralTypo")]
public class DynamicHostItemTest : ClearScriptTest

Просмотреть файл

@ -17,8 +17,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class ExplicitBaseInterfaceMemberAccessTest : ClearScriptTest
{

Просмотреть файл

@ -17,8 +17,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class ExtensionsTest : ClearScriptTest
{

Просмотреть файл

@ -17,8 +17,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class HostListTest : ClearScriptTest
{

Просмотреть файл

@ -18,8 +18,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class HostVariableTest : ClearScriptTest
{

Просмотреть файл

@ -12,6 +12,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Threading;
using Microsoft.ClearScript.JavaScript;
@ -31,8 +32,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[DeploymentItem("JavaScript", "JavaScript")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
[SuppressMessage("ReSharper", "StringLiteralTypo")]
@ -2592,6 +2593,72 @@ namespace Microsoft.ClearScript.Test
TestUtil.AssertException<FileNotFoundException>(() => engine.EvaluateDocument("JavaScript/LegacyCommonJS/Module", ModuleCategory.CommonJS));
}
[TestMethod, TestCategory("JScriptEngine")]
public void JScriptEngine_UndefinedImportValue()
{
Assert.IsNull(engine.Evaluate("null"));
Assert.IsInstanceOfType(engine.Evaluate("undefined"), typeof(Undefined));
engine.UndefinedImportValue = null;
Assert.IsNull(engine.Evaluate("null"));
Assert.IsNull(engine.Evaluate("undefined"));
engine.UndefinedImportValue = 123;
Assert.IsNull(engine.Evaluate("null"));
Assert.AreEqual(123, engine.Evaluate("undefined"));
}
[TestMethod, TestCategory("JScriptEngine")]
public void JScriptEngine_ExposeStaticMembersOnHostObjects()
{
engine.Script.utf8 = Encoding.UTF8;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Undefined));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ReferenceEquals"), typeof(Undefined));
engine.ExposeHostObjectStaticMembers = true;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Encoding));
Assert.IsTrue(Convert.ToBoolean(engine.Evaluate("utf8.ReferenceEquals(null, null)")));
engine.ExposeHostObjectStaticMembers = false;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Undefined));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ReferenceEquals"), typeof(Undefined));
}
[TestMethod, TestCategory("JScriptEngine")]
public void JScriptEngine_DirectAccess_Normal()
{
engine.Script.test = new DirectAccessTestObject();
engine.AddHostObject("daTest", HostItemFlags.DirectAccess, engine.Script.test);
Assert.AreEqual("[HostObject:JScriptEngineTest.DirectAccessTestObject]", engine.ExecuteCommand("test"));
Assert.AreEqual("[HostObject:JScriptEngineTest.DirectAccessTestObject]", engine.ExecuteCommand("daTest"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("test.Format('{0} {1} {2}', 123, 456.789, 'qux')"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("daTest.Format('{0} {1} {2}', 123, 456.789, 'qux')"));
Assert.AreEqual(0, engine.Evaluate("test.Bogus(123.456)"));
Assert.AreEqual(0, engine.Evaluate("daTest.Bogus(123.456)"));
}
[TestMethod, TestCategory("JScriptEngine")]
public void JScriptEngine_DirectAccess_ComVisible()
{
engine.Script.test = new ComVisibleTestObject();
engine.AddHostObject("daTest", HostItemFlags.DirectAccess, engine.Script.test);
Assert.AreEqual("[HostObject:JScriptEngineTest.ComVisibleTestObject]", engine.ExecuteCommand("test"));
Assert.AreNotEqual("[HostObject:JScriptEngineTest.ComVisibleTestObject]", engine.ExecuteCommand("daTest"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("test.Format('{0} {1} {2}', 123, 456.789, 'qux')"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("daTest.Format('{0} {1} {2}', 123, 456.789, 'qux')"));
Assert.AreEqual(0, engine.Evaluate("test.Bogus(123.456)"));
TestUtil.AssertException<ScriptEngineException>(() => engine.Evaluate("daTest.Bogus(123.456)"));
}
// ReSharper restore InconsistentNaming
#endregion
@ -2676,6 +2743,33 @@ namespace Microsoft.ClearScript.Test
private delegate string TestDelegate(string pre, ref string value, int post);
public sealed class DirectAccessTestObject
{
public string Format(string format, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null)
{
return MiscHelpers.FormatInvariant(format, arg0, arg1, arg2, arg3);
}
public T Bogus<T>(T arg)
{
return default(T);
}
}
[ComVisible(true)]
public sealed class ComVisibleTestObject
{
public string Format(string format, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null)
{
return MiscHelpers.FormatInvariant(format, arg0, arg1, arg2, arg3);
}
public T Bogus<T>(T arg)
{
return default(T);
}
}
// ReSharper restore UnusedMember.Local
#endregion

Просмотреть файл

@ -19,8 +19,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[DeploymentItem("JavaScript", "JavaScript")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
[SuppressMessage("ReSharper", "StringLiteralTypo")]

Просмотреть файл

@ -18,8 +18,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class MemberAccessTest : ClearScriptTest
{

Просмотреть файл

@ -11,5 +11,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.0.0")]
[assembly: AssemblyVersion("6.0.1.0")]
[assembly: AssemblyFileVersion("6.0.1.0")]

Просмотреть файл

@ -19,8 +19,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class PropertyBagTest : ClearScriptTest
{

Просмотреть файл

@ -18,8 +18,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class ScriptAccessTest : ClearScriptTest
{

Просмотреть файл

@ -17,8 +17,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class StaticMemberAccessTest : ClearScriptTest
{

Просмотреть файл

@ -14,8 +14,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class TypeRestrictionTest : ClearScriptTest
{

Просмотреть файл

@ -18,8 +18,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class V8ArrayBufferOrViewTest : ClearScriptTest
{

Просмотреть файл

@ -19,8 +19,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[DeploymentItem("JavaScript", "JavaScript")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class V8ModuleTest : ClearScriptTest

Просмотреть файл

@ -34,8 +34,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[DeploymentItem("JavaScript", "JavaScript")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
[SuppressMessage("ReSharper", "StringLiteralTypo")]
@ -1560,14 +1560,14 @@ namespace Microsoft.ClearScript.Test
public void V8ScriptEngine_MaxRuntimeHeapSize_Dual()
{
const int limit = 4 * 1024 * 1024;
const string code = @"x = []; for (i = 0; i < 16 * 1024 * 1024; i++) { x.push(x); }";
const string code = @"x = []; for (i = 0; i < 64 * 1024 * 1024; i++) { x.push(x); }";
engine.Execute(code);
engine.CollectGarbage(true);
var usedHeapSize = engine.GetRuntimeHeapInfo().UsedHeapSize;
engine.Dispose();
engine = new V8ScriptEngine { MaxRuntimeHeapSize = (UIntPtr)limit };
engine = new V8ScriptEngine(V8ScriptEngineFlags.EnableDebugging) { MaxRuntimeHeapSize = (UIntPtr)limit };
TestUtil.AssertException<ScriptEngineException>(() =>
{
@ -3479,6 +3479,40 @@ namespace Microsoft.ClearScript.Test
Assert.AreEqual("[]", JsonConvert.SerializeObject(engine.Evaluate("array")));
}
[TestMethod, TestCategory("V8ScriptEngine")]
public void V8ScriptEngine_UndefinedImportValue()
{
Assert.IsNull(engine.Evaluate("null"));
Assert.IsInstanceOfType(engine.Evaluate("undefined"), typeof(Undefined));
engine.UndefinedImportValue = null;
Assert.IsNull(engine.Evaluate("null"));
Assert.IsNull(engine.Evaluate("undefined"));
engine.UndefinedImportValue = 123;
Assert.IsNull(engine.Evaluate("null"));
Assert.AreEqual(123, engine.Evaluate("undefined"));
}
[TestMethod, TestCategory("V8ScriptEngine")]
public void V8ScriptEngine_ExposeStaticMembersOnHostObjects()
{
engine.Script.utf8 = Encoding.UTF8;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Undefined));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ReferenceEquals"), typeof(Undefined));
engine.ExposeHostObjectStaticMembers = true;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Encoding));
Assert.IsTrue(Convert.ToBoolean(engine.Evaluate("utf8.ReferenceEquals(null, null)")));
engine.ExposeHostObjectStaticMembers = false;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Undefined));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ReferenceEquals"), typeof(Undefined));
}
// ReSharper restore InconsistentNaming
#endregion

Просмотреть файл

@ -12,6 +12,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Threading;
using Microsoft.CSharp.RuntimeBinder;
@ -30,8 +31,8 @@ namespace Microsoft.ClearScript.Test
[DeploymentItem("v8-ia32.dll")]
[DeploymentItem("v8-base-x64.dll")]
[DeploymentItem("v8-base-ia32.dll")]
[DeploymentItem("v8-libcpp-x64.dll")]
[DeploymentItem("v8-libcpp-ia32.dll")]
[DeploymentItem("v8-zlib-x64.dll")]
[DeploymentItem("v8-zlib-ia32.dll")]
[DeploymentItem("VBScript", "VBScript")]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
[SuppressMessage("ReSharper", "StringLiteralTypo")]
@ -2760,6 +2761,75 @@ namespace Microsoft.ClearScript.Test
}
}
[TestMethod, TestCategory("VBScriptEngine")]
public void VBScriptEngine_UndefinedImportValue()
{
Assert.IsNull(engine.Evaluate("null"));
Assert.IsInstanceOfType(engine.Evaluate("empty"), typeof(Undefined));
Assert.IsInstanceOfType(engine.Evaluate("nothing"), typeof(Undefined));
engine.UndefinedImportValue = null;
Assert.IsNull(engine.Evaluate("null"));
Assert.IsNull(engine.Evaluate("empty"));
Assert.IsNull(engine.Evaluate("nothing"));
engine.UndefinedImportValue = 123;
Assert.IsNull(engine.Evaluate("null"));
Assert.AreEqual(123, engine.Evaluate("empty"));
Assert.AreEqual(123, engine.Evaluate("nothing"));
}
[TestMethod, TestCategory("VBScriptEngine")]
public void VBScriptEngine_ExposeStaticMembersOnHostObjects()
{
engine.Script.utf8 = Encoding.UTF8;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
TestUtil.AssertException<ScriptEngineException>(() => engine.Evaluate("utf8.ASCII"));
TestUtil.AssertException<ScriptEngineException>(() => engine.Evaluate("utf8.ReferenceEquals"));
engine.ExposeHostObjectStaticMembers = true;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Encoding));
Assert.IsTrue(Convert.ToBoolean(engine.Evaluate("utf8.ReferenceEquals(null, null)")));
engine.ExposeHostObjectStaticMembers = false;
Assert.AreEqual("utf-8", engine.Evaluate("utf8.WebName"));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ASCII"), typeof(Undefined));
Assert.IsInstanceOfType(engine.Evaluate("utf8.ReferenceEquals"), typeof(Undefined));
}
[TestMethod, TestCategory("VBScriptEngine")]
public void VBScriptEngine_DirectAccess_Normal()
{
engine.Script.test = new DirectAccessTestObject();
engine.AddHostObject("daTest", HostItemFlags.DirectAccess, engine.Script.test);
Assert.AreEqual("[HostObject:VBScriptEngineTest.DirectAccessTestObject]", engine.ExecuteCommand("eval test"));
Assert.AreEqual("[HostObject:VBScriptEngineTest.DirectAccessTestObject]", engine.ExecuteCommand("eval daTest"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("test.Format(\"{0} {1} {2}\", 123, 456.789, \"qux\")"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("daTest.Format(\"{0} {1} {2}\", 123, 456.789, \"qux\")"));
Assert.AreEqual(0, engine.Evaluate("test.Bogus(123.456)"));
Assert.AreEqual(0, engine.Evaluate("daTest.Bogus(123.456)"));
}
[TestMethod, TestCategory("VBScriptEngine")]
public void VBScriptEngine_DirectAccess_ComVisible()
{
engine.Script.test = new ComVisibleTestObject();
engine.AddHostObject("daTest", HostItemFlags.DirectAccess, engine.Script.test);
Assert.AreEqual("[HostObject:VBScriptEngineTest.ComVisibleTestObject]", engine.ExecuteCommand("eval test"));
Assert.AreNotEqual("[HostObject:VBScriptEngineTest.ComVisibleTestObject]", engine.ExecuteCommand("eval daTest"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("test.Format(\"{0} {1} {2}\", 123, 456.789, \"qux\")"));
Assert.AreEqual("123 456.789 qux", engine.Evaluate("daTest.Format(\"{0} {1} {2}\", 123, 456.789, \"qux\")"));
Assert.AreEqual(0, engine.Evaluate("test.Bogus(123.456)"));
TestUtil.AssertException<ScriptEngineException>(() => engine.Evaluate("daTest.Bogus(123.456)"));
}
// ReSharper restore InconsistentNaming
#endregion
@ -2908,6 +2978,33 @@ namespace Microsoft.ClearScript.Test
private delegate string TestDelegate(string pre, ref string value, int post);
public sealed class DirectAccessTestObject
{
public string Format(string format, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null)
{
return MiscHelpers.FormatInvariant(format, arg0, arg1, arg2, arg3);
}
public T Bogus<T>(T arg)
{
return default(T);
}
}
[ComVisible(true)]
public sealed class ComVisibleTestObject
{
public string Format(string format, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null)
{
return MiscHelpers.FormatInvariant(format, arg0, arg1, arg2, arg3);
}
public T Bogus<T>(T arg)
{
return default(T);
}
}
#endregion
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше