1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- using Jint.Native.Object;
- using Jint.Runtime;
- using Jint.Runtime.Interop;
- namespace Jint.Native.Disposable;
- internal enum DisposableState
- {
- Pending,
- Disposed,
- }
- internal sealed class DisposableStack : ObjectInstance
- {
- internal readonly DisposeHint _hint;
- private DisposeCapability _disposeCapability;
- public DisposableStack(Engine engine, DisposeHint hint) : base(engine)
- {
- _hint = hint;
- State = DisposableState.Pending;
- _disposeCapability = new DisposeCapability(engine);
- }
- public DisposableState State { get; private set; }
- public JsValue Dispose()
- {
- if (State == DisposableState.Disposed)
- {
- return Undefined;
- }
- State = DisposableState.Disposed;
- var completion = _disposeCapability.DisposeResources(new Completion(CompletionType.Normal, Undefined, _engine.GetLastSyntaxElement()));
- if (completion.Type == CompletionType.Throw)
- {
- ExceptionHelper.ThrowJavaScriptException(_engine, completion.Value, completion);
- }
- return completion.Value;
- }
- public void Defer(JsValue onDispose)
- {
- AddDisposableResource(Undefined, _hint, onDispose.GetCallable(_engine.Realm));
- }
- public JsValue Use(JsValue value)
- {
- AddDisposableResource(value, _hint);
- return value;
- }
- public JsValue Adopt(JsValue value, JsValue onDispose)
- {
- AssertNotDisposed();
- var callable = onDispose.GetCallable(_engine.Realm);
- JsCallDelegate closure = (_, _) =>
- {
- callable.Call(Undefined, value);
- return Undefined;
- };
- var f = new ClrFunction(_engine, string.Empty, closure);
- AddDisposableResource(Undefined, DisposeHint.Sync, f);
- return value;
- }
- public JsValue Move(DisposableStack newDisposableStack)
- {
- AssertNotDisposed();
- newDisposableStack.State = DisposableState.Pending;
- newDisposableStack._disposeCapability = this._disposeCapability;
- this._disposeCapability = new DisposeCapability(_engine);
- State = DisposableState.Disposed;
- return newDisposableStack;
- }
- private void AddDisposableResource(JsValue v, DisposeHint hint, ICallable? method = null)
- {
- AssertNotDisposed();
- _disposeCapability.AddDisposableResource(v, hint, method);
- }
- private void AssertNotDisposed()
- {
- if (State == DisposableState.Disposed)
- {
- ExceptionHelper.ThrowReferenceError(_engine.Realm, "Stack already disposed.");
- }
- }
- }
|