Kotlin: Refactor writeUpdateInPlaceExpr

In tryExtractArrayUpdate we need to know if writeUpdateInPlaceExpr will
succeed before we start writing any TRAP.
This commit is contained in:
Ian Lynagh
2022-08-24 14:31:10 +01:00
parent 31e1230c64
commit e4f66b8aa7

View File

@@ -2486,18 +2486,21 @@ open class KotlinFileExtractor(
}
}
private fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label<DbAssignexpr>, type: TypeResults, exprParent: ExprParent): Boolean {
private fun writeUpdateInPlaceExpr(origin: IrStatementOrigin): ((tw: TrapWriter, id: Label<out DbAssignexpr>, type: Label<out DbType>, exprParent: Label<out DbExprparent>, index: Int) -> Unit)? {
when(origin) {
IrStatementOrigin.PLUSEQ -> tw.writeExprs_assignaddexpr(id.cast<DbAssignaddexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
IrStatementOrigin.MINUSEQ -> tw.writeExprs_assignsubexpr(id.cast<DbAssignsubexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
IrStatementOrigin.MULTEQ -> tw.writeExprs_assignmulexpr(id.cast<DbAssignmulexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
IrStatementOrigin.DIVEQ -> tw.writeExprs_assigndivexpr(id.cast<DbAssigndivexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
IrStatementOrigin.PERCEQ -> tw.writeExprs_assignremexpr(id.cast<DbAssignremexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
else -> return false
IrStatementOrigin.PLUSEQ -> return { tw: TrapWriter, id: Label<out DbAssignexpr>, type: Label<out DbType>, exprParent: Label<out DbExprparent>, index: Int -> tw.writeExprs_assignaddexpr(id.cast<DbAssignaddexpr>(), type, exprParent, index) }
IrStatementOrigin.MINUSEQ -> return { tw: TrapWriter, id: Label<out DbAssignexpr>, type: Label<out DbType>, exprParent: Label<out DbExprparent>, index: Int -> tw.writeExprs_assignsubexpr(id.cast<DbAssignsubexpr>(), type, exprParent, index) }
IrStatementOrigin.MULTEQ -> return { tw: TrapWriter, id: Label<out DbAssignexpr>, type: Label<out DbType>, exprParent: Label<out DbExprparent>, index: Int -> tw.writeExprs_assignmulexpr(id.cast<DbAssignmulexpr>(), type, exprParent, index) }
IrStatementOrigin.DIVEQ -> return { tw: TrapWriter, id: Label<out DbAssignexpr>, type: Label<out DbType>, exprParent: Label<out DbExprparent>, index: Int -> tw.writeExprs_assigndivexpr(id.cast<DbAssigndivexpr>(), type, exprParent, index) }
IrStatementOrigin.PERCEQ -> return { tw: TrapWriter, id: Label<out DbAssignexpr>, type: Label<out DbType>, exprParent: Label<out DbExprparent>, index: Int -> tw.writeExprs_assignremexpr(id.cast<DbAssignremexpr>(), type, exprParent, index) }
else -> return null
}
return true
}
/**
* This tried to extract a block as an array update.
* It returns true if it succeeds, and false otherwise.
*/
private fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label<out DbCallable>, parent: StmtExprParent): Boolean {
/*
* We're expecting the pattern
@@ -2528,6 +2531,12 @@ open class KotlinFileExtractor(
},
arraySetCall.getValueArgument(1)!!
)?.let { updateRhs ->
val writeUpdateInPlaceExprFun = writeUpdateInPlaceExpr(e.origin!!)
if (writeUpdateInPlaceExprFun == null) {
logger.errorElement("Unexpected origin", e)
return false
}
// Create an assignment skeleton _ op= _
val exprParent = parent.expr(e, callable)
val assignId = tw.getFreshIdLabel<DbAssignexpr>()
@@ -2538,10 +2547,7 @@ open class KotlinFileExtractor(
tw.writeCallableEnclosingExpr(assignId, callable)
tw.writeStatementEnclosingExpr(assignId, exprParent.enclosingStmt)
if (!writeUpdateInPlaceExpr(e.origin!!, tw, assignId, type, exprParent)) {
logger.errorElement("Unexpected origin", e)
return false
}
writeUpdateInPlaceExprFun(tw, assignId, type.javaResult.id, exprParent.parent, exprParent.idx)
// Extract e1[e2]
val lhsId = tw.getFreshIdLabel<DbArrayaccess>()
@@ -2897,10 +2903,14 @@ open class KotlinFileExtractor(
if (origin == null) {
logger.errorElement("No origin for set-value", e)
return
} else if (!writeUpdateInPlaceExpr(origin, tw, id, type, exprParent)) {
} else {
val writeUpdateInPlaceExprFun = writeUpdateInPlaceExpr(origin)
if (writeUpdateInPlaceExprFun == null) {
logger.errorElement("Unexpected origin for set-value", e)
return
}
writeUpdateInPlaceExprFun(tw, id, type.javaResult.id, exprParent.parent, exprParent.idx)
}
} else {
tw.writeExprs_assignexpr(id, type.javaResult.id, exprParent.parent, exprParent.idx)
}