|
Scala example source code file (ILPrinterVisitor.scala)
This example Scala source code file (ILPrinterVisitor.scala) is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.
The Scala ILPrinterVisitor.scala source code
/*
* System.Reflection.Emit-like API for writing .NET assemblies in MSIL
*/
package ch.epfl.lamp.compiler.msil.emit
import java.io.File
import java.io.FileWriter
import java.io.BufferedWriter
import java.io.PrintWriter
import java.io.IOException
import java.util.Comparator
import ch.epfl.lamp.compiler.msil._
import ch.epfl.lamp.compiler.msil.util.Table
/**
* The MSIL printer Visitor. It prints a complete
* assembly in a single or multiple files. Then this file can be compiled by ilasm.
*
* @author Nikolay Mihaylov
* @version 1.0
*/
abstract class ILPrinterVisitor extends Visitor {
import ILPrinterVisitor._
import OpCode._
//##########################################################################
protected final val assemblyNameComparator =
new scala.math.Ordering[Assembly]() {
override def compare(o1: Assembly, o2: Assembly): Int = {
val a1 = o1.asInstanceOf[Assembly]
val a2 = o2.asInstanceOf[Assembly]
return a1.GetName().Name.compareTo(a2.GetName().Name)
}
}
// the output file writer
protected var out: PrintWriter = null
// the left margin
private var lmargin = 0
// indicate a newline
private var newline = true
// print types without or with members?
protected var nomembers: Boolean = false
// external assemblies
protected var as: Array[Assembly] = null
private def align() {
if (newline)
padding = lmargin
printPadding()
newline = false
}
private def indent() {
lmargin += TAB
}
private def undent() {
lmargin -= TAB
assert(lmargin >= 0)
}
private var padding = 0
private def pad(n: Int) {
assert(n >= 0, "negative padding: " + n)
padding += n
}
private def printPadding() {
if (padding <= 0)
return
while (padding > SPACES_LEN) {
out.print(SPACES)
padding -= SPACES_LEN
}
out.print(SPACES.substring(0, padding))
padding = 0
}
// methods to print code
protected def print(s: String) { align(); out.print(s)}
protected def print(o: Object) { align(); out.print(o) }
protected def print(c: Char) { align(); out.print(c) }
protected def print(`val`: Int) { align(); out.print(`val`)}
protected def print(`val`: Long){ align(); out.print(`val`)}
protected def println() { out.println(); newline = true; padding = 0 }
protected def println(c: Char) { print(c); println() }
protected def println(i: Int) { print(i); println() }
protected def println(l: Long) { print(l); println() }
protected def println(s: String){ print(s); println() }
protected def println(o: Object){ print(o); println() }
protected def printName(name: String) {
var ch = name.charAt(0)
//if (Character.isLetter(ch) && Character.isLowerCase(ch)) {
if ((ch != '.') && (ch != '!')) {
print('\''); print(name); print('\'')
} else
print(name)
}
protected def printAssemblyBoilerplate() {
// print all the external assemblies
for (j <- 0 until as.length) {
printAssemblySignature(as(j), true)
}
// print assembly declaration
printAssemblySignature(currAssembly, false)
}
// the entrypoint method
protected var entryPoint: MethodInfo = null
// current opcode argument
protected var argument: Object = null
/***/
@throws(classOf[IOException])
protected def print(vAble: Visitable) {
if (vAble != null)
vAble.apply(this)
}
/**
* Visit an AssemblyBuilder
*/
@throws(classOf[IOException])
def caseAssemblyBuilder(assemblyBuilder: AssemblyBuilder)
protected var currentModule: Module = null
/**
* Visit a ModuleBuilder
*/
@throws(classOf[IOException])
def caseModuleBuilder(module: ModuleBuilder)
protected var currentType: Type = null
def printTypeParams(sortedTVars : Array[GenericParamAndConstraints]) {
def constraintFlags(tVar : GenericParamAndConstraints) = {
val varianceDirective = (if (tVar.isCovariant) "+ " else (if (tVar.isContravariant) "- " else ""))
val typeKindDirective = (if (tVar.isReferenceType) "class " else (if (tVar.isValueType) "valuetype " else ""))
val dfltConstrDirective = (if (tVar.hasDefaultConstructor) ".ctor " else "")
varianceDirective + typeKindDirective + dfltConstrDirective
}
def tparamName(tVar : GenericParamAndConstraints) = {
/* TODO Type-params in referenced assemblies may lack a name (those in a TypeBuilder or MethodBuilder shouldn't).
Given that we need not list (in ilasm syntax) the original type-params' names when
providing type arguments to it, the only type-param-names we'll serialize into a .msil file
are those for type-params in a TypeBuilder or MethodBuilder. Still, more details on this
appear in Sec. 4.5 "Faulty metadata in XMLReaderFactory" of
http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/Libs4Lib.pdf
To avoid name clashes when choosing a param name,
first collect all existing tparam-names from a type (and its nested types).
Not that those names are needed (ordinal positions can be used instead)
but will look better when disassembling with ildasm. */
assert(tVar.Name != null)
tVar.Name
}
if(sortedTVars.length == 0) { return }
print('<')
val lastIdx = sortedTVars.length - 1
for (it <- 0 until sortedTVars.length) {
val tVar = sortedTVars(it)
print(constraintFlags(tVar))
if(tVar.Constraints.length > 0) {
print('(')
val lastCnstrtIdx = tVar.Constraints.length - 1
for (ic <- 0 until tVar.Constraints.length) {
val cnstrt = tVar.Constraints(ic)
printReference(cnstrt)
if (ic < lastIdx) { print(", ") }
}
print(')')
}
print(" " + tparamName(tVar))
if (it < lastIdx) { print(", ") }
}
print('>')
}
/**
* Visit a TypeBuilder
*/
@throws(classOf[IOException])
def caseTypeBuilder(`type`: TypeBuilder) {
currentType = `type`
if (!`type`.Namespace.equals("") && `type`.DeclaringType == null) {
print(".namespace \'" ); print(`type`.Namespace); println("\'")
println("{"); indent()
}
print(".class ")
// <classHead> ::=
// <classAttr>*
// [extends <typeReference>]
// [implements <typeReference> [, ]*]
print(TypeAttributes.toString(`type`.Attributes))
print(" \'"); print(`type`.Name); print("\'")
printTypeParams(`type`.getSortedTVars())
if (`type`.BaseType() != null) {
println()
print(" extends ")
printReference(`type`.BaseType())
}
var ifaces: Array[Type] = `type`.getInterfaces()
if (ifaces.length > 0) {
println()
print(" implements ")
for (i <- 0 until ifaces.length) {
if (i > 0) {
println(",")
print(" ")
}
printReference(ifaces(i))
}
}
println()
println("{")
indent()
if (!nomembers && `type`.sourceFilename != null)
println(".line " + `type`.sourceLine
+ " '" + `type`.sourceFilename + "'")
if (!nomembers) {
printAttributes(`type`)
}
// print nested classes
val nested = `type`.nestedTypeBuilders.iterator
while(nested.hasNext)
print(nested.next().asInstanceOf[TypeBuilder])
// print each field
val fields = `type`.fieldBuilders.iterator
while(fields.hasNext)
print(fields.next().asInstanceOf[FieldBuilder])
// print each constructor
val constrs = `type`.constructorBuilders.iterator
while (constrs.hasNext)
print(constrs.next().asInstanceOf[ConstructorBuilder])
// print each method
val methods = `type`.methodBuilders.iterator
while (methods.hasNext) {
val method = methods.next().asInstanceOf[MethodBuilder]
assert(method.DeclaringType == `type`)
print(method)
}
undent(); println("}")
if (!`type`.Namespace.equals("") && `type`.DeclaringType == null) {
undent(); println("}")
}
currentType = null
}
/**
* Visit a FieldBuilder
*/
@throws(classOf[IOException])
def caseFieldBuilder(field: FieldBuilder) {
if (nomembers) return
// [[int32]] <fieldAttr>* [= | at ]
print(".field ")
print(FieldAttributes.toString(field.Attributes))
print(" "); printSignature(field.FieldType, field.cmods)
print(" \'"); print(field.Name); print("\'")
if (field.IsLiteral()) {
print(" = ")
val value = field.getValue()
if (value == null) {
print("nullref")
} else if (value.isInstanceOf[String]) {
print(msilString(value.asInstanceOf[String]))
} else if (value.isInstanceOf[Boolean]) {
print("bool (")
print(if((value.asInstanceOf[Boolean]).booleanValue()) { "true" } else { "false" })
print(")")
} else if (value.isInstanceOf[Byte]) {
print("int8 (")
print(value)
print(")")
} else if (value.isInstanceOf[java.lang.Short]) {
print("int16 (")
print(value)
print(")")
} else if (value.isInstanceOf[Character]) {
print("char (")
print((value.asInstanceOf[Character]).charValue())
print(")")
} else if (value.isInstanceOf[Integer]) {
print("int32 (")
print((value.asInstanceOf[Integer]).intValue())
print(")")
} else if (value.isInstanceOf[Long]) {
print("int64 (")
print((value.asInstanceOf[Long]).longValue())
print(")")
} else if (value.isInstanceOf[Float]) {
print(msilSyntaxFloat(value.asInstanceOf[Float]))
} else if (value.isInstanceOf[Double]) {
print(msilSyntaxDouble(value.asInstanceOf[Double]))
} else {
throw new Error("ILPrinterVisitor: Illegal default value: "
+ value.getClass())
}
}
println()
printAttributes(field)
}
def msilSyntaxFloat(valFlo: java.lang.Float) : String = {
// !!! check if encoding is correct
val bits = java.lang.Float.floatToRawIntBits(valFlo.floatValue())
/* see p. 170 in Lidin's book Expert .NET 2.0 IL Assembler */
/* Note: no value is equal to Nan, including NaN. Thus, x == Float.NaN always evaluates to false. */
val res = if (valFlo.isNaN) "0xFFC00000 /* NaN */ " /* TODO this is 'quiet NaN, http://www.savrola.com/resources/NaN.html , what's the difference with a 'signaling NaN'?? */
else if (java.lang.Float.NEGATIVE_INFINITY == valFlo.floatValue) "0xFF800000 /* NEGATIVE_INFINITY */ "
else if (java.lang.Float.POSITIVE_INFINITY == valFlo.floatValue) "0x7F800000 /* POSITIVE_INFINITY */ "
else bits
"float32 (" + res + ")"
}
def msilSyntaxDouble(valDou: java.lang.Double) : String = {
// !!! check if encoding is correct
var bits = java.lang.Double.doubleToRawLongBits(valDou.doubleValue())
/* see p. 170 in Lidin's book Expert .NET 2.0 IL Assembler */
/* Note: no value is equal to Nan, including NaN. Thus, x == Double.NaN always evaluates to false. */
val res = if (valDou.isNaN) "0xffffffffffffffff /* NaN */ " /* TODO this is 'quiet NaN, http://www.savrola.com/resources/NaN.html , what's the difference with a 'signaling NaN'?? */
else if (java.lang.Double.NEGATIVE_INFINITY == valDou.doubleValue) "0xfff0000000000000 /* NEGATIVE_INFINITY */ "
else if (java.lang.Double.POSITIVE_INFINITY == valDou.doubleValue) "0x7ff0000000000000 /* POSITIVE_INFINITY */ "
else bits
// float64(float64(...)) != float64(...)
"float64 (" + res + ")"
}
/**
* Visit a ConstructorBuilder
*/
@throws(classOf[IOException])
def caseConstructorBuilder(constr: ConstructorBuilder) {
if (nomembers) return
print(".method "); printHeader(constr, VOID)
println(); println("{"); indent()
printAttributes(constr)
try {
print(constr.GetILGenerator())
} catch {
case e : RuntimeException => {
System.err.println("In method " + constr)
e.printStackTrace()
}
}
undent(); println("}")
}
/**
* Visit a MethodBuilder
*/
@throws(classOf[IOException])
def caseMethodBuilder(method: MethodBuilder) {
if (nomembers) return
print(".method "); printHeader(method, method.ReturnType)
if (method.IsAbstract()
|| (method.DeclaringType != null
&& method.DeclaringType.IsInterface()
&& !method.IsStatic()))
{
println(" {"); indent()
printAttributes(method)
undent(); println("}")
} else {
println(); println("{"); indent()
printAttributes(method)
if (method == entryPoint)
println(".entrypoint")
try {
print(method.GetILGenerator())
} catch {
case e: RuntimeException =>
System.err.println("In method " + method)
e.printStackTrace()
}
undent(); println("}")
}
}
/**
* Visit a ParameterBuilder
*/
@throws(classOf[IOException])
def caseParameterBuilder(param: ParameterBuilder) {
print(ParameterAttributes.toString(param.Attributes))
printSignature(param.ParameterType)
//print(' ') print(marshal)
print(' '); printName(param.Name)
}
var locals: Array[LocalBuilder] = null
/**
* Visit an ILGenerator
*/
@throws(classOf[IOException])
def caseILGenerator(code: ILGenerator) {
// print maxstack
println(".maxstack " + code.getMaxStacksize())
// get the local variables
locals = code.getLocals()
if (locals.length > 0) {
println(".locals init (")
indent()
for (i <- 0 until locals.length) {
if (i > 0) println(",")
print(locals(i))
} // end while
undent()
println(")")
}
// get 3 iterators for the 3 lists
val itL = code.getLabelIterator()
val itO = code.getOpcodeIterator()
val itA = code.getArgumentIterator()
// iterate over each opcode
while (itO.hasNext) {
// first print label
val label = itL.next
val oOpt = code.lineNums.get(label)
if (oOpt.isDefined) {
println(".line " + oOpt.get)
}
argument = itA.next.asInstanceOf[Object]
printLabel(label)
val o2 = itO.next
if (o2 != null) {
print(" ")
print(o2.asInstanceOf[OpCode])
}
println()
} // end while
}
/**
* visit an OpCode
*/
@throws(classOf[IOException])
def caseOpCode(opCode: OpCode) {
var opString = opCode.toString()
print(opString)
pad(14 - opString.length())
// switch opcode
if (opCode == OpCode.Ldstr) {
print(msilString(argument.toString()))
} else if(opCode == OpCode.Switch) {
// switch ( <labels> )
print("(")
val targets = argument.asInstanceOf[Array[Label]]
val m = targets.length
for (i <- 0 until m) {
if (i != 0) print(", ")
print(targets(i))
} // end for
print(")")
} else if(opCode == OpCode.Call || opCode == OpCode.Callvirt || opCode == OpCode.Jmp || opCode == OpCode.Ldftn || opCode == OpCode.Ldvirtftn) {
// call | callvirt | jmp | ldftn | ldvirtftn
// <instr_method> [ :: ]
printSignature(argument.asInstanceOf[MethodBase])
} else if (opCode == OpCode.Newobj) {
printSignature(argument.asInstanceOf[ConstructorInfo])
// ldfld | ldflda | ldsfld | ldsflda | stfld | stsfld
} else if (opCode == OpCode.Ldfld || opCode == OpCode.Ldflda || opCode == OpCode.Ldsfld || opCode == OpCode.Ldsflda || opCode == OpCode.Stfld || opCode == OpCode.Stsfld) {
printSignature(argument.asInstanceOf[FieldInfo])
} else if (opCode == OpCode.Castclass || opCode == OpCode.Isinst || opCode == OpCode.Ldobj || opCode == OpCode.Newarr) {
printSignature(argument.asInstanceOf[Type])
} else if (opCode == OpCode.Box || opCode == OpCode.Unbox || opCode == OpCode.Ldtoken || opCode == OpCode.Initobj) {
printReference(argument.asInstanceOf[Type])
} else if (opCode == OpCode.Ldloc || opCode == OpCode.Ldloc_S || opCode == OpCode.Ldloca || opCode == OpCode.Ldloca_S || opCode == OpCode.Stloc || opCode == OpCode.Stloc_S) {
val loc = argument.asInstanceOf[LocalBuilder]
print(loc.slot); print("\t// "); printSignature(loc.LocalType)
print(" \'"); print(loc.name); print("\'")
//print("'") print(((LocalBuilder)argument).name) print("'")
} else if (opCode == OpCode.Ldloc_0 || opCode == OpCode.Ldloc_1 || opCode == OpCode.Ldloc_2 || opCode == OpCode.Ldloc_3 ) {
val loc = locals(opCode.CEE_opcode - OpCode.CEE_LDLOC_0)
print("\t// "); printSignature(loc.LocalType)
print(" \'"); print(loc.name); print("\'")
} else if (opCode == OpCode.Stloc_0 || opCode == OpCode.Stloc_1 || opCode == OpCode.Stloc_2 || opCode == OpCode.Stloc_3 ) {
val loc = locals(opCode.CEE_opcode - OpCode.CEE_STLOC_0)
print("\t// "); printSignature(loc.LocalType)
print(" \'"); print(loc.name); print("\'")
} else if (opCode == OpCode.Readonly) {
// nothing to do
} else if (opCode == OpCode.Constrained) {
printReference(argument.asInstanceOf[Type])
} else if (opCode == OpCode.Ldelema) {
printReference(argument.asInstanceOf[Type])
} else {
// by default print toString argument if any
if (argument != null) {
val strArgument = java.lang.String.valueOf(argument)
if ( argument.isInstanceOf[java.lang.Float]
&& ( strArgument.equals("NaN")
|| strArgument.equals("-Infinity")
|| strArgument.equals("Infinity")))
print(msilSyntaxFloat(argument.asInstanceOf[java.lang.Float]))
else if ( argument.isInstanceOf[java.lang.Double]
&& ( strArgument.equals("NaN")
|| strArgument.equals("-Infinity")
|| strArgument.equals("Infinity")))
print(msilSyntaxDouble(argument.asInstanceOf[java.lang.Double]))
else print(strArgument)
}
} // end switch
}
/**
* Visit a Label
*/
def printLabel(label: Label) {
val kind = label.getKind()
if (kind == Label.Kind.Normal) {
print(label+ ": ")
} else if (kind == Label.Kind.NewScope) {
print("{"); indent()
} else if (kind == Label.Kind.EndScope) {
undent(); print("}")
} else if (kind == Label.Kind.Try) {
print(".try {"); indent()
} else if (kind == Label.Kind.Catch) {
undent()
println("}")
print("catch ")
printReference(argument.asInstanceOf[Type])
print(" {")
indent()
} else if (kind == Label.Kind.Filter) {
undent()
println("}")
print("filter {")
indent()
} else if (kind == Label.Kind.EndFilter) {
print("endfilter")
undent()
println("}")
} else if (kind == Label.Kind.Finally) {
undent()
println("}")
print("finally {")
indent()
} else if (kind == Label.Kind.EndTry) {
undent()
print("}")
}
}
/**
* Visit a LocalBuilder
*/
@throws(classOf[IOException])
def caseLocalBuilder(localBuilder: LocalBuilder) {
// print type
printSignature(localBuilder.LocalType)
// space
print(" \'")
// print name
print(localBuilder.name)
print("\'")
}
//##########################################################################
def printAssemblySignature(assem: Assembly, extern: Boolean) {
print(".assembly ")
if (extern)
print("extern ")
val an = assem.GetName()
printName(an.Name); println()
println("{")
if (!extern)
printAttributes(assem)
val v = an.Version
if (v != null) {
print(" .ver "); print(v.Major); print(':'); print(v.Minor)
print(':'); print(v.Build); print(':')
print(v.Revision); println()
}
var key = an.GetPublicKeyToken()
if (key != null) {
print(" .publickeytoken = ("); print(PEFile.bytes2hex(key))
println(")")
} else {
key = an.GetPublicKey()
if (key != null) {
print(" .publickey = ("); print(PEFile.bytes2hex(key))
println(")")
}
}
println("}")
}
def printSignature(field: FieldInfo) {
printSignature(field.FieldType, field.cmods)
//print(' ') print(owner)
print(' ')
//if (field.IsStatic && field.DeclaringType != currentType) {
printReference(field.DeclaringType)
print("::")
//}
printName(field.Name)
}
// print method head
@throws(classOf[IOException])
def printHeader(method: MethodBase, returnType: Type) {
print(MethodAttributes.toString(method.Attributes))
print(' '); print(CallingConventions.toString(method.CallingConvention))
print(' '); printSignature(returnType)
//print(' ') print(marshal)
print(' '); printName(method.Name)
if(method.isInstanceOf[MethodInfo]) {
val mthdInfo = method.asInstanceOf[MethodInfo]
printTypeParams(mthdInfo.getSortedMVars())
}
val params = method.GetParameters()
print('(')
for (i <- 0 until params.length) {
if (i > 0) print(", ")
print(params(i).asInstanceOf[ParameterBuilder])
}
print(") ")
print(MethodImplAttributes
.toString(method.GetMethodImplementationFlags()))
}
def printSignature(method: MethodBase) {
var returnType: Type = null
if (method.isInstanceOf[MethodInfo])
returnType = (method.asInstanceOf[MethodInfo]).ReturnType
else if (method.isInstanceOf[ConstructorInfo])
returnType = VOID
else
throw new RuntimeException()
val s = CallingConventions.toString(method.CallingConvention)
print(s)
if (s.length() > 0) print(' ')
printSignature(returnType)
//print(' ') print(owner)
print(' '); printReference(method.DeclaringType)
print("::"); printName(method.Name)
var params = method.GetParameters()
print("(")
for (i <- 0 until params.length) {
if (i > 0) print(", ")
printSignature(params(i).ParameterType)
}
print(")")
}
def printSignature(marked: Type, cmods: Array[CustomModifier]) {
printSignature(marked)
if( (cmods != null) && !cmods.isEmpty ) {
print(" ")
for(cm <- cmods) {
print(if (cm.isReqd) "modreq( " else "modopt( ")
printReference(cm.marker)
print(" ) ")
}
}
}
def printSignature(`type`: Type) {
val sigOpt = primitive.get(`type`)
if (sigOpt.isDefined) {
print(sigOpt.get)
return
}
if (`type`.HasElementType()) {
printSignature(`type`.GetElementType())
if (`type`.IsArray())
print("[]")
else if (`type`.IsPointer())
print('*')
else if (`type`.IsByRef())
print('&')
} else {
val preref = if (`type`.isInstanceOf[Type.TMVarUsage]) ""
else if(`type`.IsValueType()) "valuetype "
else "class "
print(preref)
printReference(`type`)
}
}
def printReference(`type`: Type) {
if (`type`.Module != null) { // i.e. not PrimitiveType and not TMVarUsage
if (`type`.Assembly() != currentModule.Assembly) {
print('['); print(`type`.Assembly().GetName().Name); print("]")
} else if (`type`.Module != currentModule) {
print("[.module "); print(`type`.Module.Name); print("]")
}
}
printTypeName(`type`)
}
def printTypeName(`type`: Type) {
if (`type`.isInstanceOf[ConstructedType]) {
val ct = `type`.asInstanceOf[ConstructedType]
printTypeName(ct.instantiatedType)
print("<")
var i = 0
while (i < ct.typeArgs.length) {
val ta = ct.typeArgs(i)
val sigOpt = primitive.get(ta)
if (sigOpt.isDefined) print(sigOpt.get)
else printTypeName(ta); /* should be printSignature, but don't want `class' or `valuetype'
appearing before a type param usage. */
i = i + 1;
if (i < ct.typeArgs.length) {
print(", ")
}
}
print(">")
} else if (`type`.DeclaringType != null) {
printTypeName(`type`.DeclaringType)
print('/')
printName(`type`.Name)
} else {
printName(`type`.FullName)
}
}
def printAttributes(icap: ICustomAttributeProvider) {
var attrs = icap.GetCustomAttributes(false)
for (i <- 0 until attrs.length) {
print(".custom ")
printSignature((attrs(i).asInstanceOf[Attribute]).getConstructor())
print(" = (")
print(PEFile.bytes2hex((attrs(i).asInstanceOf[Attribute]).getValue()))
println(")")
}
}
//##########################################################################
} // class ILPrinterVisitor
object ILPrinterVisitor {
final val VOID: Type = Type.GetType("System.Void")
protected final val TAB = 4
protected final val SPACES = " "
protected final val SPACES_LEN = SPACES.length()
def hasControlChars(str: String): Boolean = {
for(i <- 0 until str.length()) {
var ch = str.charAt(i)
ch match {
case '\b' =>
case '\t' =>
case '\n' =>
case '\f' =>
case '\r' =>
case _ => if(Character.isISOControl(ch)) return true
}
}
return false
}
final val EMPTY: String = ""
def msilString(s: String): String = {
if (hasControlChars(s)) {
try {
return "bytearray (" + PEFile.bytes2hex(s.getBytes("UTF-16LE")) + ")"
} catch {
case e : java.io.UnsupportedEncodingException => throw new RuntimeException(e)
}
}
var str = new StringBuffer(s)
var ss = EMPTY
var i = 0
while(i < str.length()) {
ss = EMPTY
val c = str.charAt(i)
c match {
case '\b' => ss = "\\b"
case '\t' => ss = "\\t"
case '\n' => ss = "\\n"
case '\f' => ss = "\\f"
case '\r' => ss = "\\r"
case '\"' => ss = "\\\""
case '\'' => ss = "\\\'"
case '\\' => ss = "\\\\"
case _ => if (Character.isISOControl(c))
ss = "\\u" + PEFile.int2hex(Character.getNumericValue(c))
}
if (ss != EMPTY) {
str.replace(i, i + 1, ss)
i = i + ss.length() - 1
}
i = i + 1
}
return "\"" + str.toString() + "\""
}
/**
* the main printer method
*/
@throws(classOf[IOException])
def printAssembly(assemblyBuilder: AssemblyBuilder, fileName: String) {
assemblyBuilder.apply(new SingleFileILPrinterVisitor(fileName))
}
@throws(classOf[IOException])
def printAssembly(assemblyBuilder: AssemblyBuilder, destPath: String, sourceFilesPath: String) {
assemblyBuilder.apply(new MultipleFilesILPrinterVisitor(destPath, sourceFilesPath))
}
/** The current assembly */
var currAssembly: Assembly = _
final var primitive = scala.collection.mutable.Map.empty[Type, String]
def addPrimitive(name: String, sig: String) {
var `type` =
Type.GetType(name)
assert(`type` != null, "Cannot lookup primitive type " + `type`)
primitive.put(`type`, sig)
}
addPrimitive("System.Object", "object")
addPrimitive("System.String", "string")
addPrimitive("System.Void", "void")
addPrimitive("System.Boolean", "bool")
addPrimitive("System.Char", "char")
addPrimitive("System.SByte", "int8")
addPrimitive("System.Byte", "unsigned int8")
addPrimitive("System.Int16", "int16")
addPrimitive("System.UInt16", "unsigned int16")
addPrimitive("System.Int32", "int32")
addPrimitive("System.UInt32", "unsigned int32")
addPrimitive("System.Int64", "int64")
addPrimitive("System.UInt64", "unsigned int64")
addPrimitive("System.IntPtr", "native int")
addPrimitive("System.UIntPtr", "unsigned native int")
addPrimitive("System.Single", "float32")
addPrimitive("System.Double", "float64")
addPrimitive("System.TypedReference", "typedref")
}
Other Scala examples (source code examples)
Here is a short list of links related to this Scala ILPrinterVisitor.scala source code file:
|