
apparat.tools.tdsi.TurboDieselSportInjection.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apparat-core Show documentation
Show all versions of apparat-core Show documentation
The core framework of Apparat.
The newest version!
/*
* This file is part of Apparat.
*
* Apparat is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Apparat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Apparat. If not, see .
*
* Copyright (C) 2009 Joa Ebert
* http://www.joa-ebert.com/
*
*/
package apparat.tools.tdsi
import java.io.{File => JFile}
import apparat.utils.TagContainer
import apparat.actors.Futures._
import apparat.abc._
import analysis.QuickAbcConstantPoolBuilder
import apparat.bytecode.operations._
import apparat.bytecode.combinator._
import apparat.bytecode.combinator.BytecodeChains._
import apparat.swf._
import annotation.tailrec
import apparat.bytecode.optimization._
import apparat.tools.{ApparatConfiguration, ApparatApplication, ApparatTool}
/**
* @author Joa Ebert
*/
object TurboDieselSportInjection {
def main(args: Array[String]): Unit = ApparatApplication(new TDSITool, args)
class TDSITool extends ApparatTool
{
var input: JFile = _
var output: JFile = _
var alchemy = true
var macros = true
var inline = true
var fixAlchemy = false
var asm = true
override def name = "Turbo Diesel Sport Injection"
override def help = """ -i [file] Input file
-o [file] Output file (optional)
-f (true|false) Fix bytecode generated by Alchemy
-a (true|false) Inline Alchemy operations
-e (true|false) Inline expansion
-m (true|false) Macro expansion
-s (true|false) Asm expansion"""
override def configure(config: ApparatConfiguration): Unit = configure(TDSIConfigurationFactory fromConfiguration config)
def configure(config: TDSIConfiguration): Unit = {
input = config.input
output = config.output
alchemy = config.alchemyExpansion
macros = config.macroExpansion
inline = config.inlineExpansion
fixAlchemy = config.fixAlchemy
asm = config.asmExpansion
}
override def run() = {
SwfTags.tagFactory = (kind: Int) => kind match {
case SwfTags.DoABC => Some(new DoABC)
case SwfTags.DoABC1 => Some(new DoABC)
case _ => None
}
val source = input
val target = output
val cont = TagContainer fromFile source
val allABC = (for(doABC <- cont.tags collect { case doABC: DoABC => doABC }) yield (doABC -> (Abc fromDoABC doABC))).toMap
val macroExpansion = if(macros) Some(new MacroExpansion(allABC.valuesIterator.toList)) else None
val inlineExpansion = if(inline) Some(new InlineExpansion(allABC.valuesIterator.toList)) else None
val memoryExpansion = if(alchemy) Some(new MemoryHelperExpansion(allABC.valuesIterator.toList)) else None
allABC foreach { _._2.loadBytecode() }
var rebuildCpoolSet = Set.empty[Abc]
if (asm) {
for((doABC, abc) <- allABC) {
for {
method <- abc.methods
body <- method.body
bytecode <- body.bytecode
} {
var rebuildCpool = false
@tailrec def modifyBytecode(counter: Int): Unit = {
var modified = false
if(AsmExpansion(bytecode)) {
modified = true
rebuildCpool = true
}
if (modified && (counter < 31)) {
modifyBytecode(counter + 1)
}
}
PeepholeOptimizations(bytecode)
modifyBytecode(0)
if(rebuildCpool) {
rebuildCpoolSet += abc
}
}
}
}
for((doABC, abc) <- allABC) {
var rebuildCpool = rebuildCpoolSet.contains(abc)
for {
method <- abc.methods
body <- method.body
bytecode <- body.bytecode
} {
@tailrec def modifyBytecode(counter: Int): Unit = {
var modified = false
if(inline && (inlineExpansion.get expand bytecode)) {
modified = true
rebuildCpool = true
}
if(macros && (macroExpansion.get expand bytecode)) {
modified = true
rebuildCpool = true
}
if(alchemy) {
modified |= InlineMemory(bytecode)
modified |= memoryExpansion.get expand bytecode
}
if(fixAlchemy) {
modified |= AlchemyOptimizations(bytecode)
}
modified |= PeepholeOptimizations(bytecode)
if (modified && (counter < 31)) {
modifyBytecode(counter + 1)
}
}
modifyBytecode(0)
}
if(rebuildCpool) {
//
// We have to rebuild the cpool here since both Macro and Inline
// expansion could include operations from a different ABC
// and in that case its values do not belong to the cpool.
//
log.info("Cpool rebuild required.")
abc.cpool = QuickAbcConstantPoolBuilder using abc
}
abc.saveBytecode()
abc write doABC
}
cont write target
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy