Version 5.4.3: Added support for Visual Studio 2015; changed V8Update to use installed Python 2.x; fixed hangs in V8 proxy finalizers during script execution (Issue #86); fixed V8 weak handle callback context leak (Issue #90); fixed dynamic method invocation with value-typed arguments (Issue #89); improved V8ScriptEngine::Interrupt() latency and reliability; added tests for bug fixes. Tested with V8 4.4.63.29.

This commit is contained in:
ClearScript 2015-08-16 12:42:51 -04:00
Родитель 8baf6a9ee6
Коммит ba8bf459e4
78 изменённых файлов: 1787 добавлений и 768 удалений

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

@ -1,12 +1,15 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp40</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToConditionalTernaryExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToNullCoalescingExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImpureMethodCallOnReadonlyValueField/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBeConvertedToQuery/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterTypeCanBeEnumerable_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveConstuctorInvocation/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringEndsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringStartsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VBStringEndsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VBStringStartsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String>
@ -18,7 +21,21 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_TYPEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CLSID/@EntryIndexedValue">CLSID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=COM/@EntryIndexedValue">COM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DOM/@EntryIndexedValue">DOM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GC/@EntryIndexedValue">GC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JIT/@EntryIndexedValue">JIT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JS/@EntryIndexedValue">JS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LCID/@EntryIndexedValue">LCID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=URL/@EntryIndexedValue">URL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VB/@EntryIndexedValue">VB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VBS/@EntryIndexedValue">VBS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

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

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp40</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToConditionalTernaryExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToNullCoalescingExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImpureMethodCallOnReadonlyValueField/@EntryIndexedValue">DO_NOT_SHOW</s:String>
@ -35,4 +36,6 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

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

@ -94,6 +94,7 @@
<Compile Include="Util\IScriptMarshalWrapper.cs" />
<Compile Include="Util\MemberHelpers.cs" />
<Compile Include="Util\MemberMap.cs" />
<Compile Include="Util\Scope.cs" />
<Compile Include="Util\SocketHelpers.cs" />
<Compile Include="Util\SpecialDispIDs.cs" />
<Compile Include="V8\IV8DebugListener.cs" />
@ -105,6 +106,7 @@
<Compile Include="V8\V8RuntimeConstraints.cs" />
<Compile Include="V8\V8Runtime.cs" />
<Compile Include="V8\V8RuntimeFlags.cs" />
<Compile Include="V8\V8TestProxy.cs" />
<Compile Include="Windows\IHostWindow.cs" />
<Compile Include="Windows\WindowsScriptEngineFlags.cs" />
<Compile Include="Util\IDynamic.cs" />

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

@ -195,7 +195,7 @@ namespace Microsoft.ClearScript
// ReSharper disable AssignNullToNotNullAttribute
var constructor = innerParamTypes[index].GetConstructor(new[] { paramTypes[index].GetElementType() });
topExprs.Add(Expression.Assign(varExprs[index], Expression.New(constructor, new[] { paramExprs[index] })));
topExprs.Add(Expression.Assign(varExprs[index], Expression.New(constructor, paramExprs[index])));
// ReSharper restore AssignNullToNotNullAttribute
}

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

@ -63,5 +63,5 @@
#pragma once
#define CLEARSCRIPT_VERSION_STRING "5.4.2.1"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 5,4,2,1
#define CLEARSCRIPT_VERSION_STRING "5.4.3.0"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 5,4,3,0

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

@ -246,7 +246,9 @@ namespace Microsoft.ClearScript
{
var hostItem = engine.MarshalToScript(value) as HostItem;
if (hostItem != null)
{
return hostItem.InvokeMember(SpecialMemberNames.Default, invokeFlags, args, bindArgs, culture, true, out isCacheable);
}
}
}
}

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

@ -92,7 +92,7 @@ namespace Microsoft.ClearScript
#endregion
#region Nested type : CollateralObject
#region Nested type : CollateralObject<T>
public class CollateralObject<T> : CollateralObject<HostItem, T> where T : class
{

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

@ -189,7 +189,7 @@ namespace Microsoft.ClearScript
#endregion
#region Nested type: NullWrapper
#region Nested type: NullWrapper<T>
// ReSharper disable UnusedMember.Local

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

@ -75,5 +75,5 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ClearScriptTest")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("5.4.2.1")]
[assembly: AssemblyFileVersion("5.4.2.1")]
[assembly: AssemblyVersion("5.4.3.0")]
[assembly: AssemblyFileVersion("5.4.3.0")]

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

@ -1222,6 +1222,9 @@ namespace Microsoft.ClearScript
internal void RequestInterrupt()
{
// Some script engines don't support IActiveScript::InterruptScriptThread(). This
// method provides an alternate mechanism based on IActiveScriptSiteInterruptPoll.
var tempScriptFrame = CurrentScriptFrame;
if (tempScriptFrame != null)
{

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

@ -90,6 +90,7 @@ namespace Microsoft.ClearScript
public ScriptEngineException()
: base(defaultMessage)
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
@ -100,6 +101,7 @@ namespace Microsoft.ClearScript
public ScriptEngineException(string message)
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage))
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
@ -111,6 +113,7 @@ namespace Microsoft.ClearScript
public ScriptEngineException(string message, Exception innerException)
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage), innerException)
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
@ -131,6 +134,7 @@ namespace Microsoft.ClearScript
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage), innerException)
{
this.engineName = engineName;
// ReSharper disable once RedundantBaseQualifier
this.errorDetails = MiscHelpers.EnsureNonBlank(errorDetails, base.Message);
this.isFatal = isFatal;

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

@ -90,6 +90,7 @@ namespace Microsoft.ClearScript
public ScriptInterruptedException()
: base(defaultMessage)
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
@ -100,6 +101,7 @@ namespace Microsoft.ClearScript
public ScriptInterruptedException(string message)
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage))
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
@ -111,6 +113,7 @@ namespace Microsoft.ClearScript
public ScriptInterruptedException(string message, Exception innerException)
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage), innerException)
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
@ -131,6 +134,7 @@ namespace Microsoft.ClearScript
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage), innerException)
{
this.engineName = engineName;
// ReSharper disable once RedundantBaseQualifier
this.errorDetails = MiscHelpers.EnsureNonBlank(errorDetails, base.Message);
this.isFatal = isFatal;

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

@ -64,6 +64,21 @@ using System.Threading;
namespace Microsoft.ClearScript.Util
{
internal struct DisposedFlag
{
private bool disposed;
public bool IsSet()
{
return disposed;
}
public bool Set()
{
return MiscHelpers.Exchange(ref disposed, true) == false;
}
}
internal struct InterlockedDisposedFlag
{
private int disposed;

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

@ -731,10 +731,16 @@ namespace Microsoft.ClearScript.Util
}
// construct an algorithm for invoking a member value
var argExprs = new[] { Expression.Constant(context), target.Expression, Expression.Constant(invokeFlags), Expression.NewArrayInit(typeof(object), args.Select(arg => arg.Expression)) };
var argExprs = new[] { Expression.Constant(context), target.Expression, Expression.Constant(invokeFlags), Expression.NewArrayInit(typeof(object), args.Select(GetArgRefExpr)) };
return new DynamicMetaObject(Expression.Call(invokeMemberValueMethod, argExprs), BindingRestrictions.Empty);
}
private static Expression GetArgRefExpr(DynamicMetaObject arg)
{
var argExpr = arg.Expression;
return argExpr.Type.IsValueType ? Expression.Convert(argExpr, typeof(object)) : argExpr;
}
// ReSharper disable UnusedMember.Local
private static object InvokeMemberValue(IHostInvokeContext context, object target, BindingFlags invokeFlags, object[] args)

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

@ -418,7 +418,7 @@ namespace Microsoft.ClearScript.Util
#endregion
#region Nested type: MemberMapImpl
#region Nested type: MemberMapImpl<T>
private class MemberMapImpl<T> : MemberMapBase where T : MemberInfo
{

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

@ -353,7 +353,14 @@ namespace Microsoft.ClearScript.Util
}
}
#region Nested type: EmptyArray
public static T Exchange<T>(ref T target, T value)
{
T oldValue = target;
target = value;
return oldValue;
}
#region Nested type: EmptyArray<T>
private static class EmptyArray<T>
{

145
ClearScript/Util/Scope.cs Normal file
Просмотреть файл

@ -0,0 +1,145 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Microsoft Public License (MS-PL)
//
// This license governs use of the accompanying software. If you use the
// software, you accept this license. If you do not accept the license, do not
// use the software.
//
// 1. Definitions
//
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S. copyright law. A
// "contribution" is the original software, or any additions or changes to
// the software. A "contributor" is any person that distributes its
// contribution under this license. "Licensed patents" are a contributor's
// patent claims that read directly on its contribution.
//
// 2. Grant of Rights
//
// (A) Copyright Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free copyright license
// to reproduce its contribution, prepare derivative works of its
// contribution, and distribute its contribution or any derivative works
// that you create.
//
// (B) Patent Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free license under its
// licensed patents to make, have made, use, sell, offer for sale,
// import, and/or otherwise dispose of its contribution in the software
// or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
//
// (A) No Trademark License- This license does not grant you rights to use
// any contributors' name, logo, or trademarks.
//
// (B) If you bring a patent claim against any contributor over patents that
// you claim are infringed by the software, your patent license from such
// contributor to the software ends automatically.
//
// (C) If you distribute any portion of the software, you must retain all
// copyright, patent, trademark, and attribution notices that are present
// in the software.
//
// (D) If you distribute any portion of the software in source code form, you
// may do so only under this license by including a complete copy of this
// license with your distribution. If you distribute any portion of the
// software in compiled or object code form, you may only do so under a
// license that complies with this license.
//
// (E) The software is licensed "as-is." You bear the risk of using it. The
// contributors give no express warranties, guarantees or conditions. You
// may have additional consumer rights under your local laws which this
// license cannot change. To the extent permitted under your local laws,
// the contributors exclude the implied warranties of merchantability,
// fitness for a particular purpose and non-infringement.
//
using System;
namespace Microsoft.ClearScript.Util
{
internal interface IScope<out T>: IDisposable
{
T Value { get; }
}
internal static class Scope
{
public static IDisposable Create(Action enterAction, Action exitAction)
{
return new ScopeImpl(enterAction, exitAction);
}
public static IScope<T> Create<T>(Func<T> enterFunc, Action<T> exitAction)
{
return new ScopeImpl<T>(enterFunc, exitAction);
}
#region Nested type: ScopeImpl
private class ScopeImpl : IDisposable
{
private readonly Action exitAction;
private DisposedFlag disposedFlag = new DisposedFlag();
public ScopeImpl(Action enterAction, Action exitAction)
{
this.exitAction = exitAction;
enterAction();
}
#region IDisposable implementation
public void Dispose()
{
if (disposedFlag.Set() && (exitAction != null))
{
exitAction();
}
}
#endregion
}
#endregion
#region Nested type: ScopeImpl<T>
private class ScopeImpl<T> : IScope<T>
{
private readonly T value;
private readonly Action<T> exitAction;
private DisposedFlag disposedFlag = new DisposedFlag();
public ScopeImpl(Func<T> enterFunc, Action<T> exitAction)
{
this.exitAction = exitAction;
value = enterFunc();
}
#region IScope<T> implementation
public T Value
{
get { return value; }
}
public void Dispose()
{
if (disposedFlag.Set() && (exitAction != null))
{
exitAction(value);
}
}
#endregion
}
#endregion
}
}

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

@ -30,7 +30,10 @@
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='14.0'">
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='12.0'">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -164,6 +167,7 @@
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
</ClCompile>
<ClCompile Include="..\V8ScriptImpl.cpp" />
<ClCompile Include="..\V8TestProxyImpl.cpp" />
<ClCompile Include="AssemblyInfo.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -236,6 +240,7 @@
<ClInclude Include="..\V8ScriptHolder.h" />
<ClInclude Include="..\V8ScriptHolderImpl.h" />
<ClInclude Include="..\V8ScriptImpl.h" />
<ClInclude Include="..\V8TestProxyImpl.h" />
<ClInclude Include="..\V8Value.h" />
<ClInclude Include="..\V8WeakContextBinding.h" />
<ClInclude Include="..\WeakRef.h" />

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

@ -58,6 +58,9 @@
<ClCompile Include="..\HighResolutionClock.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\V8TestProxyImpl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
@ -187,5 +190,8 @@
<ClInclude Include="..\HighResolutionClock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\V8TestProxyImpl.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

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

@ -30,7 +30,10 @@
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='14.0'">
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='12.0'">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -165,6 +168,7 @@
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
</ClCompile>
<ClCompile Include="..\V8ScriptImpl.cpp" />
<ClCompile Include="..\V8TestProxyImpl.cpp" />
<ClCompile Include="AssemblyInfo.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -237,6 +241,7 @@
<ClInclude Include="..\V8ScriptHolder.h" />
<ClInclude Include="..\V8ScriptHolderImpl.h" />
<ClInclude Include="..\V8ScriptImpl.h" />
<ClInclude Include="..\V8TestProxyImpl.h" />
<ClInclude Include="..\V8Value.h" />
<ClInclude Include="..\V8WeakContextBinding.h" />
<ClInclude Include="..\WeakRef.h" />

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

@ -58,6 +58,9 @@
<ClCompile Include="..\HighResolutionClock.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\V8TestProxyImpl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
@ -187,5 +190,8 @@
<ClInclude Include="..\HighResolutionClock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\V8TestProxyImpl.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

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

@ -85,3 +85,4 @@
#include "V8ObjectImpl.h"
#include "V8ScriptImpl.h"
#include "V8DebugListenerImpl.h"
#include "V8TestProxyImpl.h"

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

@ -67,6 +67,7 @@
#include <algorithm>
#include <functional>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>

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

@ -100,3 +100,12 @@ using namespace Microsoft::ClearScript::Util;
#define END_LOCK_SCOPE \
IGNORE_UNUSED(t_Lock); \
}
//-----------------------------------------------------------------------------
#define ENSURE_INTERNAL_CLASS(NAME) \
public ref class NAME##Hook \
{ \
private: \
static String^ m_gcName = NAME::typeid->Name; \
};

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

@ -80,6 +80,11 @@ public:
m_Mutex.lock();
}
bool TryLock()
{
return m_Mutex.try_lock();
}
void Unlock()
{
m_Mutex.unlock();
@ -108,6 +113,13 @@ void SimpleMutex::Lock()
//-----------------------------------------------------------------------------
bool SimpleMutex::TryLock()
{
return m_pImpl->TryLock();
}
//-----------------------------------------------------------------------------
void SimpleMutex::Unlock()
{
m_pImpl->Unlock();
@ -139,6 +151,11 @@ public:
m_Mutex.lock();
}
bool TryLock()
{
return m_Mutex.try_lock();
}
void Unlock()
{
m_Mutex.unlock();
@ -167,6 +184,13 @@ void RecursiveMutex::Lock()
//-----------------------------------------------------------------------------
bool RecursiveMutex::TryLock()
{
return m_pImpl->TryLock();
}
//-----------------------------------------------------------------------------
void RecursiveMutex::Unlock()
{
m_pImpl->Unlock();

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

@ -74,6 +74,7 @@ public:
SimpleMutex();
void Lock();
bool TryLock();
void Unlock();
~SimpleMutex();
@ -96,6 +97,7 @@ public:
RecursiveMutex();
void Lock();
bool TryLock();
void Unlock();
~RecursiveMutex();
@ -118,6 +120,7 @@ public:
NullMutex() {}
void Lock() {}
bool TryLock() { return true; }
void Unlock() {}
};
@ -138,6 +141,15 @@ public:
m_Mutex.Lock();
}
MutexLock(TMutex& mutex, bool doLock):
m_Mutex(mutex)
{
if (doLock)
{
m_Mutex.Lock();
}
}
~MutexLock()
{
m_Mutex.Unlock();

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

@ -127,6 +127,23 @@ private:
IGNORE_UNUSED(t_AddRefScope); \
}
//-----------------------------------------------------------------------------
// SharedPtrTraits
//-----------------------------------------------------------------------------
template <typename T>
class SharedPtrTraits
{
PROHIBIT_CONSTRUCT(SharedPtrTraits)
public:
static void Destroy(T* pTarget)
{
delete pTarget;
}
};
//-----------------------------------------------------------------------------
// SharedPtr
//-----------------------------------------------------------------------------
@ -318,7 +335,7 @@ private:
if (pRefCount->Decrement() == 0)
{
DetachRefCount(pTarget, pRefCount);
delete pTarget;
SharedPtrTraits<T>::Destroy(pTarget);
}
}
}

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

@ -268,21 +268,21 @@ public:
public:
explicit StdString(Handle<Value> hValue):
explicit StdString(v8::Local<v8::Value> hValue):
m_Value(GetValue(hValue))
{
}
Local<String> ToV8String(Isolate* pIsolate) const
v8::Local<v8::String> ToV8String(v8::Isolate* pIsolate) const
{
return String::NewFromTwoByte(pIsolate, reinterpret_cast<const uint16_t*>(ToCString()), String::kNormalString, GetLength());
return v8::String::NewFromTwoByte(pIsolate, reinterpret_cast<const uint16_t*>(ToCString()), v8::String::kNormalString, GetLength());
}
private:
static std::wstring GetValue(Handle<Value> hValue)
static std::wstring GetValue(v8::Local<v8::Value> hValue)
{
String::Value value(hValue);
v8::String::Value value(hValue);
return std::wstring(*value, value.length());
}

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

@ -69,3 +69,10 @@ V8Context* V8Context::Create(const SharedPtr<V8Isolate>& spIsolate, const StdStr
{
return new V8ContextImpl(static_cast<V8IsolateImpl*>(spIsolate.GetRawPtr()), name, enableDebugging, disableGlobalMembers, debugPort);
}
//-----------------------------------------------------------------------------
size_t V8Context::GetInstanceCount()
{
return V8ContextImpl::GetInstanceCount();
}

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

@ -70,14 +70,15 @@ class V8Context: public WeakRefTarget<V8Context>
public:
static V8Context* Create(const SharedPtr<V8Isolate>& spIsolate, const StdString& name, bool enableDebugging, bool disableGlobalMembers, int debugPort);
static size_t GetInstanceCount();
virtual size_t GetMaxIsolateHeapSize() = 0;
virtual void SetMaxIsolateHeapSize(size_t value) = 0;
virtual double GetIsolateHeapSizeSampleInterval() = 0;
virtual void SetIsolateHeapSizeSampleInterval(double value) = 0;
virtual size_t GetMaxIsolateStackUsage() = 0;
virtual void SetMaxIsolateStackUsage(size_t value) = 0;
virtual double GetIsolateHeapSizeSampleInterval() = 0;
virtual void SetIsolateHeapSizeSampleInterval(double value) = 0;
typedef void LockCallbackT(void* pvArg);
virtual void CallWithLock(LockCallbackT* pCallback, void* pvArg) = 0;
@ -95,5 +96,26 @@ public:
virtual void CollectGarbage(bool exhaustive) = 0;
virtual void OnAccessSettingsChanged() = 0;
virtual ~V8Context() {}
virtual void Destroy() = 0;
protected:
virtual ~V8Context() {};
};
//-----------------------------------------------------------------------------
// SharedPtrTraits<V8Context>
//-----------------------------------------------------------------------------
template<>
class SharedPtrTraits<V8Context>
{
PROHIBIT_CONSTRUCT(SharedPtrTraits)
public:
static void Destroy(V8Context* pTarget)
{
pTarget->Destroy();
}
};

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

@ -65,7 +65,7 @@
// local helper functions
//-----------------------------------------------------------------------------
static HostObjectHolder* GetHostObjectHolder(Handle<Object> hObject)
static HostObjectHolder* GetHostObjectHolder(v8::Local<v8::Object> hObject)
{
_ASSERTE(hObject->InternalFieldCount() > 0);
return static_cast<HostObjectHolder*>(hObject->GetAlignedPointerFromInternalField(0));
@ -73,7 +73,7 @@ static HostObjectHolder* GetHostObjectHolder(Handle<Object> hObject)
//-----------------------------------------------------------------------------
static void SetHostObjectHolder(Handle<Object> hObject, HostObjectHolder* pHolder)
static void SetHostObjectHolder(v8::Local<v8::Object> hObject, HostObjectHolder* pHolder)
{
_ASSERTE(hObject->InternalFieldCount() > 0);
hObject->SetAlignedPointerInInternalField(0, pHolder);
@ -81,7 +81,7 @@ static void SetHostObjectHolder(Handle<Object> hObject, HostObjectHolder* pHolde
//-----------------------------------------------------------------------------
static void* GetHostObject(Handle<Object> hObject)
static void* GetHostObject(v8::Local<v8::Object> hObject)
{
auto pHolder = ::GetHostObjectHolder(hObject);
return (pHolder != nullptr) ? pHolder->GetObject() : nullptr;
@ -89,24 +89,34 @@ static void* GetHostObject(Handle<Object> hObject)
//-----------------------------------------------------------------------------
template <typename T>
static V8ContextImpl* UnwrapContextImpl(const PropertyCallbackInfo<T>& info)
template<typename T>
static V8ContextImpl* UnwrapContextImplFromHolder(const v8::PropertyCallbackInfo<T>& info)
{
return static_cast<V8ContextImpl*>(Local<External>::Cast(info.Data())->Value());
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
return static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
}
//-----------------------------------------------------------------------------
template <typename T>
static V8ContextImpl* UnwrapContextImpl(const FunctionCallbackInfo<T>& info)
static V8ContextImpl* UnwrapContextImplFromData(const v8::PropertyCallbackInfo<T>& info)
{
return static_cast<V8ContextImpl*>(Local<External>::Cast(info.Data())->Value());
return static_cast<V8ContextImpl*>(v8::Local<v8::External>::Cast(info.Data())->Value());
}
//-----------------------------------------------------------------------------
template <typename T>
static void* UnwrapHostObject(const PropertyCallbackInfo<T>& info)
static V8ContextImpl* UnwrapContextImplFromData(const v8::FunctionCallbackInfo<T>& info)
{
return static_cast<V8ContextImpl*>(v8::Local<v8::External>::Cast(info.Data())->Value());
}
//-----------------------------------------------------------------------------
template <typename T>
static void* UnwrapHostObject(const v8::PropertyCallbackInfo<T>& info)
{
return ::GetHostObject(info.Holder());
}
@ -114,9 +124,17 @@ static void* UnwrapHostObject(const PropertyCallbackInfo<T>& info)
//-----------------------------------------------------------------------------
template <typename T>
static void* UnwrapHostObject(const FunctionCallbackInfo<T>& args)
static void* UnwrapHostObject(const v8::FunctionCallbackInfo<T>& info)
{
return ::GetHostObject(args.Holder());
return ::GetHostObject(info.Holder());
}
//-----------------------------------------------------------------------------
template <typename T>
static T CombineFlags(T flag1, T flag2)
{
return static_cast<T>(static_cast<std::underlying_type_t<T>>(flag1) | static_cast<std::underlying_type_t<T>>(flag2));
}
//-----------------------------------------------------------------------------
@ -142,7 +160,7 @@ static void* UnwrapHostObject(const FunctionCallbackInfo<T>& args)
#define BEGIN_EXECUTION_SCOPE \
{ \
V8IsolateImpl::ExecutionScope t_IsolateExecutionScope(m_spIsolateImpl); \
TryCatch t_TryCatch;
v8::TryCatch t_TryCatch;
#define END_EXECUTION_SCOPE \
IGNORE_UNUSED(t_TryCatch); \
@ -163,6 +181,10 @@ static void* UnwrapHostObject(const FunctionCallbackInfo<T>& args)
//-----------------------------------------------------------------------------
static std::atomic<size_t> s_InstanceCount(0);
//-----------------------------------------------------------------------------
V8ContextImpl::V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name, bool enableDebugging, bool disableGlobalMembers, int debugPort):
m_Name(name),
m_spIsolateImpl(pIsolateImpl),
@ -181,8 +203,9 @@ V8ContextImpl::V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name,
{
auto hGlobalTemplate = CreateObjectTemplate();
hGlobalTemplate->SetInternalFieldCount(1);
hGlobalTemplate->SetNamedPropertyHandler(GetGlobalProperty, SetGlobalProperty, QueryGlobalProperty, DeleteGlobalProperty, GetGlobalPropertyNames);
hGlobalTemplate->SetIndexedPropertyHandler(GetGlobalProperty, SetGlobalProperty, QueryGlobalProperty, DeleteGlobalProperty, GetGlobalPropertyIndices);
auto propertyHandlerFlags = ::CombineFlags(v8::PropertyHandlerFlags::kNonMasking, v8::PropertyHandlerFlags::kOnlyInterceptStrings);
hGlobalTemplate->SetHandler(v8::NamedPropertyHandlerConfiguration(GetGlobalProperty, SetGlobalProperty, QueryGlobalProperty, DeleteGlobalProperty, GetGlobalPropertyNames, v8::Local<v8::Value>(), propertyHandlerFlags));
hGlobalTemplate->SetHandler(v8::IndexedPropertyHandlerConfiguration(GetGlobalProperty, SetGlobalProperty, QueryGlobalProperty, DeleteGlobalProperty, GetGlobalPropertyIndices));
m_hContext = CreatePersistent(CreateContext(nullptr, hGlobalTemplate));
@ -206,9 +229,10 @@ V8ContextImpl::V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name,
m_hHostObjectTemplate->InstanceTemplate()->SetIndexedPropertyHandler(GetHostObjectProperty, SetHostObjectProperty, QueryHostObjectProperty, DeleteHostObjectProperty, GetHostObjectPropertyIndices, Wrap());
m_hHostObjectTemplate->InstanceTemplate()->SetCallAsFunctionHandler(InvokeHostObject, Wrap());
Local<Function> hToFunction;
v8::Local<v8::Function> hToFunction;
BEGIN_CONTEXT_SCOPE
hToFunction = CreateFunction(CreateFunctionForHostDelegate, Wrap());
m_hTerminationException = CreatePersistent(v8::Exception::Error(CreateString(StdString(L"Script execution was interrupted"))));
END_CONTEXT_SCOPE
m_hHostDelegateTemplate = CreatePersistent(CreateFunctionTemplate());
@ -224,6 +248,15 @@ V8ContextImpl::V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name,
m_pvV8ObjectCache = HostObjectHelpers::CreateV8ObjectCache();
END_ISOLATE_SCOPE
++s_InstanceCount;
}
//-----------------------------------------------------------------------------
size_t V8ContextImpl::GetInstanceCount()
{
return s_InstanceCount;
}
//-----------------------------------------------------------------------------
@ -301,13 +334,13 @@ void V8ContextImpl::SetGlobalProperty(const StdString& name, const V8Value& valu
auto hName = CreateString(name);
auto hValue = ImportValue(value);
Local<Value> hOldValue;
v8::Local<v8::Value> hOldValue;
if (m_hContext->Global()->HasOwnProperty(hName))
{
hOldValue = m_hContext->Global()->GetRealNamedProperty(hName);
}
m_hContext->Global()->ForceSet(hName, hValue, (PropertyAttribute)(ReadOnly | DontDelete));
m_hContext->Global()->ForceSet(hName, hValue, (v8::PropertyAttribute)(v8::ReadOnly | v8::DontDelete));
if (globalMembers && hValue->IsObject())
{
if (!hOldValue.IsEmpty() && hOldValue->IsObject())
@ -336,7 +369,7 @@ V8Value V8ContextImpl::Execute(const StdString& documentName, const StdString& c
BEGIN_CONTEXT_SCOPE
BEGIN_EXECUTION_SCOPE
ScriptCompiler::Source source(CreateString(code), ScriptOrigin(CreateString(documentName)));
v8::ScriptCompiler::Source source(CreateString(code), v8::ScriptOrigin(CreateString(documentName)));
auto hScript = VERIFY(CreateScript(&source));
auto hResult = VERIFY(hScript->Run());
if (!evaluate)
@ -357,7 +390,7 @@ V8ScriptHolder* V8ContextImpl::Compile(const StdString& documentName, const StdS
BEGIN_CONTEXT_SCOPE
BEGIN_EXECUTION_SCOPE
ScriptCompiler::Source source(CreateString(code), ScriptOrigin(CreateString(documentName)));
v8::ScriptCompiler::Source source(CreateString(code), v8::ScriptOrigin(CreateString(documentName)));
auto hScript = VERIFY(CreateUnboundScript(&source));
return new V8ScriptHolderImpl(GetWeakBinding(), ::PtrFromScriptHandle(CreatePersistent(hScript)));
@ -429,6 +462,16 @@ void V8ContextImpl::OnAccessSettingsChanged()
//-----------------------------------------------------------------------------
void V8ContextImpl::Destroy()
{
m_spIsolateImpl->CallWithLockNoWait([this] (V8IsolateImpl* /*pIsolateImpl*/)
{
delete this;
});
}
//-----------------------------------------------------------------------------
V8Value V8ContextImpl::GetV8ObjectProperty(void* pvObject, const StdString& name)
{
BEGIN_CONTEXT_SCOPE
@ -532,7 +575,7 @@ V8Value V8ContextImpl::InvokeV8Object(void* pvObject, const std::vector<V8Value>
auto hObject = ::ObjectHandleFromPtr(pvObject);
std::vector<Handle<Value>> importedArgs;
std::vector<v8::Local<v8::Value>> importedArgs;
ImportValues(args, importedArgs);
if (asConstructor)
@ -558,18 +601,18 @@ V8Value V8ContextImpl::InvokeV8ObjectMethod(void* pvObject, const StdString& nam
auto hName = CreateString(name);
if (!hObject->Has(hName))
{
auto hError = Exception::TypeError(CreateString(StdString(L"Method or property not found")))->ToObject();
auto hError = v8::Exception::TypeError(CreateString(StdString(L"Method or property not found")))->ToObject();
throw V8Exception(V8Exception::Type_General, m_Name, StdString(hError), StdString(hError->Get(CreateString(StdString(L"stack")))), V8Value(V8Value::Undefined));
}
auto hValue = hObject->Get(hName);
if (hValue->IsUndefined() || hValue->IsNull())
{
auto hError = Exception::TypeError(CreateString(StdString(L"Property value does not support invocation")))->ToObject();
auto hError = v8::Exception::TypeError(CreateString(StdString(L"Property value does not support invocation")))->ToObject();
throw V8Exception(V8Exception::Type_General, m_Name, StdString(hError), StdString(hError->Get(CreateString(StdString(L"stack")))), V8Value(V8Value::Undefined));
}
std::vector<Handle<Value>> importedArgs;
std::vector<v8::Local<v8::Value>> importedArgs;
ImportValues(args, importedArgs);
auto hMethod = VERIFY(hValue->ToObject());
@ -585,7 +628,7 @@ void V8ContextImpl::ProcessDebugMessages()
{
BEGIN_CONTEXT_SCOPE
Debug::ProcessDebugMessages();
v8::Debug::ProcessDebugMessages();
END_CONTEXT_SCOPE
}
@ -594,51 +637,51 @@ void V8ContextImpl::ProcessDebugMessages()
V8ContextImpl::~V8ContextImpl()
{
BEGIN_ISOLATE_SCOPE
_ASSERTE(m_spIsolateImpl->IsCurrent() && m_spIsolateImpl->IsLocked());
--s_InstanceCount;
std::vector<void*> v8ObjectPtrs;
HostObjectHelpers::GetAllCachedV8Objects(m_pvV8ObjectCache, v8ObjectPtrs);
for (auto pvV8Object: v8ObjectPtrs)
{
auto hObject = ::ObjectHandleFromPtr(pvV8Object);
delete ::GetHostObjectHolder(hObject);
Dispose(hObject);
}
std::vector<void*> v8ObjectPtrs;
HostObjectHelpers::GetAllCachedV8Objects(m_pvV8ObjectCache, v8ObjectPtrs);
for (auto pvV8Object: v8ObjectPtrs)
{
auto hObject = ::ObjectHandleFromPtr(pvV8Object);
delete ::GetHostObjectHolder(hObject);
ClearWeak(hObject);
Dispose(hObject);
}
HostObjectHelpers::Release(m_pvV8ObjectCache);
m_spIsolateImpl->RemoveContext(this);
HostObjectHelpers::Release(m_pvV8ObjectCache);
m_spIsolateImpl->RemoveContext(this);
for (auto it = m_GlobalMembersStack.rbegin(); it != m_GlobalMembersStack.rend(); it++)
{
Dispose(it->second);
}
for (auto it = m_GlobalMembersStack.rbegin(); it != m_GlobalMembersStack.rend(); it++)
{
Dispose(it->second);
}
Dispose(m_hHostDelegateTemplate);
Dispose(m_hHostObjectTemplate);
Dispose(m_hAccessToken);
Dispose(m_hAccessTokenName);
Dispose(m_hHostExceptionName);
Dispose(m_hHostObjectCookieName);
Dispose(m_hHostDelegateTemplate);
Dispose(m_hHostObjectTemplate);
Dispose(m_hAccessToken);
Dispose(m_hAccessTokenName);
Dispose(m_hHostExceptionName);
Dispose(m_hHostObjectCookieName);
// As of V8 3.16.0, the global property getter for a disposed context
// may be invoked during GC after the V8ContextImpl instance is gone.
// As of V8 3.16.0, the global property getter for a disposed context
// may be invoked during GC after the V8ContextImpl instance is gone.
if (!m_hGlobal.IsEmpty())
{
_ASSERTE(m_hGlobal->InternalFieldCount() > 0);
m_hGlobal->SetAlignedPointerInInternalField(0, nullptr);
Dispose(m_hGlobal);
}
if (!m_hGlobal.IsEmpty())
{
_ASSERTE(m_hGlobal->InternalFieldCount() > 0);
m_hGlobal->SetAlignedPointerInInternalField(0, nullptr);
Dispose(m_hGlobal);
}
Dispose(m_hContext);
ContextDisposedNotification();
END_ISOLATE_SCOPE
Dispose(m_hContext);
ContextDisposedNotification();
}
//-----------------------------------------------------------------------------
Handle<Value> V8ContextImpl::Wrap()
v8::Local<v8::Value> V8ContextImpl::Wrap()
{
return CreateExternal(this);
}
@ -657,7 +700,48 @@ SharedPtr<V8WeakContextBinding> V8ContextImpl::GetWeakBinding()
//-----------------------------------------------------------------------------
void V8ContextImpl::GetV8ObjectPropertyNames(Handle<Object> hObject, std::vector<StdString>& names)
bool V8ContextImpl::CheckContextImplForGlobalObjectCallback(V8ContextImpl* pContextImpl)
{
if (pContextImpl == nullptr)
{
return false;
}
if (pContextImpl->IsExecutionTerminating())
{
pContextImpl->ThrowException(pContextImpl->m_hTerminationException);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
bool V8ContextImpl::CheckContextImplForHostObjectCallback(V8ContextImpl* pContextImpl)
{
if (pContextImpl == nullptr)
{
return false;
}
if (pContextImpl->m_DisableHostObjectInterception)
{
return false;
}
if (pContextImpl->IsExecutionTerminating())
{
pContextImpl->ThrowException(pContextImpl->m_hTerminationException);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
void V8ContextImpl::GetV8ObjectPropertyNames(v8::Local<v8::Object> hObject, std::vector<StdString>& names)
{
names.clear();
@ -686,7 +770,7 @@ void V8ContextImpl::GetV8ObjectPropertyNames(Handle<Object> hObject, std::vector
//-----------------------------------------------------------------------------
void V8ContextImpl::GetV8ObjectPropertyIndices(Handle<Object> hObject, std::vector<int>& indices)
void V8ContextImpl::GetV8ObjectPropertyIndices(v8::Local<v8::Object> hObject, std::vector<int>& indices)
{
indices.clear();
@ -715,95 +799,96 @@ void V8ContextImpl::GetV8ObjectPropertyIndices(Handle<Object> hObject, std::vect
//-----------------------------------------------------------------------------
void V8ContextImpl::GetGlobalProperty(Local<String> hName, const PropertyCallbackInfo<Value>& info)
void V8ContextImpl::GetGlobalProperty(v8::Local<v8::Name> hName, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if ((stack.size() > 0) && !hName->Equals(pContextImpl->m_hHostObjectCookieName))
{
for (auto it = stack.rbegin(); it != stack.rend(); it++)
{
if (it->second->HasOwnProperty(hName))
{
CALLBACK_RETURN(it->second->Get(hName));
}
}
}
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::SetGlobalProperty(Local<String> hName, Local<Value> hValue, const PropertyCallbackInfo<Value>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if ((stack.size() > 0) && !hName->Equals(pContextImpl->m_hHostObjectCookieName))
{
for (auto it = stack.rbegin(); it != stack.rend(); it++)
{
if (it->second->HasOwnProperty(hName))
{
it->second->Set(hName, hValue);
CALLBACK_RETURN(hValue);
}
}
}
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::QueryGlobalProperty(Local<String> hName, const PropertyCallbackInfo<Integer>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if ((stack.size() > 0) && !hName->Equals(pContextImpl->m_hHostObjectCookieName))
{
for (auto it = stack.rbegin(); it != stack.rend(); it++)
{
if (it->second->HasOwnProperty(hName))
{
CALLBACK_RETURN(it->second->GetPropertyAttributes(hName));
}
}
}
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::DeleteGlobalProperty(Local<String> hName, const PropertyCallbackInfo<Boolean>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
{
auto hKey = hName->ToString();
if (!hKey->Equals(pContextImpl->m_hHostObjectCookieName))
{
for (auto it = stack.rbegin(); it != stack.rend(); it++)
{
if (it->second->HasOwnProperty(hKey))
{
CALLBACK_RETURN(it->second->Get(hKey));
}
}
}
}
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::SetGlobalProperty(v8::Local<v8::Name> hName, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
{
auto hKey = hName->ToString();
if (!hKey->Equals(pContextImpl->m_hHostObjectCookieName))
{
for (auto it = stack.rbegin(); it != stack.rend(); it++)
{
if (it->second->HasOwnProperty(hKey))
{
it->second->Set(hKey, hValue);
CALLBACK_RETURN(hValue);
}
}
}
}
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::QueryGlobalProperty(v8::Local<v8::Name> hName, const v8::PropertyCallbackInfo<v8::Integer>& info)
{
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
{
auto hKey = hName->ToString();
if (!hKey->Equals(pContextImpl->m_hHostObjectCookieName))
{
for (auto it = stack.rbegin(); it != stack.rend(); it++)
{
if (it->second->HasOwnProperty(hKey))
{
CALLBACK_RETURN(it->second->GetPropertyAttributes(hKey));
}
}
}
}
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::DeleteGlobalProperty(v8::Local<v8::Name> hName, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
{
auto hKey = hName->ToString();
for (auto it = stack.rbegin(); it != stack.rend(); it++)
{
if (it->second->HasOwnProperty(hName))
if (it->second->HasOwnProperty(hKey))
{
// WORKAROUND: Object::Delete() crashes if a custom property deleter calls
// WORKAROUND: v8::Object::Delete() crashes if a custom property deleter calls
// ThrowException(). Interestingly, there is no crash if the same deleter is
// invoked directly from script via the delete operator.
@ -811,7 +896,7 @@ void V8ContextImpl::DeleteGlobalProperty(Local<String> hName, const PropertyCall
{
try
{
CALLBACK_RETURN(HostObjectHelpers::DeleteProperty(::GetHostObject(it->second), StdString(hName)));
CALLBACK_RETURN(HostObjectHelpers::DeleteProperty(::GetHostObject(it->second), StdString(hKey)));
}
catch (const HostException&)
{
@ -819,7 +904,7 @@ void V8ContextImpl::DeleteGlobalProperty(Local<String> hName, const PropertyCall
}
}
CALLBACK_RETURN(it->second->Delete(hName));
CALLBACK_RETURN(it->second->Delete(hKey));
}
}
}
@ -828,13 +913,10 @@ void V8ContextImpl::DeleteGlobalProperty(Local<String> hName, const PropertyCall
//-----------------------------------------------------------------------------
void V8ContextImpl::GetGlobalPropertyNames(const PropertyCallbackInfo<Array>& info)
void V8ContextImpl::GetGlobalPropertyNames(const v8::PropertyCallbackInfo<v8::Array>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
try
{
@ -857,8 +939,8 @@ void V8ContextImpl::GetGlobalPropertyNames(const PropertyCallbackInfo<Array>& in
names.insert(names.end(), tempNames.begin(), tempNames.end());
}
sort(names.begin(), names.end());
auto newEnd = unique(names.begin(), names.end());
std::sort(names.begin(), names.end());
auto newEnd = std::unique(names.begin(), names.end());
auto nameCount = static_cast<int>(newEnd - names.begin());
auto hImportedNames = pContextImpl->CreateArray(nameCount);
@ -879,13 +961,10 @@ void V8ContextImpl::GetGlobalPropertyNames(const PropertyCallbackInfo<Array>& in
//-----------------------------------------------------------------------------
void V8ContextImpl::GetGlobalProperty(unsigned __int32 index, const PropertyCallbackInfo<Value>& info)
void V8ContextImpl::GetGlobalProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
@ -904,13 +983,10 @@ void V8ContextImpl::GetGlobalProperty(unsigned __int32 index, const PropertyCall
//-----------------------------------------------------------------------------
void V8ContextImpl::SetGlobalProperty(unsigned __int32 index, Local<Value> hValue, const PropertyCallbackInfo<Value>& info)
void V8ContextImpl::SetGlobalProperty(unsigned __int32 index, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
@ -930,13 +1006,10 @@ void V8ContextImpl::SetGlobalProperty(unsigned __int32 index, Local<Value> hValu
//-----------------------------------------------------------------------------
void V8ContextImpl::QueryGlobalProperty(unsigned __int32 index, const PropertyCallbackInfo<Integer>& info)
void V8ContextImpl::QueryGlobalProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Integer>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
@ -956,13 +1029,10 @@ void V8ContextImpl::QueryGlobalProperty(unsigned __int32 index, const PropertyCa
//-----------------------------------------------------------------------------
void V8ContextImpl::DeleteGlobalProperty(unsigned __int32 index, const PropertyCallbackInfo<Boolean>& info)
void V8ContextImpl::DeleteGlobalProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
const auto& stack = pContextImpl->m_GlobalMembersStack;
if (stack.size() > 0)
@ -981,13 +1051,10 @@ void V8ContextImpl::DeleteGlobalProperty(unsigned __int32 index, const PropertyC
//-----------------------------------------------------------------------------
void V8ContextImpl::GetGlobalPropertyIndices(const PropertyCallbackInfo<Array>& info)
void V8ContextImpl::GetGlobalPropertyIndices(const v8::PropertyCallbackInfo<v8::Array>& info)
{
auto hGlobal = info.Holder();
_ASSERTE(hGlobal->InternalFieldCount() > 0);
auto pContextImpl = static_cast<V8ContextImpl*>(hGlobal->GetAlignedPointerFromInternalField(0));
if (pContextImpl != nullptr)
auto pContextImpl = ::UnwrapContextImplFromHolder(info);
if (CheckContextImplForGlobalObjectCallback(pContextImpl))
{
try
{
@ -1010,8 +1077,8 @@ void V8ContextImpl::GetGlobalPropertyIndices(const PropertyCallbackInfo<Array>&
indices.insert(indices.end(), tempIndices.begin(), tempIndices.end());
}
sort(indices.begin(), indices.end());
auto newEnd = unique(indices.begin(), indices.end());
std::sort(indices.begin(), indices.end());
auto newEnd = std::unique(indices.begin(), indices.end());
auto indexCount = static_cast<int>(newEnd - indices.begin());
auto hImportedIndices = pContextImpl->CreateArray(indexCount);
@ -1032,24 +1099,29 @@ void V8ContextImpl::GetGlobalPropertyIndices(const PropertyCallbackInfo<Array>&
//-----------------------------------------------------------------------------
void V8ContextImpl::HostObjectConstructorCallHandler(const FunctionCallbackInfo<Value>& info)
void V8ContextImpl::HostObjectConstructorCallHandler(const v8::FunctionCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_AllowHostObjectConstructorCall)
pContextImpl->ThrowException(Exception::Error(pContextImpl->CreateString(StdString(L"This function is for ClearScript internal use only"))));
auto pContextImpl = ::UnwrapContextImplFromData(info);
if ((pContextImpl != nullptr) && !pContextImpl->m_AllowHostObjectConstructorCall)
{
pContextImpl->ThrowException(v8::Exception::Error(pContextImpl->CreateString(StdString(L"This function is for ClearScript internal use only"))));
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::CreateFunctionForHostDelegate(const FunctionCallbackInfo<Value>& info)
void V8ContextImpl::CreateFunctionForHostDelegate(const v8::FunctionCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
CALLBACK_RETURN(pContextImpl->CreateFunction(InvokeHostDelegate, info.This()));
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (pContextImpl != nullptr)
{
CALLBACK_RETURN(pContextImpl->CreateFunction(InvokeHostDelegate, info.This()));
}
}
//-----------------------------------------------------------------------------
void V8ContextImpl::InvokeHostDelegate(const FunctionCallbackInfo<Value>& info)
void V8ContextImpl::InvokeHostDelegate(const v8::FunctionCallbackInfo<v8::Value>& info)
{
auto hTarget = info.Data();
@ -1064,7 +1136,7 @@ void V8ContextImpl::InvokeHostDelegate(const FunctionCallbackInfo<Value>& info)
CALLBACK_RETURN(hTarget->ToObject()->CallAsFunction(hTarget, 0, nullptr));
}
std::vector<Handle<Value>> args;
std::vector<v8::Local<v8::Value>> args;
args.reserve(argCount);
for (auto index = 0; index < argCount; index++)
@ -1082,10 +1154,10 @@ void V8ContextImpl::InvokeHostDelegate(const FunctionCallbackInfo<Value>& info)
//-----------------------------------------------------------------------------
void V8ContextImpl::GetHostObjectProperty(Local<String> hName, const PropertyCallbackInfo<Value>& info)
void V8ContextImpl::GetHostObjectProperty(v8::Local<v8::String> hName, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1134,10 +1206,10 @@ void V8ContextImpl::GetHostObjectProperty(Local<String> hName, const PropertyCal
//-----------------------------------------------------------------------------
void V8ContextImpl::SetHostObjectProperty(Local<String> hName, Local<Value> hValue, const PropertyCallbackInfo<Value>& info)
void V8ContextImpl::SetHostObjectProperty(v8::Local<v8::String> hName, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1153,16 +1225,16 @@ void V8ContextImpl::SetHostObjectProperty(Local<String> hName, Local<Value> hVal
//-----------------------------------------------------------------------------
void V8ContextImpl::QueryHostObjectProperty(Local<String> hName, const PropertyCallbackInfo<Integer>& info)
void V8ContextImpl::QueryHostObjectProperty(v8::Local<v8::String> hName, const v8::PropertyCallbackInfo<v8::Integer>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
if (hName->Equals(pContextImpl->m_hHostObjectCookieName))
{
CALLBACK_RETURN(ReadOnly | DontEnum | DontDelete);
CALLBACK_RETURN(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
}
std::vector<StdString> names;
@ -1173,7 +1245,7 @@ void V8ContextImpl::QueryHostObjectProperty(Local<String> hName, const PropertyC
{
if (it->Compare(name) == 0)
{
CALLBACK_RETURN(None);
CALLBACK_RETURN(v8::None);
}
}
}
@ -1186,10 +1258,10 @@ void V8ContextImpl::QueryHostObjectProperty(Local<String> hName, const PropertyC
//-----------------------------------------------------------------------------
void V8ContextImpl::DeleteHostObjectProperty(Local<String> hName, const PropertyCallbackInfo<Boolean>& info)
void V8ContextImpl::DeleteHostObjectProperty(v8::Local<v8::String> hName, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1204,10 +1276,10 @@ void V8ContextImpl::DeleteHostObjectProperty(Local<String> hName, const Property
//-----------------------------------------------------------------------------
void V8ContextImpl::GetHostObjectPropertyNames(const PropertyCallbackInfo<Array>& info)
void V8ContextImpl::GetHostObjectPropertyNames(const v8::PropertyCallbackInfo<v8::Array>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1232,10 +1304,10 @@ void V8ContextImpl::GetHostObjectPropertyNames(const PropertyCallbackInfo<Array>
//-----------------------------------------------------------------------------
void V8ContextImpl::GetHostObjectProperty(unsigned __int32 index, const PropertyCallbackInfo<Value>& info)
void V8ContextImpl::GetHostObjectProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1250,10 +1322,10 @@ void V8ContextImpl::GetHostObjectProperty(unsigned __int32 index, const Property
//-----------------------------------------------------------------------------
void V8ContextImpl::SetHostObjectProperty(unsigned __int32 index, Local<Value> hValue, const PropertyCallbackInfo<Value>& info)
void V8ContextImpl::SetHostObjectProperty(unsigned __int32 index, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1269,10 +1341,10 @@ void V8ContextImpl::SetHostObjectProperty(unsigned __int32 index, Local<Value> h
//-----------------------------------------------------------------------------
void V8ContextImpl::QueryHostObjectProperty(unsigned __int32 index, const PropertyCallbackInfo<Integer>& info)
void V8ContextImpl::QueryHostObjectProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Integer>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1283,7 +1355,7 @@ void V8ContextImpl::QueryHostObjectProperty(unsigned __int32 index, const Proper
{
if (*it == static_cast<int>(index))
{
CALLBACK_RETURN(None);
CALLBACK_RETURN(v8::None);
}
}
}
@ -1296,10 +1368,10 @@ void V8ContextImpl::QueryHostObjectProperty(unsigned __int32 index, const Proper
//-----------------------------------------------------------------------------
void V8ContextImpl::DeleteHostObjectProperty(unsigned __int32 index, const PropertyCallbackInfo<Boolean>& info)
void V8ContextImpl::DeleteHostObjectProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1314,10 +1386,10 @@ void V8ContextImpl::DeleteHostObjectProperty(unsigned __int32 index, const Prope
//-----------------------------------------------------------------------------
void V8ContextImpl::GetHostObjectPropertyIndices(const PropertyCallbackInfo<Array>& info)
void V8ContextImpl::GetHostObjectPropertyIndices(const v8::PropertyCallbackInfo<v8::Array>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1342,10 +1414,10 @@ void V8ContextImpl::GetHostObjectPropertyIndices(const PropertyCallbackInfo<Arra
//-----------------------------------------------------------------------------
void V8ContextImpl::InvokeHostObject(const FunctionCallbackInfo<Value>& info)
void V8ContextImpl::InvokeHostObject(const v8::FunctionCallbackInfo<v8::Value>& info)
{
auto pContextImpl = ::UnwrapContextImpl(info);
if (!pContextImpl->m_DisableHostObjectInterception)
auto pContextImpl = ::UnwrapContextImplFromData(info);
if (CheckContextImplForHostObjectCallback(pContextImpl))
{
try
{
@ -1370,7 +1442,7 @@ void V8ContextImpl::InvokeHostObject(const FunctionCallbackInfo<Value>& info)
//-----------------------------------------------------------------------------
void V8ContextImpl::DisposeWeakHandle(Isolate* pIsolate, Persistent<Object>* phObject, void* pvV8ObjectCache)
void V8ContextImpl::DisposeWeakHandle(v8::Isolate* pIsolate, Persistent<v8::Object>* phObject, void* pvV8ObjectCache)
{
IGNORE_UNUSED(pIsolate);
@ -1383,11 +1455,11 @@ void V8ContextImpl::DisposeWeakHandle(Isolate* pIsolate, Persistent<Object>* phO
//-----------------------------------------------------------------------------
Handle<Value> V8ContextImpl::ImportValue(const V8Value& value)
v8::Local<v8::Value> V8ContextImpl::ImportValue(const V8Value& value)
{
if (value.IsNonexistent())
{
return Handle<Value>();
return v8::Local<v8::Value>();
}
if (value.IsUndefined())
@ -1450,7 +1522,7 @@ Handle<Value> V8ContextImpl::ImportValue(const V8Value& value)
return CreateLocal(::ObjectHandleFromPtr(pvV8Object));
}
Local<Object> hObject;
v8::Local<v8::Object> hObject;
if (HostObjectHelpers::IsDelegate(pHolder->GetObject()))
{
BEGIN_PULSE_VALUE_SCOPE(&m_AllowHostObjectConstructorCall, true)
@ -1492,7 +1564,7 @@ Handle<Value> V8ContextImpl::ImportValue(const V8Value& value)
//-----------------------------------------------------------------------------
V8Value V8ContextImpl::ExportValue(Handle<Value> hValue)
V8Value V8ContextImpl::ExportValue(v8::Local<v8::Value> hValue)
{
if (hValue.IsEmpty())
{
@ -1550,7 +1622,7 @@ V8Value V8ContextImpl::ExportValue(Handle<Value> hValue)
//-----------------------------------------------------------------------------
void V8ContextImpl::ImportValues(const std::vector<V8Value>& values, std::vector<Handle<Value>>& importedValues)
void V8ContextImpl::ImportValues(const std::vector<V8Value>& values, std::vector<v8::Local<v8::Value>>& importedValues)
{
importedValues.clear();
@ -1565,7 +1637,7 @@ void V8ContextImpl::ImportValues(const std::vector<V8Value>& values, std::vector
//-----------------------------------------------------------------------------
void V8ContextImpl::Verify(const TryCatch& tryCatch)
void V8ContextImpl::Verify(const v8::TryCatch& tryCatch)
{
if (tryCatch.HasCaught())
{
@ -1576,6 +1648,11 @@ void V8ContextImpl::Verify(const TryCatch& tryCatch)
}
auto hException = tryCatch.Exception();
if (hException->SameValue(m_hTerminationException))
{
VerifyNotOutOfMemory();
throw V8Exception(V8Exception::Type_Interrupt, m_Name, StdString(L"Script execution interrupted by host"), StdString(tryCatch.StackTrace()), V8Value(V8Value::Undefined));
}
StdString message;
bool stackOverflow;
@ -1640,8 +1717,8 @@ void V8ContextImpl::Verify(const TryCatch& tryCatch)
stackTrace = message;
auto hStackTrace = hMessage->GetStackTrace();
int frameCount = !hStackTrace.IsEmpty() ? hStackTrace->GetFrameCount() : 0;
auto hMessageStackTrace = hMessage->GetStackTrace();
int frameCount = !hMessageStackTrace.IsEmpty() ? hMessageStackTrace->GetFrameCount() : 0;
if (frameCount < 1)
{
@ -1680,7 +1757,7 @@ void V8ContextImpl::Verify(const TryCatch& tryCatch)
{
for (int index = 0; index < frameCount; index++)
{
auto hFrame = hStackTrace->GetFrame(index);
auto hFrame = hMessageStackTrace->GetFrame(index);
stackTrace += L"\n at ";
auto hFunctionName = hFrame->GetFunctionName();
@ -1707,14 +1784,14 @@ void V8ContextImpl::Verify(const TryCatch& tryCatch)
stackTrace += L':';
auto lineNumber = hFrame->GetLineNumber();
if (lineNumber != Message::kNoLineNumberInfo)
if (lineNumber != v8::Message::kNoLineNumberInfo)
{
stackTrace += std::to_wstring(lineNumber);
}
stackTrace += L':';
auto column = hFrame->GetColumn();
if (column != Message::kNoColumnInfo)
if (column != v8::Message::kNoColumnInfo)
{
stackTrace += std::to_wstring(column);
}
@ -1761,7 +1838,7 @@ void V8ContextImpl::VerifyNotOutOfMemory()
void V8ContextImpl::ThrowScriptException(const HostException& exception)
{
auto hException = Exception::Error(CreateString(exception.GetMessage()))->ToObject();
auto hException = v8::Exception::Error(CreateString(exception.GetMessage()))->ToObject();
auto hHostException = ImportValue(exception.GetException());
if (!hHostException.IsEmpty() && hHostException->IsObject())

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

@ -78,6 +78,8 @@ class V8ContextImpl: public V8Context
public:
V8ContextImpl(V8IsolateImpl* pIsolateImpl, const StdString& name, bool enableDebugging, bool disableGlobalMembers, int debugPort);
static size_t GetInstanceCount();
const StdString& GetName() const { return m_Name; }
size_t GetMaxIsolateHeapSize();
@ -89,17 +91,22 @@ public:
void SetMaxIsolateStackUsage(size_t value);
void CallWithLock(LockCallbackT* pCallback, void* pvArg);
V8Value GetRootObject();
void SetGlobalProperty(const StdString& name, const V8Value& value, bool globalMembers);
V8Value Execute(const StdString& documentName, const StdString& code, bool evaluate, bool discard);
V8ScriptHolder* Compile(const StdString& documentName, const StdString& code);
bool CanExecute(V8ScriptHolder* pHolder);
V8Value Execute(V8ScriptHolder* pHolder, bool evaluate);
void Interrupt();
void GetIsolateHeapInfo(V8IsolateHeapInfo& heapInfo);
void CollectGarbage(bool exhaustive);
void OnAccessSettingsChanged();
void Destroy();
V8Value GetV8ObjectProperty(void* pvObject, const StdString& name);
void SetV8ObjectProperty(void* pvObject, const StdString& name, const V8Value& value);
bool DeleteV8ObjectProperty(void* pvObject, const StdString& name);
@ -114,7 +121,6 @@ public:
V8Value InvokeV8ObjectMethod(void* pvObject, const StdString& name, const std::vector<V8Value>& args);
void ProcessDebugMessages();
~V8ContextImpl();
private:
@ -134,108 +140,108 @@ private:
private:
V8ContextImpl* m_pContextImpl;
Context::Scope m_ContextScope;
v8::Context::Scope m_ContextScope;
};
Local<Context> CreateContext(ExtensionConfiguration* pExtensionConfiguation = nullptr, Handle<ObjectTemplate> hGlobalTemplate = Handle<ObjectTemplate>(), Handle<Value> hGlobalObject = Handle<Value>())
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 m_spIsolateImpl->CreateContext(pExtensionConfiguation, hGlobalTemplate, hGlobalObject);
}
Handle<Primitive> GetUndefined()
v8::Local<v8::Primitive> GetUndefined()
{
return m_spIsolateImpl->GetUndefined();
}
Handle<Primitive> GetNull()
v8::Local<v8::Primitive> GetNull()
{
return m_spIsolateImpl->GetNull();
}
Handle<Boolean> GetTrue()
v8::Local<v8::Boolean> GetTrue()
{
return m_spIsolateImpl->GetTrue();
}
Handle<Boolean> GetFalse()
v8::Local<v8::Boolean> GetFalse()
{
return m_spIsolateImpl->GetFalse();
}
Local<Object> CreateObject()
v8::Local<v8::Object> CreateObject()
{
return m_spIsolateImpl->CreateObject();
}
Local<Number> CreateNumber(double value)
v8::Local<v8::Number> CreateNumber(double value)
{
return m_spIsolateImpl->CreateNumber(value);
}
Local<Integer> CreateInteger(__int32 value)
v8::Local<v8::Integer> CreateInteger(__int32 value)
{
return m_spIsolateImpl->CreateInteger(value);
}
Local<Integer> CreateInteger(unsigned __int32 value)
v8::Local<v8::Integer> CreateInteger(unsigned __int32 value)
{
return m_spIsolateImpl->CreateInteger(value);
}
Local<String> CreateString(const StdString& value)
v8::Local<v8::String> CreateString(const StdString& value)
{
return m_spIsolateImpl->CreateString(value);
}
Local<Array> CreateArray(int length = 0)
v8::Local<v8::Array> CreateArray(int length = 0)
{
return m_spIsolateImpl->CreateArray(length);
}
Local<External> CreateExternal(void* pvValue)
v8::Local<v8::External> CreateExternal(void* pvValue)
{
return m_spIsolateImpl->CreateExternal(pvValue);
}
Local<ObjectTemplate> CreateObjectTemplate()
v8::Local<v8::ObjectTemplate> CreateObjectTemplate()
{
return m_spIsolateImpl->CreateObjectTemplate();
}
Local<FunctionTemplate> CreateFunctionTemplate()
v8::Local<v8::FunctionTemplate> CreateFunctionTemplate()
{
return m_spIsolateImpl->CreateFunctionTemplate();
}
Local<Function> CreateFunction(FunctionCallback callback, Local<Value> data = Local<Value>(), int length = 0)
v8::Local<v8::Function> CreateFunction(v8::FunctionCallback callback, v8::Local<v8::Value> data = v8::Local<v8::Value>(), int length = 0)
{
return m_spIsolateImpl->CreateFunction(callback, data, length);
}
Local<Script> CreateScript(ScriptCompiler::Source* pSource, ScriptCompiler::CompileOptions options = ScriptCompiler::kNoCompileOptions)
v8::Local<v8::Script> CreateScript(v8::ScriptCompiler::Source* pSource, v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileOptions)
{
return m_spIsolateImpl->CreateScript(pSource, options);
}
Local<UnboundScript> CreateUnboundScript(ScriptCompiler::Source* pSource, ScriptCompiler::CompileOptions options = ScriptCompiler::kNoCompileOptions)
v8::Local<v8::UnboundScript> CreateUnboundScript(v8::ScriptCompiler::Source* pSource, v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileOptions)
{
return m_spIsolateImpl->CreateUnboundScript(pSource, options);
}
template <typename T>
Local<T> CreateLocal(Handle<T> hTarget)
v8::Local<T> CreateLocal(v8::Local<T> hTarget)
{
return m_spIsolateImpl->CreateLocal(hTarget);
}
template <typename T>
Local<T> CreateLocal(Persistent<T> hTarget)
v8::Local<T> CreateLocal(Persistent<T> hTarget)
{
return m_spIsolateImpl->CreateLocal(hTarget);
}
template <typename T>
Persistent<T> CreatePersistent(Handle<T> hTarget)
Persistent<T> CreatePersistent(v8::Local<T> hTarget)
{
return m_spIsolateImpl->CreatePersistent(hTarget);
}
@ -247,18 +253,24 @@ private:
}
template <typename T, typename TArg>
Persistent<T> MakeWeak(Persistent<T> hTarget, TArg* pArg, void (*pCallback)(Isolate*, Persistent<T>*, TArg*))
Persistent<T> MakeWeak(Persistent<T> hTarget, TArg* pArg, void (*pCallback)(v8::Isolate*, Persistent<T>*, TArg*))
{
return m_spIsolateImpl->MakeWeak(hTarget, pArg, pCallback);
}
template<typename T>
void ClearWeak(Persistent<T> hTarget)
{
return m_spIsolateImpl->ClearWeak(hTarget);
}
template <typename T>
void Dispose(Persistent<T> hTarget)
{
return m_spIsolateImpl->Dispose(hTarget);
}
Local<Value> ThrowException(Local<Value> hException)
v8::Local<v8::Value> ThrowException(v8::Local<v8::Value> hException)
{
return m_spIsolateImpl->ThrowException(hException);
}
@ -268,6 +280,11 @@ private:
return m_spIsolateImpl->TerminateExecution();
}
bool IsExecutionTerminating()
{
return m_spIsolateImpl->IsExecutionTerminating();
}
int ContextDisposedNotification()
{
return m_spIsolateImpl->ContextDisposedNotification();
@ -284,70 +301,93 @@ private:
}
template <typename T>
T Verify(const TryCatch& tryCatch, T result)
T Verify(const v8::TryCatch& tryCatch, T result)
{
Verify(tryCatch);
return result;
}
Handle<Value> Wrap();
~V8ContextImpl();
v8::Local<v8::Value> Wrap();
SharedPtr<V8WeakContextBinding> GetWeakBinding();
void GetV8ObjectPropertyNames(Handle<Object> hObject, std::vector<StdString>& names);
void GetV8ObjectPropertyIndices(Handle<Object> hObject, std::vector<int>& indices);
static bool CheckContextImplForGlobalObjectCallback(V8ContextImpl* pContextImpl);
static bool CheckContextImplForHostObjectCallback(V8ContextImpl* pContextImpl);
static void GetGlobalProperty(Local<String> hName, const PropertyCallbackInfo<Value>& info);
static void SetGlobalProperty(Local<String> hName, Local<Value> hValue, const PropertyCallbackInfo<Value>& info);
static void QueryGlobalProperty(Local<String> hName, const PropertyCallbackInfo<Integer>& info);
static void DeleteGlobalProperty(Local<String> hName, const PropertyCallbackInfo<Boolean>& info);
static void GetGlobalPropertyNames(const PropertyCallbackInfo<Array>& info);
void GetV8ObjectPropertyNames(v8::Local<v8::Object> hObject, std::vector<StdString>& names);
void GetV8ObjectPropertyIndices(v8::Local<v8::Object> hObject, std::vector<int>& indices);
static void GetGlobalProperty(unsigned __int32 index, const PropertyCallbackInfo<Value>& info);
static void SetGlobalProperty(unsigned __int32 index, Local<Value> hValue, const PropertyCallbackInfo<Value>& info);
static void QueryGlobalProperty(unsigned __int32 index, const PropertyCallbackInfo<Integer>& info);
static void DeleteGlobalProperty(unsigned __int32 index, const PropertyCallbackInfo<Boolean>& info);
static void GetGlobalPropertyIndices(const PropertyCallbackInfo<Array>& info);
static void GetGlobalProperty(v8::Local<v8::Name> hName, const v8::PropertyCallbackInfo<v8::Value>& info);
static void SetGlobalProperty(v8::Local<v8::Name> hName, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info);
static void QueryGlobalProperty(v8::Local<v8::Name> hName, const v8::PropertyCallbackInfo<v8::Integer>& info);
static void DeleteGlobalProperty(v8::Local<v8::Name> hName, const v8::PropertyCallbackInfo<v8::Boolean>& info);
static void GetGlobalPropertyNames(const v8::PropertyCallbackInfo<v8::Array>& info);
static void HostObjectConstructorCallHandler(const FunctionCallbackInfo<Value>& info);
static void CreateFunctionForHostDelegate(const FunctionCallbackInfo<Value>& info);
static void InvokeHostDelegate(const FunctionCallbackInfo<Value>& info);
static void GetGlobalProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Value>& info);
static void SetGlobalProperty(unsigned __int32 index, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info);
static void QueryGlobalProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Integer>& info);
static void DeleteGlobalProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Boolean>& info);
static void GetGlobalPropertyIndices(const v8::PropertyCallbackInfo<v8::Array>& info);
static void GetHostObjectProperty(Local<String> hName, const PropertyCallbackInfo<Value>& info);
static void SetHostObjectProperty(Local<String> hName, Local<Value> hValue, const PropertyCallbackInfo<Value>& info);
static void QueryHostObjectProperty(Local<String> hName, const PropertyCallbackInfo<Integer>& info);
static void DeleteHostObjectProperty(Local<String> hName, const PropertyCallbackInfo<Boolean>& info);
static void GetHostObjectPropertyNames(const PropertyCallbackInfo<Array>& info);
static void HostObjectConstructorCallHandler(const v8::FunctionCallbackInfo<v8::Value>& info);
static void CreateFunctionForHostDelegate(const v8::FunctionCallbackInfo<v8::Value>& info);
static void InvokeHostDelegate(const v8::FunctionCallbackInfo<v8::Value>& info);
static void GetHostObjectProperty(unsigned __int32 index, const PropertyCallbackInfo<Value>& info);
static void SetHostObjectProperty(unsigned __int32 index, Local<Value> hValue, const PropertyCallbackInfo<Value>& info);
static void QueryHostObjectProperty(unsigned __int32 index, const PropertyCallbackInfo<Integer>& info);
static void DeleteHostObjectProperty(unsigned __int32 index, const PropertyCallbackInfo<Boolean>& info);
static void GetHostObjectPropertyIndices(const PropertyCallbackInfo<Array>& info);
static void GetHostObjectProperty(v8::Local<v8::String> hName, const v8::PropertyCallbackInfo<v8::Value>& info);
static void SetHostObjectProperty(v8::Local<v8::String> hName, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info);
static void QueryHostObjectProperty(v8::Local<v8::String> hName, const v8::PropertyCallbackInfo<v8::Integer>& info);
static void DeleteHostObjectProperty(v8::Local<v8::String> hName, const v8::PropertyCallbackInfo<v8::Boolean>& info);
static void GetHostObjectPropertyNames(const v8::PropertyCallbackInfo<v8::Array>& info);
static void InvokeHostObject(const FunctionCallbackInfo<Value>& info);
static void DisposeWeakHandle(Isolate* pIsolate, Persistent<Object>* phObject, void* pvV8ObjectCache);
static void GetHostObjectProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Value>& info);
static void SetHostObjectProperty(unsigned __int32 index, v8::Local<v8::Value> hValue, const v8::PropertyCallbackInfo<v8::Value>& info);
static void QueryHostObjectProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Integer>& info);
static void DeleteHostObjectProperty(unsigned __int32 index, const v8::PropertyCallbackInfo<v8::Boolean>& info);
static void GetHostObjectPropertyIndices(const v8::PropertyCallbackInfo<v8::Array>& info);
Handle<Value> ImportValue(const V8Value& value);
V8Value ExportValue(Handle<Value> hValue);
void ImportValues(const std::vector<V8Value>& values, std::vector<Handle<Value>>& importedValues);
static void InvokeHostObject(const v8::FunctionCallbackInfo<v8::Value>& info);
static void DisposeWeakHandle(v8::Isolate* pIsolate, Persistent<v8::Object>* phObject, void* pvV8ObjectCache);
void Verify(const TryCatch& tryCatch);
v8::Local<v8::Value> ImportValue(const V8Value& value);
V8Value ExportValue(v8::Local<v8::Value> hValue);
void ImportValues(const std::vector<V8Value>& values, std::vector<v8::Local<v8::Value>>& importedValues);
void Verify(const v8::TryCatch& tryCatch);
void VerifyNotOutOfMemory();
void ThrowScriptException(const HostException& exception);
StdString m_Name;
SharedPtr<V8IsolateImpl> m_spIsolateImpl;
Persistent<Context> m_hContext;
Persistent<Object> m_hGlobal;
std::vector<std::pair<StdString, Persistent<Object>>> m_GlobalMembersStack;
Persistent<String> m_hHostObjectCookieName;
Persistent<String> m_hHostExceptionName;
Persistent<String> m_hAccessTokenName;
Persistent<Object> m_hAccessToken;
Persistent<FunctionTemplate> m_hHostObjectTemplate;
Persistent<FunctionTemplate> m_hHostDelegateTemplate;
Persistent<v8::Context> m_hContext;
Persistent<v8::Object> m_hGlobal;
std::vector<std::pair<StdString, Persistent<v8::Object>>> m_GlobalMembersStack;
Persistent<v8::String> m_hHostObjectCookieName;
Persistent<v8::String> m_hHostExceptionName;
Persistent<v8::String> m_hAccessTokenName;
Persistent<v8::Object> m_hAccessToken;
Persistent<v8::FunctionTemplate> m_hHostObjectTemplate;
Persistent<v8::FunctionTemplate> m_hHostDelegateTemplate;
Persistent<v8::Value> m_hTerminationException;
SharedPtr<V8WeakContextBinding> m_spWeakBinding;
void* m_pvV8ObjectCache;
bool m_AllowHostObjectConstructorCall;
bool m_DisableHostObjectInterception;
};
//-----------------------------------------------------------------------------
// SharedPtrTraits<V8ContextImpl>
//-----------------------------------------------------------------------------
template<>
class SharedPtrTraits<V8ContextImpl>
{
PROHIBIT_CONSTRUCT(SharedPtrTraits)
public:
static void Destroy(V8ContextImpl* pTarget)
{
pTarget->Destroy();
}
};

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

@ -518,7 +518,7 @@ namespace V8 {
return nullptr;
}
//-----------------------------------------------------------------------------
//-------------------------------------------------------------------------
SharedPtr<V8Context> V8ContextProxyImpl::GetContext()
{
@ -534,4 +534,8 @@ namespace V8 {
END_LOCK_SCOPE
}
//-------------------------------------------------------------------------
ENSURE_INTERNAL_CLASS(V8ContextProxyImpl)
}}}

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

@ -69,3 +69,10 @@ V8Isolate* V8Isolate::Create(const StdString& name, const V8IsolateConstraints*
{
return new V8IsolateImpl(name, pConstraints, enableDebugging, debugPort);
}
//-----------------------------------------------------------------------------
size_t V8Isolate::GetInstanceCount()
{
return V8IsolateImpl::GetInstanceCount();
}

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

@ -70,6 +70,7 @@ class V8Isolate: public WeakRefTarget<V8Isolate>
public:
static V8Isolate* Create(const StdString& name, const V8IsolateConstraints* pConstraints, bool enableDebugging, int debugPort);
static size_t GetInstanceCount();
virtual size_t GetMaxHeapSize() = 0;
virtual void SetMaxHeapSize(size_t value) = 0;

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

@ -65,14 +65,14 @@
// V8Platform
//-----------------------------------------------------------------------------
class V8Platform: public Platform
class V8Platform: public v8::Platform
{
public:
static void EnsureInstalled();
virtual void CallOnBackgroundThread(Task* pTask, ExpectedRuntime runtime) override;
virtual void CallOnForegroundThread(Isolate* pIsolate, Task* pTask) override;
virtual void CallOnBackgroundThread(v8::Task* pTask, ExpectedRuntime runtime) override;
virtual void CallOnForegroundThread(v8::Isolate* pIsolate, v8::Task* pTask) override;
virtual double MonotonicallyIncreasingTime() override;
private:
@ -89,22 +89,22 @@ void V8Platform::EnsureInstalled()
{
std::call_once(ms_InstallationFlag, []
{
V8::InitializePlatform(&ms_Instance);
ASSERT_EVAL(V8::Initialize());
v8::V8::InitializePlatform(&ms_Instance);
ASSERT_EVAL(v8::V8::Initialize());
});
}
//-----------------------------------------------------------------------------
void V8Platform::CallOnBackgroundThread(Task* pTask, ExpectedRuntime /*runtime*/)
void V8Platform::CallOnBackgroundThread(v8::Task* pTask, ExpectedRuntime /*runtime*/)
{
std::shared_ptr<Task> spTask(pTask);
std::shared_ptr<v8::Task> spTask(pTask);
Concurrency::create_task([spTask] { spTask->Run(); });
}
//-----------------------------------------------------------------------------
void V8Platform::CallOnForegroundThread(Isolate* /*pIsolate*/, Task* /*pTask*/)
void V8Platform::CallOnForegroundThread(v8::Isolate* /*pIsolate*/, v8::Task* /*pTask*/)
{
// unexpected call to unsupported method
std::terminate();
@ -132,7 +132,7 @@ std::once_flag V8Platform::ms_InstallationFlag;
// V8ArrayBufferAllocator
//-----------------------------------------------------------------------------
class V8ArrayBufferAllocator: public ArrayBuffer::Allocator
class V8ArrayBufferAllocator: public v8::ArrayBuffer::Allocator
{
public:
@ -156,7 +156,7 @@ void V8ArrayBufferAllocator::EnsureInstalled()
{
std::call_once(ms_InstallationFlag, []
{
V8::SetArrayBufferAllocator(&ms_Instance);
v8::V8::SetArrayBufferAllocator(&ms_Instance);
});
}
@ -198,12 +198,20 @@ std::once_flag V8ArrayBufferAllocator::ms_InstallationFlag;
#define BEGIN_ISOLATE_ENTRY_SCOPE \
{ \
Isolate::Scope t_IsolateEntryScope(m_pIsolate);
v8::Isolate::Scope t_IsolateEntryScope(m_pIsolate);
#define END_ISOLATE_ENTRY_SCOPE \
IGNORE_UNUSED(t_IsolateEntryScope); \
}
#define BEGIN_ISOLATE_NATIVE_SCOPE \
{ \
NativeScope t_IsolateNativeScope(this);
#define END_ISOLATE_NATIVE_SCOPE \
IGNORE_UNUSED(t_IsolateNativeScope); \
}
#define BEGIN_ISOLATE_SCOPE \
{ \
Scope t_IsolateScope(this);
@ -216,10 +224,11 @@ std::once_flag V8ArrayBufferAllocator::ms_InstallationFlag;
static const size_t s_StackBreathingRoom = static_cast<size_t>(16 * 1024);
static size_t* const s_pMinStackLimit = reinterpret_cast<size_t*>(sizeof(size_t));
static std::atomic<size_t> s_InstanceCount(0);
//-----------------------------------------------------------------------------
V8IsolateImpl::V8IsolateImpl(const StdString& name, const V8IsolateConstraints* pConstraints, bool enableDebugging, int debugPort):
V8IsolateImpl::V8IsolateImpl(const StdString& name, const V8IsolateConstraints* pConstraints, bool enableDebugging, int debugPort) :
m_Name(name),
m_DebuggingEnabled(false),
m_DebugMessageDispatchCount(0),
@ -228,12 +237,13 @@ V8IsolateImpl::V8IsolateImpl(const StdString& name, const V8IsolateConstraints*
m_MaxStackUsage(0),
m_StackWatchLevel(0),
m_pStackLimit(nullptr),
m_IsOutOfMemory(false)
m_IsOutOfMemory(false),
m_IsExecutionTerminating(false)
{
V8Platform::EnsureInstalled();
V8ArrayBufferAllocator::EnsureInstalled();
Isolate::CreateParams params;
v8::Isolate::CreateParams params;
if (pConstraints != nullptr)
{
params.constraints.set_max_semi_space_size(pConstraints->GetMaxNewSpaceSize());
@ -241,37 +251,40 @@ V8IsolateImpl::V8IsolateImpl(const StdString& name, const V8IsolateConstraints*
params.constraints.set_max_executable_size(pConstraints->GetMaxExecutableSize());
}
m_pIsolate = Isolate::New(params);
m_pIsolate = v8::Isolate::New(params);
BEGIN_ADDREF_SCOPE
m_pIsolate->SetData(0, this);
BEGIN_ISOLATE_ENTRY_SCOPE
V8::SetCaptureStackTraceForUncaughtExceptions(true, 64, StackTrace::kDetailed);
v8::V8::SetCaptureStackTraceForUncaughtExceptions(true, 64, v8::StackTrace::kDetailed);
END_ISOLATE_ENTRY_SCOPE
if (enableDebugging)
{
BEGIN_ISOLATE_SCOPE
EnableDebugging(debugPort);
END_ISOLATE_SCOPE
}
END_ADDREF_SCOPE
++s_InstanceCount;
}
//-----------------------------------------------------------------------------
size_t V8IsolateImpl::GetInstanceCount()
{
return s_InstanceCount;
}
//-----------------------------------------------------------------------------
void V8IsolateImpl::AddContext(V8ContextImpl* pContextImpl, bool enableDebugging, int debugPort)
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
if (!enableDebugging)
{
m_ContextPtrs.push_back(pContextImpl);
@ -287,9 +300,7 @@ void V8IsolateImpl::AddContext(V8ContextImpl* pContextImpl, bool enableDebugging
void V8IsolateImpl::RemoveContext(V8ContextImpl* pContextImpl)
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
m_ContextPtrs.remove(pContextImpl);
}
@ -297,12 +308,10 @@ void V8IsolateImpl::RemoveContext(V8ContextImpl* pContextImpl)
void V8IsolateImpl::EnableDebugging(int debugPort)
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
if (!m_DebuggingEnabled)
{
StdString version(String::NewFromUtf8(m_pIsolate, V8::GetVersion()));
StdString version(v8::String::NewFromUtf8(m_pIsolate, v8::V8::GetVersion()));
if (debugPort < 1)
{
debugPort = 9222;
@ -326,7 +335,7 @@ void V8IsolateImpl::EnableDebugging(int debugPort)
}
});
Debug::SetMessageHandler(OnDebugMessageShared);
v8::Debug::SetMessageHandler(OnDebugMessageShared);
m_DebuggingEnabled = true;
m_DebugPort = debugPort;
@ -337,12 +346,10 @@ void V8IsolateImpl::EnableDebugging(int debugPort)
void V8IsolateImpl::DisableDebugging()
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
if (m_DebuggingEnabled)
{
Debug::SetMessageHandler(nullptr);
v8::Debug::SetMessageHandler(nullptr);
HostObjectHelpers::DestroyDebugAgent(m_pvDebugAgent);
m_DebuggingEnabled = false;
@ -411,7 +418,7 @@ void V8IsolateImpl::GetHeapInfo(V8IsolateHeapInfo& heapInfo)
{
BEGIN_ISOLATE_SCOPE
HeapStatistics heapStatistics;
v8::HeapStatistics heapStatistics;
m_pIsolate->GetHeapStatistics(&heapStatistics);
heapInfo.Set(
@ -458,11 +465,10 @@ void* V8IsolateImpl::AddRefV8Object(void* pvObject)
void V8IsolateImpl::ReleaseV8Object(void* pvObject)
{
BEGIN_ISOLATE_SCOPE
Dispose(::ObjectHandleFromPtr(pvObject));
END_ISOLATE_SCOPE
CallWithLockNoWait([pvObject] (V8IsolateImpl* pIsolateImpl)
{
pIsolateImpl->Dispose(::ObjectHandleFromPtr(pvObject));
});
}
//-----------------------------------------------------------------------------
@ -480,11 +486,34 @@ void* V8IsolateImpl::AddRefV8Script(void* pvScript)
void V8IsolateImpl::ReleaseV8Script(void* pvScript)
{
BEGIN_ISOLATE_SCOPE
CallWithLockNoWait([pvScript] (V8IsolateImpl* pIsolateImpl)
{
pIsolateImpl->Dispose(::ScriptHandleFromPtr(pvScript));
});
}
Dispose(::ScriptHandleFromPtr(pvScript));
//-----------------------------------------------------------------------------
END_ISOLATE_SCOPE
void V8IsolateImpl::CallWithLockNoWait(std::function<void(V8IsolateImpl*)>&& callback)
{
if (m_Mutex.TryLock())
{
// the callback may release this instance; hold it for destruction outside isolate scope
SharedPtr<V8IsolateImpl> spThis(this);
MutexLock<RecursiveMutex> lock(m_Mutex, false);
BEGIN_ISOLATE_NATIVE_SCOPE
callback(this);
END_ISOLATE_NATIVE_SCOPE
}
else
{
std::function<void(V8IsolateImpl*)> userCallback(std::move(callback));
CallWithLockAsync([userCallback] (V8IsolateImpl* pIsolateImpl)
{
userCallback(pIsolateImpl);
});
}
}
//-----------------------------------------------------------------------------
@ -499,10 +528,10 @@ void DECLSPEC_NORETURN V8IsolateImpl::ThrowOutOfMemoryException()
V8IsolateImpl::~V8IsolateImpl()
{
--s_InstanceCount;
BEGIN_ISOLATE_SCOPE
DisableDebugging();
END_ISOLATE_SCOPE
m_pIsolate->Dispose();
@ -510,26 +539,45 @@ V8IsolateImpl::~V8IsolateImpl()
//-----------------------------------------------------------------------------
void V8IsolateImpl::OnInterruptShared(Isolate* pIsolate, void* /*pvData*/)
void V8IsolateImpl::CallWithLockAsync(std::function<void(V8IsolateImpl*)>&& callback)
{
static_cast<V8IsolateImpl*>(pIsolate->GetData(0))->OnInterrupt();
if (callback)
{
size_t queueLength;
BEGIN_MUTEX_SCOPE(m_CallWithLockQueueMutex)
m_CallWithLockQueue.push(std::move(callback));
queueLength = m_CallWithLockQueue.size();
END_MUTEX_SCOPE
if (queueLength == 1)
{
RequestInterrupt(ProcessCallWithLockQueue, this);
}
}
}
//-----------------------------------------------------------------------------
void V8IsolateImpl::OnInterrupt()
void V8IsolateImpl::ProcessCallWithLockQueue(v8::Isolate* /*pIsolate*/, void* pvIsolateImpl)
{
std::function<void(V8IsolateImpl*)> callback;
static_cast<V8IsolateImpl*>(pvIsolateImpl)->ProcessCallWithLockQueue();
}
BEGIN_MUTEX_SCOPE(m_InterruptMutex)
//-----------------------------------------------------------------------------
callback = std::move(m_InterruptCallback);
void V8IsolateImpl::ProcessCallWithLockQueue()
{
std::queue<std::function<void(V8IsolateImpl*)>> callWithLockQueue;
BEGIN_MUTEX_SCOPE(m_CallWithLockQueueMutex)
std::swap(callWithLockQueue, m_CallWithLockQueue);
END_MUTEX_SCOPE
if (callback)
while (callWithLockQueue.size() > 0)
{
callback(this);
callWithLockQueue.front()(this);
callWithLockQueue.pop();
}
}
@ -537,19 +585,19 @@ void V8IsolateImpl::OnInterrupt()
void V8IsolateImpl::SendDebugCommand(const StdString& command)
{
Debug::SendCommand(m_pIsolate, command.ToCString(), command.GetLength());
v8::Debug::SendCommand(m_pIsolate, command.ToCString(), command.GetLength());
}
//-----------------------------------------------------------------------------
void V8IsolateImpl::OnDebugMessageShared(const Debug::Message& message)
void V8IsolateImpl::OnDebugMessageShared(const v8::Debug::Message& message)
{
static_cast<V8IsolateImpl*>(message.GetIsolate()->GetData(0))->OnDebugMessage(message);
}
//-----------------------------------------------------------------------------
void V8IsolateImpl::OnDebugMessage(const Debug::Message& message)
void V8IsolateImpl::OnDebugMessage(const v8::Debug::Message& message)
{
if (m_pvDebugAgent)
{
@ -586,8 +634,7 @@ void V8IsolateImpl::ProcessDebugMessages()
void V8IsolateImpl::EnterExecutionScope(size_t* pStackMarker)
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
// is heap size monitoring in progress?
if (m_HeapWatchLevel == 0)
@ -658,14 +705,16 @@ void V8IsolateImpl::EnterExecutionScope(size_t* pStackMarker)
// enter nested stack usage monitoring scope
m_StackWatchLevel++;
}
// clear termination flag
m_IsExecutionTerminating = false;
}
//-----------------------------------------------------------------------------
void V8IsolateImpl::ExitExecutionScope()
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
// is stack usage monitoring in progress?
if (m_StackWatchLevel > 0)
@ -699,8 +748,7 @@ void V8IsolateImpl::ExitExecutionScope()
void V8IsolateImpl::SetUpHeapWatchTimer(size_t maxHeapSize)
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
// create heap watch timer
auto wrIsolate = CreateWeakRef();
@ -712,7 +760,7 @@ void V8IsolateImpl::SetUpHeapWatchTimer(size_t maxHeapSize)
{
// yes; request callback on execution thread
auto wrTimer = pTimer->CreateWeakRef();
static_cast<V8IsolateImpl*>(spIsolate.GetRawPtr())->RequestInterrupt([wrTimer, maxHeapSize] (V8IsolateImpl* pIsolateImpl)
static_cast<V8IsolateImpl*>(spIsolate.GetRawPtr())->CallWithLockAsync([wrTimer, maxHeapSize] (V8IsolateImpl* pIsolateImpl)
{
// execution thread callback; is the timer still alive?
auto spTimer = wrTimer.GetTarget();
@ -733,8 +781,7 @@ void V8IsolateImpl::SetUpHeapWatchTimer(size_t maxHeapSize)
void V8IsolateImpl::CheckHeapSize(size_t maxHeapSize)
{
_ASSERTE(m_pIsolate == Isolate::GetCurrent());
_ASSERTE(Locker::IsLocked(m_pIsolate));
_ASSERTE(IsCurrent() && IsLocked());
// is the total heap size over the limit?
V8IsolateHeapInfo heapInfo;

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

@ -75,6 +75,35 @@ class V8IsolateImpl: public V8Isolate
{
PROHIBIT_COPY(V8IsolateImpl)
class NativeScope
{
PROHIBIT_COPY(NativeScope)
PROHIBIT_HEAP(NativeScope)
public:
explicit NativeScope(V8IsolateImpl* pIsolateImpl):
m_pIsolateImpl(pIsolateImpl),
m_LockScope(m_pIsolateImpl->m_pIsolate),
m_IsolateScope(m_pIsolateImpl->m_pIsolate),
m_HandleScope(m_pIsolateImpl->m_pIsolate)
{
m_pIsolateImpl->ProcessCallWithLockQueue();
}
~NativeScope()
{
m_pIsolateImpl->ProcessCallWithLockQueue();
}
private:
V8IsolateImpl* m_pIsolateImpl;
v8::Locker m_LockScope;
v8::Isolate::Scope m_IsolateScope;
v8::HandleScope m_HandleScope;
};
public:
class Scope
@ -85,17 +114,15 @@ public:
public:
explicit Scope(V8IsolateImpl* pIsolateImpl):
m_LockScope(pIsolateImpl->m_pIsolate),
m_IsolateScope(pIsolateImpl->m_pIsolate),
m_HandleScope(pIsolateImpl->m_pIsolate)
m_MutexLock(pIsolateImpl->m_Mutex),
m_NativeScope(pIsolateImpl)
{
}
private:
Locker m_LockScope;
Isolate::Scope m_IsolateScope;
HandleScope m_HandleScope;
MutexLock<RecursiveMutex> m_MutexLock;
NativeScope m_NativeScope;
};
class ExecutionScope
@ -122,107 +149,109 @@ public:
};
V8IsolateImpl(const StdString& name, const V8IsolateConstraints* pConstraints, bool enableDebugging, int debugPort);
static size_t GetInstanceCount();
const StdString& GetName() const { return m_Name; }
Local<Context> CreateContext(ExtensionConfiguration* pExtensionConfiguation = nullptr, Handle<ObjectTemplate> hGlobalTemplate = Handle<ObjectTemplate>(), Handle<Value> hGlobalObject = Handle<Value>())
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 Context::New(m_pIsolate, pExtensionConfiguation, hGlobalTemplate, hGlobalObject);
return v8::Context::New(m_pIsolate, pExtensionConfiguation, hGlobalTemplate, hGlobalObject);
}
Handle<Primitive> GetUndefined()
v8::Local<v8::Primitive> GetUndefined()
{
return Undefined(m_pIsolate);
return v8::Undefined(m_pIsolate);
}
Handle<Primitive> GetNull()
v8::Local<v8::Primitive> GetNull()
{
return Null(m_pIsolate);
return v8::Null(m_pIsolate);
}
Handle<Boolean> GetTrue()
v8::Local<v8::Boolean> GetTrue()
{
return True(m_pIsolate);
return v8::True(m_pIsolate);
}
Handle<Boolean> GetFalse()
v8::Local<v8::Boolean> GetFalse()
{
return False(m_pIsolate);
return v8::False(m_pIsolate);
}
Local<Object> CreateObject()
v8::Local<v8::Object> CreateObject()
{
return Object::New(m_pIsolate);
return v8::Object::New(m_pIsolate);
}
Local<Number> CreateNumber(double value)
v8::Local<v8::Number> CreateNumber(double value)
{
return Number::New(m_pIsolate, value);
return v8::Number::New(m_pIsolate, value);
}
Local<Integer> CreateInteger(__int32 value)
v8::Local<v8::Integer> CreateInteger(__int32 value)
{
return Int32::New(m_pIsolate, value);
return v8::Int32::New(m_pIsolate, value);
}
Local<Integer> CreateInteger(unsigned __int32 value)
v8::Local<v8::Integer> CreateInteger(unsigned __int32 value)
{
return Uint32::NewFromUnsigned(m_pIsolate, value);
return v8::Uint32::NewFromUnsigned(m_pIsolate, value);
}
Local<String> CreateString(const StdString& value)
v8::Local<v8::String> CreateString(const StdString& value)
{
return value.ToV8String(m_pIsolate);
}
Local<Array> CreateArray(int length = 0)
v8::Local<v8::Array> CreateArray(int length = 0)
{
return Array::New(m_pIsolate, length);
return v8::Array::New(m_pIsolate, length);
}
Local<External> CreateExternal(void* pvValue)
v8::Local<v8::External> CreateExternal(void* pvValue)
{
return External::New(m_pIsolate, pvValue);
return v8::External::New(m_pIsolate, pvValue);
}
Local<ObjectTemplate> CreateObjectTemplate()
v8::Local<v8::ObjectTemplate> CreateObjectTemplate()
{
return ObjectTemplate::New(m_pIsolate);
return v8::ObjectTemplate::New(m_pIsolate);
}
Local<FunctionTemplate> CreateFunctionTemplate()
v8::Local<v8::FunctionTemplate> CreateFunctionTemplate()
{
return FunctionTemplate::New(m_pIsolate);
return v8::FunctionTemplate::New(m_pIsolate);
}
Local<Function> CreateFunction(FunctionCallback callback, Local<Value> data = Local<Value>(), int length = 0)
v8::Local<v8::Function> CreateFunction(v8::FunctionCallback callback, v8::Local<v8::Value> data = v8::Local<v8::Value>(), int length = 0)
{
return Function::New(m_pIsolate, callback, data, length);
return v8::Function::New(m_pIsolate, callback, data, length);
}
Local<Script> CreateScript(ScriptCompiler::Source* pSource, ScriptCompiler::CompileOptions options = ScriptCompiler::kNoCompileOptions)
v8::Local<v8::Script> CreateScript(v8::ScriptCompiler::Source* pSource, v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileOptions)
{
return ScriptCompiler::Compile(m_pIsolate, pSource, options);
return v8::ScriptCompiler::Compile(m_pIsolate, pSource, options);
}
Local<UnboundScript> CreateUnboundScript(ScriptCompiler::Source* pSource, ScriptCompiler::CompileOptions options = ScriptCompiler::kNoCompileOptions)
v8::Local<v8::UnboundScript> CreateUnboundScript(v8::ScriptCompiler::Source* pSource, v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileOptions)
{
return ScriptCompiler::CompileUnbound(m_pIsolate, pSource, options);
return v8::ScriptCompiler::CompileUnbound(m_pIsolate, pSource, options);
}
template <typename T>
Local<T> CreateLocal(Handle<T> hTarget)
v8::Local<T> CreateLocal(v8::Local<T> hTarget)
{
return Local<T>::New(m_pIsolate, hTarget);
return v8::Local<T>::New(m_pIsolate, hTarget);
}
template <typename T>
Local<T> CreateLocal(Persistent<T> hTarget)
v8::Local<T> CreateLocal(Persistent<T> hTarget)
{
return hTarget.CreateLocal(m_pIsolate);
}
template <typename T>
Persistent<T> CreatePersistent(Handle<T> hTarget)
Persistent<T> CreatePersistent(v8::Local<T> hTarget)
{
return Persistent<T>::New(m_pIsolate, hTarget);
}
@ -234,25 +263,37 @@ public:
}
template <typename T, typename TArg>
Persistent<T> MakeWeak(Persistent<T> hTarget, TArg* pArg, void (*pCallback)(Isolate*, Persistent<T>*, TArg*))
Persistent<T> MakeWeak(Persistent<T> hTarget, TArg* pArg, void (*pCallback)(v8::Isolate*, Persistent<T>*, TArg*))
{
return hTarget.MakeWeak(m_pIsolate, pArg, pCallback);
}
template<typename T>
void ClearWeak(Persistent<T> hTarget)
{
return hTarget.ClearWeak();
}
template <typename T>
void Dispose(Persistent<T> hTarget)
{
hTarget.Dispose();
}
Local<Value> ThrowException(Local<Value> hException)
v8::Local<v8::Value> ThrowException(v8::Local<v8::Value> hException)
{
return m_pIsolate->ThrowException(hException);
}
void TerminateExecution()
{
V8::TerminateExecution(m_pIsolate);
m_pIsolate->TerminateExecution();
m_IsExecutionTerminating = true;
}
bool IsExecutionTerminating()
{
return m_pIsolate->IsExecutionTerminating() || m_IsExecutionTerminating;
}
int ContextDisposedNotification()
@ -270,24 +311,19 @@ public:
m_pIsolate->LowMemoryNotification();
}
void RequestInterrupt(std::function<void(V8IsolateImpl*)>&& callback)
void RequestInterrupt(v8::InterruptCallback callback, void* pvData)
{
BEGIN_MUTEX_SCOPE(m_InterruptMutex)
m_InterruptCallback = std::move(callback);
m_pIsolate->RequestInterrupt(OnInterruptShared, nullptr);
END_MUTEX_SCOPE
m_pIsolate->RequestInterrupt(callback, pvData);
}
void ClearInterrupt()
bool IsCurrent() const
{
BEGIN_MUTEX_SCOPE(m_InterruptMutex)
return m_pIsolate == v8::Isolate::GetCurrent();
}
m_InterruptCallback = nullptr;
m_pIsolate->ClearInterrupt();
END_MUTEX_SCOPE
bool IsLocked() const
{
return v8::Locker::IsLocked(m_pIsolate);
}
bool IsOutOfMemory() const
@ -319,18 +355,20 @@ public:
void* AddRefV8Script(void* pvScript);
void ReleaseV8Script(void* pvScript);
void CallWithLockNoWait(std::function<void(V8IsolateImpl*)>&& callback);
void DECLSPEC_NORETURN ThrowOutOfMemoryException();
~V8IsolateImpl();
private:
static void OnInterruptShared(Isolate* pIsolate, void* pvData);
void OnInterrupt();
void CallWithLockAsync(std::function<void(V8IsolateImpl*)>&& callback);
static void ProcessCallWithLockQueue(v8::Isolate* pIsolate, void* pvIsolateImpl);
void ProcessCallWithLockQueue();
void SendDebugCommand(const StdString& command);
static void OnDebugMessageShared(const Debug::Message& message);
void OnDebugMessage(const Debug::Message& message);
static void OnDebugMessageShared(const v8::Debug::Message& message);
void OnDebugMessage(const v8::Debug::Message& message);
void DispatchDebugMessages();
void ProcessDebugMessages();
@ -341,25 +379,22 @@ private:
void CheckHeapSize(size_t maxHeapSize);
StdString m_Name;
Isolate* m_pIsolate;
v8::Isolate* m_pIsolate;
RecursiveMutex m_Mutex;
std::list<V8ContextImpl*> m_ContextPtrs;
SimpleMutex m_InterruptMutex;
std::function<void(V8IsolateImpl*)> m_InterruptCallback;
SimpleMutex m_CallWithLockQueueMutex;
std::queue<std::function<void(V8IsolateImpl*)>> m_CallWithLockQueue;
bool m_DebuggingEnabled;
int m_DebugPort;
void* m_pvDebugAgent;
std::atomic<size_t> m_DebugMessageDispatchCount;
std::atomic<size_t> m_MaxHeapSize;
std::atomic<double> m_HeapSizeSampleInterval;
size_t m_HeapWatchLevel;
SharedPtr<Timer> m_spHeapWatchTimer;
std::atomic<size_t> m_MaxStackUsage;
size_t m_StackWatchLevel;
size_t* m_pStackLimit;
std::atomic<bool> m_IsOutOfMemory;
std::atomic<bool> m_IsExecutionTerminating;
};

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

@ -230,4 +230,8 @@ namespace V8 {
return value;
}
//-------------------------------------------------------------------------
ENSURE_INTERNAL_CLASS(V8IsolateProxyImpl)
}}}

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

@ -70,7 +70,6 @@
#include "v8.h"
#include "v8-platform.h"
#include "v8-debug.h"
using namespace v8;
#pragma warning(pop)
@ -95,21 +94,21 @@ public:
}
template <typename TOther>
static V8FastPersistent<T> New(Isolate* pIsolate, const Handle<TOther>& hValue)
static V8FastPersistent<T> New(v8::Isolate* pIsolate, const v8::Local<TOther>& hValue)
{
Persistent<T> hTemp(pIsolate, hValue);
v8::Persistent<T> hTemp(pIsolate, hValue);
return V8FastPersistent<T>(GetPtrAndClear(hTemp));
}
template <typename TOther>
static V8FastPersistent<T> New(Isolate* pIsolate, const V8FastPersistent<TOther>& hValue)
static V8FastPersistent<T> New(v8::Isolate* pIsolate, const V8FastPersistent<TOther>& hValue)
{
Persistent<T> hTemp(pIsolate, hValue.AsPersistent());
v8::Persistent<T> hTemp(pIsolate, hValue.AsPersistent());
return V8FastPersistent<T>(GetPtrAndClear(hTemp));
}
template <typename TOther>
bool operator==(const Handle<TOther>& hValue)
bool operator==(const v8::Local<TOther>& hValue)
{
return AsPersistent() == hValue;
}
@ -121,7 +120,7 @@ public:
}
template <typename TOther>
bool operator!=(const Handle<TOther>& hValue)
bool operator!=(const v8::Local<TOther>& hValue)
{
return AsPersistent() != hValue;
}
@ -147,36 +146,44 @@ public:
return V8FastPersistent<T>(static_cast<T*>(pvValue));
}
Local<T> operator->() const
v8::Local<T> operator->() const
{
return CreateLocal();
}
template <typename TOther>
operator Handle<TOther>() const
operator v8::Local<TOther>() const
{
return CreateLocal();
}
template <typename TOther>
operator Local<TOther>() const
v8::Local<T> CreateLocal(v8::Isolate* pIsolate) const
{
return CreateLocal();
return v8::Local<T>::New(pIsolate, AsPersistent());
}
Local<T> CreateLocal(Isolate* pIsolate) const
bool IsWeak() const
{
return Local<T>::New(pIsolate, AsPersistent());
return AsPersistent().IsWeak();
}
template <typename TArg>
V8FastPersistent<T> MakeWeak(Isolate* pIsolate, TArg* pArg, void (*pCallback)(Isolate*, V8FastPersistent<T>*, TArg*))
V8FastPersistent<T> MakeWeak(v8::Isolate* pIsolate, TArg* pArg, void (*pCallback)(v8::Isolate*, V8FastPersistent<T>*, TArg*))
{
IGNORE_UNUSED(pIsolate);
_ASSERTE(!IsWeak() && !IsEmpty());
AsPersistent().SetWeak(new WeakCallbackContext<TArg>(m_pValue, pArg, pCallback), WeakCallback);
return *this;
}
void ClearWeak()
{
_ASSERTE(IsWeak());
auto pContext = AsPersistent().ClearWeak<WeakCallbackContextBase>();
_ASSERTE(pContext);
delete pContext;
}
void Dispose()
{
AsPersistent().Reset();
@ -189,22 +196,22 @@ private:
{
}
Local<T> CreateLocal() const
v8::Local<T> CreateLocal() const
{
return Local<T>::New(Isolate::GetCurrent(), AsPersistent());
return v8::Local<T>::New(v8::Isolate::GetCurrent(), AsPersistent());
}
const Persistent<T>& AsPersistent() const
const v8::Persistent<T>& AsPersistent() const
{
return *(reinterpret_cast<const Persistent<T>*>(&m_pValue));
return *(reinterpret_cast<const v8::Persistent<T>*>(&m_pValue));
}
Persistent<T>& AsPersistent()
v8::Persistent<T>& AsPersistent()
{
return *(reinterpret_cast<Persistent<T>*>(&m_pValue));
return *(reinterpret_cast<v8::Persistent<T>*>(&m_pValue));
}
static T* GetPtrAndClear(Persistent<T>& hValue)
static T* GetPtrAndClear(v8::Persistent<T>& hValue)
{
auto ppValue = reinterpret_cast<T**>(&hValue);
auto pValue = *ppValue;
@ -213,19 +220,26 @@ private:
return pValue;
}
template <typename TArg>
class WeakCallbackContext
class WeakCallbackContextBase
{
public:
WeakCallbackContext(T* pValue, TArg* pArg, void (*pCallback)(Isolate*, V8FastPersistent<T>*, TArg*)):
virtual ~WeakCallbackContextBase() {}
};
template <typename TArg>
class WeakCallbackContext: public WeakCallbackContextBase
{
public:
WeakCallbackContext(T* pValue, TArg* pArg, void (*pCallback)(v8::Isolate*, V8FastPersistent<T>*, TArg*)):
m_pValue(pValue),
m_pArg(pArg),
m_pCallback(pCallback)
{
}
void InvokeCallback(Isolate* pIsolate) const
void InvokeCallback(v8::Isolate* pIsolate) const
{
V8FastPersistent<T> hTarget(m_pValue);
m_pCallback(pIsolate, &hTarget, m_pArg);
@ -235,11 +249,11 @@ private:
T* m_pValue;
TArg* m_pArg;
void (*m_pCallback)(Isolate*, V8FastPersistent<T>*, TArg*);
void (*m_pCallback)(v8::Isolate*, V8FastPersistent<T>*, TArg*);
};
template <typename TArg>
static void WeakCallback(const WeakCallbackData<T, TArg>& data)
static void WeakCallback(const v8::WeakCallbackData<T, TArg>& data)
{
auto pContext = data.GetParameter();
_ASSERTE(pContext);
@ -268,19 +282,19 @@ public:
}
template <typename TOther>
static V8SafePersistent<T> New(Isolate* pIsolate, const Handle<TOther>& hValue)
static V8SafePersistent<T> New(v8::Isolate* pIsolate, const v8::Local<TOther>& hValue)
{
return V8SafePersistent<T>(new Persistent<T>(pIsolate, hValue));
return V8SafePersistent<T>(new v8::Persistent<T>(pIsolate, hValue));
}
template <typename TOther>
static V8SafePersistent<T> New(Isolate* pIsolate, const V8SafePersistent<TOther>& hValue)
static V8SafePersistent<T> New(v8::Isolate* pIsolate, const V8SafePersistent<TOther>& hValue)
{
return V8SafePersistent<T>(new Persistent<T>(pIsolate, hValue.GetImpl()));
return V8SafePersistent<T>(new v8::Persistent<T>(pIsolate, hValue.GetImpl()));
}
template <typename TOther>
bool operator==(const Handle<TOther>& hValue)
bool operator==(const v8::Local<TOther>& hValue)
{
return GetImpl() == hValue;
}
@ -292,7 +306,7 @@ public:
}
template <typename TOther>
bool operator!=(const Handle<TOther>& hValue)
bool operator!=(const v8::Local<TOther>& hValue)
{
return GetImpl() != hValue;
}
@ -315,40 +329,47 @@ public:
static V8SafePersistent<T> FromPtr(void* pvImpl)
{
return V8SafePersistent<T>(static_cast<Persistent<T>*>(pvImpl));
return V8SafePersistent<T>(static_cast<v8::Persistent<T>*>(pvImpl));
}
Local<T> operator->() const
v8::Local<T> operator->() const
{
return CreateLocal();
}
template <typename TOther>
operator Handle<TOther>() const
operator v8::Local<TOther>() const
{
return CreateLocal();
}
template <typename TOther>
operator Local<TOther>() const
v8::Local<T> CreateLocal(v8::Isolate* pIsolate) const
{
return CreateLocal();
return v8::Local<T>::New(pIsolate, GetImpl());
}
Local<T> CreateLocal(Isolate* pIsolate) const
bool IsWeak() const
{
return Local<T>::New(pIsolate, GetImpl());
return (m_pImpl != nullptr) && m_pImpl->IsWeak();
}
template <typename TArg>
V8SafePersistent<T> MakeWeak(Isolate* pIsolate, TArg* pArg, void (*pCallback)(Isolate*, V8SafePersistent<T>*, TArg*))
V8SafePersistent<T> MakeWeak(v8::Isolate* pIsolate, TArg* pArg, void (*pCallback)(v8::Isolate*, V8SafePersistent<T>*, TArg*))
{
IGNORE_UNUSED(pIsolate);
_ASSERTE(m_pImpl != nullptr);
_ASSERTE(!IsWeak() && !IsEmpty());
m_pImpl->SetWeak(new WeakCallbackContext<TArg>(m_pImpl, pArg, pCallback), WeakCallback);
return *this;
}
void ClearWeak()
{
_ASSERTE(IsWeak());
auto pContext = m_pImpl->ClearWeak<WeakCallbackContextBase>();
_ASSERTE(pContext);
delete pContext;
}
void Dispose()
{
if (m_pImpl != nullptr)
@ -361,34 +382,41 @@ public:
private:
explicit V8SafePersistent<T>(Persistent<T>* pImpl):
explicit V8SafePersistent<T>(v8::Persistent<T>* pImpl):
m_pImpl(pImpl)
{
}
Local<T> CreateLocal() const
v8::Local<T> CreateLocal() const
{
return Local<T>::New(Isolate::GetCurrent(), GetImpl());
return v8::Local<T>::New(v8::Isolate::GetCurrent(), GetImpl());
}
const Persistent<T>& GetImpl() const
const v8::Persistent<T>& GetImpl() const
{
return (m_pImpl != nullptr) ? *m_pImpl : ms_EmptyImpl;
}
template <typename TArg>
class WeakCallbackContext
class WeakCallbackContextBase
{
public:
WeakCallbackContext(Persistent<T>* pImpl, TArg* pArg, void (*pCallback)(Isolate*, V8SafePersistent<T>*, TArg*)):
virtual ~WeakCallbackContextBase() {}
};
template <typename TArg>
class WeakCallbackContext: public WeakCallbackContextBase
{
public:
WeakCallbackContext(v8::Persistent<T>* pImpl, TArg* pArg, void (*pCallback)(v8::Isolate*, V8SafePersistent<T>*, TArg*)):
m_pImpl(pImpl),
m_pArg(pArg),
m_pCallback(pCallback)
{
}
void InvokeCallback(Isolate* pIsolate) const
void InvokeCallback(v8::Isolate* pIsolate) const
{
V8SafePersistent<T> hTarget(m_pImpl);
m_pCallback(pIsolate, &hTarget, m_pArg);
@ -396,13 +424,13 @@ private:
private:
Persistent<T>* m_pImpl;
v8::Persistent<T>* m_pImpl;
TArg* m_pArg;
void (*m_pCallback)(Isolate*, V8SafePersistent<T>*, TArg*);
void (*m_pCallback)(v8::Isolate*, V8SafePersistent<T>*, TArg*);
};
template <typename TArg>
static void WeakCallback(const WeakCallbackData<T, TArg>& data)
static void WeakCallback(const v8::WeakCallbackData<T, TArg>& data)
{
auto pContext = data.GetParameter();
_ASSERTE(pContext);
@ -410,45 +438,46 @@ private:
delete pContext;
}
Persistent<T>* m_pImpl;
static const Persistent<T> ms_EmptyImpl;
v8::Persistent<T>* m_pImpl;
static const v8::Persistent<T> ms_EmptyImpl;
};
template <typename T>
const Persistent<T> V8SafePersistent<T>::ms_EmptyImpl;
const v8::Persistent<T> V8SafePersistent<T>::ms_EmptyImpl;
//-----------------------------------------------------------------------------
// define classic v8::Persistent replacement
//-----------------------------------------------------------------------------
#define Persistent V8FastPersistent
template <typename T>
using Persistent = V8FastPersistent<T>;
//-----------------------------------------------------------------------------
// helper functions
//-----------------------------------------------------------------------------
inline void* PtrFromObjectHandle(Persistent<Object> hObject)
inline void* PtrFromObjectHandle(Persistent<v8::Object> hObject)
{
return hObject.ToPtr();
}
//-----------------------------------------------------------------------------
inline Persistent<Object> ObjectHandleFromPtr(void* pvObject)
inline Persistent<v8::Object> ObjectHandleFromPtr(void* pvObject)
{
return Persistent<Object>::FromPtr(pvObject);
return Persistent<v8::Object>::FromPtr(pvObject);
}
//-----------------------------------------------------------------------------
inline void* PtrFromScriptHandle(Persistent<UnboundScript> hScript)
inline void* PtrFromScriptHandle(Persistent<v8::UnboundScript> hScript)
{
return hScript.ToPtr();
}
//-----------------------------------------------------------------------------
inline Persistent<UnboundScript> ScriptHandleFromPtr(void* pvScript)
inline Persistent<v8::UnboundScript> ScriptHandleFromPtr(void* pvScript)
{
return Persistent<UnboundScript>::FromPtr(pvScript);
return Persistent<v8::UnboundScript>::FromPtr(pvScript);
}

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

@ -0,0 +1,84 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Microsoft Public License (MS-PL)
//
// This license governs use of the accompanying software. If you use the
// software, you accept this license. If you do not accept the license, do not
// use the software.
//
// 1. Definitions
//
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S. copyright law. A
// "contribution" is the original software, or any additions or changes to
// the software. A "contributor" is any person that distributes its
// contribution under this license. "Licensed patents" are a contributor's
// patent claims that read directly on its contribution.
//
// 2. Grant of Rights
//
// (A) Copyright Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free copyright license
// to reproduce its contribution, prepare derivative works of its
// contribution, and distribute its contribution or any derivative works
// that you create.
//
// (B) Patent Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free license under its
// licensed patents to make, have made, use, sell, offer for sale,
// import, and/or otherwise dispose of its contribution in the software
// or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
//
// (A) No Trademark License- This license does not grant you rights to use
// any contributors' name, logo, or trademarks.
//
// (B) If you bring a patent claim against any contributor over patents that
// you claim are infringed by the software, your patent license from such
// contributor to the software ends automatically.
//
// (C) If you distribute any portion of the software, you must retain all
// copyright, patent, trademark, and attribution notices that are present
// in the software.
//
// (D) If you distribute any portion of the software in source code form, you
// may do so only under this license by including a complete copy of this
// license with your distribution. If you distribute any portion of the
// software in compiled or object code form, you may only do so under a
// license that complies with this license.
//
// (E) The software is licensed "as-is." You bear the risk of using it. The
// contributors give no express warranties, guarantees or conditions. You
// may have additional consumer rights under your local laws which this
// license cannot change. To the extent permitted under your local laws,
// the contributors exclude the implied warranties of merchantability,
// fitness for a particular purpose and non-infringement.
//
#include "ClearScriptV8Managed.h"
namespace Microsoft {
namespace ClearScript {
namespace V8 {
//-------------------------------------------------------------------------
// V8TestProxyImpl implementation
//-------------------------------------------------------------------------
V8ProxyCounters^ V8TestProxyImpl::GetCounters()
{
auto gcCounters = gcnew V8ProxyCounters();
gcCounters->IsolateCount = V8Isolate::GetInstanceCount();
gcCounters->ContextCount = V8Context::GetInstanceCount();
return gcCounters;
}
//-------------------------------------------------------------------------
ENSURE_INTERNAL_CLASS(V8TestProxyImpl)
}}}

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

@ -0,0 +1,81 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Microsoft Public License (MS-PL)
//
// This license governs use of the accompanying software. If you use the
// software, you accept this license. If you do not accept the license, do not
// use the software.
//
// 1. Definitions
//
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S. copyright law. A
// "contribution" is the original software, or any additions or changes to
// the software. A "contributor" is any person that distributes its
// contribution under this license. "Licensed patents" are a contributor's
// patent claims that read directly on its contribution.
//
// 2. Grant of Rights
//
// (A) Copyright Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free copyright license
// to reproduce its contribution, prepare derivative works of its
// contribution, and distribute its contribution or any derivative works
// that you create.
//
// (B) Patent Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free license under its
// licensed patents to make, have made, use, sell, offer for sale,
// import, and/or otherwise dispose of its contribution in the software
// or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
//
// (A) No Trademark License- This license does not grant you rights to use
// any contributors' name, logo, or trademarks.
//
// (B) If you bring a patent claim against any contributor over patents that
// you claim are infringed by the software, your patent license from such
// contributor to the software ends automatically.
//
// (C) If you distribute any portion of the software, you must retain all
// copyright, patent, trademark, and attribution notices that are present
// in the software.
//
// (D) If you distribute any portion of the software in source code form, you
// may do so only under this license by including a complete copy of this
// license with your distribution. If you distribute any portion of the
// software in compiled or object code form, you may only do so under a
// license that complies with this license.
//
// (E) The software is licensed "as-is." You bear the risk of using it. The
// contributors give no express warranties, guarantees or conditions. You
// may have additional consumer rights under your local laws which this
// license cannot change. To the extent permitted under your local laws,
// the contributors exclude the implied warranties of merchantability,
// fitness for a particular purpose and non-infringement.
//
#pragma once
namespace Microsoft {
namespace ClearScript {
namespace V8 {
//-------------------------------------------------------------------------
// V8TestProxyImpl
//-------------------------------------------------------------------------
private ref class V8TestProxyImpl : V8TestProxy
{
public:
virtual V8ProxyCounters^ GetCounters() override;
~V8TestProxyImpl() {}
};
}}}

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

@ -1,8 +1,21 @@
diff --git a/build/standalone.gypi b/build/standalone.gypi
index 7c96720..0b046cd 100644
--- a/build/standalone.gypi
+++ b/build/standalone.gypi
@@ -464,7 +464,7 @@
'EnableFunctionLevelLinking': 'true',
'RuntimeTypeInfo': 'false',
'WarningLevel': '3',
- 'WarnAsError': 'true',
+ 'WarnAsError': 'false',
'DebugInformationFormat': '3',
'Detect64BitPortabilityProblems': 'false',
'conditions': [
diff --git a/src/api.cc b/src/api.cc
index 48872b6..332a193 100644
index 4f06873..546f1f5 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -5164,10 +5164,6 @@ void v8::V8::SetReturnAddressLocationResolver(
@@ -5319,10 +5319,6 @@ void v8::V8::SetReturnAddressLocationResolver(
void v8::V8::SetArrayBufferAllocator(
ArrayBuffer::Allocator* allocator) {
@ -14,36 +27,36 @@ index 48872b6..332a193 100644
}
diff --git a/src/objects.cc b/src/objects.cc
index 0eda491..c9bd2fb 100644
index f0dcaab..4cc1d99 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6595,7 +6595,7 @@ MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
@@ -6690,7 +6690,7 @@ MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
if (is_observed) {
if (is_element) {
Maybe<bool> maybe = HasOwnElement(object, index);
- // Workaround for a GCC 4.4.3 bug which leads to "preexists may be used
+ // Workaround for a GCC 4.4.3 bug which leads to "'preexists' may be used
// uninitialized in this function".
if (!maybe.has_value) {
if (!maybe.IsJust()) {
DCHECK(false);
diff --git a/src/parser.cc b/src/parser.cc
index 985a90f..b59c86f 100644
index 3b537d2..17d8c97 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -2436,7 +2436,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
@@ -2642,7 +2642,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
// Identifier ':' Statement
//
// ExpressionStatement[Yield] :
- // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
+ // [lookahead o {{, function, class, let [}] Expression[In, ?Yield] ;
switch (peek()) {
case Token::FUNCTION:
int pos = peek_position();
diff --git a/src/v8.cc b/src/v8.cc
index 495921e..460885f 100644
index 49a104f..08fd6f3 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -104,7 +104,6 @@ void V8::InitializeOncePerProcess() {
@@ -109,7 +109,6 @@ void V8::InitializeOncePerProcess() {
void V8::InitializePlatform(v8::Platform* platform) {
@ -64,14 +77,14 @@ index 211f3c6..7e29fc2 100644
}
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 7f08ee2..8ef09f7 100644
index 70d4dee..7fd3018 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -37,6 +37,7 @@
@@ -38,6 +38,7 @@
'targets': [
{
'target_name': 'v8',
+ 'product_name': 'v8-' + '<(v8_target_arch)',
'dependencies_traverse': 1,
'dependencies': ['v8_maybe_snapshot'],
'conditions': [
['want_separate_host_toolset==1', {

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

@ -87,7 +87,7 @@ namespace Microsoft.ClearScript.V8
private readonly AutoResetEvent queueEvent = new AutoResetEvent(false);
private RegisteredWaitHandle queueWaitHandle;
private DisposedFlag disposedFlag = new DisposedFlag();
private InterlockedDisposedFlag disposedFlag = new InterlockedDisposedFlag();
#endregion

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

@ -78,7 +78,7 @@ namespace Microsoft.ClearScript.V8
private readonly HostItemCollateral hostItemCollateral = new HostItemCollateral();
private readonly V8IsolateProxy proxy;
private DisposedFlag disposedFlag = new DisposedFlag();
private InterlockedDisposedFlag disposedFlag = new InterlockedDisposedFlag();
#endregion

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

@ -86,7 +86,7 @@ namespace Microsoft.ClearScript.V8
private readonly V8ScriptEngineFlags engineFlags;
private readonly V8ContextProxy proxy;
private readonly object script;
private DisposedFlag disposedFlag = new DisposedFlag();
private InterlockedDisposedFlag disposedFlag = new InterlockedDisposedFlag();
private const int continuationInterval = 2000;
private bool inContinuationTimerScope;

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

@ -71,7 +71,7 @@ namespace Microsoft.ClearScript.V8
private readonly V8ScriptEngine engine;
private readonly IV8Object target;
private V8ScriptItem holder;
private DisposedFlag disposedFlag = new DisposedFlag();
private InterlockedDisposedFlag disposedFlag = new InterlockedDisposedFlag();
private V8ScriptItem(V8ScriptEngine engine, IV8Object target)
{

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

@ -0,0 +1,80 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Microsoft Public License (MS-PL)
//
// This license governs use of the accompanying software. If you use the
// software, you accept this license. If you do not accept the license, do not
// use the software.
//
// 1. Definitions
//
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S. copyright law. A
// "contribution" is the original software, or any additions or changes to
// the software. A "contributor" is any person that distributes its
// contribution under this license. "Licensed patents" are a contributor's
// patent claims that read directly on its contribution.
//
// 2. Grant of Rights
//
// (A) Copyright Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free copyright license
// to reproduce its contribution, prepare derivative works of its
// contribution, and distribute its contribution or any derivative works
// that you create.
//
// (B) Patent Grant- Subject to the terms of this license, including the
// license conditions and limitations in section 3, each contributor
// grants you a non-exclusive, worldwide, royalty-free license under its
// licensed patents to make, have made, use, sell, offer for sale,
// import, and/or otherwise dispose of its contribution in the software
// or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
//
// (A) No Trademark License- This license does not grant you rights to use
// any contributors' name, logo, or trademarks.
//
// (B) If you bring a patent claim against any contributor over patents that
// you claim are infringed by the software, your patent license from such
// contributor to the software ends automatically.
//
// (C) If you distribute any portion of the software, you must retain all
// copyright, patent, trademark, and attribution notices that are present
// in the software.
//
// (D) If you distribute any portion of the software in source code form, you
// may do so only under this license by including a complete copy of this
// license with your distribution. If you distribute any portion of the
// software in compiled or object code form, you may only do so under a
// license that complies with this license.
//
// (E) The software is licensed "as-is." You bear the risk of using it. The
// contributors give no express warranties, guarantees or conditions. You
// may have additional consumer rights under your local laws which this
// license cannot change. To the extent permitted under your local laws,
// the contributors exclude the implied warranties of merchantability,
// fitness for a particular purpose and non-infringement.
//
namespace Microsoft.ClearScript.V8
{
internal class V8ProxyCounters
{
public ulong IsolateCount { get; set; }
public ulong ContextCount { get; set; }
}
internal abstract class V8TestProxy : V8Proxy
{
public static V8TestProxy Create()
{
return CreateImpl<V8TestProxy>();
}
public abstract V8ProxyCounters GetCounters();
}
}

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

@ -140,6 +140,8 @@ namespace Microsoft.ClearScript.Windows
public ActiveScriptWrapper32(string progID, WindowsScriptEngineFlags flags)
{
// ReSharper disable SuspiciousTypeConversion.Global
pActiveScript = RawCOMHelpers.CreateInstance<IActiveScript>(progID);
pActiveScriptParse = RawCOMHelpers.QueryInterface<IActiveScriptParse32>(pActiveScript);
pActiveScriptDebug = RawCOMHelpers.QueryInterface<IActiveScriptDebug32>(pActiveScript);
@ -166,6 +168,8 @@ namespace Microsoft.ClearScript.Windows
}
}
}
// ReSharper restore SuspiciousTypeConversion.Global
}
public override void SetScriptSite(IActiveScriptSite site)
@ -282,6 +286,8 @@ namespace Microsoft.ClearScript.Windows
public ActiveScriptWrapper64(string progID, WindowsScriptEngineFlags flags)
{
// ReSharper disable SuspiciousTypeConversion.Global
pActiveScript = RawCOMHelpers.CreateInstance<IActiveScript>(progID);
pActiveScriptParse = RawCOMHelpers.QueryInterface<IActiveScriptParse64>(pActiveScript);
pActiveScriptDebug = RawCOMHelpers.QueryInterface<IActiveScriptDebug64>(pActiveScript);
@ -308,6 +314,8 @@ namespace Microsoft.ClearScript.Windows
}
}
}
// ReSharper restore SuspiciousTypeConversion.Global
}
public override void SetScriptSite(IActiveScriptSite site)

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

@ -123,7 +123,55 @@ namespace Microsoft.ClearScript.Windows
private static readonly Dictionary<int, string> syntaxErrorMap = new Dictionary<int, string>
{
// https://msdn.microsoft.com/en-us/library/2z84dwk8(v=vs.84).aspx
{ 1052, "Cannot have multiple default property/method in a Class" }, { 1044, "Cannot use parentheses when calling a Sub" }, { 1053, "Class initialize or terminate do not have arguments" }, { 1058, "'Default' specification can only be on Property Get" }, { 1057, "'Default' specification must also specify 'Public'" }, { 1005, "Expected '('" }, { 1006, "Expected ')'" }, { 1011, "Expected '='" }, { 1021, "Expected 'Case'" }, { 1047, "Expected 'Class'" }, { 1025, "Expected end of statement" }, { 1014, "Expected 'End'" }, { 1023, "Expected expression" }, { 1015, "Expected 'Function'" }, { 1010, "Expected identifier" }, { 1012, "Expected 'If'" }, { 1046, "Expected 'In'" }, { 1026, "Expected integer constant" }, { 1049, "Expected Let or Set or Get in property declaration" }, { 1045, "Expected literal constant" }, { 1019, "Expected 'Loop'" }, { 1020, "Expected 'Next'" }, { 1050, "Expected 'Property'" }, { 1022, "Expected 'Select'" }, { 1024, "Expected statement" }, { 1016, "Expected 'Sub'" }, { 1017, "Expected 'Then'" }, { 1013, "Expected 'To'" }, { 1018, "Expected 'Wend'" }, { 1027, "Expected 'While' or 'Until'" }, { 1028, "Expected 'While,' 'Until,' or end of statement" }, { 1029, "Expected 'With'" }, { 1030, "Identifier too long" }, { 1032, "Invalid character" }, // incorrectly listed as 1014 in the online documentation { 1039, "Invalid 'exit' statement" }, { 1040, "Invalid 'for' loop control variable" }, { 1031, "Invalid number" }, // incorrectly listed as 1013 in the online documentation { 1037, "Invalid use of 'Me' keyword" }, { 1038, "'loop' without 'do'" }, { 1048, "Must be defined inside a Class" }, { 1042, "Must be first statement on the line" }, { 1041, "Name redefined" }, { 1051, "Number of arguments must be consistent across properties specification" }, { 1001, "Out of Memory" }, { 1054, "Property Set or Let must have at least one argument" }, { 1002, "Syntax error" }, { 1055, "Unexpected 'Next'" }, { 1033, "Unterminated string constant" } // incorrectly listed as 1015 in the online documentation };
{ 1052, "Cannot have multiple default property/method in a Class" },
{ 1044, "Cannot use parentheses when calling a Sub" },
{ 1053, "Class initialize or terminate do not have arguments" },
{ 1058, "'Default' specification can only be on Property Get" },
{ 1057, "'Default' specification must also specify 'Public'" },
{ 1005, "Expected '('" },
{ 1006, "Expected ')'" },
{ 1011, "Expected '='" },
{ 1021, "Expected 'Case'" },
{ 1047, "Expected 'Class'" },
{ 1025, "Expected end of statement" },
{ 1014, "Expected 'End'" },
{ 1023, "Expected expression" },
{ 1015, "Expected 'Function'" },
{ 1010, "Expected identifier" },
{ 1012, "Expected 'If'" },
{ 1046, "Expected 'In'" },
{ 1026, "Expected integer constant" },
{ 1049, "Expected Let or Set or Get in property declaration" },
{ 1045, "Expected literal constant" },
{ 1019, "Expected 'Loop'" },
{ 1020, "Expected 'Next'" },
{ 1050, "Expected 'Property'" },
{ 1022, "Expected 'Select'" },
{ 1024, "Expected statement" },
{ 1016, "Expected 'Sub'" },
{ 1017, "Expected 'Then'" },
{ 1013, "Expected 'To'" },
{ 1018, "Expected 'Wend'" },
{ 1027, "Expected 'While' or 'Until'" },
{ 1028, "Expected 'While,' 'Until,' or end of statement" },
{ 1029, "Expected 'With'" },
{ 1030, "Identifier too long" },
{ 1032, "Invalid character" }, // incorrectly listed as 1014 in the online documentation
{ 1039, "Invalid 'exit' statement" },
{ 1040, "Invalid 'for' loop control variable" },
{ 1031, "Invalid number" }, // incorrectly listed as 1013 in the online documentation
{ 1037, "Invalid use of 'Me' keyword" },
{ 1038, "'loop' without 'do'" },
{ 1048, "Must be defined inside a Class" },
{ 1042, "Must be first statement on the line" },
{ 1041, "Name redefined" },
{ 1051, "Number of arguments must be consistent across properties specification" },
{ 1001, "Out of Memory" },
{ 1054, "Property Set or Let must have at least one argument" },
{ 1002, "Syntax error" },
{ 1055, "Unexpected 'Next'" },
{ 1033, "Unterminated string constant" } // incorrectly listed as 1015 in the online documentation
};
#endregion

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

@ -103,7 +103,7 @@ namespace Microsoft.ClearScript.Windows
private uint nextSourceContext = 1;
private readonly Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
private DisposedFlag disposedFlag = new DisposedFlag();
private InterlockedDisposedFlag disposedFlag = new InterlockedDisposedFlag();
#endregion

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

@ -76,7 +76,7 @@ namespace Microsoft.ClearScript.Windows
private readonly WindowsScriptEngine engine;
private readonly IExpando target;
private WindowsScriptItem holder;
private DisposedFlag disposedFlag = new DisposedFlag();
private InterlockedDisposedFlag disposedFlag = new InterlockedDisposedFlag();
private WindowsScriptItem(WindowsScriptEngine engine, IExpando target)
{

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

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

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

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

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

@ -92,6 +92,7 @@ namespace Microsoft.ClearScript.Test
{
testObject = null;
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -96,6 +96,7 @@ namespace Microsoft.ClearScript.Test
{
testObject = null;
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -100,6 +100,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion
@ -1226,6 +1227,71 @@ namespace Microsoft.ClearScript.Test
Assert.IsNull(typeof(AssemblyHelpers).TypeInitializer);
}
[TestMethod, TestCategory("BugFix")]
public void BugFix_FinalizerHang_V8ScriptItem()
{
engine.Script.foo = new Action<object>(arg => {});
engine.Script.bar = new Action(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
});
engine.Execute(@"
for (var i = 0; i < 100; i++) {
foo({ index: i });
}
bar();
");
}
[TestMethod, TestCategory("BugFix")]
public void BugFix_FinalizerHang_V8Script()
{
engine.Script.bar = new Action(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
});
for (var index = 0; index < 100; index++)
{
((V8ScriptEngine)engine).Compile("function foo() { return " + index + "; }");
}
engine.Execute("bar()");
}
[TestMethod, TestCategory("BugFix")]
public void BugFix_FinalizerHang_V8ScriptEngine()
{
engine.Dispose();
using (var runtime = new V8Runtime(V8RuntimeFlags.EnableDebugging))
{
engine = runtime.CreateScriptEngine();
engine.Script.bar = new Action(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
});
for (var index = 0; index < 100; index++)
{
runtime.CreateScriptEngine();
}
engine.Execute("bar()");
}
}
[TestMethod, TestCategory("BugFix")]
public void BugFix_DynamicMethodArgs()
{
engine.Script.foo = new DynamicMethodArgTest();
Assert.AreEqual("123 456.789 hello", engine.Evaluate("foo.RunTest(123, 456.789, 'hello')"));
}
// ReSharper restore InconsistentNaming
#endregion
@ -1249,12 +1315,12 @@ namespace Microsoft.ClearScript.Test
public object Method(int? value)
{
return value.HasValue ? (value + 1) : null;
return value + 1;
}
public object Method(double? value)
{
return value.HasValue ? (value * 2.0) : null;
return value * 2.0;
}
}
@ -1271,7 +1337,7 @@ namespace Microsoft.ClearScript.Test
public override object this[string key] { get { return null; } }
public void Foo() { }
public void Foo() {}
}
public class ResurrectionTestWrapper
@ -1385,6 +1451,35 @@ namespace Microsoft.ClearScript.Test
// ReSharper restore UnusedMember.Local
}
public class DynamicMethodArgTest : DynamicObject
{
public override IEnumerable<string> GetDynamicMemberNames()
{
yield return "RunTest";
}
// ReSharper disable RedundantOverridenMember
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
// this override is redundant, but required for the test
return base.TryGetMember(binder, out result);
}
// ReSharper restore RedundantOverridenMember
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "RunTest")
{
result = string.Join(" ", args);
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
}
#endregion
}
}

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

@ -59,13 +59,24 @@
// fitness for a particular purpose and non-infringement.
//
using System;
using Microsoft.ClearScript.V8;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.ClearScript.Test
{
[TestClass]
public class ClearScriptTest
{
public TestContext TestContext { get; set; }
public void BaseTestCleanup()
{
GC.Collect();
GC.WaitForPendingFinalizers();
var counters = V8TestProxy.Create().GetCounters();
Assert.AreEqual(0UL, counters.ContextCount, "Not all V8 contexts were destroyed.");
Assert.AreEqual(0UL, counters.IsolateCount, "Not all V8 isolates were destroyed.");
}
}
}

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

@ -100,6 +100,7 @@ namespace Microsoft.ClearScript.Test
{
Iterate((engine, type) => engine.Execute(type.Name + ".Dispose()"));
engines.ForEach(engine => engine.Dispose());
BaseTestCleanup();
}
#endregion

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

@ -88,6 +88,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -98,6 +98,7 @@ namespace Microsoft.ClearScript.Test
{
testInterface = null;
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -94,6 +94,7 @@ namespace Microsoft.ClearScript.Test
{
testInterface = null;
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -89,6 +89,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -93,6 +93,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -91,6 +91,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -92,6 +92,7 @@ namespace Microsoft.ClearScript.Test
{
testObject = null;
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -96,6 +96,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion
@ -796,76 +797,82 @@ namespace Microsoft.ClearScript.Test
[TestMethod, TestCategory("JScriptEngine")]
public void JScriptEngine_ErrorHandling_NestedScriptError()
{
var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging);
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
using (var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging))
{
try
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
{
engine.Execute("engine.Execute('foo = {}; foo();')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
try
{
engine.Execute("engine.Execute('foo = {}; foo();')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNull(nestedException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
// ReSharper disable once AccessToDisposedClosure
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNull(nestedException.InnerException);
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
}
}
[TestMethod, TestCategory("JScriptEngine")]
public void JScriptEngine_ErrorHandling_NestedHostException()
{
var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging);
innerEngine.AddHostObject("host", new HostFunctions());
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
using (var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging))
{
try
innerEngine.AddHostObject("host", new HostFunctions());
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
{
engine.Execute("engine.Evaluate('host.proc(0)')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
try
{
engine.Execute("engine.Evaluate('host.proc(0)')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNotNull(nestedException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
// ReSharper disable once AccessToDisposedClosure
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNotNull(nestedException.InnerException);
var nestedHostException = nestedException.InnerException;
Assert.IsInstanceOfType(nestedHostException, typeof(RuntimeBinderException));
TestUtil.AssertValidException(nestedHostException);
Assert.IsNull(nestedHostException.InnerException);
var nestedHostException = nestedException.InnerException;
Assert.IsInstanceOfType(nestedHostException, typeof(RuntimeBinderException));
TestUtil.AssertValidException(nestedHostException);
Assert.IsNull(nestedHostException.InnerException);
Assert.AreEqual(nestedHostException.Message, nestedException.Message);
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
Assert.AreEqual(nestedHostException.Message, nestedException.Message);
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
}
}
[TestMethod, TestCategory("JScriptEngine")]

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

@ -96,6 +96,7 @@ namespace Microsoft.ClearScript.Test
{
testObject = null;
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -168,7 +168,7 @@ namespace Microsoft.ClearScript.Test
options.ReferencedAssemblies.Add("ClearScriptTest.dll");
options.ReferencedAssemblies.Add(typeof(Enumerable).Assembly.Location);
options.ReferencedAssemblies.Add(typeof(Assert).Assembly.Location);
var results = new VBCodeProvider().CompileAssemblyFromSource(options, new[] { MiscHelpers.FormatInvariant(@"
var results = new VBCodeProvider().CompileAssemblyFromSource(options, MiscHelpers.FormatInvariant(@"
Imports System
Imports System.Linq
Imports System.Runtime.InteropServices
@ -183,7 +183,7 @@ namespace Microsoft.ClearScript.Test
{0}
End Sub
End Module
", code, extraDefinitions ?? string.Empty)});
", code, extraDefinitions ?? string.Empty));
if (results.Errors.HasErrors)
{
@ -207,7 +207,7 @@ namespace Microsoft.ClearScript.Test
options.ReferencedAssemblies.Add("ClearScriptTest.dll");
options.ReferencedAssemblies.Add(typeof(Enumerable).Assembly.Location);
options.ReferencedAssemblies.Add(typeof(Assert).Assembly.Location);
var results = new VBCodeProvider().CompileAssemblyFromSource(options, new[] { MiscHelpers.FormatInvariant(@"
var results = new VBCodeProvider().CompileAssemblyFromSource(options, MiscHelpers.FormatInvariant(@"
Imports System
Imports System.Linq
Imports System.Runtime.InteropServices
@ -222,7 +222,7 @@ namespace Microsoft.ClearScript.Test
{0}
End Function
End Module
", code, extraDefinitions ?? string.Empty)});
", code, extraDefinitions ?? string.Empty));
if (results.Errors.HasErrors)
{

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

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

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

@ -92,6 +92,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -117,6 +117,7 @@ namespace Microsoft.ClearScript.Test
testInterface = null;
testObject = null;
engine.Dispose();
BaseTestCleanup();
}
#endregion
@ -548,16 +549,16 @@ namespace Microsoft.ClearScript.Test
{
public double BlockedMethod(object arg) { return TestUtil.CalcTestValue(new Guid("de3d88bf-a148-4bf2-ab67-b27a7ff6cf21"), "BlockedMethod", arg); }
[ScriptMember(ScriptAccess.Full)] public double UnblockedMethod(object arg) { return TestUtil.CalcTestValue(new Guid("ab0e94e7-445e-4fcf-8fe1-94a2c0724915"), "UnblockedMethod", arg); }
public class BlockedNestedType { }
[ScriptUsage(ScriptAccess.Full)] public class UnblockedNestedType { }
public class BlockedNestedType {}
[ScriptUsage(ScriptAccess.Full)] public class UnblockedNestedType {}
}
public class UnblockedTestObject
{
[NoScriptAccess] public double BlockedMethod(object arg) { return TestUtil.CalcTestValue(new Guid("de3d88bf-a148-4bf2-ab67-b27a7ff6cf21"), "BlockedMethod", arg); }
public double UnblockedMethod(object arg) { return TestUtil.CalcTestValue(new Guid("ab0e94e7-445e-4fcf-8fe1-94a2c0724915"), "UnblockedMethod", arg); }
[NoScriptAccess] public class BlockedNestedType { }
public class UnblockedNestedType { }
[NoScriptAccess] public class BlockedNestedType {}
public class UnblockedNestedType {}
}
private void AssertBlockedMember(string objectName, string memberName)

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

@ -93,6 +93,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -88,6 +88,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion

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

@ -100,6 +100,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion
@ -1000,76 +1001,82 @@ namespace Microsoft.ClearScript.Test
[TestMethod, TestCategory("V8ScriptEngine")]
public void V8ScriptEngine_ErrorHandling_NestedScriptError()
{
var innerEngine = new V8ScriptEngine("inner", V8ScriptEngineFlags.EnableDebugging);
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
using (var innerEngine = new V8ScriptEngine("inner", V8ScriptEngineFlags.EnableDebugging))
{
try
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
{
engine.Execute("engine.Execute('foo = {}; foo();')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
try
{
engine.Execute("engine.Execute('foo = {}; foo();')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNull(nestedException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
// ReSharper disable once AccessToDisposedClosure
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNull(nestedException.InnerException);
Assert.AreEqual("Error: " + hostException.GetBaseException().Message, exception.Message);
throw;
}
});
Assert.AreEqual("Error: " + hostException.GetBaseException().Message, exception.Message);
throw;
}
});
}
}
[TestMethod, TestCategory("V8ScriptEngine")]
public void V8ScriptEngine_ErrorHandling_NestedHostException()
{
var innerEngine = new V8ScriptEngine("inner", V8ScriptEngineFlags.EnableDebugging);
innerEngine.AddHostObject("host", new HostFunctions());
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
using (var innerEngine = new V8ScriptEngine("inner", V8ScriptEngineFlags.EnableDebugging))
{
try
innerEngine.AddHostObject("host", new HostFunctions());
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
{
engine.Execute("engine.Evaluate('host.proc(0)')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
try
{
engine.Execute("engine.Evaluate('host.proc(0)')");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNotNull(nestedException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
// ReSharper disable once AccessToDisposedClosure
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNotNull(nestedException.InnerException);
var nestedHostException = nestedException.InnerException;
Assert.IsInstanceOfType(nestedHostException, typeof(RuntimeBinderException));
TestUtil.AssertValidException(nestedHostException);
Assert.IsNull(nestedHostException.InnerException);
var nestedHostException = nestedException.InnerException;
Assert.IsInstanceOfType(nestedHostException, typeof(RuntimeBinderException));
TestUtil.AssertValidException(nestedHostException);
Assert.IsNull(nestedHostException.InnerException);
Assert.AreEqual("Error: " + nestedHostException.Message, nestedException.Message);
Assert.AreEqual("Error: " + hostException.GetBaseException().Message, exception.Message);
throw;
}
});
Assert.AreEqual("Error: " + nestedHostException.Message, nestedException.Message);
Assert.AreEqual("Error: " + hostException.GetBaseException().Message, exception.Message);
throw;
}
});
}
}
[TestMethod, TestCategory("V8ScriptEngine")]
@ -1137,7 +1144,7 @@ namespace Microsoft.ClearScript.Test
public void V8ScriptEngine_MaxRuntimeHeapSize_Dual()
{
const int limit = 4 * 1024 * 1024;
const string code = @"x = []; for (i = 0; i < 4 * 1024 * 1024; i++) { x.push(x); }";
const string code = @"x = []; for (i = 0; i < 8 * 1024 * 1024; i++) { x.push(x); }";
engine.Execute(code);
engine.CollectGarbage(true);

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

@ -98,6 +98,7 @@ namespace Microsoft.ClearScript.Test
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion
@ -708,76 +709,82 @@ namespace Microsoft.ClearScript.Test
[TestMethod, TestCategory("VBScriptEngine")]
public void VBScriptEngine_ErrorHandling_NestedScriptError()
{
var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging);
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
using (var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging))
{
try
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
{
engine.Execute("engine.Execute(\"foo = {}; foo();\")");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
try
{
engine.Execute("engine.Execute(\"foo = {}; foo();\")");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNull(nestedException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
// ReSharper disable once AccessToDisposedClosure
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNull(nestedException.InnerException);
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
}
}
[TestMethod, TestCategory("VBScriptEngine")]
public void VBScriptEngine_ErrorHandling_NestedHostException()
{
var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging);
innerEngine.AddHostObject("host", new HostFunctions());
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
using (var innerEngine = new JScriptEngine("inner", WindowsScriptEngineFlags.EnableDebugging))
{
try
innerEngine.AddHostObject("host", new HostFunctions());
engine.AddHostObject("engine", innerEngine);
TestUtil.AssertException<ScriptEngineException>(() =>
{
engine.Execute("engine.Evaluate(\"host.proc(0)\")");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
try
{
engine.Execute("engine.Evaluate(\"host.proc(0)\")");
}
catch (ScriptEngineException exception)
{
TestUtil.AssertValidException(engine, exception);
Assert.IsNotNull(exception.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var hostException = exception.InnerException;
Assert.IsInstanceOfType(hostException, typeof(TargetInvocationException));
TestUtil.AssertValidException(hostException);
Assert.IsNotNull(hostException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNotNull(nestedException.InnerException);
var nestedException = hostException.InnerException as ScriptEngineException;
Assert.IsNotNull(nestedException);
// ReSharper disable once AccessToDisposedClosure
TestUtil.AssertValidException(innerEngine, nestedException);
// ReSharper disable once PossibleNullReferenceException
Assert.IsNotNull(nestedException.InnerException);
var nestedHostException = nestedException.InnerException;
Assert.IsInstanceOfType(nestedHostException, typeof(RuntimeBinderException));
TestUtil.AssertValidException(nestedHostException);
Assert.IsNull(nestedHostException.InnerException);
var nestedHostException = nestedException.InnerException;
Assert.IsInstanceOfType(nestedHostException, typeof(RuntimeBinderException));
TestUtil.AssertValidException(nestedHostException);
Assert.IsNull(nestedHostException.InnerException);
Assert.AreEqual(nestedHostException.Message, nestedException.Message);
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
Assert.AreEqual(nestedHostException.Message, nestedException.Message);
Assert.AreEqual(hostException.Message, exception.Message);
throw;
}
});
}
}
[TestMethod, TestCategory("VBScriptEngine")]

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

@ -20,9 +20,9 @@ See ClearScript\doc for information about using ClearScript.
II. Building ClearScript
------------------------
The provided project and solution files support Visual Studio 2013. They
produce architecture-neutral managed libraries that target .NET Framework 4.0.
ClearScript has been tested with .NET Framework 4.5 as well. It does not
The provided project and solution files support Visual Studio 2013 and 2015.
They produce architecture-neutral managed libraries that target .NET Framework
4.0. ClearScript has been tested with .NET Framework 4.5 as well. It does not
support older environments. The output directory is bin\[Debug|Release].
There are two ways to build ClearScript - with and without V8 support.
@ -38,15 +38,22 @@ build, and import V8:
with any third-party software required to download and build V8. Rights to
V8 and its prerequisites are provided by their rights holders.
2. Install Git (http://www.git-scm.com/download/win). IMPORTANT: Ensure that
Git is added to your executable path by selecting the option "Use Git from
the Windows Command Prompt".
2. Install Git (http://www.git-scm.com/download/win). Ensure that Git is added
to your executable path by selecting the option "Use Git from the Windows
Command Prompt".
3. IMPORTANT: Ensure that the path to your ClearScript root directory does not
3. Install the latest Python 2.x (http://www.python.org/downloads/) and add it
to your executable path. V8's build process requires at least Python 2.7 and
does not support Python 3.x.
4. Unzip or clone the ClearScript source code into a convenient directory.
IMPORTANT: Ensure that the path to your ClearScript root directory does not
contain any non-ASCII characters.
5. Ensure that your Visual Studio installation includes C++ support.
4. Open a Visual Studio 2013 developer command prompt and run the V8Update
script from your ClearScript root directory:
6. Open a Visual Studio developer command prompt and run the V8Update script
from your ClearScript root directory:
C:\ClearScript> V8Update [/N] [Debug|Release] [Latest|Tested|<Revision>]
@ -128,7 +135,11 @@ Once you've built ClearScript, here's how to add it to your application:
4. IMPORTANT: If Visual Studio is not installed on your deployment machine,
you must install 32-bit and 64-bit Visual C++ Redistributable packages:
Visual Studio 2013
http://www.microsoft.com/en-us/download/details.aspx?id=40784
Visual Studio 2015
http://www.microsoft.com/en-us/download/details.aspx?id=48145
------------------------------------
V. Debugging with ClearScript and V8

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

@ -5,10 +5,9 @@ setlocal
:: process arguments
::-----------------------------------------------------------------------------
set v8testedrev=4.2.77.18
set v8testedrev=4.4.63.29
set gyprev=34640080d08ab2a37665512e52142947def3056d
set pythonrev=5bb4080c33f369a81017c2767142fb34981f2a54
set gyprev=0bb67471bca068996e15b56738fa4824dfa19de0
set cygwinrev=c89e446b273697fadf3a10ff1007a97c0b7de6df
:ProcessArgs
@ -65,11 +64,15 @@ goto ProcessArg
:CheckMSVS
if "%VisualStudioVersion%"=="12.0" goto UseMSVS2013
echo Error: This script requires a Visual Studio 2013 Developer Command Prompt.
echo Browse to http://www.visualstudio.com for more information.
if "%VisualStudioVersion%"=="14.0" goto UseMSVS2015
echo Error: This script requires a Visual Studio 2013 or 2015 Developer Command
echo Prompt. Browse to http://www.visualstudio.com for more information.
goto Exit
:UseMSVS2013
set GYP_MSVS_VERSION=2013
goto CheckMSVSDone
:UseMSVS2015
set GYP_MSVS_VERSION=2015
:CheckMSVSDone
::-----------------------------------------------------------------------------
@ -162,16 +165,6 @@ if errorlevel 1 goto Error
cd ..\..
:DownloadGYPDone
:DownloadPython
echo Downloading Python ...
git clone -n -q https://chromium.googlesource.com/chromium/deps/python_26.git third_party/python_26
if errorlevel 1 goto Error
cd third_party/python_26
git checkout -q "%pythonrev%"
if errorlevel 1 goto Error
cd ..\..
:DownloadPythonDone
:DownloadCygwin
echo Downloading Cygwin ...
git clone -n -q https://chromium.googlesource.com/chromium/deps/cygwin.git third_party/cygwin
@ -192,10 +185,6 @@ cd ..
:Build
set PYTHONHOME=
set PYTHONPATH=
set basepath=%PATH%
:CreatePatchFile
echo Creating patch file ...
cd v8
@ -215,12 +204,10 @@ if errorlevel 1 goto Error
:Build32Bit
cd v8-ia32
path %CD%\third_party\python_26;%basepath%
python build\gyp_v8 -Dtarget_arch=ia32 -Dcomponent=shared_library -Dv8_use_snapshot=false -Dv8_enable_i18n_support=0 >gyp.log
if errorlevel 1 goto Error
msbuild /p:Configuration=%mode% /p:Platform=Win32 /t:v8 tools\gyp\v8.sln >build.log
if errorlevel 1 goto Error
path %basepath%
cd ..
:Build32BitDone
@ -235,12 +222,10 @@ if errorlevel 1 goto Error
:Build64Bit
cd v8-x64
path %CD%\third_party\python_26;%basepath%
python build\gyp_v8 -Dtarget_arch=x64 -Dcomponent=shared_library -Dv8_use_snapshot=false -Dv8_enable_i18n_support=0 >gyp.log
if errorlevel 1 goto Error
msbuild /p:Configuration=%mode% /p:Platform=x64 /t:v8 tools\gyp\v8.sln >build.log
if errorlevel 1 goto Error
path %basepath%
cd ..
:Build64BitDone

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

@ -1 +1 @@
<# var version = new Version(5, 4, 2, 1); #>
<# var version = new Version(5, 4, 3, 0); #>