use of org.wso2.ballerinalang.programfile.attributes.ErrorTableAttributeInfo in project ballerina by ballerina-lang.
the class PackageInfoWriter method writeAttributeInfo.
private static void writeAttributeInfo(DataOutputStream dataOutStream, AttributeInfo attributeInfo) throws IOException {
AttributeInfo.Kind attributeKind = attributeInfo.getKind();
dataOutStream.writeInt(attributeInfo.getAttributeNameIndex());
switch(attributeKind) {
case CODE_ATTRIBUTE:
CodeAttributeInfo codeAttributeInfo = (CodeAttributeInfo) attributeInfo;
dataOutStream.writeInt(codeAttributeInfo.codeAddrs);
dataOutStream.writeShort(codeAttributeInfo.maxLongLocalVars);
dataOutStream.writeShort(codeAttributeInfo.maxDoubleLocalVars);
dataOutStream.writeShort(codeAttributeInfo.maxStringLocalVars);
dataOutStream.writeShort(codeAttributeInfo.maxIntLocalVars);
dataOutStream.writeShort(codeAttributeInfo.maxByteLocalVars);
dataOutStream.writeShort(codeAttributeInfo.maxRefLocalVars);
dataOutStream.writeShort(codeAttributeInfo.maxLongRegs);
dataOutStream.writeShort(codeAttributeInfo.maxDoubleRegs);
dataOutStream.writeShort(codeAttributeInfo.maxStringRegs);
dataOutStream.writeShort(codeAttributeInfo.maxIntRegs);
dataOutStream.writeShort(codeAttributeInfo.maxByteRegs);
dataOutStream.writeShort(codeAttributeInfo.maxRefRegs);
break;
case VARIABLE_TYPE_COUNT_ATTRIBUTE:
VarTypeCountAttributeInfo varCountAttributeInfo = (VarTypeCountAttributeInfo) attributeInfo;
dataOutStream.writeShort(varCountAttributeInfo.getMaxLongVars());
dataOutStream.writeShort(varCountAttributeInfo.getMaxDoubleVars());
dataOutStream.writeShort(varCountAttributeInfo.getMaxStringVars());
dataOutStream.writeShort(varCountAttributeInfo.getMaxIntVars());
dataOutStream.writeShort(varCountAttributeInfo.getMaxByteVars());
dataOutStream.writeShort(varCountAttributeInfo.getMaxRefVars());
break;
case ERROR_TABLE:
ErrorTableAttributeInfo errTable = (ErrorTableAttributeInfo) attributeInfo;
ErrorTableEntry[] errorTableEntries = errTable.getErrorTableEntriesList().toArray(new ErrorTableEntry[0]);
dataOutStream.writeShort(errorTableEntries.length);
for (ErrorTableEntry errorTableEntry : errorTableEntries) {
dataOutStream.writeInt(errorTableEntry.ipFrom);
dataOutStream.writeInt(errorTableEntry.ipTo);
dataOutStream.writeInt(errorTableEntry.ipTarget);
dataOutStream.writeInt(errorTableEntry.priority);
dataOutStream.writeInt(errorTableEntry.errorStructCPIndex);
}
break;
case LOCAL_VARIABLES_ATTRIBUTE:
LocalVariableAttributeInfo localVarAttrInfo = (LocalVariableAttributeInfo) attributeInfo;
LocalVariableInfo[] localVarInfoArray = localVarAttrInfo.localVars.toArray(new LocalVariableInfo[0]);
dataOutStream.writeShort(localVarInfoArray.length);
for (LocalVariableInfo localVariableInfo : localVarInfoArray) {
writeLocalVariableInfo(dataOutStream, localVariableInfo);
}
break;
case LINE_NUMBER_TABLE_ATTRIBUTE:
LineNumberTableAttributeInfo lnNoTblAttrInfo = (LineNumberTableAttributeInfo) attributeInfo;
LineNumberInfo[] lineNumberInfoEntries = lnNoTblAttrInfo.getLineNumberInfoEntries();
dataOutStream.writeShort(lineNumberInfoEntries.length);
for (LineNumberInfo lineNumberInfo : lineNumberInfoEntries) {
writeLineNumberInfo(dataOutStream, lineNumberInfo);
}
break;
case DEFAULT_VALUE_ATTRIBUTE:
DefaultValueAttributeInfo defaultValAttrInfo = (DefaultValueAttributeInfo) attributeInfo;
writeDefaultValue(dataOutStream, defaultValAttrInfo.getDefaultValue());
break;
case PARAMETER_DEFAULTS_ATTRIBUTE:
ParamDefaultValueAttributeInfo paramDefaultValAttrInfo = (ParamDefaultValueAttributeInfo) attributeInfo;
DefaultValue[] defaultValues = paramDefaultValAttrInfo.getDefaultValueInfo();
dataOutStream.writeShort(defaultValues.length);
for (DefaultValue defaultValue : defaultValues) {
writeDefaultValue(dataOutStream, defaultValue);
}
break;
}
// TODO Support other types of attributes
}
use of org.wso2.ballerinalang.programfile.attributes.ErrorTableAttributeInfo in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
public void visit(BLangLock lockNode) {
if (lockNode.lockVariables.isEmpty()) {
this.genNode(lockNode.body, this.env);
return;
}
Operand gotoLockEndAddr = getOperand(-1);
Instruction instructGotoLockEnd = InstructionFactory.get(InstructionCodes.GOTO, gotoLockEndAddr);
Operand[] operands = getOperands(lockNode);
ErrorTableAttributeInfo errorTable = createErrorTableIfAbsent(currentPkgInfo);
int fromIP = nextIP();
emit((InstructionCodes.LOCK), operands);
this.genNode(lockNode.body, this.env);
int toIP = nextIP() - 1;
emit((InstructionCodes.UNLOCK), operands);
emit(instructGotoLockEnd);
ErrorTableEntry errorTableEntry = new ErrorTableEntry(fromIP, toIP, nextIP(), 0, -1);
errorTable.addErrorTableEntry(errorTableEntry);
emit((InstructionCodes.UNLOCK), operands);
emit(InstructionFactory.get(InstructionCodes.THROW, getOperand(-1)));
gotoLockEndAddr.value = nextIP();
}
use of org.wso2.ballerinalang.programfile.attributes.ErrorTableAttributeInfo in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
public void visit(BLangTransaction transactionNode) {
++transactionIndex;
Operand transactionIndexOperand = getOperand(transactionIndex);
Operand retryCountRegIndex = new RegIndex(-1, TypeTags.INT);
if (transactionNode.retryCount != null) {
this.genNode(transactionNode.retryCount, this.env);
retryCountRegIndex = transactionNode.retryCount.regIndex;
}
Operand committedFuncRegIndex = new RegIndex(-1, TypeTags.INVOKABLE);
if (transactionNode.onCommitFunction != null) {
committedFuncRegIndex.value = getFuncRefCPIndex((BInvokableSymbol) ((BLangFunctionVarRef) transactionNode.onCommitFunction).symbol);
}
Operand abortedFuncRegIndex = new RegIndex(-1, TypeTags.INVOKABLE);
if (transactionNode.onAbortFunction != null) {
abortedFuncRegIndex.value = getFuncRefCPIndex((BInvokableSymbol) ((BLangFunctionVarRef) transactionNode.onAbortFunction).symbol);
}
ErrorTableAttributeInfo errorTable = createErrorTableIfAbsent(currentPkgInfo);
Operand transStmtEndAddr = getOperand(-1);
Operand transStmtAbortEndAddr = getOperand(-1);
Operand transStmtFailEndAddr = getOperand(-1);
Instruction gotoAbortTransBlockEnd = InstructionFactory.get(InstructionCodes.GOTO, transStmtAbortEndAddr);
Instruction gotoFailTransBlockEnd = InstructionFactory.get(InstructionCodes.GOTO, transStmtFailEndAddr);
abortInstructions.push(gotoAbortTransBlockEnd);
failInstructions.push(gotoFailTransBlockEnd);
// start transaction
this.emit(InstructionCodes.TR_BEGIN, transactionIndexOperand, retryCountRegIndex, committedFuncRegIndex, abortedFuncRegIndex);
Operand transBlockStartAddr = getOperand(nextIP());
// retry transaction;
Operand retryEndWithThrowAddr = getOperand(-1);
Operand retryEndWithNoThrowAddr = getOperand(-1);
this.emit(InstructionCodes.TR_RETRY, transactionIndexOperand, retryEndWithThrowAddr, retryEndWithNoThrowAddr);
// process transaction statements
this.genNode(transactionNode.transactionBody, this.env);
// end the transaction
int transBlockEndAddr = nextIP();
this.emit(InstructionCodes.TR_END, transactionIndexOperand, getOperand(TransactionStatus.SUCCESS.value()));
abortInstructions.pop();
failInstructions.pop();
emit(InstructionCodes.GOTO, transStmtEndAddr);
// CodeGen for error handling.
int errorTargetIP = nextIP();
transStmtFailEndAddr.value = errorTargetIP;
emit(InstructionCodes.TR_END, transactionIndexOperand, getOperand(TransactionStatus.FAILED.value()));
if (transactionNode.onRetryBody != null) {
this.genNode(transactionNode.onRetryBody, this.env);
}
emit(InstructionCodes.GOTO, transBlockStartAddr);
retryEndWithThrowAddr.value = nextIP();
emit(InstructionCodes.TR_END, transactionIndexOperand, getOperand(TransactionStatus.END.value()));
emit(InstructionCodes.THROW, getOperand(-1));
ErrorTableEntry errorTableEntry = new ErrorTableEntry(transBlockStartAddr.value, transBlockEndAddr, errorTargetIP, 0, -1);
errorTable.addErrorTableEntry(errorTableEntry);
transStmtAbortEndAddr.value = nextIP();
emit(InstructionCodes.TR_END, transactionIndexOperand, getOperand(TransactionStatus.ABORTED.value()));
int transactionEndIp = nextIP();
transStmtEndAddr.value = transactionEndIp;
retryEndWithNoThrowAddr.value = transactionEndIp;
emit(InstructionCodes.TR_END, transactionIndexOperand, getOperand(TransactionStatus.END.value()));
}
use of org.wso2.ballerinalang.programfile.attributes.ErrorTableAttributeInfo 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.programfile.attributes.ErrorTableAttributeInfo in project ballerina by ballerina-lang.
the class CodeGenerator method createErrorTableIfAbsent.
private ErrorTableAttributeInfo createErrorTableIfAbsent(PackageInfo packageInfo) {
ErrorTableAttributeInfo errorTable = (ErrorTableAttributeInfo) packageInfo.getAttributeInfo(AttributeInfo.Kind.ERROR_TABLE);
if (errorTable == null) {
UTF8CPEntry attribNameCPEntry = new UTF8CPEntry(AttributeInfo.Kind.ERROR_TABLE.toString());
int attribNameCPIndex = packageInfo.addCPEntry(attribNameCPEntry);
errorTable = new ErrorTableAttributeInfo(attribNameCPIndex);
packageInfo.addAttributeInfo(AttributeInfo.Kind.ERROR_TABLE, errorTable);
}
return errorTable;
}
Aggregations