Skip to content

Commit

Permalink
Mark static methods as such
Browse files Browse the repository at this point in the history
  • Loading branch information
romainguy committed Dec 11, 2024
1 parent 4500f3b commit b185b02
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,19 @@ enum class ISA(val branchInstructions: ScatterSet<String>, val returnInstruction

data class Class(val header: String, val methods: List<Method>, val builtIn: Boolean)

data class Method(val header: String, val instructionSet: InstructionSet, val index: Int = -1, val codeSize: Int = -1)
const val AccessPublic = 0x00001
const val AccessPrivate = 0x00002
const val AccessStatic = 0x00008
const val AccessFinal = 0x00010
const val AccessSynthetic = 0x01000
const val AccessConstructor = 0x10000

data class Method(
val header: String,
val instructionSet: InstructionSet,
val index: Int = -1,
val codeSize: Int = -1
)

data class InstructionSet(
val isa: ISA,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ import dev.romainguy.kotlin.explorer.oat.codeToOpAndOperands
private val PositionRegex = Regex("^\\s*0x(?<address>[0-9a-f]+) line=(?<line>\\d+)$")

private val JumpRegex = Regex("^$HexDigit{4}: .* (?<address>$HexDigit{4}) // [+-]$HexDigit{4}$")
private val AccessRegex = Regex("^access\\s+:\\s+0x(?<bitField>[0-9a-fA-F]+)\\s+\\(.+\\)$")

private const val ClassStart = "Class #"
private const val ClassEnd = "source_file_idx"
private const val ClassName = "Class descriptor"
private const val Instructions = "insns size"
private const val Positions = "positions"
private const val Access = "access"

internal class DexDumpParser {
fun parse(text: String): CodeContent {
println(text)
return try {
val lines = text.lineSequence().iterator()
val classes = buildList {
Expand All @@ -61,18 +64,20 @@ internal class DexDumpParser {
return null
}
val methods = buildList {
var access = 0
while (hasNext()) {
val line = next().trim()
if (line.startsWith(Access)) access = readAccess(line)
when {
line.startsWith(ClassEnd) -> break
line.startsWith(Instructions) -> add(readMethod(className))
line.startsWith(Instructions) -> add(readMethod(className, access))
}
}
}
return Class("class $className", methods, false)
}

private fun Iterator<String>.readMethod(className: String): Method {
private fun Iterator<String>.readMethod(className: String, access: Int): Method {
val (name, type) = next().substringAfterLast(".").split(':', limit = 2)
val instructions = readInstructions()

Expand All @@ -83,16 +88,23 @@ internal class DexDumpParser {
val paramTypes = paramTypesFromType(type).joinToString(", ")

return Method(
"$returnType $className.$name($paramTypes)",
"$returnType $className.$name($paramTypes)${accessToString(access)}",
InstructionSet(ISA.Dex, instructions.withLineNumbers(positions))
)
}

private fun accessToString(access: Int) = if (access and AccessStatic != 0) " // static" else ""

private fun readAccess(line: String): Int {
val bitField = AccessRegex.matchEntire(line)?.getValue("bitField")
return if (bitField != null) bitField.toInt(16) else 0
}

private fun Iterator<String>.readInstructions(): List<Instruction> {
return buildList {
while (hasNext()) {
val line = next()
if (line.startsWith(" ")) {
if (line[0] == ' ') {
break
}
val code = line.substringAfter('|')
Expand Down

0 comments on commit b185b02

Please sign in to comment.