Skip to content

Commit

Permalink
Propagate the ExpressionNode down for use in findConversionNode
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Nov 14, 2024
1 parent 1999523 commit 04d3835
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.oracle.truffle.api.nodes.ExplodeLoop;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.runtime.data.EnsoMultiValue;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
Expand All @@ -30,12 +31,12 @@ Object findDirectMatch(VirtualFrame frame, Object value) {

@Override
@ExplodeLoop
Object executeCheckOrConversion(VirtualFrame frame, Object value) {
Object executeCheckOrConversion(VirtualFrame frame, Object value, ExpressionNode expr) {
var values = new Object[checks.length];
var valueTypes = new Type[checks.length];
var at = 0;
for (var n : checks) {
var result = n.executeCheckOrConversion(frame, value);
var result = n.executeCheckOrConversion(frame, value, expr);
if (result == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public Object execute(VirtualFrame frame) {
assert args[0] instanceof Function fn && fn.isThunk();
java.lang.Object raw =
evalThunk.executeThunk(frame, args[0], state, BaseNode.TailStatus.NOT_TAIL);
java.lang.Object result = check.handleCheckOrConversion(frame, raw);
java.lang.Object result = check.handleCheckOrConversion(frame, raw, null);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.oracle.truffle.api.nodes.ExplodeLoop;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.enso.interpreter.node.ExpressionNode;

final class OneOfNode extends TypeCheckValueNode {

Expand All @@ -28,13 +29,13 @@ final Object findDirectMatch(VirtualFrame frame, Object value) {

@Override
@ExplodeLoop
Object executeCheckOrConversion(VirtualFrame frame, Object value) {
Object executeCheckOrConversion(VirtualFrame frame, Object value, ExpressionNode expr) {
java.lang.Object direct = findDirectMatch(frame, value);
if (direct != null) {
return direct;
}
for (org.enso.interpreter.node.typecheck.TypeCheckValueNode n : checks) {
java.lang.Object result = n.executeCheckOrConversion(frame, value);
java.lang.Object result = n.executeCheckOrConversion(frame, value, expr);
if (result != null) {
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ExpressionNode getOriginal() {
@Override
public Object executeGeneric(VirtualFrame frame) {
java.lang.Object value = original.executeGeneric(frame);
java.lang.Object result = check.handleCheckOrConversion(frame, value);
java.lang.Object result = check.handleCheckOrConversion(frame, value, original);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeUtil;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.node.EnsoRootNode;
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.node.callable.ApplicationNode;
import org.enso.interpreter.node.callable.InvokeCallableNode;
import org.enso.interpreter.node.callable.argument.ReadArgumentNode;
import org.enso.interpreter.node.expression.builtin.meta.IsValueOfTypeNode;
import org.enso.interpreter.node.expression.literal.LiteralNode;
import org.enso.interpreter.runtime.EnsoContext;
Expand Down Expand Up @@ -42,24 +41,27 @@ abstract class TypeCheckNode extends TypeCheckValueNode {
this.expectedType = expectedType;
}

abstract Object executeCheckOrConversion(VirtualFrame frame, Object value);
abstract Object executeCheckOrConversion(
VirtualFrame frame, Object value, ExpressionNode valueSource);

@Specialization
Object doPanicSentinel(VirtualFrame frame, PanicSentinel panicSentinel) {
Object doPanicSentinel(VirtualFrame frame, PanicSentinel panicSentinel, ExpressionNode ignore) {
throw panicSentinel;
}

@Specialization
Object doUnresolvedConstructor(
VirtualFrame frame,
UnresolvedConstructor unresolved,
ExpressionNode ignore,
@Cached UnresolvedConstructor.ConstructNode construct) {
var state = Function.ArgumentsHelper.getState(frame.getArguments());
return construct.execute(frame, state, expectedType, unresolved);
}

@Specialization(rewriteOn = InvalidAssumptionException.class)
Object doCheckNoConversionNeeded(VirtualFrame frame, Object v) throws InvalidAssumptionException {
Object doCheckNoConversionNeeded(VirtualFrame frame, Object v, ExpressionNode ignore)
throws InvalidAssumptionException {
var ret = findDirectMatch(frame, v);
if (ret != null) {
return ret;
Expand All @@ -74,17 +76,22 @@ Object doCheckNoConversionNeeded(VirtualFrame frame, Object v) throws InvalidAss
Object doWithConversionCached(
VirtualFrame frame,
Object v,
ExpressionNode valueSource,
@Cached.Shared("typeOfNode") @Cached TypeOfNode typeOfNode,
@Cached(value = "findType(typeOfNode, v)", dimensions = 1) Type[] cachedType,
@Cached("findConversionNode(cachedType)") ApplicationNode convertNode) {
@Cached("findConversionNode(valueSource, cachedType)") ApplicationNode convertNode) {
return handleWithConversion(frame, v, convertNode);
}

@Specialization(replaces = "doWithConversionCached")
Object doWithConversionUncached(
VirtualFrame frame, Object v, @Cached.Shared("typeOfNode") @Cached TypeOfNode typeOfNode) {
VirtualFrame frame,
Object v,
ExpressionNode expr,
@Cached.Shared("typeOfNode") @Cached TypeOfNode typeOfNode) {
var type = findType(typeOfNode, v);
return doWithConversionUncachedBoundary(frame == null ? null : frame.materialize(), v, type);
return doWithConversionUncachedBoundary(
frame == null ? null : frame.materialize(), v, expr, type);
}

@ExplodeLoop
Expand Down Expand Up @@ -134,38 +141,26 @@ private Pair<Function, Type> findConversion(Type from) {
return null;
}

ApplicationNode findConversionNode(Type[] allTypes) {
ApplicationNode findConversionNode(ExpressionNode valueNode, Type[] allTypes) {
if (valueNode == null) {
return null;
}
if (allTypes == null) {
allTypes = new Type[] {null};
}
for (var from : allTypes) {
var convAndType = findConversion(from);

if (convAndType != null) {
if (NodeUtil.findParent(this, ReadArgumentNode.class) instanceof ReadArgumentNode ran) {
CompilerAsserts.neverPartOfCompilation();
var convNode = LiteralNode.build(convAndType.getLeft());
var intoNode = LiteralNode.build(convAndType.getRight());
var valueNode = ran.copyWithoutCheck();
var args =
new CallArgument[] {
new CallArgument(null, intoNode), new CallArgument(null, valueNode)
};
return ApplicationNode.build(
convNode, args, InvokeCallableNode.DefaultsExecutionMode.EXECUTE);
} else if (NodeUtil.findParent(this, TypeCheckExpressionNode.class)
instanceof TypeCheckExpressionNode tcen) {
CompilerAsserts.neverPartOfCompilation();
var convNode = LiteralNode.build(convAndType.getLeft());
var intoNode = LiteralNode.build(convAndType.getRight());
var valueNode = tcen.getOriginal();
var args =
new CallArgument[] {
new CallArgument(null, intoNode), new CallArgument(null, valueNode)
};
return ApplicationNode.build(
convNode, args, InvokeCallableNode.DefaultsExecutionMode.EXECUTE);
}
CompilerAsserts.neverPartOfCompilation();
var convNode = LiteralNode.build(convAndType.getLeft());
var intoNode = LiteralNode.build(convAndType.getRight());
var args =
new CallArgument[] {
new CallArgument(null, intoNode), new CallArgument(null, valueNode)
};
return ApplicationNode.build(
convNode, args, InvokeCallableNode.DefaultsExecutionMode.EXECUTE);
}
}
return null;
Expand Down Expand Up @@ -207,8 +202,9 @@ private Object handleWithConversion(VirtualFrame frame, Object v, ApplicationNod
}

@CompilerDirectives.TruffleBoundary
private Object doWithConversionUncachedBoundary(MaterializedFrame frame, Object v, Type[] type) {
var convertNode = findConversionNode(type);
private Object doWithConversionUncachedBoundary(
MaterializedFrame frame, Object v, ExpressionNode expr, Type[] type) {
var convertNode = findConversionNode(expr, type);
return handleWithConversion(frame, v, convertNode);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ public static ExpressionNode wrap(ExpressionNode original, TypeCheckValueNode ch
* @return {@code null} when the check isn't satisfied and conversion isn't possible or non-{@code
* null} value that can be used as a result
*/
public final Object handleCheckOrConversion(VirtualFrame frame, Object value) {
var result = executeCheckOrConversion(frame, value);
public final Object handleCheckOrConversion(
VirtualFrame frame, Object value, ExpressionNode expr) {
var result = executeCheckOrConversion(frame, value, expr);
if (result == null) {
throw panicAtTheEnd(value);
}
Expand All @@ -60,7 +61,8 @@ public final Object handleCheckOrConversion(VirtualFrame frame, Object value) {

abstract Object findDirectMatch(VirtualFrame frame, Object value);

abstract Object executeCheckOrConversion(VirtualFrame frame, Object value);
abstract Object executeCheckOrConversion(
VirtualFrame frame, Object value, ExpressionNode valueNode);

abstract String expectedTypeMessage();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ private CheckFieldSetterNode(

@Override
public void execute(Atom atom, Object value) {
var valueOrConvertedValue = checkNode.handleCheckOrConversion(null, value);
var valueOrConvertedValue = checkNode.handleCheckOrConversion(null, value, null);
setterNode.execute(atom, valueOrConvertedValue);
}
}
Expand Down

0 comments on commit 04d3835

Please sign in to comment.