Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
03d2e54
Initial plan
Copilot Nov 17, 2025
25c2942
Update projects to .NET 8 - migrate C++/CLI and convert C# projects t…
Copilot Nov 17, 2025
3564dc7
Disable ImplicitUsings and handle AppDomain test for .NET 8 compatibi…
Copilot Nov 17, 2025
9ada44b
Add documentation for .NET 8 migration
Copilot Nov 17, 2025
c1f735a
Add validation report for .NET 8 migration
Copilot Nov 17, 2025
ce2ab18
Update configuration settings
bwinsley Nov 17, 2025
afcc0f9
Update Tests to use new api
bwinsley Nov 17, 2025
fb6309e
upgrade to net8
bwinsley Nov 18, 2025
11c3087
remove md files
bwinsley Nov 19, 2025
bb8a340
Fix garbage collection issues
bwinsley Nov 19, 2025
cb444b8
Clean up for warnings
bwinsley Nov 19, 2025
e1b65b0
update memory leak tests
bwinsley Nov 19, 2025
912ff2e
make mExternals protected again
bwinsley Nov 19, 2025
b711a17
Enable nullables
bwinsley Nov 19, 2025
f53f091
Fix typo and update git tracking
bwinsley Nov 20, 2025
8781813
Restore mExternals dictionary cleanup
bwinsley Nov 20, 2025
51059b4
Fix memory leak issues with JavascriptFunction
bwinsley Nov 21, 2025
58ec6d4
Fix dispose of function test by ensuring scope is entered before crea…
bwinsley Nov 21, 2025
c548315
Minor clean ups
bwinsley Nov 21, 2025
b1b412a
Add forward declaration
bwinsley Nov 21, 2025
9efebec
Update build configurations to be specific so that you can batch rebu…
bwinsley Nov 21, 2025
e7fd887
Fix javascript method invoking
bwinsley Dec 4, 2025
e30d5b9
Clean up, add comments, remove unneeded paths
bwinsley Dec 11, 2025
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
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,12 @@ _ReSharper*/
*.sdf
*.opensdf
TestResult.xml
/.vs
.vs/
/Source/Noesis.Javascript/packages

# NuGet
.nuget/
packages/
*.nupkg
*.snupkg

103 changes: 18 additions & 85 deletions Fiddling/Fiddling.csproj
Original file line number Diff line number Diff line change
@@ -1,99 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Fiddling</RootNamespace>
<AssemblyName>Fiddling</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Platforms>AnyCPU;x64;x86</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

<PropertyGroup Condition="'$(Platform)'=='x64'">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<V8Platform>x64</V8Platform>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<V8Platform>x64</V8Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>

<PropertyGroup Condition="'$(Platform)'=='x86'">
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<V8Platform>Win32</V8Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<V8Platform>Win32</V8Platform>

<PropertyGroup Condition="'$(Platform)'=='AnyCPU'">
<PlatformTarget>x64</PlatformTarget>
<V8Platform>x64</V8Platform>
</PropertyGroup>

<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<ProjectReference Include="..\Source\Noesis.Javascript\JavaScript.Net.vcxproj" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Source\Noesis.Javascript\JavaScript.Net.vcxproj">
<Project>{7ecfed5e-8b33-4065-acbf-ab1050fb0f4c}</Project>
<Name>JavaScript.Net</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8.dll $(ProjectDir)$(OutDir)
copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8_libbase.dll $(ProjectDir)$(OutDir)
copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8_libplatform.dll $(ProjectDir)$(OutDir)
copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\zlib.dll $(ProjectDir)$(OutDir)
copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\icu*.* $(ProjectDir)$(OutDir)
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8.dll $(ProjectDir)$(OutDir)&#xD;&#xA;copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8_libbase.dll $(ProjectDir)$(OutDir)&#xD;&#xA;copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8_libplatform.dll $(ProjectDir)$(OutDir)&#xD;&#xA;copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\zlib.dll $(ProjectDir)$(OutDir)&#xD;&#xA;copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\icu*.* $(ProjectDir)$(OutDir)" />
</Target>
-->
</Project>
82 changes: 54 additions & 28 deletions Fiddling/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Text;
using Noesis.Javascript;

Expand All @@ -15,45 +14,72 @@ class Program
{
public class Product
{
public Product(decimal price)
{
Price = price;
}
public decimal Price { get; set; }
public void DoSomething() { }
public void DoSomethingElse() { }
public IEnumerable<decimal> GetTaxes() => new List<decimal> { 0.01m, 0.02m };
public decimal GetSalesTax(JavascriptFunction callback) => Convert.ToDecimal(callback.Call(Price));
public override string ToString() => Price.ToString();
}

// ...

static void Main(string[] args)
{
using (JavascriptContext context = new JavascriptContext())
{
try
{
// breakpoint here
context.SetConstructor<Product>("Product", (Func<decimal, Product>)(price => new Product(price)));
context.SetParameter("globalProduct", new Product(2));
var result = context.Run($@"
{{
const importantProduct = new Product(3);
let sum = 0;
for (let i = 0; i < 200_000; i++) {{

JavascriptContext.SetFatalErrorHandler(FatalErrorHandler);
using (JavascriptContext context = new JavascriptContext()) {
//int[] ints = new[] { 1, 2, 3 };
//_context.SetParameter("n", ints);
//var result = _context.Run("n[1]");
//Console.WriteLine(result.ToString());
//_context.SetParameter("bozo", new Bozo(ints));
// Commit 1 - creating managed objects from JS
const product = new Product(Math.random());

context.SetParameter("test", new Product() { Price = new decimal(0.333) });
context.Run("test.Price = test.Price * 2");
Console.WriteLine(context.Run("test.Price").ToString());
//context.Run("modified_price = test.Price * 2");
//Console.WriteLine(context.GetParameter("modified_price").ToString()); //returns 0.... not good
// Commit 2 - calling methods on managed objects
product.DoSomething();
product.DoSomething();
product.DoSomethingElse();

// Commits 3 and 4 - using iterators
for (const tax of product.GetTaxes())
{{
sum += tax;
}}

try {
//_context.Run("a=[]; while(true) a.push(0)");
//_context.Run("function f() { f(); } f()");
// Commit 5 - using JS callbacks in managed code without disposing them explicitly
sum += product.GetSalesTax(p => p * 0.19);
// End of scenarios

//while(true) {
// Console.Write("> ");
// var input = Console.ReadLine();
// if (input == "quit")
// break;
// var result = _context.Run(input);
// Console.WriteLine("Result is: `{0}`", result);
//}
} catch (Exception ex) {
string s = (string)ex.Data["V8StackTrace"];
sum += product.Price;
}}
[sum, importantProduct.Price, globalProduct.Price].toString();
}}
");
Console.WriteLine(result);
Console.WriteLine(context.GetParameter("globalProduct"));
// breakpoint here - pre dispose of the context
}
catch (Exception ex)
{
var s = (string)ex.Data["V8StackTrace"]!;
Console.WriteLine(s);
}
//Console.WriteLine(ints[1]);
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
// breakpoint here - after dispose of the context (the garbage collection was only triggered to compare the object count in the memory dump)
}

static void FatalErrorHandler(string a, string b)
Expand All @@ -69,7 +95,7 @@ class Bozo
internal Bozo(Array a) { this.a = a; }
public object this[int i]
{
get { throw new ApplicationException("bozo"); return a.GetValue(i); }
get { throw new ApplicationException("bozo"); }
set { a.SetValue(value, i); }
}
}
Expand Down
3 changes: 0 additions & 3 deletions Fiddling/app.config

This file was deleted.

36 changes: 18 additions & 18 deletions JavaScript.Net.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2020
# Visual Studio Version 17
VisualStudioVersion = 17.14.36705.20 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScript.Net", "Source\Noesis.Javascript\JavaScript.Net.vcxproj", "{7ECFED5E-8B33-4065-ACBF-AB1050FB0F4C}"
EndProject
Expand Down Expand Up @@ -36,28 +36,28 @@ Global
{7ECFED5E-8B33-4065-ACBF-AB1050FB0F4C}.Release|x64.Build.0 = Release|x64
{7ECFED5E-8B33-4065-ACBF-AB1050FB0F4C}.Release|x86.ActiveCfg = Release|Win32
{7ECFED5E-8B33-4065-ACBF-AB1050FB0F4C}.Release|x86.Build.0 = Release|Win32
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|x64.ActiveCfg = Debug|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|x64.Build.0 = Debug|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|Any CPU.ActiveCfg = Debug|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|Any CPU.Build.0 = Debug|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|x64.ActiveCfg = Debug|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|x64.Build.0 = Debug|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|x86.ActiveCfg = Debug|x86
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Debug|x86.Build.0 = Debug|x86
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|Any CPU.Build.0 = Release|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|x64.ActiveCfg = Release|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|x64.Build.0 = Release|Any CPU
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|Any CPU.ActiveCfg = Release|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|Any CPU.Build.0 = Release|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|x64.ActiveCfg = Release|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|x64.Build.0 = Release|x64
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|x86.ActiveCfg = Release|x86
{9E0C9657-BC4C-4A25-B7DD-9C772FC5670D}.Release|x86.Build.0 = Release|x86
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|x64.ActiveCfg = Debug|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|x64.Build.0 = Debug|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|Any CPU.ActiveCfg = Debug|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|Any CPU.Build.0 = Debug|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|x64.ActiveCfg = Debug|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|x64.Build.0 = Debug|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|x86.ActiveCfg = Debug|x86
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Debug|x86.Build.0 = Debug|x86
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|Any CPU.Build.0 = Release|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|x64.ActiveCfg = Release|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|x64.Build.0 = Release|Any CPU
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|Any CPU.ActiveCfg = Release|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|Any CPU.Build.0 = Release|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|x64.ActiveCfg = Release|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|x64.Build.0 = Release|x64
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|x86.ActiveCfg = Release|x86
{1659A790-7DAC-4E1C-B2C8-B51AC6B0AF87}.Release|x86.Build.0 = Release|x86
EndGlobalSection
Expand Down
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,31 @@ when you redistribute Noesis.Javascript.dll then you will get errors
when loading the DLL on some users machines. (Many, but not all users
will already have it.)

Targets: .NET Framework 4.5
Targets: .NET 8

For legacy .NET Framework 4.7.2 support, see previous versions.


Building from Source
====================

Open the .sln file in Visual Studio, use Configuration Manager to switch to platform to x64, and build. I've been working using Visual Studio 2017,
but 2015 will probably work too.
**Requirements:**
* Visual Studio 2022 (17.0+) or Visual Studio 2019 (16.4+)
* .NET 8 SDK
* Windows SDK 10.0 or later

**Steps:**

1. Open the .sln file in Visual Studio
2. Use Configuration Manager to switch the platform to x64
3. Build the solution

The project uses:
* C++/CLI with .NET Core support (`CLRSupport=NetCore`)
* .NET 8 SDK-style projects for C# code
* V8 version 9.8.177.4 via NuGet packages

**Note:** The C++/CLI project requires Windows and Visual Studio with C++/CLI support for .NET Core. This is available in Visual Studio 2019 16.4+ and Visual Studio 2022.

The following warnings are expected:

Expand Down
Loading