Removed a few JDK dependencies

This commit is contained in:
Smallhacker 2019-01-18 22:51:37 +01:00
parent 1e2cf6978d
commit 19424abe28
8 changed files with 40 additions and 23 deletions

View File

@ -4,8 +4,6 @@ import com.smallhacker.disbrowser.util.UInt24
import com.smallhacker.disbrowser.util.joinBytes
import com.smallhacker.disbrowser.util.joinNullableBytes
import com.smallhacker.disbrowser.util.toUInt24
import java.nio.file.Files
import java.nio.file.Path
interface MemorySpace {
val size: UInt

View File

@ -1,7 +1,5 @@
package com.smallhacker.disbrowser.asm
import java.util.HashMap
import com.smallhacker.disbrowser.asm.Mnemonic.*
typealias SegmentEnder = Instruction.() -> SegmentEnd?

View File

@ -3,8 +3,6 @@ package com.smallhacker.disbrowser.asm
import com.smallhacker.disbrowser.datatype.MutableRangeMap
import com.smallhacker.disbrowser.datatype.NaiveRangeMap
import com.smallhacker.disbrowser.util.toUInt24
import java.nio.file.Files
import java.nio.file.Path
abstract class SnesMemory: MemorySpace {
override val size = 0x100_0000u
@ -28,9 +26,8 @@ abstract class SnesMemory: MemorySpace {
}
companion object {
fun loadRom(path: Path): SnesMemory {
val bytes = Files.readAllBytes(path).toUByteArray()
val romSpace = ArrayMemorySpace(bytes)
fun loadRom(fileData: UByteArray): SnesMemory {
val romSpace = ArrayMemorySpace(fileData)
// TODO: Auto-detect ROM type
return SnesLoRom(romSpace)
}

View File

@ -2,16 +2,16 @@ package com.smallhacker.disbrowser.disassembler
import com.smallhacker.disbrowser.asm.*
import com.smallhacker.disbrowser.game.*
import com.smallhacker.disbrowser.util.LifoQueue
import com.smallhacker.disbrowser.util.mutableMultiMap
import com.smallhacker.disbrowser.util.putSingle
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
object Disassembler {
fun disassemble(initialState: State, gameData: GameData, global: Boolean): Disassembly {
val seen = HashSet<SnesAddress>()
val queue = ArrayDeque<State>()
val queue = LifoQueue<State>()
val origins = mutableMultiMap<SnesAddress, SnesAddress>()
val instructionMap = HashMap<SnesAddress, MutableInstruction>()
@ -27,7 +27,7 @@ object Disassembler {
val instructions = ArrayList<CodeUnit>()
while (queue.isNotEmpty()) {
val state = queue.remove()
val state = queue.removeNext()
val ins = disassembleInstruction(state)
instructions.add(ins)
@ -98,10 +98,10 @@ object Disassembler {
}
val fatalSeen = HashSet<SnesAddress>()
val fatalQueue = ArrayDeque<SnesAddress>()
val fatalQueue = LifoQueue<SnesAddress>()
fun tryAddFatal(snesAddress: SnesAddress) {
if (fatalSeen.add(snesAddress)) {
fatalQueue.addLast(snesAddress)
fatalQueue.add(snesAddress)
}
}
@ -111,7 +111,7 @@ object Disassembler {
.forEach { tryAddFatal(it.address) }
while (fatalQueue.isNotEmpty()) {
val badAddress = fatalQueue.removeFirst()!!
val badAddress = fatalQueue.removeNext()!!
val instruction = instructionMap[badAddress] ?: continue
val mnemonic = instruction.opcode.mnemonic
if (mnemonic == Mnemonic.JSL || mnemonic == Mnemonic.JSR) continue
@ -128,7 +128,7 @@ object Disassembler {
fun disassembleSegments(initialState: State): List<Segment> {
val mapping = HashMap<SnesAddress, Segment>()
val queue = ArrayDeque<State>()
val queue = LifoQueue<State>()
val segments = ArrayList<Segment>()
@ -141,7 +141,7 @@ object Disassembler {
while (queue.isNotEmpty()) {
val state = queue.remove()
val state = queue.removeNext()
if (mapping.containsKey(state.address)) {
continue
@ -169,7 +169,7 @@ object Disassembler {
val instructions = ArrayList<Instruction>()
var lastState = initialState
val queue = ArrayDeque<State>()
val queue = LifoQueue<State>()
val seen = HashSet<SnesAddress>()
fun finalize(segment: Segment): Segment {
@ -187,7 +187,7 @@ object Disassembler {
tryAdd(initialState)
while (queue.isNotEmpty()) {
val state = queue.remove()
val state = queue.removeNext()
val ins = disassembleInstruction(state)
instructions.add(ins)

View File

@ -3,6 +3,7 @@ package com.smallhacker.disbrowser.game
import com.smallhacker.disbrowser.asm.SnesMemory
import com.smallhacker.disbrowser.util.jsonFile
import org.glassfish.jersey.server.ResourceConfig
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.concurrent.ConcurrentHashMap
@ -34,7 +35,8 @@ class GameSource(private val gameDataDir: Path) {
val gameData = gameDataJsonFile.load()
val gamePath = Paths.get(gameData.path)
val rom = SnesMemory.loadRom(gamePath)
val romData = Files.readAllBytes(gamePath).toUByteArray()
val rom = SnesMemory.loadRom(romData)
Game(name, rom, gameData, gameDataJsonFile)
} catch (e: Exception) {
e.printStackTrace()

View File

@ -0,0 +1,14 @@
package com.smallhacker.disbrowser.util
// The Kotlin standard library does not contain a counterpart to Java's ArrayDeque<E>, so let's implement a simplistic
// one ourselves for portability.
interface ItemQueue<E> : MutableCollection<E> {
fun removeNext(): E
}
class LifoQueue<E> private constructor(private val list: MutableList<E>) : ItemQueue<E>, MutableCollection<E> by list {
constructor() : this(ArrayList())
override fun removeNext(): E = list.removeAt(0)
}

View File

@ -1,7 +1,5 @@
package com.smallhacker.disbrowser.util
import java.util.*
abstract class UType(val bytes: Int, val name: String) {
val mask = (1 shl (bytes * 8)) - 1
}
@ -22,7 +20,7 @@ class UVal<U : UType>(value: Int, val type: U) : Comparable<UVal<U>> {
override fun compareTo(other: UVal<U>): Int = Integer.compare(value, other.value)
override fun hashCode() = Objects.hash(value, type)
override fun hashCode() = hashOf(value, type)
//fun value(value: Int) = UVal(value, type)
//fun mutate(mutator: (Int) -> Int) = UVal(mutator(value), type)

View File

@ -86,4 +86,14 @@ fun <K, V> MutableMap<K, V>.removeIf(condition: (K, V) -> Boolean) {
.map { it.key }
.toList()
.forEach { remove(it) }
}
fun hashOf(vararg values: Any?): Int {
return if (values.isEmpty()) {
0
} else {
values.asSequence()
.map { it.hashCode() }
.reduce { acc, v -> (acc * 31) + v }
}
}