Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

78 setmapvector equality #79

Merged
merged 2 commits into from
Sep 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion chi-stdlib
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public class ChiLanguage extends TruffleLanguage<ChiContext> {

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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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));
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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() {
Expand Down Expand Up @@ -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;
}
}

Expand All @@ -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;
}
}