package com.oracle.truffle.llvm.runtime;
import java.util.ArrayList;
import java.util.List;
import com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceLocation;
public final class SulongStackTrace {
private final ArrayList<Element> trace = new ArrayList<>();
private final String summary;
public SulongStackTrace(String summary) {
this.summary = summary;
}
public static final class Element {
private final String sourceFunctionName;
private final LLVMSourceLocation sourceLocation;
private final String irFunctionName;
private final String irBlock;
private final String irSourceName;
Element(String sourceFunctionName, LLVMSourceLocation sourceLocation, String irFunctionName, String llvmirSourceName, String irBlock) {
this.sourceFunctionName = sourceFunctionName;
this.irFunctionName = irFunctionName;
this.irBlock = irBlock;
this.sourceLocation = sourceLocation;
this.irSourceName = llvmirSourceName;
}
Element(String irFunctionName, String llvmirSourceName, String irBlock) {
this(null, null, irFunctionName, llvmirSourceName, irBlock);
}
void appendToStackTrace(StringBuilder builder) {
builder.append("\t ");
boolean encloseIRScope = false;
if (sourceFunctionName != null) {
builder.append(sourceFunctionName);
encloseIRScope = true;
} else if (sourceLocation != null) {
builder.append("<unknown>");
}
if (sourceLocation != null) {
builder.append(" in ");
builder.append(sourceLocation.describeLocation());
encloseIRScope = true;
}
if (encloseIRScope) {
builder.append(" (");
}
builder.append("LLVM IR Function ").append(irFunctionName);
if (irSourceName != null) {
builder.append(" in ").append(irSourceName);
}
if (irBlock != null) {
builder.append(" in Block {").append(irBlock).append('}');
}
if (encloseIRScope) {
builder.append(')');
}
builder.append('\n');
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
appendToStackTrace(sb);
return sb.toString();
}
}
public void addStackTraceElement(String sourceFunctionName, LLVMSourceLocation sourceLocation, String irFunctionName, String irSourceName, String irBlock) {
trace.add(new Element(sourceFunctionName, sourceLocation, irFunctionName, irSourceName, irBlock));
}
public void addStackTraceElement(String irFunctionName, String irSourceName, String irBlock) {
trace.add(new Element(irFunctionName, irSourceName, irBlock));
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append(summary);
sb.append("\n\n");
sb.append("C stack trace:\n");
for (Element e : trace) {
e.appendToStackTrace(sb);
}
return sb.toString();
}
public List<Element> getTrace() {
return java.util.Collections.unmodifiableList(trace);
}
}