package com.oracle.truffle.llvm.runtime.global;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.llvm.runtime.LLVMContext;
import com.oracle.truffle.llvm.runtime.LLVMFunction;
import com.oracle.truffle.llvm.runtime.LLVMSymbol;
import com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceSymbol;
import com.oracle.truffle.llvm.runtime.debug.type.LLVMSourceType;
import com.oracle.truffle.llvm.runtime.interop.access.LLVMInteropType;
import com.oracle.truffle.llvm.runtime.types.PointerType;
import com.oracle.truffle.llvm.runtime.types.Type;
public final class LLVMGlobal extends LLVMSymbol {
private final LLVMSourceSymbol sourceSymbol;
private final boolean readOnly;
public static final LLVMGlobal[] EMPTY = {};
private final String name;
private final PointerType type;
@CompilationFinal private boolean interopTypeCached;
@CompilationFinal private LLVMInteropType interopType;
public static LLVMGlobal create(String name, PointerType type, LLVMSourceSymbol sourceSymbol, boolean readOnly, int index, int id, boolean exported) {
if (index < 0) {
throw new AssertionError("Invalid index for LLVM global: " + index);
}
if (id < 0) {
throw new AssertionError("Invalid index for LLVM global: " + id);
}
return new LLVMGlobal(name, type, sourceSymbol, readOnly, index, id, exported);
}
public static LLVMGlobal createUnavailable(String name) {
return new LLVMGlobal(name + " (unavailable)", PointerType.VOID, null, true, -1, -1, false);
}
private LLVMGlobal(String name, PointerType type, LLVMSourceSymbol sourceSymbol, boolean readOnly, int globalIndex, int moduleId, boolean exported) {
super(name, moduleId, globalIndex, exported);
this.name = name;
this.type = type;
this.sourceSymbol = sourceSymbol;
this.readOnly = readOnly;
this.interopTypeCached = false;
this.interopType = null;
}
@Override
public String toString() {
return "(" + type + ")" + name;
}
public LLVMInteropType getInteropType(LLVMContext context) {
if (!interopTypeCached) {
CompilerDirectives.transferToInterpreterAndInvalidate();
LLVMSourceType sourceType = sourceSymbol != null ? sourceSymbol.getType() : null;
interopType = context.getLanguage().getInteropType(sourceType);
interopTypeCached = true;
}
return interopType;
}
public String getSourceName() {
return sourceSymbol != null ? sourceSymbol.getName() : name;
}
public Type getPointeeType() {
return type.getPointeeType();
}
public boolean isReadOnly() {
return readOnly;
}
@Override
public boolean isFunction() {
return false;
}
@Override
public boolean isGlobalVariable() {
return true;
}
@Override
public boolean isAlias() {
return false;
}
@Override
public LLVMFunction asFunction() {
throw new IllegalStateException("Global " + name + " is not a function.");
}
@Override
public LLVMGlobal asGlobalVariable() {
return this;
}
}