-
Notifications
You must be signed in to change notification settings - Fork 323
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Enso-specific assert (#7883)
Implement Enso-specific assert - `Runtime.assert` that works like asserts in any other runtime. # Important Notes - Enso-specific assertions are enabled when JVM assertions are enabled, or when `ENSO_ENABLE_ASSERTIONS` env var is not empty (See https://github.com/enso-org/enso/blob/72cd8361cb337d34f7e917c0a6af18ea48e0e90b/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java#L139)
- Loading branch information
Showing
13 changed files
with
453 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
...time/src/main/java/org/enso/interpreter/node/expression/builtin/error/AssertionError.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.enso.interpreter.node.expression.builtin.error; | ||
|
||
import java.util.List; | ||
import org.enso.interpreter.dsl.BuiltinType; | ||
import org.enso.interpreter.node.expression.builtin.UniquelyConstructibleBuiltin; | ||
|
||
@BuiltinType | ||
public final class AssertionError extends UniquelyConstructibleBuiltin { | ||
@Override | ||
protected String getConstructorName() { | ||
return "Error"; | ||
} | ||
|
||
@Override | ||
protected List<String> getConstructorParamNames() { | ||
return List.of("message"); | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
...untime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/AssertNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package org.enso.interpreter.node.expression.builtin.runtime; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; | ||
import com.oracle.truffle.api.dsl.Cached; | ||
import com.oracle.truffle.api.dsl.Idempotent; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.interop.InteropLibrary; | ||
import com.oracle.truffle.api.interop.UnsupportedMessageException; | ||
import com.oracle.truffle.api.nodes.Node; | ||
import com.oracle.truffle.api.profiles.BranchProfile; | ||
import org.enso.interpreter.dsl.BuiltinMethod; | ||
import org.enso.interpreter.dsl.Suspend; | ||
import org.enso.interpreter.node.BaseNode; | ||
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode; | ||
import org.enso.interpreter.node.expression.builtin.meta.TypeOfNode; | ||
import org.enso.interpreter.runtime.EnsoContext; | ||
import org.enso.interpreter.runtime.callable.atom.Atom; | ||
import org.enso.interpreter.runtime.data.text.Text; | ||
import org.enso.interpreter.runtime.error.PanicException; | ||
import org.enso.interpreter.runtime.state.State; | ||
|
||
@BuiltinMethod( | ||
type = "Runtime", | ||
name = "assert_builtin", | ||
description = "Asserts that the given condition is true", | ||
autoRegister = false) | ||
public abstract class AssertNode extends Node { | ||
|
||
public static AssertNode build() { | ||
return AssertNodeGen.create(); | ||
} | ||
|
||
public abstract Object execute(VirtualFrame frame, State state, @Suspend Object action, Text msg); | ||
|
||
@Idempotent | ||
protected boolean isAssertionsEnabled() { | ||
return EnsoContext.get(this).isAssertionsEnabled(); | ||
} | ||
|
||
@Specialization(guards = "!isAssertionsEnabled()") | ||
Object doAssertionsDisabled(VirtualFrame frame, State state, Object action, Text msg) { | ||
return EnsoContext.get(this).getNothing(); | ||
} | ||
|
||
@Specialization(replaces = "doAssertionsDisabled") | ||
Object doAssertionsEnabled( | ||
VirtualFrame frame, | ||
State state, | ||
Object action, | ||
Text msg, | ||
@Cached("create()") ThunkExecutorNode thunkExecutorNode, | ||
@Cached BranchProfile resultIsNotAtomProfile) { | ||
var ctx = EnsoContext.get(this); | ||
var builtins = ctx.getBuiltins(); | ||
Object actionRes = | ||
thunkExecutorNode.executeThunk(frame, action, state, BaseNode.TailStatus.TAIL_DIRECT); | ||
if (actionRes instanceof Atom resAtom) { | ||
var isTrue = resAtom.getConstructor() == builtins.bool().getTrue(); | ||
if (isTrue) { | ||
return ctx.getNothing(); | ||
} else { | ||
throw new PanicException(builtins.error().makeAssertionError(msg), this); | ||
} | ||
} else { | ||
resultIsNotAtomProfile.enter(); | ||
return checkResultSlowPath(actionRes, msg); | ||
} | ||
} | ||
|
||
@TruffleBoundary | ||
private Object checkResultSlowPath(Object actionRes, Text msg) { | ||
var ctx = EnsoContext.get(this); | ||
var builtins = ctx.getBuiltins(); | ||
try { | ||
if (InteropLibrary.getUncached().asBoolean(actionRes)) { | ||
return ctx.getNothing(); | ||
} else { | ||
throw new PanicException(builtins.error().makeAssertionError(msg), this); | ||
} | ||
} catch (UnsupportedMessageException e) { | ||
var typeError = | ||
builtins | ||
.error() | ||
.makeTypeError( | ||
builtins.bool().getType(), | ||
TypeOfNode.getUncached().execute(actionRes), | ||
"Result of assert action"); | ||
throw new PanicException(typeError, this); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.