Skip to content

Commit 963c069

Browse files
committed
Now store references to extand JavascriptFunctions in weak references, so they won't take so much space when not needed anymore.
1 parent f9ffa44 commit 963c069

File tree

6 files changed

+27
-6
lines changed

6 files changed

+27
-6
lines changed

Source/Noesis.Javascript/JavaScript.Net.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
</ItemDefinitionGroup>
154154
<ItemGroup>
155155
<Reference Include="System" />
156+
<Reference Include="System.Core" />
156157
<Reference Include="System.Data" />
157158
<Reference Include="System.Xml" />
158159
</ItemGroup>

Source/Noesis.Javascript/JavascriptContext.cpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ JavascriptContext::JavascriptContext()
163163
isolate->SetFatalErrorHandler(FatalErrorCallback);
164164

165165
mExternals = gcnew System::Collections::Generic::Dictionary<System::Object ^, WrappedJavascriptExternal>();
166-
mFunctions = gcnew System::Collections::Generic::List<System::Object ^>();
166+
mFunctions = gcnew System::Collections::Generic::HashSet<System::WeakReference ^>();
167167
HandleScope scope(isolate);
168168
mContext = new Persistent<Context>(isolate, Context::New(isolate));
169169
terminateRuns = false;
@@ -178,8 +178,11 @@ JavascriptContext::~JavascriptContext()
178178
v8::Isolate::Scope isolate_scope(isolate);
179179
for each (WrappedJavascriptExternal wrapped in mExternals->Values)
180180
delete wrapped.Pointer;
181-
for each (JavascriptFunction^ f in mFunctions)
182-
delete f;
181+
for each (System::WeakReference^ f in mFunctions) {
182+
JavascriptFunction ^function = safe_cast<JavascriptFunction ^>(f->Target);
183+
if (function != nullptr)
184+
delete function;
185+
}
183186
delete mContext;
184187
delete mExternals;
185188
delete mFunctions;
@@ -499,7 +502,9 @@ JavascriptContext::GetObjectWrapperTemplate()
499502
void
500503
JavascriptContext::RegisterFunction(System::Object^ f)
501504
{
502-
mFunctions->Add(f);
505+
// Note that while we do store WeakReferences, we never clean up this hashtable,
506+
// so it will just grow and grow.
507+
mFunctions->Add(gcnew System::WeakReference(f));
503508
}
504509

505510
////////////////////////////////////////////////////////////////////////////////////////////////////

Source/Noesis.Javascript/JavascriptContext.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public ref class JavascriptContext: public System::IDisposable
220220

221221
// Stores every JavascriptFunction we create. Ensures we dispose of them
222222
// all.
223-
System::Collections::Generic::List<System::Object ^> ^mFunctions;
223+
System::Collections::Generic::HashSet<System::WeakReference ^> ^mFunctions;
224224

225225
// See comment for TerminateExecution().
226226
bool terminateRuns;

Source/Noesis.Javascript/JavascriptFunction.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,19 @@ JavascriptFunction::~JavascriptFunction()
3131
{
3232
if (mContext)
3333
{
34-
JavascriptScope scope(mContext);
34+
JavascriptScope scope(mContext);
3535
mFuncHandle->Reset();
3636
}
3737
delete mFuncHandle;
3838
mFuncHandle = nullptr;
3939
}
4040
}
4141

42+
JavascriptFunction::!JavascriptFunction()
43+
{
44+
delete this;
45+
}
46+
4247
System::Object^ JavascriptFunction::Call(... cli::array<System::Object^>^ args)
4348
{
4449
if (mFuncHandle == nullptr)

Source/Noesis.Javascript/JavascriptFunction.h

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public ref class JavascriptFunction
2626
public:
2727
JavascriptFunction(v8::Handle<v8::Object> iFunction, JavascriptContext^ context);
2828
~JavascriptFunction();
29+
!JavascriptFunction();
2930

3031
System::Object^ Call(... cli::array<System::Object^>^ args);
3132

Tests/Noesis.Javascript.Tests/JavascriptFunctionTests.cs

+9
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ public void CannotUseAFunctionWhenItsContextIsDisposed()
8686
Action action = () => function.Call();
8787
action.ShouldThrowExactly<JavascriptException>().WithMessage("This function's owning JavascriptContext has been disposed");
8888
}
89+
90+
[TestMethod]
91+
public void DisposingAFunction()
92+
{
93+
using (var context = new JavascriptContext()) {
94+
var function = context.Run("() => { throw new Error('test'); }") as JavascriptFunction;
95+
function.Dispose();
96+
}
97+
}
8998
}
9099

91100
class CollectionWrapper

0 commit comments

Comments
 (0)