diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/Managed_Resource.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/Managed_Resource.enso index 35701ebfdc74..9312b0a121b6 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/Managed_Resource.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/Managed_Resource.enso @@ -58,11 +58,15 @@ type Managed_Resource ADVANCED Executes the provided action on the resource managed by the managed - resource object. + resource object. The action is only invoked if the managed resource + has not yet been finalized. Arguments: - action: The action that will be applied to the resource managed by resource. + Returns: + Value returned from the `action` or `Nothing` if the managed resource + was already finalized with : (Any -> Any) -> Any with self ~action = @Builtin_Method "Managed_Resource.with" diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/resource/WithNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/resource/WithNode.java index 2dd940690f4c..1f61fab30186 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/resource/WithNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/resource/WithNode.java @@ -6,7 +6,6 @@ import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.callable.InvokeCallableNode; import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.ResourceManager; import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo; import org.enso.interpreter.runtime.data.ManagedResource; import org.enso.interpreter.runtime.state.State; @@ -33,12 +32,17 @@ static WithNode build() { @Specialization Object doWith(State state, VirtualFrame frame, ManagedResource self, Object action) { - ResourceManager resourceManager = EnsoContext.get(this).getResourceManager(); - resourceManager.park(self); - try { - return invokeCallableNode.execute(action, frame, state, new Object[] {self.getResource()}); - } finally { - resourceManager.unpark(self); + var ctx = EnsoContext.get(this); + var resourceManager = ctx.getResourceManager(); + if (self.getPhantomReference().refersTo(self)) { + resourceManager.park(self); + try { + return invokeCallableNode.execute(action, frame, state, new Object[] {self.getResource()}); + } finally { + resourceManager.unpark(self); + } + } else { + return ctx.getBuiltins().nothing(); } } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/ResourceManager.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/ResourceManager.java index b8295c6b9457..78c8bb26937f 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/ResourceManager.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/ResourceManager.java @@ -408,6 +408,7 @@ private Item( @CompilerDirectives.TruffleBoundary private void finalizeNow(EnsoContext context) { try { + clear(); InteropLibrary.getUncached(finalizer).execute(finalizer, underlying); } catch (Exception e) { context.getErr().println("Exception in finalizer: " + e.getMessage()); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java index 424eac477f3c..826e5554e788 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java @@ -1,5 +1,6 @@ package org.enso.interpreter.runtime.data; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.interop.InteropLibrary; @@ -12,7 +13,27 @@ import org.enso.interpreter.runtime.callable.function.Function; import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; -/** A runtime representation of a managed resource. */ +/** + * An Enso runtime representation of a managed resource. + * + *
Instance of this class is convoluted with instances playing various roles: + * + *