Skip to content

Instantly share code, notes, and snippets.

@khakionion
Last active May 24, 2017 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khakionion/16e5ff803fba9c0a616895b9d9d7ded2 to your computer and use it in GitHub Desktop.
Save khakionion/16e5ff803fba9c0a616895b9d9d7ded2 to your computer and use it in GitHub Desktop.
Finds all void returning methods that take one Object, generates SIL forward declarations
//Use the output of this script like so:
//💻 ⤴️ ⤵️ 🌊 swiftli $ /swift/build/Ninja-DebugAssert/swift-macosx-x86_64/bin/swiftc -emit-cil -module-name="swiftli" ./SILGenOutput.swift BananaStatement.swift
import Foundation
func confirmUsage() -> Bool
{
if(CommandLine.arguments.count != 3)
{
print("Usage: dump_silgen_methods <path_to_monodis> <path_to_dotnet_dll>")
return false;
}
return true;
}
if(confirmUsage())
{
let proc=Process()
proc.launchPath = CommandLine.arguments[1]
proc.arguments = ["--method",CommandLine.arguments[2]]
proc.standardOutput = Pipe()
proc.launch()
let data = (proc.standardOutput! as! Pipe).fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
let monodisFunctionPreamble = "^[0-9]+: default"
var silgen = "@_silgen_name(\"SILGENNAME\") func SILGENNAME(_:Any) -> (RETURNS)"
var classNum=0
var funcNum=0
let splitLines = (output as NSString!).components(separatedBy: NSCharacterSet.newlines)
let knownReturnTypes: [String:String] = ["void":"Void"]
let knownObjectTypes: [String:String] = ["object":"Any"]
var currentNamespace = ""
for nextLine in splitLines {
if(nextLine.contains("##########"))
{
classNum+=1
let methodSig = nextLine.components(separatedBy: "########## ").last!
if(!(methodSig.hasPrefix(".")))
{
print("// Class " + methodSig)
currentNamespace = methodSig.replacingOccurrences(of: ".", with: "_")
}
}
else
{
let preambleRange = nextLine.range(of: monodisFunctionPreamble, options: .regularExpression)
if(preambleRange != nil)
{
let preambleSplice = nextLine.substring(from: preambleRange!.upperBound)
let returnTypeRange = preambleSplice.range(of: "[a-zA-Z]+", options: .regularExpression)
if(returnTypeRange != nil)
{
let returnType = preambleSplice.substring(with: returnTypeRange!)
if(knownReturnTypes.keys.contains(returnType))
{
let funcAndSig = preambleSplice.substring(from: returnTypeRange!.upperBound)
let funcRange = funcAndSig.range(of: "[a-zA-Z]+", options: .regularExpression)
if(funcRange != nil)
{
let funcName = funcAndSig.substring(with: funcRange!)
let paramString = funcAndSig.substring(from: funcRange!.upperBound)
let singleObjectArgRange = paramString.range(of: "\\(object [a-zA-Z]+\\)", options: .regularExpression)
if(singleObjectArgRange != nil)
{
print(silgen.replacingOccurrences(of: "RETURNS", with:knownReturnTypes[returnType]!)
.replacingOccurrences(of: "SILGENNAME", with: currentNamespace + "_" + funcName)
)
funcNum+=1
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment