package com.oracle.truffle.llvm.runtime.pointer;
import java.util.Objects;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.ValueType;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.library.DynamicDispatchLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.llvm.runtime.interop.access.LLVMInteropType;
@ValueType
@ExportLibrary(DynamicDispatchLibrary.class)
final class LLVMPointerImpl implements LLVMManagedPointer, LLVMNativePointer {
static final LLVMPointerImpl NULL = new LLVMPointerImpl(null, 0, null);
final Object object;
private final long offset;
private final LLVMInteropType exportType;
LLVMPointerImpl(Object object, long offset, LLVMInteropType exportType) {
this.object = object;
this.offset = offset;
this.exportType = exportType;
}
@Override
@Deprecated
@SuppressWarnings("deprecation")
public boolean equals(Object obj) {
CompilerAsserts.neverPartOfCompilation();
if (!(obj instanceof LLVMPointerImpl)) {
return false;
}
LLVMPointerImpl other = (LLVMPointerImpl) obj;
return Objects.equals(this.object, other.object) && this.offset == other.offset;
}
@Override
public boolean isSame(LLVMPointer o) {
LLVMPointerImpl other = (LLVMPointerImpl) o;
return this.object == other.object && this.offset == other.offset;
}
@Override
public int hashCode() {
int result = 1;
result = 31 * result + Objects.hashCode(object);
result = 31 * result + Long.hashCode(offset);
return result;
}
boolean isNative() {
return object == null;
}
@Override
public long asNative() {
assert isNative();
return offset;
}
boolean isManaged() {
return object != null;
}
@Override
public Object getObject() {
assert isManaged();
return object;
}
@Override
public long getOffset() {
assert isManaged();
return offset;
}
@Override
public boolean isNull() {
return object == null && offset == 0;
}
@Override
public LLVMInteropType getExportType() {
return exportType;
}
@Override
public LLVMPointerImpl copy() {
if (CompilerDirectives.inCompiledCode()) {
return new LLVMPointerImpl(object, offset, exportType);
} else {
return this;
}
}
@Override
public LLVMPointerImpl increment(long incr) {
return new LLVMPointerImpl(object, offset + incr, null);
}
@Override
public LLVMPointerImpl export(LLVMInteropType newType) {
return new LLVMPointerImpl(object, offset, newType);
}
@Override
public String toString() {
CompilerAsserts.neverPartOfCompilation();
if (isNative()) {
return String.format("0x%x", asNative());
} else {
return String.format("%s+0x%x", getObject().getClass().getSimpleName(), getOffset());
}
}
@ExportMessage
Class<?> dispatch(@Cached ConditionProfile isNativeProfile) {
if (isNativeProfile.profile(isNative())) {
return NativePointerLibraries.class;
} else {
assert isManaged();
return ManagedPointerLibraries.class;
}
}
}