Skip to content

Commit

Permalink
Use BuiltinRootNode.ArgNode to extract argument for a builtin method
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Jan 30, 2025
1 parent caec1e6 commit e261e8d
Show file tree
Hide file tree
Showing 25 changed files with 336 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin;

import com.oracle.truffle.api.interop.TruffleObject;
import org.enso.interpreter.dsl.BuiltinType;

@BuiltinType(name = "Standard.Base.Any.Any")
public class Any extends Builtin {
public final class Any extends Builtin {
public Any() {
super(TruffleObject.class);
}

@Override
public Class<? extends Builtin> getSuperType() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
// Before moving this definition to the `bool` package, as we should, one would have to address that
// problem first.
@BuiltinType(name = "Standard.Base.Data.Boolean.Boolean")
public class Boolean extends Builtin {
public final class Boolean extends Builtin {
public Boolean() {
super(java.lang.Boolean.class);
}

@Override
protected List<Cons> getDeclaredConstructors() {
return List.of(new Cons("False"), new Cons("True"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,33 @@ private AtomConstructor build(EnsoLanguage language, ModuleScope.Builder scope,
}
}

private final Class<?> representationType;
private final String name;

public Builtin() {
name = this.getClass().getSimpleName().replaceAll("([^_A-Z])([A-Z])", "$1_$2");
protected Builtin(String representationType) {
this(findType(representationType));
}

protected Builtin(Class<?> representationType) {
this.representationType = representationType;
this.name = this.getClass().getSimpleName().replaceAll("([^_A-Z])([A-Z])", "$1_$2");
}

private static Class<?> findType(String fqn) {
try {
return Class.forName(fqn);
} catch (ClassNotFoundException ex) {
throw new IllegalArgumentException(ex);
}
}

private @CompilerDirectives.CompilationFinal Type type;
private @CompilerDirectives.CompilationFinal(dimensions = 1) AtomConstructor[] constructors;

public final boolean isRepresentedBy(Class<?> clazz) {
return representationType == clazz;
}

protected Class<? extends Builtin> getSuperType() {
return Any.class;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
package org.enso.interpreter.node.expression.builtin;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.ControlFlowException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.RootNode;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoMultiValue;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.pkg.QualifiedName;

/** Root node for use by all the builtin functions. */
@NodeInfo(shortName = "BuiltinRoot", description = "Root node for builtin functions.")
public abstract class BuiltinRootNode extends RootNode {
private QualifiedName moduleName;
private QualifiedName typeName;

protected BuiltinRootNode(EnsoLanguage language) {
super(language);
}

protected QualifiedName moduleName = null;
protected QualifiedName typeName = null;

/** Get the module name where the builtin is defined. */
public QualifiedName getModuleName() {
return moduleName;
Expand Down Expand Up @@ -52,4 +64,104 @@ public void setTypeName(QualifiedName typeName) {
*/
@Override
public abstract String getName();

protected static final class ReturnValue extends ControlFlowException {
private final TruffleObject value;

private ReturnValue(TruffleObject value) {
this.value = value;
}

public TruffleObject get() {
return value;
}
}

protected abstract static class ArgNode extends Node {
private final boolean isSelf;
private final boolean isArray;
private final boolean requiresCast;
private final boolean checkErrors;
private final boolean checkPanicSentinel;
private final boolean checkWarnings;
@CompilerDirectives.CompilationFinal private Type ensoType;

ArgNode(
boolean isSelf,
boolean isArray,
boolean requiresCast,
boolean checkErrors,
boolean checkPanicSentinel,
boolean checkWarnings) {
this.isSelf = isSelf;
this.isArray = isArray;
this.requiresCast = requiresCast;
this.checkErrors = checkErrors;
this.checkPanicSentinel = checkPanicSentinel;
this.checkWarnings = checkWarnings;
}

@SuppressWarnings("unchecked")
public final <T> T processArgument(Class<T> type, Object value) throws ReturnValue {
if (checkErrors && value instanceof DataflowError err) {
throw new ReturnValue(err);
}
var ctx = EnsoContext.get(this);
if (this.ensoType == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
var builtin = ctx.getBuiltins().getByRepresentationType(type);
if (builtin == null) {
System.err.println("found no builtin for " + type);
this.ensoType = ctx.getBuiltins().any();
} else {
this.ensoType = builtin.getType();
}
}
assert value != null;
var conv = executeConversion(value);
if (conv == null) {
CompilerDirectives.transferToInterpreter();
var err = ctx.getBuiltins().error().makeTypeError(this.ensoType, value, type.getName());
throw new PanicException(err, this);
}
return type.cast(conv);
}

abstract Object executeConversion(Object obj);

@Specialization
final Object extractMultiValue(EnsoMultiValue emv, @Cached EnsoMultiValue.CastToNode castTo) {
var extracted = castTo.findTypeOrNull(ensoType, emv, false, false);
return extracted;
}

@Fallback
final Object justReturnIt(Object obj) {
return obj;
}

public static ArgNode create(
boolean isSelf,
boolean isArray,
boolean requiresCast,
boolean checkErrors,
boolean checkPanicSentinel,
boolean checkWarnings) {
return BuiltinRootNodeFactory.ArgNodeGen.create(
isSelf, isArray, requiresCast, checkErrors, checkPanicSentinel, checkWarnings);
}

/*
if (!arg.requiresCast()) {
generateUncastedArgumentRead(out, arg, argsArray);
} else if (arg.isSelf()) {
generateUncheckedArgumentRead(out, arg, argsArray);
} else if (arg.isArray()) {
generateUncheckedArrayCast(out, arg, argsArray);
} else {
generateCheckedArgumentRead(out, arg, argsArray);
}
*/
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin;

import org.enso.interpreter.dsl.BuiltinType;
import org.enso.interpreter.runtime.error.DataflowError;

@BuiltinType(name = "Standard.Base.Error.Error")
public class Error extends Builtin {
public final class Error extends Builtin {
public Error() {
super(DataflowError.class);
}

@Override
protected Class<? extends Builtin> getSuperType() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import org.enso.interpreter.dsl.BuiltinType;

@BuiltinType(name = "Standard.Base.Nothing.Nothing")
public class Nothing extends Builtin {
public final class Nothing extends Builtin {
public Nothing() {
super(Void.class);
}

@Override
public boolean containsValues() {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
import org.enso.interpreter.dsl.BuiltinType;

@BuiltinType
public class Polyglot extends Builtin {}
public final class Polyglot extends Builtin {
public Polyglot() {
super(Object.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
public abstract class UniquelyConstructibleBuiltin extends Builtin {
private @CompilerDirectives.CompilationFinal AtomConstructor uniqueConstructor;

protected UniquelyConstructibleBuiltin() {
super(Object.class);
}

public final AtomConstructor getUniqueConstructor() {
return uniqueConstructor;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
import org.enso.interpreter.node.expression.builtin.Builtin;

@BuiltinType
public class Debug extends Builtin {}
public class Debug extends Builtin {
public Debug() {
super(Object.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

@BuiltinType
public final class NumberParseError extends Builtin {
public NumberParseError() {
super(Object.class);
}

@Override
protected final List<Cons> getDeclaredConstructors() {
return List.of(new Cons("Error", "text"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

import org.enso.interpreter.dsl.BuiltinType;
import org.enso.interpreter.node.expression.builtin.Builtin;
import org.enso.interpreter.runtime.error.PanicException;

@BuiltinType(name = "Standard.Base.Panic.Panic")
public class Panic extends Builtin {
public final class Panic extends Builtin {
public Panic() {
super(PanicException.class);
}

@Override
public boolean containsValues() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
import org.enso.interpreter.runtime.data.atom.AtomConstructor;

@BuiltinType(name = "Standard.Base.Errors.Problem_Behavior.Problem_Behavior")
public class ProblemBehavior extends Builtin {
public final class ProblemBehavior extends Builtin {
public ProblemBehavior() {
super(Object.class);
}

@Override
protected List<Cons> getDeclaredConstructors() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import org.enso.interpreter.node.expression.builtin.Builtin;

@BuiltinType(name = "Standard.Base.Function.Function")
public class Function extends Builtin {
public final class Function extends Builtin {
public Function() {
super(org.enso.interpreter.runtime.callable.function.Function.class);
}

@Override
public boolean containsValues() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

@BuiltinType(name = "Standard.Base.Data.Numbers.Float")
public class Float extends Builtin {
public Float() {
super(Double.class);
}

@Override
protected Class<? extends Builtin> getSuperType() {
return Number.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

@BuiltinType(name = "Standard.Base.Data.Numbers.Integer")
public class Integer extends Builtin {
public Integer() {
super(Long.class);
}

@Override
protected Class<? extends Builtin> getSuperType() {
return Number.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

@BuiltinType(name = "Standard.Base.Data.Numbers.Number")
public class Number extends Builtin {
public Number() {
super(Number.class);
}

@Override
public boolean containsValues() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
/** A hidden builtin. Only conversions with target type of Comparable are visible. */
@BuiltinType
public final class Comparable extends Builtin {

public Comparable() {
super(Object.class);
}

@Override
protected List<Cons> getDeclaredConstructors() {
return List.of(new Cons("By", List.of("value", "comparator")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
import org.enso.interpreter.node.expression.builtin.Builtin;

@BuiltinType
public class DefaultComparator extends Builtin {}
public final class DefaultComparator extends Builtin {
public DefaultComparator() {
super(Object.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

@BuiltinType
public class Ordering extends Builtin {
public Ordering() {
super(Object.class);
}

@Override
protected List<Cons> getDeclaredConstructors() {
return List.of(new Cons("Less"), new Cons("Equal"), new Cons("Greater"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
import org.enso.interpreter.runtime.data.atom.AtomConstructor;

@BuiltinType
public class Context extends Builtin {
public final class Context extends Builtin {
public Context() {
super(Object.class);
}

@Override
protected List<Cons> getDeclaredConstructors() {
return List.of(
Expand Down
Loading

0 comments on commit e261e8d

Please sign in to comment.