use of org.wso2.ballerinalang.compiler.tree.statements.BLangTryCatchFinally in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
public void visit(BLangTryCatchFinally tryNode) {
Operand gotoTryCatchEndAddr = getOperand(-1);
Instruction instructGotoTryCatchEnd = InstructionFactory.get(InstructionCodes.GOTO, gotoTryCatchEndAddr);
List<int[]> unhandledErrorRangeList = new ArrayList<>();
ErrorTableAttributeInfo errorTable = createErrorTableIfAbsent(currentPkgInfo);
// Handle try block.
int fromIP = nextIP();
genNode(tryNode.tryBody, env);
int toIP = nextIP() - 1;
// Append finally block instructions.
if (tryNode.finallyBody != null) {
genNode(tryNode.finallyBody, env);
}
emit(instructGotoTryCatchEnd);
unhandledErrorRangeList.add(new int[] { fromIP, toIP });
// Handle catch blocks.
int order = 0;
for (BLangCatch bLangCatch : tryNode.getCatchBlocks()) {
addLineNumberInfo(bLangCatch.pos);
int targetIP = nextIP();
genNode(bLangCatch, env);
unhandledErrorRangeList.add(new int[] { targetIP, nextIP() - 1 });
// Append finally block instructions.
if (tryNode.finallyBody != null) {
genNode(tryNode.finallyBody, env);
}
emit(instructGotoTryCatchEnd);
// Create Error table entry for this catch block
BTypeSymbol structSymbol = bLangCatch.param.symbol.type.tsymbol;
BPackageSymbol packageSymbol = (BPackageSymbol) bLangCatch.param.symbol.type.tsymbol.owner;
int pkgCPIndex = addPackageRefCPEntry(currentPkgInfo, packageSymbol.pkgID);
int structNameCPIndex = addUTF8CPEntry(currentPkgInfo, structSymbol.name.value);
StructureRefCPEntry structureRefCPEntry = new StructureRefCPEntry(pkgCPIndex, structNameCPIndex);
int structCPEntryIndex = currentPkgInfo.addCPEntry(structureRefCPEntry);
StructInfo errorStructInfo = this.programFile.packageInfoMap.get(packageSymbol.pkgID.bvmAlias()).getStructInfo(structSymbol.name.value);
ErrorTableEntry errorTableEntry = new ErrorTableEntry(fromIP, toIP, targetIP, order++, structCPEntryIndex);
errorTableEntry.setError(errorStructInfo);
errorTable.addErrorTableEntry(errorTableEntry);
}
if (tryNode.finallyBody != null) {
// Create Error table entry for unhandled errors in try and catch(s) blocks
for (int[] range : unhandledErrorRangeList) {
ErrorTableEntry errorTableEntry = new ErrorTableEntry(range[0], range[1], nextIP(), order++, -1);
errorTable.addErrorTableEntry(errorTableEntry);
}
// Append finally block instruction.
genNode(tryNode.finallyBody, env);
emit(InstructionFactory.get(InstructionCodes.THROW, getOperand(-1)));
}
gotoTryCatchEndAddr.value = nextIP();
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangTryCatchFinally in project ballerina by ballerina-lang.
the class CodeGenerator method generateFinallyInstructions.
private void generateFinallyInstructions(BLangStatement statement, NodeKind... expectedParentKinds) {
BLangStatement current = statement;
while (current != null && current.statementLink.parent != null) {
BLangStatement parent = current.statementLink.parent.statement;
for (NodeKind expected : expectedParentKinds) {
if (expected == parent.getKind()) {
return;
}
}
if (NodeKind.TRY == parent.getKind()) {
BLangTryCatchFinally tryCatchFinally = (BLangTryCatchFinally) parent;
if (tryCatchFinally.finallyBody != null && current != tryCatchFinally.finallyBody) {
genNode(tryCatchFinally.finallyBody, env);
}
} else if (NodeKind.LOCK == parent.getKind()) {
BLangLock lockNode = (BLangLock) parent;
if (!lockNode.lockVariables.isEmpty()) {
Operand[] operands = getOperands(lockNode);
emit((InstructionCodes.UNLOCK), operands);
}
}
current = parent;
}
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangTryCatchFinally in project ballerina by ballerina-lang.
the class CodeAnalyzer method visit.
public void visit(BLangTryCatchFinally tryNode) {
this.checkStatementExecutionValidity(tryNode);
tryNode.tryBody.accept(this);
this.resetStatementReturns();
List<BType> caughtTypes = new ArrayList<>();
for (BLangCatch bLangCatch : tryNode.getCatchBlocks()) {
if (caughtTypes.contains(bLangCatch.getParameter().type)) {
dlog.error(bLangCatch.getParameter().pos, DiagnosticCode.DUPLICATED_ERROR_CATCH, bLangCatch.getParameter().type);
}
caughtTypes.add(bLangCatch.getParameter().type);
bLangCatch.body.accept(this);
this.resetStatementReturns();
}
if (tryNode.finallyBody != null) {
tryNode.finallyBody.accept(this);
this.resetStatementReturns();
}
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangTryCatchFinally in project ballerina by ballerina-lang.
the class BLangPackageBuilder method addTryCatchFinallyStmt.
public void addTryCatchFinallyStmt(DiagnosticPos poc, Set<Whitespace> ws) {
BLangTryCatchFinally stmtNode = tryCatchFinallyNodesStack.pop();
stmtNode.pos = poc;
stmtNode.addWS(ws);
addStmtToCurrentBlock(stmtNode);
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangTryCatchFinally in project ballerina by ballerina-lang.
the class BLangPackageBuilder method addFinallyBlock.
public void addFinallyBlock(DiagnosticPos poc, Set<Whitespace> ws) {
BLangBlockStmt blockNode = (BLangBlockStmt) this.blockNodeStack.pop();
BLangTryCatchFinally rootTry = tryCatchFinallyNodesStack.peek();
rootTry.finallyBody = blockNode;
rootTry.addWS(ws);
blockNode.pos = poc;
}
Aggregations