Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NET 8 support #1686

Merged
merged 1 commit into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
<PackageVersion Include="Esprima" Version="3.0.2" />
<PackageVersion Include="Flurl.Http.Signed" Version="3.2.4" />
<PackageVersion Include="Jurassic" Version="3.2.7" />
<PackageVersion Include="Meziantou.Analyzer" Version="2.0.106" />
<PackageVersion Include="Meziantou.Analyzer" Version="2.0.110" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="MongoDB.Bson.signed" Version="2.19.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NiL.JS" Version="2.5.1674" />
Expand All @@ -21,13 +21,13 @@
<PackageVersion Include="Spectre.Console.Cli" Version="0.45.0" />
<PackageVersion Include="System.Text.Json" Version="6.0.8" />
<PackageVersion Include="Test262Harness" Version="0.0.22" />
<PackageVersion Include="xunit" Version="2.6.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.3" />
<PackageVersion Include="xunit" Version="2.6.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.4" PrivateAssets="all" />
<PackageVersion Include="YantraJS.Core" Version="1.2.203" />
</ItemGroup>
<ItemGroup>
<GlobalPackageReference Include="GitHubActionsTestLogger" Version="2.3.3" />
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<GlobalPackageReference Include="PolySharp" Version="1.13.2" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion Jint.Benchmark/Jint.Benchmark.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
Expand Down
2 changes: 1 addition & 1 deletion Jint.Repl/Jint.Repl.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
5 changes: 3 additions & 2 deletions Jint.Tests.CommonScripts/Jint.Tests.CommonScripts.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!--<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net461</TargetFrameworks>-->
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
<IsPackable>false</IsPackable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 3 additions & 1 deletion Jint.Tests.PublicInterface/ConstraintUsageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ public class ConstraintUsageTests
{
// this test case is problematic due to nature of cancellation token source in old framework
// in NET 6 it's better designed and signals more reliably
#if NET6_0_OR_GREATER

// TODO NET 8 also has problems with this
#if NET6_0
[Fact]
public void CanFindAndResetCancellationConstraint()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
<AssemblyOriginatorKeyFile>..\Jint\Jint.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
Expand Down
2 changes: 1 addition & 1 deletion Jint.Tests.Test262/Jint.Tests.Test262.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<!--<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net461</TargetFrameworks>-->
<AssemblyOriginatorKeyFile>..\Jint\Jint.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
Expand Down
4 changes: 2 additions & 2 deletions Jint.Tests.Test262/Test262Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private Engine BuildTestExecutor(Test262File file)
cfg.EnableModules(new Test262ModuleLoader(State.Test262Stream.Options.FileSystem, relativePath));
});

if (file.Flags.IndexOf("raw") != -1)
if (file.Flags.Contains("raw"))
{
// nothing should be loaded
return engine;
Expand Down Expand Up @@ -76,7 +76,7 @@ private Engine BuildTestExecutor(Test262File file)
engine.Execute(State.Sources[include]);
}

if (file.Flags.IndexOf("async") != -1)
if (file.Flags.Contains("async"))
{
engine.Execute(State.Sources["doneprintHandle.js"]);
}
Expand Down
2 changes: 1 addition & 1 deletion Jint.Tests/Jint.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
<AssemblyOriginatorKeyFile>..\Jint\Jint.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
Expand Down
16 changes: 11 additions & 5 deletions Jint.Tests/Runtime/DateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,17 @@ public void ValuePrecisionIsIntegral()
[Fact]
public void ToStringFollowsJavaScriptFormat()
{
var engine = new Engine(
conf =>
{
conf.LocalTimeZone(TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"));
});
TimeZoneInfo timeZoneInfo;
try
{
timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Asia/Shanghai");
}
catch
{
timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
}

var engine = new Engine(options => options.LocalTimeZone(timeZoneInfo));

Assert.Equal("Tue Feb 01 2022 00:00:00 GMT+0800 (China Standard Time)", engine.Evaluate("new Date(2022,1,1).toString()"));
Assert.Equal("Tue Feb 01 2022 00:00:00 GMT+0800 (China Standard Time)", engine.Evaluate("new Date(2022,1,1)").ToString());
Expand Down
4 changes: 2 additions & 2 deletions Jint.Tests/Runtime/EngineLimitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ public class EngineLimitTests
{

#if RELEASE
const int FunctionNestingCount = 960;
const int FunctionNestingCount = 840;
#else
const int FunctionNestingCount = 520;
const int FunctionNestingCount = 510;
#endif

[Fact]
Expand Down
21 changes: 8 additions & 13 deletions Jint.Tests/Runtime/EngineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,35 @@ public partial class EngineTests : IDisposable
private static readonly TimeZoneInfo _tongaTimeZone;
private static readonly TimeZoneInfo _easternTimeZone;


static EngineTests()
{
// https://stackoverflow.com/questions/47848111/how-should-i-fetch-timezoneinfo-in-a-platform-agnostic-way
// should be natively supported soon https://github.com/dotnet/runtime/issues/18644
try
{
_pacificTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
_pacificTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
}
catch (TimeZoneNotFoundException)
{
// https://stackoverflow.com/questions/47848111/how-should-i-fetch-timezoneinfo-in-a-platform-agnostic-way
// should be natively supported soon https://github.com/dotnet/runtime/issues/18644
_pacificTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
_pacificTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
}

try
{
_tongaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tonga Standard Time");
_tongaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific/Tongatapu");
}
catch (TimeZoneNotFoundException)
{
// https://stackoverflow.com/questions/47848111/how-should-i-fetch-timezoneinfo-in-a-platform-agnostic-way
// should be natively supported soon https://github.com/dotnet/runtime/issues/18644
_tongaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific/Tongatapu");
_tongaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tonga Standard Time");
}

try
{
_easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
_easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
}
catch (TimeZoneNotFoundException)
{
// https://stackoverflow.com/questions/47848111/how-should-i-fetch-timezoneinfo-in-a-platform-agnostic-way
// should be natively supported soon https://github.com/dotnet/runtime/issues/18644
_easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
_easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
}
}

Expand Down
5 changes: 3 additions & 2 deletions Jint.Tests/Runtime/InteropTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2809,8 +2809,9 @@ public void ShouldBeAbleToHandleInvalidClrConversionViaCatchClrExceptions()
{
var engine = new Engine(cfg => cfg.CatchClrExceptions());
engine.SetValue("a", new Person());
var ex = Assert.Throws<JavaScriptException>(() => engine.Execute("a.age = \"It won't work, but it's normal\""));
Assert.Equal("Input string was not in a correct format.", ex.Message);
var ex = Assert.Throws<JavaScriptException>(() => engine.Execute("a.age = 'It will not work, but it is normal'"));
Assert.Contains("input string ", ex.Message, StringComparison.OrdinalIgnoreCase);
Assert.Contains(" was not in a correct format", ex.Message, StringComparison.OrdinalIgnoreCase);
}

[Fact]
Expand Down
9 changes: 9 additions & 0 deletions Jint/Extensions/Polyfills.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
using System.Runtime.CompilerServices;

namespace Jint;

internal static class Polyfills
{
#if NETFRAMEWORK || NETSTANDARD2_0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool Contains(this string source, char c) => source.IndexOf(c) != -1;
#endif

#if NETFRAMEWORK
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool Contains(this ReadOnlySpan<string> source, string c) => source.IndexOf(c) != -1;
#endif

#if NETFRAMEWORK || NETSTANDARD2_0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool StartsWith(this string source, char c) => source.Length > 0 && source[0] == c;
#endif
}
44 changes: 44 additions & 0 deletions Jint/Extensions/SearchValues.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#if !NET8_0_OR_GREATER

using System.Runtime.CompilerServices;

namespace System.Buffers;

internal static class SearchValues
{
internal static SearchValues<char> Create(string input) => new(input.AsSpan());
internal static SearchValues<char> Create(ReadOnlySpan<char> input) => new(input);
}

internal sealed class SearchValues<T>
{
private readonly bool[] _data;
private readonly char _min;
private readonly char _max;

internal SearchValues(ReadOnlySpan<char> input)
{
_min = char.MaxValue;
_max = char.MinValue;
foreach (var c in input)
{
_min = (char) Math.Min(_min, c);
_max = (char) Math.Max(_max, c);
}

_data = new bool[_max - _min + 1];
foreach (var c in input)
{
_data[c - _min] = true;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Contains(char c)
{
var i = (uint) (c - _min);
var temp = _data;
return i < temp.Length && temp[i];
}
}
#endif
4 changes: 2 additions & 2 deletions Jint/Jint.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NeutralLanguage>en-US</NeutralLanguage>
<TargetFrameworks>net462;netstandard2.0;netstandard2.1;net6.0</TargetFrameworks>
<TargetFrameworks>net462;netstandard2.0;netstandard2.1;net6.0;net8.0</TargetFrameworks>

<AssemblyOriginatorKeyFile>Jint.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
Expand All @@ -21,7 +21,7 @@

</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'netstandard2.1' ">
<PropertyGroup Condition=" '$(TargetFramework)' != 'net462' and '$(TargetFramework)' != 'netstandard2.0' ">
<DefineConstants>$(DefineConstants);SUPPORTS_SPAN_PARSE;SUPPORTS_WEAK_TABLE_ADD_OR_UPDATE;SUPPORTS_WEAK_TABLE_CLEAR</DefineConstants>
</PropertyGroup>

Expand Down
27 changes: 15 additions & 12 deletions Jint/Native/Global/GlobalObject.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Buffers;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -272,12 +273,11 @@ public static JsValue IsFinite(JsValue thisObject, JsValue[] arguments)
return true;
}

private static readonly string UriReserved = new (new [] { ';', '/', '?', ':', '@', '&', '=', '+', '$', ',' });
private static readonly string UriUnescaped = new(new [] { '-', '_', '.', '!', '~', '*', '\'', '(', ')' });
private static readonly string UnescapedUriSet = UriReserved + UriUnescaped + '#';
private static readonly string ReservedUriSet = UriReserved + '#';

private const string HexaMap = "0123456789ABCDEF";
private const string UriReservedString = ";/?:@&=+$,";
private const string UriUnescapedString = "-_.!~*'()";
private static readonly SearchValues<char> UriUnescaped = SearchValues.Create(UriUnescapedString);
private static readonly SearchValues<char> UnescapedUriSet = SearchValues.Create(UriReservedString + UriUnescapedString + '#');
private static readonly SearchValues<char> ReservedUriSet = SearchValues.Create(UriReservedString + '#');

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsValidHexaChar(char c) => Uri.IsHexDigit(c);
Expand Down Expand Up @@ -309,13 +309,15 @@ public JsValue EncodeUriComponent(JsValue thisObject, JsValue[] arguments)
return Encode(uriString, UriUnescaped);
}

private JsValue Encode(string uriString, string unescapedUriSet)
private JsValue Encode(string uriString, SearchValues<char> unescapedUriSet)
{
const string HexaMap = "0123456789ABCDEF";

var strLen = uriString.Length;

_stringBuilder.EnsureCapacity(uriString.Length);
_stringBuilder.Clear();
var buffer = new byte[4];
Span<byte> buffer = stackalloc byte[4];

for (var k = 0; k < strLen; k++)
{
Expand Down Expand Up @@ -421,7 +423,7 @@ public JsValue DecodeUriComponent(JsValue thisObject, JsValue[] arguments)
return Decode(componentString, null);
}

private JsValue Decode(string uriString, string? reservedSet)
private JsValue Decode(string uriString, SearchValues<char>? reservedSet)
{
var strLen = uriString.Length;

Expand Down Expand Up @@ -463,7 +465,7 @@ private JsValue Decode(string uriString, string? reservedSet)
{
C = (char)B;
#pragma warning disable CA2249
if (reservedSet == null || reservedSet.IndexOf(C) == -1)
if (reservedSet == null || !reservedSet.Contains(C))
#pragma warning restore CA2249
{
_stringBuilder.Append(C);
Expand Down Expand Up @@ -589,12 +591,13 @@ private static bool IsDigit(char c, int radix, out int result)
return tmp < radix;
}

private static readonly SearchValues<char> EscapeAllowList = SearchValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_ + -./");

/// <summary>
/// http://www.ecma-international.org/ecma-262/5.1/#sec-B.2.1
/// </summary>
public JsValue Escape(JsValue thisObject, JsValue[] arguments)
{
const string AllowList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_ + -./";
var uriString = TypeConverter.ToString(arguments.At(0));

var strLen = uriString.Length;
Expand All @@ -605,7 +608,7 @@ public JsValue Escape(JsValue thisObject, JsValue[] arguments)
for (var k = 0; k < strLen; k++)
{
var c = uriString[k];
if (AllowList.Contains(c))
if (EscapeAllowList.Contains(c))
{
_stringBuilder.Append(c);
}
Expand Down
Loading