use of org.wso2.ballerinalang.programfile.Instruction.Operand in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
@Override
public void visit(BLangMapAccessExpr mapKeyAccessExpr) {
boolean variableStore = this.varAssignment;
this.varAssignment = false;
genNode(mapKeyAccessExpr.expr, this.env);
Operand varRefRegIndex = mapKeyAccessExpr.expr.regIndex;
genNode(mapKeyAccessExpr.indexExpr, this.env);
Operand keyRegIndex = mapKeyAccessExpr.indexExpr.regIndex;
BMapType mapType = (BMapType) mapKeyAccessExpr.expr.type;
if (variableStore) {
int opcode = getValueToRefTypeCastOpcode(mapType.constraint.tag);
if (opcode == InstructionCodes.NOP) {
emit(InstructionCodes.MAPSTORE, varRefRegIndex, keyRegIndex, mapKeyAccessExpr.regIndex);
} else {
RegIndex refRegMapValue = getRegIndex(TypeTags.ANY);
emit(opcode, mapKeyAccessExpr.regIndex, refRegMapValue);
emit(InstructionCodes.MAPSTORE, varRefRegIndex, keyRegIndex, refRegMapValue);
}
} else {
int opcode = getRefToValueTypeCastOpcode(mapType.constraint.tag);
if (opcode == InstructionCodes.NOP) {
emit(InstructionCodes.MAPLOAD, varRefRegIndex, keyRegIndex, calcAndGetExprRegIndex(mapKeyAccessExpr));
} else {
RegIndex refRegMapValue = getRegIndex(TypeTags.ANY);
emit(InstructionCodes.MAPLOAD, varRefRegIndex, keyRegIndex, refRegMapValue);
emit(opcode, refRegMapValue, calcAndGetExprRegIndex(mapKeyAccessExpr));
}
}
this.varAssignment = variableStore;
}
use of org.wso2.ballerinalang.programfile.Instruction.Operand in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
public void visit(BLangWhile whileNode) {
Instruction gotoTopJumpInstr = InstructionFactory.get(InstructionCodes.GOTO, getOperand(this.nextIP()));
this.genNode(whileNode.expr, this.env);
Operand exitLoopJumpAddr = getOperand(-1);
Instruction exitLoopJumpInstr = InstructionFactory.get(InstructionCodes.GOTO, exitLoopJumpAddr);
emit(InstructionCodes.BR_FALSE, whileNode.expr.regIndex, exitLoopJumpAddr);
this.loopResetInstructionStack.push(gotoTopJumpInstr);
this.loopExitInstructionStack.push(exitLoopJumpInstr);
this.genNode(whileNode.body, this.env);
this.loopResetInstructionStack.pop();
this.loopExitInstructionStack.pop();
this.emit(gotoTopJumpInstr);
exitLoopJumpAddr.value = nextIP();
}
use of org.wso2.ballerinalang.programfile.Instruction.Operand in project ballerina by ballerina-lang.
the class CodeGenerator method generateNamedArgs.
private int generateNamedArgs(BLangInvocation iExpr, Operand[] operands, int currentIndex) {
if (iExpr.namedArgs.isEmpty()) {
return currentIndex;
}
PackageInfo pkgInfo = programFile.packageInfoMap.get(iExpr.symbol.pkgID.bvmAlias());
CallableUnitInfo callableUnitInfo;
if (iExpr.symbol.kind == SymbolKind.FUNCTION) {
callableUnitInfo = pkgInfo.functionInfoMap.get(iExpr.symbol.name.value);
} else if (iExpr.symbol.kind == SymbolKind.ACTION) {
ConnectorInfo connectorInfo = pkgInfo.connectorInfoMap.get(iExpr.symbol.owner.name.value);
callableUnitInfo = connectorInfo.actionInfoMap.get(iExpr.symbol.name.value);
} else {
throw new IllegalStateException("Unsupported callable unit");
}
ParamDefaultValueAttributeInfo defaultValAttrInfo = (ParamDefaultValueAttributeInfo) callableUnitInfo.getAttributeInfo(AttributeInfo.Kind.PARAMETER_DEFAULTS_ATTRIBUTE);
for (int i = 0; i < iExpr.namedArgs.size(); i++) {
BLangExpression argExpr = iExpr.namedArgs.get(i);
// at this point. If so, get the default value for that parameter from the function info.
if (argExpr == null) {
DefaultValue defaultVal = defaultValAttrInfo.getDefaultValueInfo()[i];
argExpr = getDefaultValExpr(defaultVal);
}
operands[currentIndex++] = genNode(argExpr, this.env).regIndex;
}
return currentIndex;
}
use of org.wso2.ballerinalang.programfile.Instruction.Operand in project ballerina by ballerina-lang.
the class CodeGenerator method visitAndExpression.
private void visitAndExpression(BLangBinaryExpr binaryExpr) {
// Code address to jump if at least one of the expressions get evaluated to false.
// short-circuit evaluation
Operand falseJumpAddr = getOperand(-1);
// Generate code for the left hand side
genNode(binaryExpr.lhsExpr, this.env);
emit(InstructionCodes.BR_FALSE, binaryExpr.lhsExpr.regIndex, falseJumpAddr);
// Generate code for the right hand side
genNode(binaryExpr.rhsExpr, this.env);
emit(InstructionCodes.BR_FALSE, binaryExpr.rhsExpr.regIndex, falseJumpAddr);
// If both l and r conditions are true, then load 'true'
calcAndGetExprRegIndex(binaryExpr);
emit(InstructionCodes.BCONST_1, binaryExpr.regIndex);
Operand gotoAddr = getOperand(-1);
emit(InstructionCodes.GOTO, gotoAddr);
falseJumpAddr.value = nextIP();
// Load 'false' if the both conditions are false;
emit(InstructionCodes.BCONST_0, binaryExpr.regIndex);
gotoAddr.value = nextIP();
}
use of org.wso2.ballerinalang.programfile.Instruction.Operand in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
// Expressions
@Override
public void visit(BLangLiteral literalExpr) {
int opcode;
Operand regIndex = calcAndGetExprRegIndex(literalExpr);
int typeTag = literalExpr.type.tag;
switch(typeTag) {
case TypeTags.INT:
long longVal = (Long) literalExpr.value;
if (longVal >= 0 && longVal <= 5) {
opcode = InstructionCodes.ICONST_0 + (int) longVal;
emit(opcode, regIndex);
} else {
int intCPEntryIndex = currentPkgInfo.addCPEntry(new IntegerCPEntry(longVal));
emit(InstructionCodes.ICONST, getOperand(intCPEntryIndex), regIndex);
}
break;
case TypeTags.FLOAT:
double doubleVal = (Double) literalExpr.value;
if (doubleVal == 0 || doubleVal == 1 || doubleVal == 2 || doubleVal == 3 || doubleVal == 4 || doubleVal == 5) {
opcode = InstructionCodes.FCONST_0 + (int) doubleVal;
emit(opcode, regIndex);
} else {
int floatCPEntryIndex = currentPkgInfo.addCPEntry(new FloatCPEntry(doubleVal));
emit(InstructionCodes.FCONST, getOperand(floatCPEntryIndex), regIndex);
}
break;
case TypeTags.STRING:
String strValue = (String) literalExpr.value;
StringCPEntry stringCPEntry = new StringCPEntry(addUTF8CPEntry(currentPkgInfo, strValue), strValue);
int strCPIndex = currentPkgInfo.addCPEntry(stringCPEntry);
emit(InstructionCodes.SCONST, getOperand(strCPIndex), regIndex);
break;
case TypeTags.BOOLEAN:
boolean booleanVal = (Boolean) literalExpr.value;
if (!booleanVal) {
opcode = InstructionCodes.BCONST_0;
} else {
opcode = InstructionCodes.BCONST_1;
}
emit(opcode, regIndex);
break;
case TypeTags.NULL:
emit(InstructionCodes.RCONST_NULL, regIndex);
}
}
Aggregations