package com.oracle.svm.hosted.meta;
import org.graalvm.compiler.core.common.CompressEncoding;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.graal.meta.SubstrateMemoryAccessProvider;
import com.oracle.svm.core.meta.CompressedNullConstant;
import com.oracle.svm.core.meta.SubstrateObjectConstant;
import com.oracle.svm.core.util.VMError;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
public class HostedMemoryAccessProvider implements SubstrateMemoryAccessProvider {
private final HostedMetaAccess metaAccess;
public HostedMemoryAccessProvider(HostedMetaAccess metaAccess) {
this.metaAccess = metaAccess;
}
@Override
public JavaConstant readPrimitiveConstant(JavaKind stackKind, Constant base, long displacement, int bits) {
JavaConstant result = doRead(stackKind, (JavaConstant) base, displacement);
if (result == null) {
return null;
}
JavaConstant wrappedResult;
switch (stackKind) {
case Int:
wrappedResult = JavaConstant.forInt(result.asInt());
break;
case Long:
case Float:
case Double:
assert result.getJavaKind() == stackKind;
wrappedResult = result;
break;
default:
throw VMError.shouldNotReachHere();
}
return wrappedResult;
}
@Override
public JavaConstant readObjectConstant(Constant base, long displacement) {
return doRead(JavaKind.Object, (JavaConstant) base, displacement);
}
@Override
public JavaConstant readNarrowObjectConstant(Constant base, long displacement, CompressEncoding encoding) {
assert SubstrateOptions.SpawnIsolates.getValue();
JavaConstant result = readObjectConstant(base, displacement);
if (result == null) {
return null;
}
if (JavaConstant.NULL_POINTER.equals(result)) {
return CompressedNullConstant.COMPRESSED_NULL;
}
return ((SubstrateObjectConstant) result).compress();
}
private JavaConstant doRead(JavaKind stackKind, JavaConstant base, long displacement) {
if (base.getJavaKind() != JavaKind.Object) {
return null;
}
HostedType type = (HostedType) metaAccess.lookupJavaType(base);
HostedField field = (HostedField) type.findInstanceFieldWithOffset(displacement, null);
if (field == null) {
return null;
}
assert field.getStorageKind().getStackKind() == stackKind;
JavaConstant result = field.readValue(base);
assert result.getJavaKind().getStackKind() == stackKind;
return result;
}
}