diff --git a/chi-stdlib b/chi-stdlib index 9a3b3413..ae5a5c42 160000 --- a/chi-stdlib +++ b/chi-stdlib @@ -1 +1 @@ -Subproject commit 9a3b34132c02d507b8e3e4d87369cf30c3a25627 +Subproject commit ae5a5c4271f54c4635c4d089c048fc48f1f15ff7 diff --git a/chi-truffle-language/src/main/java/gh/marad/chi/truffle/ChiLanguage.java b/chi-truffle-language/src/main/java/gh/marad/chi/truffle/ChiLanguage.java index 2111a5e3..a3f0ef83 100644 --- a/chi-truffle-language/src/main/java/gh/marad/chi/truffle/ChiLanguage.java +++ b/chi-truffle-language/src/main/java/gh/marad/chi/truffle/ChiLanguage.java @@ -31,8 +31,8 @@ public class ChiLanguage extends TruffleLanguage { private final Shape initialObjectShape = Shape.newBuilder().build(); - public Object createObject(String[] fieldNames, VariantType variant) { - return new ChiObject(fieldNames, variant, initialObjectShape); + public Object createObject(String[] fieldNames, VariantType variant, TruffleLanguage.Env env) { + return new ChiObject(fieldNames, variant, initialObjectShape, env); } public static ChiLanguage get(Node node) { diff --git a/chi-truffle-language/src/main/java/gh/marad/chi/truffle/nodes/objects/ConstructChiObject.java b/chi-truffle-language/src/main/java/gh/marad/chi/truffle/nodes/objects/ConstructChiObject.java index 06e5af62..3748ffdc 100644 --- a/chi-truffle-language/src/main/java/gh/marad/chi/truffle/nodes/objects/ConstructChiObject.java +++ b/chi-truffle-language/src/main/java/gh/marad/chi/truffle/nodes/objects/ConstructChiObject.java @@ -8,6 +8,7 @@ import com.oracle.truffle.api.interop.UnsupportedTypeException; import gh.marad.chi.core.VariantType; import gh.marad.chi.truffle.ChiArgs; +import gh.marad.chi.truffle.ChiContext; import gh.marad.chi.truffle.ChiLanguage; import gh.marad.chi.truffle.nodes.expr.ExpressionNode; @@ -29,7 +30,8 @@ public ConstructChiObject(ChiLanguage language, VariantType type) { @Override public Object executeGeneric(VirtualFrame frame) { - var object = language.createObject(fieldNames, type); + var env = ChiContext.get(this).getEnv(); + var object = language.createObject(fieldNames, type, env); for (int i = 0; i < fieldNames.length; i++) { try { interopLibrary.writeMember(object, fieldNames[i], ChiArgs.getArgument(frame, i)); diff --git a/chi-truffle-language/src/main/java/gh/marad/chi/truffle/runtime/ChiObject.java b/chi-truffle-language/src/main/java/gh/marad/chi/truffle/runtime/ChiObject.java index e964552b..7ebc7a0e 100644 --- a/chi-truffle-language/src/main/java/gh/marad/chi/truffle/runtime/ChiObject.java +++ b/chi-truffle-language/src/main/java/gh/marad/chi/truffle/runtime/ChiObject.java @@ -1,6 +1,8 @@ package gh.marad.chi.truffle.runtime; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.*; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; @@ -18,10 +20,13 @@ public class ChiObject extends DynamicObject implements ChiValue { private final String[] fieldNames; private final VariantType type; - public ChiObject(String[] fieldNames, VariantType type, Shape shape) { + private final TruffleLanguage.Env env; + + public ChiObject(String[] fieldNames, VariantType type, Shape shape, TruffleLanguage.Env env) { super(shape); this.fieldNames = fieldNames; this.type = type; + this.env = env; } public VariantType getType() { @@ -120,20 +125,35 @@ public Object toDisplayString(boolean allowSideEffects, } @ExportMessage - @CompilerDirectives.TruffleBoundary - public TriState isIdenticalOrUndefined(Object obj, - @CachedLibrary("this") DynamicObjectLibrary objectLibrary) { - if (obj instanceof ChiObject other && objectLibrary.getShape(this).equals(objectLibrary.getShape(other))) { - boolean valuesEqual = true; - for (var key : fieldNames) { - var thisField = objectLibrary.getOrDefault(this, key, null); - var otherField = objectLibrary.getOrDefault(other, key, null); - valuesEqual = valuesEqual && Objects.equals(thisField, otherField); + static final class IsIdenticalOrUndefined { + @Specialization + static TriState doChiObject(ChiObject receiver, ChiObject other, + @CachedLibrary("receiver") DynamicObjectLibrary objectLibrary) { + var recvShape = objectLibrary.getShape(receiver); + var otherShape = objectLibrary.getShape(other); + if (recvShape.equals(otherShape)) { + var equal = true; + for (var key : receiver.fieldNames) { + var thisField = objectLibrary.getOrDefault(receiver, key, null); + var otherField = objectLibrary.getOrDefault(other, key, null); + if (receiver.env.isHostObject(thisField) && receiver.env.isHostObject(otherField)) { + equal = equal && receiver.env.asHostObject(thisField) + .equals(receiver.env.asHostObject(otherField)); + } else { + var thisIop = InteropLibrary.getUncached(thisField); + var otherIop = InteropLibrary.getUncached(otherField); + equal = equal && thisIop.isIdentical(thisField, otherField, otherIop); + } + } + return equal ? TriState.TRUE : TriState.FALSE; + } else { + return TriState.FALSE; } + } - return valuesEqual ? TriState.TRUE : TriState.FALSE; - } else { - return TriState.FALSE; + @Specialization + static TriState doOther(ChiObject receiver, Object other) { + return TriState.UNDEFINED; } } @@ -147,14 +167,4 @@ public int identityHashCode(@CachedLibrary("this") DynamicObjectLibrary objectLi } return Objects.hash(values); } - - @Override - public int hashCode() { - return identityHashCode(DynamicObjectLibrary.getUncached()); - } - - @Override - public boolean equals(Object obj) { - return isIdenticalOrUndefined(obj, DynamicObjectLibrary.getUncached()) == TriState.TRUE; - } }