|
@@ -2,6 +2,7 @@
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.CompilerServices;
|
|
using Jint.Collections;
|
|
using Jint.Collections;
|
|
using Jint.Native;
|
|
using Jint.Native;
|
|
|
|
+using Jint.Native.Disposable;
|
|
|
|
|
|
namespace Jint.Runtime.Environments;
|
|
namespace Jint.Runtime.Environments;
|
|
|
|
|
|
@@ -13,6 +14,7 @@ internal class DeclarativeEnvironment : Environment
|
|
{
|
|
{
|
|
internal HybridDictionary<Binding>? _dictionary;
|
|
internal HybridDictionary<Binding>? _dictionary;
|
|
internal readonly bool _catchEnvironment;
|
|
internal readonly bool _catchEnvironment;
|
|
|
|
+ private DisposeCapability? _disposeCapability;
|
|
|
|
|
|
public DeclarativeEnvironment(Engine engine, bool catchEnvironment = false) : base(engine)
|
|
public DeclarativeEnvironment(Engine engine, bool catchEnvironment = false) : base(engine)
|
|
{
|
|
{
|
|
@@ -35,16 +37,24 @@ internal class DeclarativeEnvironment : Environment
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- internal void CreateMutableBindingAndInitialize(Key name, bool canBeDeleted, JsValue value)
|
|
|
|
|
|
+ internal void CreateMutableBindingAndInitialize(Key name, bool canBeDeleted, JsValue value, DisposeHint hint)
|
|
{
|
|
{
|
|
_dictionary ??= new HybridDictionary<Binding>();
|
|
_dictionary ??= new HybridDictionary<Binding>();
|
|
_dictionary[name] = new Binding(value, canBeDeleted, mutable: true, strict: false);
|
|
_dictionary[name] = new Binding(value, canBeDeleted, mutable: true, strict: false);
|
|
|
|
+ if (hint != DisposeHint.Normal)
|
|
|
|
+ {
|
|
|
|
+ HandleDisposal(value, hint);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- internal void CreateImmutableBindingAndInitialize(Key name, bool strict, JsValue value)
|
|
|
|
|
|
+ internal void CreateImmutableBindingAndInitialize(Key name, bool strict, JsValue value, DisposeHint hint)
|
|
{
|
|
{
|
|
_dictionary ??= new HybridDictionary<Binding>();
|
|
_dictionary ??= new HybridDictionary<Binding>();
|
|
_dictionary[name] = new Binding(value, canBeDeleted: false, mutable: false, strict);
|
|
_dictionary[name] = new Binding(value, canBeDeleted: false, mutable: false, strict);
|
|
|
|
+ if (hint != DisposeHint.Normal)
|
|
|
|
+ {
|
|
|
|
+ HandleDisposal(value, hint);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
internal sealed override void CreateMutableBinding(Key name, bool canBeDeleted = false)
|
|
internal sealed override void CreateMutableBinding(Key name, bool canBeDeleted = false)
|
|
@@ -59,10 +69,14 @@ internal class DeclarativeEnvironment : Environment
|
|
_dictionary.CreateImmutableBinding(name, strict);
|
|
_dictionary.CreateImmutableBinding(name, strict);
|
|
}
|
|
}
|
|
|
|
|
|
- internal sealed override void InitializeBinding(Key name, JsValue value)
|
|
|
|
|
|
+ internal sealed override void InitializeBinding(Key name, JsValue value, DisposeHint hint)
|
|
{
|
|
{
|
|
_dictionary ??= new HybridDictionary<Binding>();
|
|
_dictionary ??= new HybridDictionary<Binding>();
|
|
_dictionary.SetOrUpdateValue(name, static (current, value) => current.ChangeValue(value), value);
|
|
_dictionary.SetOrUpdateValue(name, static (current, value) => current.ChangeValue(value), value);
|
|
|
|
+ if (hint != DisposeHint.Normal)
|
|
|
|
+ {
|
|
|
|
+ HandleDisposal(value, hint);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
internal sealed override void SetMutableBinding(BindingName name, JsValue value, bool strict) => SetMutableBinding(name.Key, value, strict);
|
|
internal sealed override void SetMutableBinding(BindingName name, JsValue value, bool strict) => SetMutableBinding(name.Key, value, strict);
|
|
@@ -169,6 +183,8 @@ internal class DeclarativeEnvironment : Environment
|
|
|
|
|
|
internal override JsValue GetThisBinding() => Undefined;
|
|
internal override JsValue GetThisBinding() => Undefined;
|
|
|
|
|
|
|
|
+ internal sealed override Completion DisposeResources(Completion c) => _disposeCapability?.DisposeResources(c) ?? c;
|
|
|
|
+
|
|
public void Clear()
|
|
public void Clear()
|
|
{
|
|
{
|
|
_dictionary = null;
|
|
_dictionary = null;
|
|
@@ -185,6 +201,13 @@ internal class DeclarativeEnvironment : Environment
|
|
target[bn] = new Binding(lastValue.Value, canBeDeleted: false, mutable: true, strict: false);
|
|
target[bn] = new Binding(lastValue.Value, canBeDeleted: false, mutable: true, strict: false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ [MethodImpl(MethodImplOptions.NoInlining)]
|
|
|
|
+ private void HandleDisposal(JsValue value, DisposeHint hint)
|
|
|
|
+ {
|
|
|
|
+ _disposeCapability ??= new DisposeCapability(_engine);
|
|
|
|
+ _disposeCapability.AddDisposableResource(value, hint);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
internal static class DictionaryExtensions
|
|
internal static class DictionaryExtensions
|