package com.oracle.truffle.llvm.runtime;
import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.llvm.runtime.LLVMFunctionCode.Function;
import com.oracle.truffle.llvm.runtime.global.LLVMGlobal;
import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer;
import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer;
import com.oracle.truffle.llvm.runtime.types.FunctionType;
public final class LLVMFunction extends LLVMSymbol {
public static final LLVMFunction[] EMPTY = {};
private final FunctionType type;
private final Function function;
private final String path;
private final Assumption fixedCodeAssumption = Truffle.getRuntime().createAssumption();
@CompilationFinal private LLVMFunctionCode fixedCode;
public static LLVMFunction create(String name, Function function, FunctionType type, int bitcodeID, int symbolIndex, boolean exported, String path) {
return new LLVMFunction(name, function, type, bitcodeID, symbolIndex, exported, path);
}
public LLVMFunction(String name, Function function, FunctionType type, int bitcodeID, int symbolIndex, boolean exported, String path) {
super(name, bitcodeID, symbolIndex, exported);
this.type = type;
this.function = function;
this.path = path;
}
public String getStringPath() {
return path;
}
public FunctionType getType() {
return type;
}
public Function getFunction() {
return function;
}
@Override
public boolean isFunction() {
return true;
}
@Override
public boolean isGlobalVariable() {
return false;
}
@Override
public boolean isAlias() {
return false;
}
@Override
public LLVMFunction asFunction() {
return this;
}
@Override
public LLVMGlobal asGlobalVariable() {
throw new IllegalStateException("Function " + getName() + " is not a global variable.");
}
public Assumption getFixedCodeAssumption() {
return fixedCodeAssumption;
}
public LLVMFunctionCode getFixedCode() {
return fixedCode;
}
public void setValue(LLVMPointer pointer) {
if (fixedCodeAssumption.isValid()) {
if (LLVMManagedPointer.isInstance(pointer)) {
Object value = LLVMManagedPointer.cast(pointer).getObject();
if (value instanceof LLVMFunctionDescriptor) {
LLVMFunctionDescriptor descriptor = (LLVMFunctionDescriptor) value;
LLVMFunctionCode code = descriptor.getFunctionCode();
if (fixedCode == null) {
fixedCode = code;
return;
} else if (fixedCode == code) {
return;
}
}
}
fixedCode = null;
fixedCodeAssumption.invalidate();
}
}
}