Skip to content

Commit

Permalink
getPolyglotSymbolSupplier returns a supplier
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Aug 28, 2024
1 parent 0fba66b commit 6ee9c8f
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.oracle.truffle.api.nodes.RootNode;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.enso.interpreter.EnsoLanguage;
Expand Down Expand Up @@ -162,8 +163,9 @@ public static ReadArgumentCheckNode build(EnsoContext ctx, String comment, Type
return ReadArgumentCheckNodeFactory.TypeCheckNodeGen.create(comment, expectedType);
}

public static ReadArgumentCheckNode meta(String comment, Object metaObject) {
return ReadArgumentCheckNodeFactory.MetaCheckNodeGen.create(comment, metaObject);
public static ReadArgumentCheckNode meta(
String comment, Supplier<? extends Object> metaObjectSupplier) {
return ReadArgumentCheckNodeFactory.MetaCheckNodeGen.create(comment, metaObjectSupplier);
}

public static boolean isWrappedThunk(Function fn) {
Expand Down Expand Up @@ -475,12 +477,12 @@ String expectedTypeMessage() {
}

abstract static class MetaCheckNode extends ReadArgumentCheckNode {
private final Object expectedMeta;
private final Supplier<? extends Object> expectedSupplier;
@CompilerDirectives.CompilationFinal private String expectedTypeMessage;

MetaCheckNode(String name, Object expectedMeta) {
MetaCheckNode(String name, Supplier<? extends Object> expectedMetaSupplier) {
super(name);
this.expectedMeta = expectedMeta;
this.expectedSupplier = expectedMetaSupplier;
}

@Override
Expand All @@ -493,7 +495,7 @@ Object verifyMetaObject(VirtualFrame frame, Object v, @Cached IsValueOfTypeNode
if (isAllFitValue(v)) {
return v;
}
if (isA.execute(expectedMeta, v)) {
if (isA.execute(expectedSupplier.get(), v)) {
return v;
} else {
return null;
Expand All @@ -508,9 +510,9 @@ String expectedTypeMessage() {
CompilerDirectives.transferToInterpreterAndInvalidate();
var iop = InteropLibrary.getUncached();
try {
expectedTypeMessage = iop.asString(iop.getMetaQualifiedName(expectedMeta));
expectedTypeMessage = iop.asString(iop.getMetaQualifiedName(expectedSupplier.get()));
} catch (UnsupportedMessageException ex) {
expectedTypeMessage = expectedMeta.toString();
expectedTypeMessage = expectedSupplier.get().toString();
}
return expectedTypeMessage;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,29 @@
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.CountingConditionProfile;
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.node.expression.builtin.meta.IsSameObjectNode;

public class ObjectEqualityBranchNode extends BranchNode {
private final Object expected;
private @Child ExpressionNode expected;
private @Child IsSameObjectNode isSameObject = IsSameObjectNode.build();
private final CountingConditionProfile profile = CountingConditionProfile.create();

private ObjectEqualityBranchNode(RootCallTarget branch, Object expected, boolean terminalBranch) {
private ObjectEqualityBranchNode(
RootCallTarget branch, ExpressionNode expected, boolean terminalBranch) {
super(branch, terminalBranch);
this.expected = expected;
}

public static BranchNode build(RootCallTarget branch, Object expected, boolean terminalBranch) {
public static BranchNode build(
RootCallTarget branch, ExpressionNode expected, boolean terminalBranch) {
return new ObjectEqualityBranchNode(branch, expected, terminalBranch);
}

@Override
public void execute(VirtualFrame frame, Object state, Object target) {
if (profile.profile(isSameObject.execute(target, expected))) {
var exp = expected.executeGeneric(frame);
if (profile.profile(isSameObject.execute(target, exp))) {
accept(frame, state, new Object[0]);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

/** Represents a compile-time constant. */
@NodeInfo(shortName = "const", description = "Represents an arbitrary compile-time constant.")
public class ConstantObjectNode extends ExpressionNode {
public final class ConstantObjectNode extends ExpressionNode {
private final Object object;

private ConstantObjectNode(Object object) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.enso.interpreter.node.expression.constant;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.NodeInfo;
import java.util.function.Supplier;
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.util.CachingSupplier;

@NodeInfo(
shortName = "lazy",
description = "Represents an arbitrary compile-time constant computed lazily.")
public final class LazyObjectNode extends ExpressionNode {

private final String error;
private final Supplier<? extends Object> supply;

private LazyObjectNode(String error, Supplier<? extends Object> supply) {
this.error = error;
this.supply = supply;
}

/**
* Creates a node that returns lazily computed value.
*
* @param errorMessage the error message to show when the value is {@code null}
* @param supplier computes the value lazily. Can return {@code null} and then the {@code
* errorMessage} error is created
*/
public static ExpressionNode build(String errorMessage, Supplier<TruffleObject> supplier) {
return new LazyObjectNode(errorMessage, new CachingSupplier<>(supplier));
}

@Override
public Object executeGeneric(VirtualFrame frame) {
var result = supply.get();
if (result instanceof TruffleObject) {
return result;
}
return DataflowError.withDefaultTrace(Text.create(error), this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.oracle.truffle.api.TruffleLogger;
import com.oracle.truffle.api.interop.InteropException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.io.TruffleProcessBuilder;
Expand Down Expand Up @@ -556,15 +557,15 @@ public boolean isColorTerminalOutput() {
* @return If the java class is found, return it, otherwise return null.
*/
@TruffleBoundary
public Object lookupJavaClass(String className) {
public TruffleObject lookupJavaClass(String className) {
var binaryName = new StringBuilder(className);
var collectedExceptions = new ArrayList<Exception>();
for (; ; ) {
var fqn = binaryName.toString();
try {
var hostSymbol = lookupHostSymbol(fqn);
if (hostSymbol != null) {
return hostSymbol;
return (TruffleObject) hostSymbol;
}
} catch (ClassNotFoundException | RuntimeException | InteropException ex) {
collectedExceptions.add(ex);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.scope;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import java.util.*;
Expand All @@ -21,7 +22,7 @@
public final class ModuleScope implements EnsoObject {
private final Type associatedType;
private final Module module;
private final Map<String, Supplier<Object>> polyglotSymbols;
private final Map<String, Supplier<TruffleObject>> polyglotSymbols;
private final Map<String, Type> types;
private final Map<Type, Map<String, Supplier<Function>>> methods;

Expand All @@ -43,7 +44,7 @@ public final class ModuleScope implements EnsoObject {
public ModuleScope(
Module module,
Type associatedType,
Map<String, Supplier<Object>> polyglotSymbols,
Map<String, Supplier<TruffleObject>> polyglotSymbols,
Map<String, Type> types,
Map<Type, Map<String, Supplier<Function>>> methods,
Map<Type, Map<Type, Function>> conversions,
Expand Down Expand Up @@ -257,14 +258,15 @@ public List<Function> getConversions() {
}

/**
* Finds a polyglot symbol.
* Finds a polyglot symbol supplier. The supplier will then load the provided {@code symbolName}
* when its {@link Supplier#get()} method is called.
*
* @param symbolName name of the symbol to search for
* @return the polyglot symbol imported into this scope or {@code null} if it cannot be found
* @return non-{@code null} supplier of a polyglot symbol imported into this scope
*/
public Object getPolyglotSymbol(String symbolName) {
public Supplier<TruffleObject> getPolyglotSymbolSupplier(String symbolName) {
var supplier = polyglotSymbols.get(symbolName);
return supplier == null ? null : supplier.get();
return supplier != null ? supplier : CachingSupplier.nullSupplier();
}

@ExportMessage
Expand All @@ -287,7 +289,7 @@ public static class Builder {
@CompilerDirectives.CompilationFinal private ModuleScope moduleScope = null;
private final Module module;
private final Type associatedType;
private final Map<String, Supplier<Object>> polyglotSymbols;
private final Map<String, Supplier<TruffleObject>> polyglotSymbols;
private final Map<String, Type> types;
private final Map<Type, Map<String, Supplier<Function>>> methods;
private final Map<Type, Map<Type, Function>> conversions;
Expand Down Expand Up @@ -319,7 +321,7 @@ public Builder(Module module, Map<String, Type> types) {
public Builder(
Module module,
Type associatedType,
Map<String, Supplier<Object>> polyglotSymbols,
Map<String, Supplier<TruffleObject>> polyglotSymbols,
Map<String, Type> types,
Map<Type, Map<String, Supplier<Function>>> methods,
Map<Type, Map<Type, Function>> conversions,
Expand Down Expand Up @@ -415,7 +417,7 @@ public void registerConversionMethod(Type toType, Type fromType, Function functi
* @param name the name of the symbol
* @param symbolFactory the value being exposed
*/
public void registerPolyglotSymbol(String name, Supplier<Object> symbolFactory) {
public void registerPolyglotSymbol(String name, Supplier<TruffleObject> symbolFactory) {
assert moduleScope == null;
polyglotSymbols.put(name, new CachingSupplier<>(symbolFactory));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package org.enso.interpreter.runtime.util;

import com.oracle.truffle.api.CompilerDirectives;
import java.util.function.Supplier;

public final class CachingSupplier<T> implements Supplier<T> {
@SuppressWarnings("unchecked")
private static final Supplier EMPTY = new CachingSupplier(null);

private final Supplier<T> supply;
private T memo;
@CompilerDirectives.CompilationFinal private boolean memoComputed;
@CompilerDirectives.CompilationFinal private T memo;

public CachingSupplier(Supplier<T> supply) {
this.supply = supply;
Expand All @@ -17,9 +22,33 @@ public CachingSupplier(T memo) {

@Override
public T get() {
if (memo == null) {
memo = supply.get();
synchronized (this) {
if (memoComputed) {
return memo;
}
CompilerDirectives.transferToInterpreterAndInvalidate();
if (supply == null) {
memoComputed = true;
return memo;
}
}
var v = supply.get();
synchronized (this) {
if (!memoComputed) {
memo = v;
}
return memo;
}
return memo;
}

/**
* Returns a supplier that always returns {@code null} when its {@link Supplier#get()} method is
* called.
*
* @return non-{@code null} instance of supplier
*/
@SuppressWarnings("unchecked")
public static <V> Supplier<V> nullSupplier() {
return EMPTY;
}
}
Loading

0 comments on commit 6ee9c8f

Please sign in to comment.