Added <throws> node for a function’s DFG

This commit is contained in:
Igor Chevdar
2017-12-14 23:29:45 +03:00
parent 56a214c454
commit 013a4abba3
3 changed files with 18 additions and 9 deletions
@@ -272,7 +272,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
}
val function = FunctionDFGBuilder(expressionValuesExtractor, visitor.variableValues,
descriptor, visitor.expressions, visitor.returnValues).build()
descriptor, visitor.expressions, visitor.returnValues, visitor.thrownValues).build()
DEBUG_OUTPUT(1) {
function.debugOutput()
@@ -306,6 +306,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
val expressions = mutableListOf<IrExpression>()
val variableValues = VariableValues()
val returnValues = mutableListOf<IrExpression>()
val thrownValues = mutableListOf<IrExpression>()
private val returnableBlocks = mutableMapOf<FunctionDescriptor, IrReturnableBlock>()
private val suspendableExpressionStack = mutableListOf<IrSuspendableExpression>()
@@ -369,6 +370,11 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
super.visitReturn(expression)
}
override fun visitThrow(expression: IrThrow) {
thrownValues += expression.value
super.visitThrow(expression)
}
override fun visitSetVariable(expression: IrSetVariable) {
super.visitSetVariable(expression)
assignVariable(expression.descriptor, expression.value)
@@ -389,7 +395,8 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
val variableValues: VariableValues,
val descriptor: CallableDescriptor,
val expressions: List<IrExpression>,
val returnValues: List<IrExpression>) {
val returnValues: List<IrExpression>,
val thrownValues: List<IrExpression>) {
private val allParameters = (descriptor as? FunctionDescriptor)?.allParameters ?: emptyList()
private val templateParameters = allParameters.withIndex().associateBy({ it.value }, { DataFlowIR.Node.Parameter(it.index) })
@@ -414,19 +421,20 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
fun build(): DataFlowIR.Function {
expressions.forEach { getNode(it) }
val returnsNode = DataFlowIR.Node.Variable(returnValues.map { expressionToEdge(it) }, true)
val throwsNode = DataFlowIR.Node.Variable(thrownValues.map { expressionToEdge(it) }, true)
variables.forEach { descriptor, node ->
variableValues.elementData[descriptor]!!.forEach {
node.values += expressionToEdge(it)
}
}
val allNodes = nodes.values + variables.values + templateParameters.values + returnsNode +
val allNodes = nodes.values + variables.values + templateParameters.values + returnsNode + throwsNode +
(if (descriptor.isSuspend) listOf(continuationParameter!!) else emptyList())
return DataFlowIR.Function(
symbol = symbolTable.mapFunction(descriptor),
isGlobalInitializer = descriptor is PropertyDescriptor,
numberOfParameters = templateParameters.size + if (descriptor.isSuspend) 1 else 0,
body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode)
body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode, throwsNode)
)
}
@@ -582,13 +582,14 @@ internal object DFGSerializer {
}
}
class FunctionBody(val nodes: Array<Node>, val returns: Int) {
class FunctionBody(val nodes: Array<Node>, val returns: Int, val throws: Int) {
constructor(data: ArraySlice) : this(data.readArray { Node.read(this) }, data.readInt())
constructor(data: ArraySlice) : this(data.readArray { Node.read(this) }, data.readInt(), data.readInt())
fun write(result: ArraySlice) {
result.writeArray(nodes) { it.write(this) }
result.writeInt(returns)
result.writeInt(throws)
}
}
@@ -737,7 +738,7 @@ internal object DFGSerializer {
functionSymbolMap[function.symbol]!!,
function.isGlobalInitializer,
function.numberOfParameters,
FunctionBody(nodes, nodeMap[body.returns]!!)
FunctionBody(nodes, nodeMap[body.returns]!!, nodeMap[body.throws]!!)
)
}
.toTypedArray()
@@ -985,7 +986,7 @@ internal object DFGSerializer {
else -> { }
}
}
return DataFlowIR.FunctionBody(nodes, nodes[body.returns] as DataFlowIR.Node.Variable)
return DataFlowIR.FunctionBody(nodes, nodes[body.returns] as DataFlowIR.Node.Variable, nodes[body.throws] as DataFlowIR.Node.Variable)
}
moduleDataFlowGraph.functions.forEach {
@@ -193,7 +193,7 @@ internal object DataFlowIR {
}
}
class FunctionBody(val nodes: List<Node>, val returns: Node.Variable)
class FunctionBody(val nodes: List<Node>, val returns: Node.Variable, val throws: Node.Variable)
class Function(val symbol: FunctionSymbol,
val isGlobalInitializer: Boolean,