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

This commit is contained in:
ClearScript 2023-05-31 21:42:43 -04:00
Родитель d9a58a66e6
Коммит a02a01f24a
32 изменённых файлов: 686 добавлений и 185 удалений

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

@ -5,7 +5,7 @@
#pragma once
#define CLEARSCRIPT_VERSION_STRING "7.4.1"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,4,1
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.4.1"
#define CLEARSCRIPT_VERSION_STRING "7.4.2"
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 7,4,2
#define CLEARSCRIPT_VERSION_STRING_INFORMATIONAL "7.4.2"
#define CLEARSCRIPT_FILE_FLAGS 0L

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

@ -1408,6 +1408,30 @@ namespace Microsoft.ClearScript
return GetHostProperty(signature, defaultProperty, invokeFlags, args);
}
if (Target.Type.IsArray && (Target.Type.GetArrayRank() == args.Length))
{
// special case to enable VBScript "x(a, b, ...)" syntax when x is a multidimensional array
var indices = new long[args.Length];
var failed = false;
for (var position = 0; position < args.Length; position++)
{
if (!MiscHelpers.TryGetNumericIndex(args[position], out long index))
{
failed = true;
break;
}
indices[position] = index;
}
if (!failed)
{
return ((Array)Target.InvokeTarget).GetValue(indices);
}
}
if (TargetDynamicMetaObject != null)
{
if (TargetDynamicMetaObject.TryGetIndex(args, out var result))
@ -1641,6 +1665,32 @@ namespace Microsoft.ClearScript
throw new InvalidOperationException("Invalid argument count");
}
if (Target.Type.IsArray && (Target.Type.GetArrayRank() == (args.Length - 1)))
{
// special case to enable VBScript "x(a, b, ...) = value" syntax when x is a multidimensional array
var indices = new long[args.Length - 1];
var failed = false;
for (var position = 0; position < (args.Length - 1); position++)
{
if (!MiscHelpers.TryGetNumericIndex(args[position], out long index))
{
failed = true;
break;
}
indices[position] = index;
}
if (!failed)
{
var value = args[args.Length - 1];
((Array)Target.InvokeTarget).SetValue(value, indices);
return value;
}
}
if (TargetDynamicMetaObject != null)
{
if (TargetDynamicMetaObject.TrySetIndex(args.Take(args.Length - 1).ToArray(), args[args.Length - 1], out result))

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

@ -18,15 +18,15 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ClearScriptTest")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]
namespace Microsoft.ClearScript.Properties
{
internal static class ClearScriptVersion
{
public const string Triad = "7.4.1";
public const string Informational = "7.4.1";
public const string Triad = "7.4.2";
public const string Informational = "7.4.2";
}
}

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

@ -15,6 +15,6 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ClearScript.V8")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]

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

@ -15,6 +15,6 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ClearScriptTest")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]

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

@ -16,6 +16,6 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ClearScriptTest")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]

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

@ -15,6 +15,6 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ClearScriptTest")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]

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

@ -2,6 +2,7 @@
// Licensed under the MIT license.
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
@ -9,17 +10,23 @@ namespace Microsoft.ClearScript.Util.COM
{
internal static partial class TypeInfoHelpers
{
private static readonly ConcurrentDictionary<Guid, Type> managedTypeMap = new ConcurrentDictionary<Guid, Type>();
public static Type GetManagedType(this ITypeInfo typeInfo)
{
var pTypeInfo = Marshal.GetComInterfaceForObject(typeInfo, typeof(ITypeInfo));
try
var guid = typeInfo.GetGuid();
return (guid == Guid.Empty) ? null : managedTypeMap.GetOrAdd(guid, _ =>
{
return Marshal.GetTypeForITypeInfo(pTypeInfo);
}
finally
{
Marshal.Release(pTypeInfo);
}
var pTypeInfo = Marshal.GetComInterfaceForObject(typeInfo, typeof(ITypeInfo));
try
{
return Marshal.GetTypeForITypeInfo(pTypeInfo);
}
finally
{
Marshal.Release(pTypeInfo);
}
});
}
}
}

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

@ -487,7 +487,7 @@ namespace Microsoft.ClearScript.Util
public static object CreateInstance(this Type type, IHostInvokeContext invokeContext, HostTarget target, object[] args, object[] bindArgs)
{
if (type.IsCOMObject || (type.IsValueType && (args.Length < 1)))
if (type.IsCOMObject)
{
return type.CreateInstance(args);
}
@ -500,7 +500,13 @@ namespace Microsoft.ClearScript.Util
return InvokeHelpers.InvokeConstructor(invokeContext, boundConstructor, args);
}
var candidates = type.GetConstructors(flags).Where(testConstructor => testConstructor.IsAccessible(invokeContext.AccessContext) && !testConstructor.IsBlockedFromScript(invokeContext.DefaultAccess)).ToArray();
var constructors = type.GetConstructors(flags);
if (type.IsValueType && (args.Length < 1) && !constructors.Any(testConstructor => testConstructor.GetParameters().Length < 1))
{
return type.CreateInstance();
}
var candidates = constructors.Where(testConstructor => testConstructor.IsAccessible(invokeContext.AccessContext) && !testConstructor.IsBlockedFromScript(invokeContext.DefaultAccess)).ToArray();
if (candidates.Length < 1)
{
throw new MissingMethodException(MiscHelpers.FormatInvariant("Type '{0}' has no constructor that matches the specified arguments", type.GetFullFriendlyName()));
@ -1271,14 +1277,16 @@ namespace Microsoft.ClearScript.Util
private sealed class BindCandidate<T> : IComparable<BindCandidate<T>> where T : MemberInfo
{
private readonly int defaultArgCount;
private readonly bool paramArray;
private readonly List<BindArgCost> argCosts;
public T Candidate { get; }
private BindCandidate(T candidate, bool paramArray, List<BindArgCost> argCosts)
private BindCandidate(T candidate, int defaultArgCount, bool paramArray, List<BindArgCost> argCosts)
{
Candidate = candidate;
this.defaultArgCount = defaultArgCount;
this.paramArray = paramArray;
this.argCosts = argCosts;
}
@ -1297,6 +1305,12 @@ namespace Microsoft.ClearScript.Util
}
}
result = defaultArgCount.CompareTo(other.defaultArgCount);
if (result != 0)
{
return result;
}
result = paramArray.CompareTo(other.paramArray);
if (result != 0)
{
@ -1316,6 +1330,7 @@ namespace Microsoft.ClearScript.Util
public static BindCandidate<T> TryCreateInstance(T candidate, ParameterInfo[] parameters, object[] args, Type[] argTypes)
{
var defaultArgCount = 0;
var paramArray = false;
var argCosts = new List<BindArgCost>();
@ -1343,6 +1358,7 @@ namespace Microsoft.ClearScript.Util
return null;
}
defaultArgCount += 1;
continue;
}
@ -1359,13 +1375,13 @@ namespace Microsoft.ClearScript.Util
{
if (argIndex >= args.Length)
{
return new BindCandidate<T>(candidate, true, argCosts);
return new BindCandidate<T>(candidate, defaultArgCount, true, argCosts);
}
if ((argIndex == (args.Length - 1)) && paramType.IsBindableFromArg(args[argIndex], argTypes[argIndex], out cost))
{
argCosts.Add(cost);
return new BindCandidate<T>(candidate, true, argCosts);
return new BindCandidate<T>(candidate, defaultArgCount, true, argCosts);
}
paramType = paramType.GetElementType();
@ -1385,7 +1401,7 @@ namespace Microsoft.ClearScript.Util
return null;
}
return new BindCandidate<T>(candidate, paramArray, argCosts);
return new BindCandidate<T>(candidate, defaultArgCount, paramArray, argCosts);
}
}

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

@ -11,6 +11,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]

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

@ -11,6 +11,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]

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

@ -1407,6 +1407,40 @@ namespace Microsoft.ClearScript.Test
Assert.AreEqual(Math.Sqrt(Math.PI * Math.E), engine.Evaluate("test.Item.get(789, \"bar\")"));
}
[TestMethod, TestCategory("BugFix")]
public void BugFix_MultidimensionalArray_VBScript()
{
engine.Dispose();
engine = new VBScriptEngine();
engine.AddHostObject("host", new HostFunctions());
engine.Script.x = new int[2];
engine.Script.y = new int[3, 4];
Assert.AreEqual(0, engine.Evaluate("x(1)"));
engine.Execute("x(1) = 123");
Assert.AreEqual(123, engine.Evaluate("x(1)"));
Assert.AreEqual(0, engine.Evaluate("y(2, 3)"));
engine.Execute("y(2, 3) = 456");
Assert.AreEqual(456, engine.Evaluate("y(2, 3)"));
engine.Execute(@"
x = host.newVar(x)
x(1) = 0
y = host.newVar(y)
y(2, 3) = 0
");
Assert.AreEqual(0, engine.Evaluate("x(1)"));
engine.Execute("x(1) = 123");
Assert.AreEqual(123, engine.Evaluate("x(1)"));
Assert.AreEqual(0, engine.Evaluate("y(2, 3)"));
engine.Execute("y(2, 3) = 456");
Assert.AreEqual(456, engine.Evaluate("y(2, 3)"));
}
// ReSharper restore InconsistentNaming
#endregion

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

@ -1178,8 +1178,11 @@ namespace Microsoft.ClearScript.Test
{
using (var runtime = new V8Runtime())
{
using (runtime.CreateScriptEngine())
for (var i = 0; i < 5; i++)
{
using (runtime.CreateScriptEngine())
{
}
}
runtime.CollectGarbage(true);
@ -1750,6 +1753,50 @@ namespace Microsoft.ClearScript.Test
engine.Execute("Array.from(test.Values)");
}
#if NET6_0_OR_GREATER
[TestMethod, TestCategory("BugFix")]
public void BugFix_StructConstructors()
{
engine.AddHostType(typeof(StructConstructorTest));
Assert.AreEqual(123, engine.Evaluate("new StructConstructorTest().Value"));
Assert.AreEqual(789, engine.Evaluate("new StructConstructorTest(789).Value"));
engine.Dispose();
engine = new V8ScriptEngine(V8ScriptEngineFlags.EnableDebugging);
engine.AddHostType(typeof(StructConstructorTest));
using (Scope.Create(() => HostSettings.CustomAttributeLoader, loader => HostSettings.CustomAttributeLoader = loader))
{
HostSettings.CustomAttributeLoader = new StructConstructorTestCustomAttributeLoader();
Assert.AreEqual(456, engine.Evaluate("new StructConstructorTest().Value"));
Assert.AreEqual(789, engine.Evaluate("new StructConstructorTest(789).Value"));
}
}
#else // !NET6_0_OR_GREATER
[TestMethod, TestCategory("BugFix")]
public void BugFix_StructConstructors()
{
engine.AddHostType(typeof(StructConstructorTest));
Assert.AreEqual(0, engine.Evaluate("new StructConstructorTest().Value"));
Assert.AreEqual(789, engine.Evaluate("new StructConstructorTest(789).Value"));
engine.Dispose();
engine = new V8ScriptEngine(V8ScriptEngineFlags.EnableDebugging);
engine.AddHostType(typeof(StructConstructorTest));
using (Scope.Create(() => HostSettings.CustomAttributeLoader, loader => HostSettings.CustomAttributeLoader = loader))
{
HostSettings.CustomAttributeLoader = new StructConstructorTestCustomAttributeLoader();
Assert.AreEqual(0, engine.Evaluate("new StructConstructorTest().Value"));
Assert.AreEqual(789, engine.Evaluate("new StructConstructorTest(789).Value"));
}
}
#endif // !NET6_0_OR_GREATER
// ReSharper restore InconsistentNaming
#endregion
@ -1918,8 +1965,8 @@ namespace Microsoft.ClearScript.Test
public int PrivateGetter
{
private get { return dummy; }
set { dummy = value; }
private get => dummy;
set => dummy = value;
}
public int NoSetter => dummy;
@ -1946,8 +1993,8 @@ namespace Microsoft.ClearScript.Test
public static int PrivateGetter
{
private get { return dummy; }
set { dummy = value; }
private get => dummy;
set => dummy = value;
}
public static int NoSetter => dummy;
@ -2251,6 +2298,50 @@ namespace Microsoft.ClearScript.Test
}
}
#if NET6_0_OR_GREATER
public struct StructConstructorTest
{
public int Value { get; }
public StructConstructorTest()
{
Value = 123;
}
public StructConstructorTest(int value = 456)
{
Value = value;
}
}
#else // !NET6_0_OR_GREATER
public struct StructConstructorTest
{
public int Value { get; }
public StructConstructorTest(int value = 456)
{
Value = value;
}
}
#endif // !NET6_0_OR_GREATER
private class StructConstructorTestCustomAttributeLoader : CustomAttributeLoader
{
public override T[] LoadCustomAttributes<T>(ICustomAttributeProvider resource, bool inherit)
{
if ((resource is ConstructorInfo constructor) && (constructor.DeclaringType == typeof(StructConstructorTest)) && (constructor.GetParameters().Length < 1) && (typeof(T) == typeof(ScriptUsageAttribute)))
{
return new[] { new ScriptUsageAttribute(ScriptAccess.None) } as T[];
}
return base.LoadCustomAttributes<T>(resource, inherit);
}
}
#endregion
}
}

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

@ -39,5 +39,7 @@ namespace Microsoft.ClearScript.Test
}
protected bool IsNetFramework => RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework", StringComparison.Ordinal);
protected string HttpBinUrl => "http://localhost:9339";
}
}

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

@ -19,10 +19,16 @@ namespace Microsoft.ClearScript.Test
var status = 0;
string data = null;
var checkpoint = new ManualResetEventSlim();
Dispatcher dispatcher = null;
var thread = new Thread(() =>
{
using (var testEngine = new JScriptEngine(Windows.WindowsScriptEngineFlags.EnableDebugging | Windows.WindowsScriptEngineFlags.EnableStandardsMode, NullSyncInvoker.Instance))
{
dispatcher = Dispatcher.CurrentDispatcher;
checkpoint.Set();
testEngine.Script.onComplete = new Action<int, string>((xhrStatus, xhrData) =>
{
status = xhrStatus;
@ -30,19 +36,19 @@ namespace Microsoft.ClearScript.Test
Dispatcher.ExitAllFrames();
});
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
dispatcher.BeginInvoke(new Action(() =>
{
// ReSharper disable AccessToDisposedClosure
testEngine.AddCOMType("XMLHttpRequest", "MSXML2.XMLHTTP");
testEngine.Execute(@"
testEngine.Execute($@"
xhr = new XMLHttpRequest();
xhr.open('POST', 'http://httpbin.org/post', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
xhr.open('POST', '{HttpBinUrl}/post', true);
xhr.onreadystatechange = function () {{
if (xhr.readyState == 4) {{
onComplete(xhr.status, JSON.parse(xhr.responseText).data);
}
};
}}
}};
xhr.send('Hello, world!');
");
@ -55,9 +61,12 @@ namespace Microsoft.ClearScript.Test
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
checkpoint.Wait();
if (!thread.Join(TimeSpan.FromSeconds(5)))
if (!thread.Join(TimeSpan.FromSeconds(10)))
{
dispatcher.Invoke(Dispatcher.ExitAllFrames);
thread.Join();
Assert.Inconclusive("The Httpbin service request timed out");
}

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

@ -2067,10 +2067,16 @@ namespace Microsoft.ClearScript.Test
var status = 0;
string data = null;
var checkpoint = new ManualResetEventSlim();
Dispatcher dispatcher = null;
var thread = new Thread(() =>
{
using (var testEngine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableStandardsMode))
{
dispatcher = Dispatcher.CurrentDispatcher;
checkpoint.Set();
testEngine.Script.onComplete = new Action<int, string>((xhrStatus, xhrData) =>
{
status = xhrStatus;
@ -2078,19 +2084,19 @@ namespace Microsoft.ClearScript.Test
Dispatcher.ExitAllFrames();
});
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
dispatcher.BeginInvoke(new Action(() =>
{
// ReSharper disable AccessToDisposedClosure
testEngine.AddCOMType("XMLHttpRequest", "MSXML2.XMLHTTP");
testEngine.Execute(@"
testEngine.Execute($@"
xhr = new XMLHttpRequest();
xhr.open('POST', 'http://httpbin.org/post', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
xhr.open('POST', '{HttpBinUrl}/post', true);
xhr.onreadystatechange = function () {{
if (xhr.readyState == 4) {{
onComplete(xhr.status, JSON.parse(xhr.responseText).data);
}
};
}}
}};
xhr.send('Hello, world!');
");
@ -2103,9 +2109,12 @@ namespace Microsoft.ClearScript.Test
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
checkpoint.Wait();
if (!thread.Join(TimeSpan.FromSeconds(5)))
if (!thread.Join(TimeSpan.FromSeconds(10)))
{
dispatcher.Invoke(Dispatcher.ExitAllFrames);
thread.Join();
Assert.Inconclusive("The Httpbin service request timed out");
}

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

@ -11,6 +11,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("7.4.1")]
[assembly: AssemblyFileVersion("7.4.1")]
[assembly: AssemblyInformationalVersion("7.4.1")]
[assembly: AssemblyVersion("7.4.2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]

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

@ -716,10 +716,16 @@ namespace Microsoft.ClearScript.Test
var status = 0;
string data = null;
var checkpoint = new ManualResetEventSlim();
Dispatcher dispatcher = null;
var thread = new Thread(() =>
{
using (var testEngine = new V8ScriptEngine(V8ScriptEngineFlags.EnableDebugging))
{
dispatcher = Dispatcher.CurrentDispatcher;
checkpoint.Set();
testEngine.Script.onComplete = new Action<int, string>((xhrStatus, xhrData) =>
{
status = xhrStatus;
@ -727,19 +733,19 @@ namespace Microsoft.ClearScript.Test
Dispatcher.ExitAllFrames();
});
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
dispatcher.BeginInvoke(new Action(() =>
{
// ReSharper disable AccessToDisposedClosure
testEngine.AddCOMType("XMLHttpRequest", "MSXML2.XMLHTTP");
testEngine.Execute(@"
testEngine.Execute($@"
xhr = new XMLHttpRequest();
xhr.open('POST', 'http://httpbin.org/post', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
xhr.open('POST', '{HttpBinUrl}/post', true);
xhr.onreadystatechange = function () {{
if (xhr.readyState == 4) {{
onComplete(xhr.status, JSON.parse(xhr.responseText).data);
}
};
}}
}};
xhr.send('Hello, world!');
");
@ -752,9 +758,12 @@ namespace Microsoft.ClearScript.Test
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
checkpoint.Wait();
if (!thread.Join(TimeSpan.FromSeconds(5)))
if (!thread.Join(TimeSpan.FromSeconds(10)))
{
dispatcher.Invoke(Dispatcher.ExitAllFrames);
thread.Join();
Assert.Inconclusive("The Httpbin service request timed out");
}

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

@ -4511,8 +4511,9 @@ namespace Microsoft.ClearScript.Test
[TestMethod, TestCategory("V8ScriptEngine")]
public void V8ScriptEngine_TotalExternalSize()
{
var size = engine.GetRuntimeHeapInfo().TotalExternalSize;
engine.Execute("arr = new Uint8Array(1234567)");
Assert.AreEqual(1234567UL, engine.GetRuntimeHeapInfo().TotalExternalSize);
Assert.AreEqual(size + 1234567UL, engine.GetRuntimeHeapInfo().TotalExternalSize);
}
[TestMethod, TestCategory("V8ScriptEngine")]
@ -4522,8 +4523,9 @@ namespace Microsoft.ClearScript.Test
{
using (var tempEngine = runtime.CreateScriptEngine())
{
var size = runtime.GetHeapInfo().TotalExternalSize;
tempEngine.Execute("arr = new Uint8Array(7654321)");
Assert.AreEqual(7654321UL, runtime.GetHeapInfo().TotalExternalSize);
Assert.AreEqual(size + 7654321UL, runtime.GetHeapInfo().TotalExternalSize);
}
}
}

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

@ -19,6 +19,9 @@ namespace Microsoft.ClearScript.Test
var status = 0;
string data = null;
var checkpoint = new ManualResetEventSlim();
Dispatcher dispatcher = null;
var thread = new Thread(() =>
{
using (var testEngine = new VBScriptEngine(Windows.WindowsScriptEngineFlags.EnableDebugging, NullSyncInvoker.Instance))
@ -27,6 +30,9 @@ namespace Microsoft.ClearScript.Test
{
// ReSharper disable AccessToDisposedClosure
dispatcher = Dispatcher.CurrentDispatcher;
checkpoint.Set();
testEngine.Script.onComplete = new Action<int, string>((xhrStatus, xhrData) =>
{
status = xhrStatus;
@ -38,18 +44,18 @@ namespace Microsoft.ClearScript.Test
helperEngine.Script.JSON.parse(responseText).data
);
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
dispatcher.BeginInvoke(new Action(() =>
{
testEngine.AddCOMType("XMLHttpRequest", "MSXML2.XMLHTTP");
testEngine.Script.host = new HostFunctions();
testEngine.Execute(@"
testEngine.Execute($@"
sub onreadystatechange
if xhr.readyState = 4 then
call onComplete(xhr.status, getData(xhr.responseText))
end if
end sub
xhr = host.newObj(XMLHttpRequest)
call xhr.open(""POST"", ""http://httpbin.org/post"", true)
call xhr.open(""POST"", ""{HttpBinUrl}/post"", true)
xhr.onreadystatechange = GetRef(""onreadystatechange"")
call xhr.send(""Hello, world!"")
");
@ -64,9 +70,12 @@ namespace Microsoft.ClearScript.Test
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
checkpoint.Wait();
if (!thread.Join(TimeSpan.FromSeconds(5)))
if (!thread.Join(TimeSpan.FromSeconds(10)))
{
dispatcher.Invoke(Dispatcher.ExitAllFrames);
thread.Join();
Assert.Inconclusive("The Httpbin service request timed out");
}

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

@ -2258,6 +2258,9 @@ namespace Microsoft.ClearScript.Test
var status = 0;
string data = null;
var checkpoint = new ManualResetEventSlim();
Dispatcher dispatcher = null;
var thread = new Thread(() =>
{
using (var testEngine = new VBScriptEngine(WindowsScriptEngineFlags.EnableDebugging))
@ -2266,6 +2269,9 @@ namespace Microsoft.ClearScript.Test
{
// ReSharper disable AccessToDisposedClosure
dispatcher = Dispatcher.CurrentDispatcher;
checkpoint.Set();
testEngine.Script.onComplete = new Action<int, string>((xhrStatus, xhrData) =>
{
status = xhrStatus;
@ -2277,18 +2283,18 @@ namespace Microsoft.ClearScript.Test
helperEngine.Script.JSON.parse(responseText).data
);
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
dispatcher.BeginInvoke(new Action(() =>
{
testEngine.AddCOMType("XMLHttpRequest", "MSXML2.XMLHTTP");
testEngine.Script.host = new HostFunctions();
testEngine.Execute(@"
testEngine.Execute($@"
sub onreadystatechange
if xhr.readyState = 4 then
call onComplete(xhr.status, getData(xhr.responseText))
end if
end sub
xhr = host.newObj(XMLHttpRequest)
call xhr.open(""POST"", ""http://httpbin.org/post"", true)
call xhr.open(""POST"", ""{HttpBinUrl}/post"", true)
xhr.onreadystatechange = GetRef(""onreadystatechange"")
call xhr.send(""Hello, world!"")
");
@ -2303,9 +2309,12 @@ namespace Microsoft.ClearScript.Test
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
checkpoint.Wait();
if (!thread.Join(TimeSpan.FromSeconds(5)))
if (!thread.Join(TimeSpan.FromSeconds(10)))
{
dispatcher.Invoke(Dispatcher.ExitAllFrames);
thread.Join();
Assert.Inconclusive("The Httpbin service request timed out");
}

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

@ -201,17 +201,23 @@ public:
virtual void QueueNativeCallback(NativeCallback&& callback) override
{
BEGIN_V8_RWX_HOST_SCOPE
V8_SPLIT_PROXY_MANAGED_INVOKE_VOID_NOTHROW(QueueNativeCallback, new NativeCallbackHandle(new NativeCallback(std::move(callback))));
END_V8_RWX_HOST_SCOPE
}
virtual void* CreateNativeCallbackTimer(int32_t dueTime, int32_t period, NativeCallback&& callback) override
{
BEGIN_V8_RWX_HOST_SCOPE
return V8_SPLIT_PROXY_MANAGED_INVOKE_NOTHROW(void*, CreateNativeCallbackTimer, dueTime, period, new NativeCallbackHandle(new NativeCallback(std::move(callback))));
END_V8_RWX_HOST_SCOPE
}
virtual bool ChangeNativeCallbackTimer(void* pvTimer, int32_t dueTime, int32_t period) override
{
BEGIN_V8_RWX_HOST_SCOPE
return V8_SPLIT_PROXY_MANAGED_INVOKE_NOTHROW(StdBool, ChangeNativeCallbackTimer, pvTimer, dueTime, period);
END_V8_RWX_HOST_SCOPE
}
virtual void DestroyNativeCallbackTimer(void* pvTimer) override

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

@ -379,14 +379,14 @@ private:
return m_spIsolateImpl->ContextDisposedNotification();
}
bool IdleNotificationDeadline(double deadlineInSeconds)
void RequestGarbageCollectionForTesting(v8::Isolate::GarbageCollectionType type)
{
return m_spIsolateImpl->IdleNotificationDeadline(deadlineInSeconds);
m_spIsolateImpl->RequestGarbageCollectionForTesting(type);
}
void LowMemoryNotification()
void ClearCachesForTesting()
{
m_spIsolateImpl->LowMemoryNotification();
m_spIsolateImpl->ClearCachesForTesting();
}
v8::Local<v8::StackFrame> GetStackFrame(v8::Local<v8::StackTrace> hStackTrace, uint32_t index)

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

@ -25,18 +25,6 @@ public:
virtual double CurrentClockTimeMillis() override;
virtual v8::TracingController* GetTracingController() override;
#if defined(__APPLE__) && defined(__arm64__)
// WORKAROUND: V8 on Apple Silicon crashes frequently without this override; it's unclear
// whether it retains correct behavior.
virtual std::unique_ptr<v8::JobHandle> PostJob(v8::TaskPriority priority, std::unique_ptr<v8::JobTask> upJobTask) override
{
return CreateJob(priority, std::move(upJobTask));
}
#endif // defined(__APPLE__) && defined(__arm64__)
private:
V8Platform();
@ -72,6 +60,7 @@ void V8Platform::EnsureInitialized()
m_GlobalFlags = V8_SPLIT_PROXY_MANAGED_INVOKE_NOTHROW(V8GlobalFlags, GetGlobalFlags);
std::vector<std::string> flagStrings;
flagStrings.push_back("--expose_gc");
#ifdef CLEARSCRIPT_TOP_LEVEL_AWAIT_CONTROL
@ -82,21 +71,6 @@ void V8Platform::EnsureInitialized()
#endif // CLEARSCRIPT_TOP_LEVEL_AWAIT_CONTROL
#if defined(__APPLE__) && defined(__arm64__)
// WORKAROUND: On Apple M1 only, our lone WebAssembly test crashes consistently unless this
// option is disabled. The crash is indicative of corruption within the SplitProxyManaged
// pointer table or of its address in thread-local storage.
// UPDATE: The crash is probably not due to method table corruption but V8's use of
// pthread_jit_write_protect_np in its WebAssembly code. If the thread's JIT protection
// state is writable (vs. executable) when V8 calls the embedder, any attempt to invoke
// managed code will trigger a bus error.
flagStrings.push_back("--no_wasm_async_compilation");
#endif // defined(__APPLE__) && defined(__arm64__)
if (HasFlag(m_GlobalFlags, V8GlobalFlags::DisableJITCompilation))
{
flagStrings.push_back("--jitless");
@ -876,11 +850,12 @@ void V8IsolateImpl::CollectGarbage(bool exhaustive)
if (exhaustive)
{
ClearScriptCache();
LowMemoryNotification();
ClearCachesForTesting();
RequestGarbageCollectionForTesting(v8::Isolate::kFullGarbageCollection);
}
else
{
while (!IdleNotificationDeadline(V8Platform::GetInstance().MonotonicallyIncreasingTime() + 0.1));
RequestGarbageCollectionForTesting(v8::Isolate::kMinorGarbageCollection);
}
END_ISOLATE_SCOPE
@ -1987,7 +1962,8 @@ void V8IsolateImpl::CheckHeapSize(const std::optional<size_t>& optMaxHeapSize, b
if (heapStatistics.total_heap_size() > maxHeapSize)
{
// yes; collect garbage
LowMemoryNotification();
ClearCachesForTesting();
RequestGarbageCollectionForTesting(v8::Isolate::kFullGarbageCollection);
// is the total heap size still over the limit?
GetHeapStatistics(heapStatistics);

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

@ -417,14 +417,14 @@ public:
return m_upIsolate->ContextDisposedNotification();
}
bool IdleNotificationDeadline(double deadlineInSeconds)
void RequestGarbageCollectionForTesting(v8::Isolate::GarbageCollectionType type)
{
return m_upIsolate->IdleNotificationDeadline(deadlineInSeconds);
m_upIsolate->RequestGarbageCollectionForTesting(type);
}
void LowMemoryNotification()
void ClearCachesForTesting()
{
m_upIsolate->LowMemoryNotification();
m_upIsolate->ClearCachesForTesting();
}
v8::Local<v8::StackFrame> GetStackFrame(v8::Local<v8::StackTrace> hStackTrace, uint32_t index)

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

@ -413,6 +413,44 @@ const v8::Persistent<T> V8SafePersistent<T>::ms_EmptyImpl;
template <typename T>
using Persistent = V8FastPersistent<T>;
//-----------------------------------------------------------------------------
// V8 host scope
//-----------------------------------------------------------------------------
class V8RwxHostScope final
{
PROHIBIT_COPY(V8RwxHostScope)
PROHIBIT_HEAP(V8RwxHostScope)
public:
V8RwxHostScope():
m_CodeSpaceWriteNestingLevel(v8::V8::EnterRwxHostScope())
{
}
~V8RwxHostScope()
{
v8::V8::ExitRwxHostScope(m_CodeSpaceWriteNestingLevel);
}
private:
int m_CodeSpaceWriteNestingLevel;
};
//-----------------------------------------------------------------------------
#define BEGIN_V8_RWX_HOST_SCOPE \
{ \
DISABLE_WARNING(4456) /* declaration hides previous local declaration */ \
V8RwxHostScope t_HostScope; \
DEFAULT_WARNING(4456)
#define END_V8_RWX_HOST_SCOPE \
IGNORE_UNUSED(t_HostScope); \
}
//-----------------------------------------------------------------------------
// helper functions
//-----------------------------------------------------------------------------

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

@ -118,7 +118,7 @@ OBJDIR = $(OUTDIR)/obj/$(CPU)
CLEARSCRIPTV8 = $(OUTDIR)/ClearScriptV8.$(OS)-$(CPU).$(EXTENSION)
CXX = clang++
CXXFLAGS = --target=$(TARGET) -std=c++17 -fvisibility=default -fPIC -fno-rtti -Wno-ignored-attributes $(CXXCONFIGFLAGS) -I$(V8INCDIR) -I$(JSONINCDIR) $(CXXCROSSFLAGS)
CXXFLAGS = --target=$(TARGET) -std=c++17 -fvisibility=default -fPIC -fno-rtti -Wno-deprecated-declarations -Wno-ignored-attributes $(CXXCONFIGFLAGS) -I$(V8INCDIR) -I$(JSONINCDIR) $(CXXCROSSFLAGS)
HEADERS = $(wildcard $(SRCDIR)/*.h) $(wildcard $(EXPORTSDIR)/*.h)
OBJECTS = \

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

@ -1,6 +1,6 @@
#!/bin/bash
v8testedrev=11.2.214.13
v8testedrev=11.4.183.17
v8testedcommit=
v8cherrypicks=
v8linuxbuildcommit=3d9590754d5d23e62d15472c5baf6777ca59df20

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

@ -1,8 +1,16 @@
diff --git a/BUILD.gn b/BUILD.gn
index 277f47717d..9589c54e60 100644
index 5cda664fdd..dcb2cb8c7b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1121,7 +1121,7 @@ config("toolchain") {
@@ -8,7 +8,6 @@ import("//build/config/coverage/coverage.gni")
import("//build/config/dcheck_always_on.gni")
import("//build/config/host_byteorder.gni")
import("//build/config/mips.gni")
-import("//build/config/riscv.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build_overrides/build.gni")
@@ -1167,7 +1166,7 @@ config("toolchain") {
visibility = [ "./*" ]
defines = []
@ -25,7 +33,7 @@ index 9ec60c04f9..a5c268db93 100644
* The same as NewDefaultPlatform but disables the worker thread pool.
* It must be used with the --single-threaded V8 flag.
diff --git a/include/v8-initialization.h b/include/v8-initialization.h
index d3e35d6ec5..2d2fb458fe 100644
index d3e35d6ec5..56b3faaa79 100644
--- a/include/v8-initialization.h
+++ b/include/v8-initialization.h
@@ -136,6 +136,7 @@ class V8_EXPORT V8 {
@ -36,11 +44,21 @@ index d3e35d6ec5..2d2fb458fe 100644
/**
* Initialize the ICU library bundled with V8. The embedder should only
@@ -264,6 +265,9 @@ class V8_EXPORT V8 {
*/
static void GetSharedMemoryStatistics(SharedMemoryStatistics* statistics);
+ static int EnterRwxHostScope();
+ static void ExitRwxHostScope(int code_space_write_nesting_level);
+
private:
V8();
diff --git a/include/v8-platform.h b/include/v8-platform.h
index 750131d4c9..c390d801ed 100644
index e34a8db6d8..1c1b2aa9a6 100644
--- a/include/v8-platform.h
+++ b/include/v8-platform.h
@@ -1089,7 +1089,7 @@ class Platform {
@@ -1168,7 +1168,7 @@ class Platform {
* required.
*/
virtual int64_t CurrentClockTimeMilliseconds() {
@ -64,7 +82,7 @@ index 11296cd488..0f090446dc 100644
* Support for TC39 "dynamic code brand checks" proposal.
*
diff --git a/include/v8config.h b/include/v8config.h
index 9410eb4135..b9bdc7a6a0 100644
index bee208ffa9..c14f5ed440 100644
--- a/include/v8config.h
+++ b/include/v8config.h
@@ -531,7 +531,7 @@ path. Add it with -I<path> to the command line
@ -77,7 +95,7 @@ index 9410eb4135..b9bdc7a6a0 100644
# define V8_PRESERVE_MOST /* NOT SUPPORTED */
#endif
diff --git a/src/api/api-natives.cc b/src/api/api-natives.cc
index 05a883f2d5..3ea0b8ce62 100644
index 905f29bf25..eff0e7d219 100644
--- a/src/api/api-natives.cc
+++ b/src/api/api-natives.cc
@@ -447,6 +447,9 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
@ -91,10 +109,10 @@ index 05a883f2d5..3ea0b8ce62 100644
// Keep prototypes in slow-mode. Let them be lazily turned fast later on.
// TODO(dcarney): is this necessary?
diff --git a/src/api/api.cc b/src/api/api.cc
index fac24bae12..0c558589ea 100644
index 94b44c14c3..eed3a6be5f 100644
--- a/src/api/api.cc
+++ b/src/api/api.cc
@@ -2057,6 +2057,17 @@ void ObjectTemplate::SetImmutableProto() {
@@ -2095,6 +2095,17 @@ void ObjectTemplate::SetImmutableProto() {
self->set_immutable_proto(true);
}
@ -112,7 +130,7 @@ index fac24bae12..0c558589ea 100644
bool ObjectTemplate::IsCodeLike() const {
return Utils::OpenHandle(this)->code_like();
}
@@ -6445,6 +6456,10 @@ bool v8::V8::InitializeICU(const char* icu_data_file) {
@@ -6556,6 +6567,10 @@ bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file);
}
@ -140,7 +158,7 @@ index 34a26d9c26..f995a2fc64 100644
MatchLiteralCompareTypeof(right_, op(), left_, expr, literal);
}
diff --git a/src/base/platform/platform.h b/src/base/platform/platform.h
index b9b734dac8..b577e3e01a 100644
index 27369a7a8d..fc58ac3d1d 100644
--- a/src/base/platform/platform.h
+++ b/src/base/platform/platform.h
@@ -52,6 +52,8 @@
@ -153,7 +171,7 @@ index b9b734dac8..b577e3e01a 100644
#if V8_CC_MSVC && V8_HOST_ARCH_IA32
// __readfsdword is supposed to be declared in intrin.h but it is missing from
diff --git a/src/builtins/builtins-async-module.cc b/src/builtins/builtins-async-module.cc
index 417e6f1dfa..108dc20972 100644
index e1a2a71c42..9152368a0e 100644
--- a/src/builtins/builtins-async-module.cc
+++ b/src/builtins/builtins-async-module.cc
@@ -15,7 +15,8 @@ BUILTIN(CallAsyncModuleFulfilled) {
@ -167,10 +185,10 @@ index 417e6f1dfa..108dc20972 100644
// The evaluation of async module can not throwing a JavaScript observable
// exception.
diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc
index 1091943889..dbc699384c 100644
index df4ba98d66..8993a77e8b 100644
--- a/src/codegen/code-stub-assembler.cc
+++ b/src/codegen/code-stub-assembler.cc
@@ -2027,6 +2027,10 @@ TNode<Uint32T> CodeStubAssembler::LoadMapBitField3(TNode<Map> map) {
@@ -2035,6 +2035,10 @@ TNode<Uint32T> CodeStubAssembler::LoadMapBitField3(TNode<Map> map) {
return LoadObjectField<Uint32T>(map, Map::kBitField3Offset);
}
@ -181,7 +199,7 @@ index 1091943889..dbc699384c 100644
TNode<Uint16T> CodeStubAssembler::LoadMapInstanceType(TNode<Map> map) {
return LoadObjectField<Uint16T>(map, Map::kInstanceTypeOffset);
}
@@ -14364,6 +14368,11 @@ TNode<String> CodeStubAssembler::Typeof(TNode<Object> value) {
@@ -14395,6 +14399,11 @@ TNode<String> CodeStubAssembler::Typeof(TNode<Object> value) {
GotoIf(InstanceTypeEqual(instance_type, ODDBALL_TYPE), &if_oddball);
@ -194,10 +212,10 @@ index 1091943889..dbc699384c 100644
Word32And(LoadMapBitField(map),
Int32Constant(Map::Bits1::IsCallableBit::kMask |
diff --git a/src/codegen/code-stub-assembler.h b/src/codegen/code-stub-assembler.h
index d4d6e12bae..890a6cf249 100644
index 0e43179204..82db618ff7 100644
--- a/src/codegen/code-stub-assembler.h
+++ b/src/codegen/code-stub-assembler.h
@@ -1409,6 +1409,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
@@ -1399,6 +1399,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Int32T> LoadMapBitField2(TNode<Map> map);
// Load bit field 3 of a map.
TNode<Uint32T> LoadMapBitField3(TNode<Map> map);
@ -206,19 +224,210 @@ index d4d6e12bae..890a6cf249 100644
// Load the instance type of a map.
TNode<Uint16T> LoadMapInstanceType(TNode<Map> map);
// Load the ElementsKind of a map.
diff --git a/src/common/globals.h b/src/common/globals.h
index 34d0c01cb6..bda045dece 100644
--- a/src/common/globals.h
+++ b/src/common/globals.h
@@ -270,7 +270,7 @@ const size_t kShortBuiltinCallsOldSpaceSizeThreshold = size_t{2} * GB;
//
#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT && \
!(defined(V8_COMPRESS_POINTERS) && !defined(V8_EXTERNAL_CODE_SPACE))
-#define V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT true
+#define V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT false
#else
#define V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT false
#endif
diff --git a/src/common/code-memory-access-inl.h b/src/common/code-memory-access-inl.h
index 2b504b86f3..3721dc2920 100644
--- a/src/common/code-memory-access-inl.h
+++ b/src/common/code-memory-access-inl.h
@@ -30,28 +30,89 @@ RwxMemoryWriteScope::~RwxMemoryWriteScope() {
}
}
-#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT
+#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT || V8_HAS_PKU_JIT_WRITE_PROTECT
// static
-bool RwxMemoryWriteScope::IsSupported() { return true; }
+int RwxMemoryWriteScope::EnterHostScope() {
+ if (v8_flags.jitless || !IsSupported()) return 0;
+ int code_space_write_nesting_level = code_space_write_nesting_level_;
+ DCHECK_GE(code_space_write_nesting_level, 0);
+ DCHECK_GE(code_space_host_nesting_level_, 0);
+ if (code_space_host_nesting_level_ == 0 && code_space_write_nesting_level > 0) {
+ code_space_write_nesting_level_ = 0;
+ SetExecutableInternal();
+ }
+ code_space_host_nesting_level_++;
+ return code_space_write_nesting_level;
+}
+
+// static
+void RwxMemoryWriteScope::ExitHostScope(int code_space_write_nesting_level) {
+ if (v8_flags.jitless || !IsSupported()) return;
+ DCHECK_GE(code_space_write_nesting_level, 0);
+ DCHECK_GT(code_space_host_nesting_level_, 0);
+ code_space_host_nesting_level_--;
+ if (code_space_host_nesting_level_ == 0 && code_space_write_nesting_level > 0) {
+ code_space_write_nesting_level_ = code_space_write_nesting_level;
+ SetWritableInternal();
+ }
+}
// static
void RwxMemoryWriteScope::SetWritable() {
+ if (!IsSupported()) return;
+ DCHECK_GE(code_space_write_nesting_level_, 0);
+ DCHECK_EQ(code_space_host_nesting_level_, 0);
if (code_space_write_nesting_level_ == 0) {
- base::SetJitWriteProtected(0);
+ SetWritableInternal();
}
code_space_write_nesting_level_++;
}
// static
void RwxMemoryWriteScope::SetExecutable() {
+ if (!IsSupported()) return;
+ DCHECK_GT(code_space_write_nesting_level_, 0);
+ DCHECK_EQ(code_space_host_nesting_level_, 0);
code_space_write_nesting_level_--;
if (code_space_write_nesting_level_ == 0) {
- base::SetJitWriteProtected(1);
+ SetExecutableInternal();
}
}
+#else // !V8_HAS_PTHREAD_JIT_WRITE_PROTECT && !V8_TRY_USE_PKU_JIT_WRITE_PROTECT
+
+// static
+int RwxMemoryWriteScope::EnterHostScope() { return 0; }
+
+// static
+void RwxMemoryWriteScope::ExitHostScope(int /*code_space_write_nesting_level*/) {}
+
+// static
+void RwxMemoryWriteScope::SetWritable() {}
+
+// static
+void RwxMemoryWriteScope::SetExecutable() {}
+
+#endif // V8_HAS_PTHREAD_JIT_WRITE_PROTECT || V8_HAS_PKU_JIT_WRITE_PROTECT
+
+#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT
+
+// static
+bool RwxMemoryWriteScope::IsSupported() { return true; }
+
+// static
+void RwxMemoryWriteScope::SetWritableInternal() {
+ base::SetJitWriteProtected(0);
+}
+
+// static
+void RwxMemoryWriteScope::SetExecutableInternal() {
+ base::SetJitWriteProtected(1);
+}
+
#elif V8_HAS_PKU_JIT_WRITE_PROTECT
+
// static
bool RwxMemoryWriteScope::IsSupported() {
static_assert(base::MemoryProtectionKey::kNoMemoryProtectionKey == -1);
@@ -60,31 +121,23 @@ bool RwxMemoryWriteScope::IsSupported() {
}
// static
-void RwxMemoryWriteScope::SetWritable() {
+void RwxMemoryWriteScope::SetWritableInternal() {
DCHECK(pkey_initialized);
- if (!IsSupported()) return;
- if (code_space_write_nesting_level_ == 0) {
DCHECK_NE(
base::MemoryProtectionKey::GetKeyPermission(memory_protection_key_),
base::MemoryProtectionKey::kNoRestrictions);
base::MemoryProtectionKey::SetPermissionsForKey(
memory_protection_key_, base::MemoryProtectionKey::kNoRestrictions);
- }
- code_space_write_nesting_level_++;
}
// static
-void RwxMemoryWriteScope::SetExecutable() {
+void RwxMemoryWriteScope::SetExecutableInternal() {
DCHECK(pkey_initialized);
- if (!IsSupported()) return;
- code_space_write_nesting_level_--;
- if (code_space_write_nesting_level_ == 0) {
DCHECK_EQ(
base::MemoryProtectionKey::GetKeyPermission(memory_protection_key_),
base::MemoryProtectionKey::kNoRestrictions);
base::MemoryProtectionKey::SetPermissionsForKey(
memory_protection_key_, base::MemoryProtectionKey::kDisableWrite);
- }
}
#else // !V8_HAS_PTHREAD_JIT_WRITE_PROTECT && !V8_TRY_USE_PKU_JIT_WRITE_PROTECT
@@ -93,10 +146,10 @@ void RwxMemoryWriteScope::SetExecutable() {
bool RwxMemoryWriteScope::IsSupported() { return false; }
// static
-void RwxMemoryWriteScope::SetWritable() {}
+void RwxMemoryWriteScope::SetWritableInternal() {}
// static
-void RwxMemoryWriteScope::SetExecutable() {}
+void RwxMemoryWriteScope::SetExecutableInternal() {}
#endif // V8_HAS_PTHREAD_JIT_WRITE_PROTECT
diff --git a/src/common/code-memory-access.cc b/src/common/code-memory-access.cc
index aaad4e000c..ec920ed48f 100644
--- a/src/common/code-memory-access.cc
+++ b/src/common/code-memory-access.cc
@@ -2,13 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "include/v8-initialization.h"
#include "src/common/code-memory-access-inl.h"
namespace v8 {
+
+// static
+int V8::EnterRwxHostScope() {
+ return i::RwxMemoryWriteScope::EnterHostScope();
+}
+
+// static
+void V8::ExitRwxHostScope(int code_space_write_nesting_level) {
+ i::RwxMemoryWriteScope::ExitHostScope(code_space_write_nesting_level);
+}
+
namespace internal {
#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT || V8_HAS_PKU_JIT_WRITE_PROTECT
thread_local int RwxMemoryWriteScope::code_space_write_nesting_level_ = 0;
+thread_local int RwxMemoryWriteScope::code_space_host_nesting_level_ = 0;
#endif // V8_HAS_PTHREAD_JIT_WRITE_PROTECT || V8_HAS_PKU_JIT_WRITE_PROTECT
#if V8_HAS_PKU_JIT_WRITE_PROTECT
diff --git a/src/common/code-memory-access.h b/src/common/code-memory-access.h
index 253cb720fe..fd878a9764 100644
--- a/src/common/code-memory-access.h
+++ b/src/common/code-memory-access.h
@@ -78,6 +78,9 @@ class V8_NODISCARD RwxMemoryWriteScope {
static void SetDefaultPermissionsForSignalHandler();
#endif // V8_HAS_PKU_JIT_WRITE_PROTECT
+ V8_INLINE static int EnterHostScope();
+ V8_INLINE static void ExitHostScope(int code_space_write_nesting_level);
+
private:
friend class CodePageCollectionMemoryModificationScope;
friend class CodePageMemoryModificationScope;
@@ -91,9 +94,13 @@ class V8_NODISCARD RwxMemoryWriteScope {
V8_INLINE static void SetWritable();
V8_INLINE static void SetExecutable();
+ V8_INLINE static void SetWritableInternal();
+ V8_INLINE static void SetExecutableInternal();
+
#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT || V8_HAS_PKU_JIT_WRITE_PROTECT
// This counter is used for supporting scope reentrance.
static thread_local int code_space_write_nesting_level_;
+ static thread_local int code_space_host_nesting_level_;
#endif // V8_HAS_PTHREAD_JIT_WRITE_PROTECT || V8_HAS_PKU_JIT_WRITE_PROTECT
#if V8_HAS_PKU_JIT_WRITE_PROTECT
diff --git a/src/diagnostics/unwinding-info-win64.cc b/src/diagnostics/unwinding-info-win64.cc
index a71b866135..4f1d26676c 100644
--- a/src/diagnostics/unwinding-info-win64.cc
@ -327,10 +536,10 @@ index ff64beb8b2..b26b3fe323 100644
set_jslimit(SimulatorStack::JsLimitFromCLimit(isolate, limit));
real_climit_ = limit;
diff --git a/src/heap/factory.cc b/src/heap/factory.cc
index 4c868825d7..a84535f103 100644
index a884f2ff16..f564c4c76b 100644
--- a/src/heap/factory.cc
+++ b/src/heap/factory.cc
@@ -2079,6 +2079,7 @@ Map Factory::InitializeMap(Map map, InstanceType type, int instance_size,
@@ -2080,6 +2080,7 @@ Map Factory::InitializeMap(Map map, InstanceType type, int instance_size,
Map::Bits3::ConstructionCounterBits::encode(Map::kNoSlackTracking) |
Map::Bits3::IsExtensibleBit::encode(true);
map.set_bit_field3(bit_field3);
@ -338,11 +547,36 @@ index 4c868825d7..a84535f103 100644
map.set_instance_type(type);
ReadOnlyRoots ro_roots(roots);
map.init_prototype_and_constructor_or_back_pointer(ro_roots);
diff --git a/src/heap/new-spaces.cc b/src/heap/new-spaces.cc
index 00e12e912d..1d323a2732 100644
--- a/src/heap/new-spaces.cc
+++ b/src/heap/new-spaces.cc
@@ -1096,6 +1096,9 @@ bool PagedSpaceForNewSpace::IsPromotionCandidate(
}
#ifdef VERIFY_HEAP
+static size_t PagedSpaceForNewSpace_Verify_accumulate_op(size_t sum, const Page* page) {
+ return sum + page->AllocatedLabSize();
+}
void PagedSpaceForNewSpace::Verify(Isolate* isolate,
SpaceVerificationVisitor* visitor) const {
PagedSpaceBase::Verify(isolate, visitor);
@@ -1104,9 +1107,7 @@ void PagedSpaceForNewSpace::Verify(Isolate* isolate,
DCHECK_EQ(
AllocatedSinceLastGC() + limit() - top(),
- std::accumulate(begin(), end(), 0, [](size_t sum, const Page* page) {
- return sum + page->AllocatedLabSize();
- }));
+ std::accumulate(begin(), end(), 0, PagedSpaceForNewSpace_Verify_accumulate_op));
}
#endif // VERIFY_HEAP
diff --git a/src/heap/setup-heap-internal.cc b/src/heap/setup-heap-internal.cc
index 5f352d1349..10020d538c 100644
index dec53bf526..63bfe0e055 100644
--- a/src/heap/setup-heap-internal.cc
+++ b/src/heap/setup-heap-internal.cc
@@ -241,6 +241,7 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
@@ -283,6 +283,7 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
Map::Bits3::OwnsDescriptorsBit::encode(true) |
Map::Bits3::ConstructionCounterBits::encode(Map::kNoSlackTracking);
map.set_bit_field3(bit_field3);
@ -403,11 +637,11 @@ index e127e75f10..b0e4bd2d68 100644
// Like above, but using the default icudt[lb].dat location if icu_data_file is
// not specified.
diff --git a/src/init/v8.cc b/src/init/v8.cc
index 4a4267f17b..d6653c4851 100644
index 9dad3911a4..0366aafbfe 100644
--- a/src/init/v8.cc
+++ b/src/init/v8.cc
@@ -94,7 +94,6 @@ V8_DECLARE_ONCE(init_snapshot_once);
@@ -95,7 +95,6 @@ V8_DECLARE_ONCE(init_snapshot_once);
// static
void V8::InitializePlatform(v8::Platform* platform) {
AdvanceStartupState(V8StartupState::kPlatformInitializing);
- CHECK(!platform_);
@ -415,7 +649,7 @@ index 4a4267f17b..d6653c4851 100644
platform_ = platform;
v8::base::SetPrintStackTrace(platform_->GetStackTracePrinter());
diff --git a/src/libplatform/default-platform.cc b/src/libplatform/default-platform.cc
index 2bbbb7e1f4..5cbd5e8c43 100644
index 0b42d5fb8b..1f72acbc06 100644
--- a/src/libplatform/default-platform.cc
+++ b/src/libplatform/default-platform.cc
@@ -55,6 +55,10 @@ std::unique_ptr<v8::Platform> NewDefaultPlatform(
@ -430,10 +664,10 @@ index 2bbbb7e1f4..5cbd5e8c43 100644
IdleTaskSupport idle_task_support,
InProcessStackDumping in_process_stack_dumping,
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 7bb2558cec..65b547b0fd 100644
index f3a45f1a12..0aea18f6d0 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -5246,6 +5246,13 @@ void JSObject::SetImmutableProto(Handle<JSObject> object) {
@@ -5269,6 +5269,13 @@ void JSObject::SetImmutableProto(Handle<JSObject> object) {
object->set_map(*new_map, kReleaseStore);
}
@ -448,10 +682,10 @@ index 7bb2558cec..65b547b0fd 100644
JavaScriptArguments* args,
uint32_t arg_count,
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index f83083cdbc..f9f274eadb 100644
index 870eb81553..2a42ca09d5 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -745,6 +745,8 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
@@ -748,6 +748,8 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
// Never called from JavaScript
static void SetImmutableProto(Handle<JSObject> object);
@ -461,10 +695,10 @@ index f83083cdbc..f9f274eadb 100644
// the caller to initialize object header. Fill the pre-allocated fields with
// undefined_value and the rest with filler_map.
diff --git a/src/objects/map-inl.h b/src/objects/map-inl.h
index 2c42cf2ee6..5fc4e46ba9 100644
index 8bcce73086..c354dd6730 100644
--- a/src/objects/map-inl.h
+++ b/src/objects/map-inl.h
@@ -125,6 +125,9 @@ BIT_FIELD_ACCESSORS(Map, bit_field3, may_have_interesting_symbols,
@@ -126,6 +126,9 @@ BIT_FIELD_ACCESSORS(Map, bit_field3, may_have_interesting_symbols,
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field3, construction_counter,
Map::Bits3::ConstructionCounterBits)
@ -475,10 +709,10 @@ index 2c42cf2ee6..5fc4e46ba9 100644
DCHECK(has_named_interceptor());
FunctionTemplateInfo info = GetFunctionTemplateInfo(cage_base);
diff --git a/src/objects/map.cc b/src/objects/map.cc
index ea57d93925..34763a37ef 100644
index db9ec690e4..0f70b3731d 100644
--- a/src/objects/map.cc
+++ b/src/objects/map.cc
@@ -1185,6 +1185,7 @@ Handle<Map> Map::RawCopy(Isolate* isolate, Handle<Map> src_handle,
@@ -1174,6 +1174,7 @@ Handle<Map> Map::RawCopy(Isolate* isolate, Handle<Map> src_handle,
}
// Same as bit_field comment above.
raw.set_bit_field3(new_bit_field3);
@ -486,7 +720,7 @@ index ea57d93925..34763a37ef 100644
raw.clear_padding();
}
Handle<HeapObject> prototype(src_handle->prototype(), isolate);
@@ -1311,6 +1312,12 @@ Handle<Map> Map::TransitionToImmutableProto(Isolate* isolate, Handle<Map> map) {
@@ -1300,6 +1301,12 @@ Handle<Map> Map::TransitionToImmutableProto(Isolate* isolate, Handle<Map> map) {
return new_map;
}
@ -500,10 +734,10 @@ index ea57d93925..34763a37ef 100644
void EnsureInitialMap(Isolate* isolate, Handle<Map> map) {
#ifdef DEBUG
diff --git a/src/objects/map.h b/src/objects/map.h
index bdc10ee2ba..838f81cd5d 100644
index ba1d379f8b..aef98f16c2 100644
--- a/src/objects/map.h
+++ b/src/objects/map.h
@@ -321,6 +321,11 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
@@ -323,6 +323,11 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
static_assert(kSlackTrackingCounterStart <=
Bits3::ConstructionCounterBits::kMax);
@ -515,7 +749,7 @@ index bdc10ee2ba..838f81cd5d 100644
// Inobject slack tracking is the way to reclaim unused inobject space.
//
// The instance size is initially determined by adding some slack to
@@ -666,6 +671,8 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
@@ -670,6 +675,8 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
DECL_BOOLEAN_ACCESSORS(is_immutable_proto)
@ -524,7 +758,7 @@ index bdc10ee2ba..838f81cd5d 100644
// This counter is used for in-object slack tracking.
// The in-object slack tracking is considered enabled when the counter is
// non zero. The counter only has a valid count for initial maps. For
@@ -834,6 +841,8 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
@@ -852,6 +859,8 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
static Handle<Map> TransitionToImmutableProto(Isolate* isolate,
Handle<Map> map);
@ -560,10 +794,10 @@ index a8b367ff82..98637087ee 100644
prototype: JSReceiver|Null;
constructor_or_back_pointer_or_native_context: Object;
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 26a8d59b34..108b20ee8b 100644
index 16e7f9cdb3..c856c02589 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -886,6 +886,12 @@ Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
@@ -887,6 +887,12 @@ Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
if (object->IsString()) return isolate->factory()->string_string();
if (object->IsSymbol()) return isolate->factory()->symbol_string();
if (object->IsBigInt()) return isolate->factory()->bigint_string();
@ -577,7 +811,7 @@ index 26a8d59b34..108b20ee8b 100644
return isolate->factory()->object_string();
}
diff --git a/src/objects/source-text-module.cc b/src/objects/source-text-module.cc
index 070788138b..2ac555d1c6 100644
index 7baf362b30..7cd7d0c5da 100644
--- a/src/objects/source-text-module.cc
+++ b/src/objects/source-text-module.cc
@@ -746,7 +746,7 @@ MaybeHandle<Object> SourceTextModule::Evaluate(

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

@ -1,7 +1,7 @@
@echo off
setlocal
set v8testedrev=11.2.214.13
set v8testedrev=11.4.183.17
set v8testedcommit=
if not "%v8testedcommit%"=="" goto ProcessArgs

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

@ -1,5 +1,5 @@
<#
var version = new Version(7, 4, 1);
var version = new Version(7, 4, 2);
var versionSuffix = string.Empty;
new Random(versionSuffix.Length); // suppress "versionSuffix not used" warning
#>

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

@ -1,12 +1,12 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (7.0.4.3)
activesupport (7.0.5)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.1)
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
coffee-script (2.4.1)
coffee-script-source
@ -15,8 +15,8 @@ GEM
colorator (1.1.0)
commonmarker (0.23.9)
concurrent-ruby (1.2.2)
dnsruby (1.61.9)
simpleidn (~> 0.1)
dnsruby (1.70.0)
simpleidn (~> 0.2.1)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
@ -24,7 +24,7 @@ GEM
ffi (>= 1.15.0)
eventmachine (1.2.7)
execjs (2.8.1)
faraday (2.7.4)
faraday (2.7.5)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
@ -86,7 +86,7 @@ GEM
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.8.0)
i18n (1.12.0)
i18n (1.13.0)
concurrent-ruby (~> 1.0)
jekyll (3.9.3)
addressable (~> 2.4)
@ -210,7 +210,7 @@ GEM
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.18.0)
nokogiri (1.14.3-x86_64-linux)
nokogiri (1.15.2-x86_64-linux)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)