Upgrade to Pro — share decks privately, control downloads, hide ads and more …

今日から始めるswift-driver

 今日から始めるswift-driver

at わいわいswiftc #22

freddi(Yuki Aki)

September 25, 2020
Tweet

More Decks by freddi(Yuki Aki)

Other Decks in Programming

Transcript

  1. ʮυϥΠόʯͱ͸ʁ • ͏·͘આ໌Ͱ͖ͳ͍ͷͰͱΓ͋͑ͣάάͬͨΒͳΜ͔͍͍ճ౴ ग़͖ͯͨ • What is a driver, for

    example, a compiler driver? at Quora • Ken Gregg (Founder and CEO, Bytellect LLC) ͞Μ͕આ໌ 3
  2. υϥΠόͷΘ͔Γ΍͔ͬͨ͢આ໌ at Quora • There are several uses of the

    term “driver” in the world of computer so8ware and hardware. • ίϯϐϡʔλͷੈք΍ͱɺϋʔυ΢ΣΞͱιϑτ΢ΣΞʢ։ ൃʣͷੈքͰҧ͏Μ΍Ͱ 4
  3. υϥΠόͷΘ͔Γ΍͔ͬͨ͢આ໌ ϋʔυ΢ΣΞฤ • The most common is device driver (some1mes

    just shortened to driver), which is a piece of so:ware that allows an opera1ng system to communicate with a hardware device. • େମͷ৔߹ʮυϥΠόʯͱ͍͏ͱϋʔυ΢ΣΞͷੈքΛࢦͯ͠ ͯɺOSͱσόΠεͷ΍ΓͱΓΛαϙʔτʢڐՄʣ͢Δ΍ͭ΍Ͱ • όευϥΠόɾϑΟϧλυϥΠόɾιϑτ΢ΣΞυϥΠόʢι ϑτ΢ΣΞͷੈքͷઆ໌Ͱ͸ͳ͍ʣ... 5
  4. υϥΠόͷΘ͔Γ΍͔ͬͨ͢આ໌ ιϑτ΢ΣΞฤ • In so'ware development in general, the term

    driver is some6mes used to refer to a piece of so'ware that controls or drives some other piece of so'ware. • ιϑτ΢ΣΞ։ൃͷੈք΍ͱҰൠతʹ͸ɺυϥΠόͱ͍͏ݴ ༿͸͍͔ͭ͘ͷύʔπʹͳ͍ͬͯΔιϑτ΢ΣΞΛࢀরͨ͠ Γɺݺͼग़ͨ͠Γ͢Διϑτ΢ΣΞͷ͜ͱΛࢦ͢΍Ͱ 6
  5. υϥΠόͷΘ͔Γ΍͔ͬͨ͢આ໌ ιϑτ΢ΣΞฤ LLVM ͷྫ • For example, the LLVM Compiler

    Driver (llvmc) is a tool that can be configured to invoke several compiler development tools and related tools, acAng as a single point of access for users of the LLVM set of tools. • ͨͱ͑͹ɺLLVM Compiler Driver ͸͍͔ͭ͘ͷίϯύΠϥʢͱͦͷؔ࿈ʣ πʔϧͷݺͼग़͠Λߏ੒͢Δ΋ͷ΍Ͱ • Ϣʔβ͔ΒݟͨΒLLVMͷπʔϧ܈ʹΞΫηεͰ͖ΔɺҰͭͷΞΫηεϙΠ ϯτͱͯ͠ৼΔ෣͏΍Ͱ 7
  6. llvmc ͷެࣜͷઆ໌ΛಡΉ • The llvmc tool is a configurable compiler

    driver. As such, it isn't a compiler, op;mizer, or a linker itself but it drives (invokes) other soAware that perform those tasks. If you are familiar with the GNU Compiler Collec;on's gcc tool, llvmc is very similar. • llvmc ࣗମ͸ ίϯύΠϥɾOp;mizerɾϦϯΧࣗ਎ ͡Όͳ͍Ͱ • llvmc ͸υϥΠόͱͯ͠ ίϯύΠϥɾOp;mizerɾϦϯΧࣗ਎ Λಈ͔͢(drivesɾݺͼग़͢)΍Ͱ 8
  7. gcc ͷྫ • Έͳ͞Μ͕ίϯύΠϥͩͱࢥ͍ͬͯΔ gcc͸ɺ ࣮͸ɺίϯύΠϥυϥΠό (compiler driver)ͱݺ͹ΕΔϓϩάϥϜͰ͋Γɺ CͳͲͷϓϩάϥϛϯάݴޠͰ ॻ͔ΕͨιʔεϓϩάϥϜ͔Β࣮ߦܗࣜΛ

    ࡞Γग़ͨ͢ΊͷॲཧΛߦ͏ɻ • gcc͸ɺʮඞཁʹԠͯ͡ίϯύΠϥ΍ ΞηϯϒϥɺϦϯέʔδΤσΟλͳͲͷ ϓϩάϥϜΛݺͼग़͢ʯͱ͍͏ ॲཧΛߦ͍ͬͯΔɻgccίϚϯυࣗମ͕௚઀ί ϯύΠϧΛߦ͍ͬͯΔΘ͚Ͱ͸ͳ͍ɻ • ʮίϯύΠϧʯͱݺ͹Ε͍ͯΔॲཧ͸ cc1 ͱ͍͏ผͷίϚϯυ͕΍͍ͬͯΔ 9
  8. Swi$ͷυϥΠόʹ͍ͭͯ • swift-frontend ίϚϯυ͔ΒγϯϘϦοΫϦϯΫͰ swift ͱ swiftc Λ࡞͍ͬͯΔ • ͷͪͷͪɺͱ͋Δ෼ذͰ͜ͷγϯϘϦοΫϦϯΫͷ໊લ͕υϥΠόͱ͠

    ͯͷڍಈͷ෼ذʹͳΔ͕ޙड़ • ͪͳΈʹɺυϥΠό͕ݺͼग़͢࢓ࣄͷ୯ҐʢϦϯΫͳͲʣΛδϣϒ ͱݺ ͹ΕΔ • main/lib/Driver ʹυϥΠόͷίʔυ͕༗Δ 11
  9. swift-driver ͷ؀ڥߏஙʹඞཁͳ΋ͷ • Xcode 12 (ࢼͨ͠؀ڥ) • swift-driver ͷίʔυ •

    h-ps:/ /github.com/apple/swi<-driver • ͳΔ΂͘৽͠Ίͷ Swi< Trunk ToolChain(SnapShot) • h-ps:/ /swi<.org/download/#snapshots 22
  10. swift-driver ΛϏϧυ͢Δ (swift build) • Ϗϧυ͞Εͨ swift-driver Λ swift swiftc

    ͱ͍͏໊લͰ γϯϘϦοΫϦϯΫΛషΔ $ ln -s .build/debug/swift-driver swift $ ln -s .build/debug/swift-driver swiftc 25
  11. swift-driver Λىಈ͢Δ (swift build) • ࢼ͠ʹ swift Λಈ͔͢ $ ./swift

    error: failed to retrieve frontend target info • ಈ͔ͳ͍ 26
  12. swift-driver Λىಈ͢Δ (swift build) • ಈ͔͢ʹ͸ swi&-frontend ͷ৘ใ͕ඞཁ $ /Library/Developer/Toolchains/{ઌఔΠϯετʔϧͨ͠ToolChainͷύε}/usr/bin/swift-frontend

    -frontend -print-target-info { "compilerVersion": "Apple Swift version 5.3-dev (LLVM 2685951d827b16e, Swift ec72db1d8ab63fa)", "target": { "triple": "x86_64-apple-macosx10.15", "unversionedTriple": "x86_64-apple-macosx", "moduleTriple": "x86_64-apple-macos", "swiftRuntimeCompatibilityVersion": "5.1", "compatibilityLibraries": [ { "libraryName": "swiftCompatibility51", "filter": "all" } ], "librariesRequireRPath": false }, "paths": { "runtimeLibraryPaths": [ "/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2020-09-22-a.xctoolchain/usr/lib/swift/macosx", "/usr/lib/swift" ], "runtimeLibraryImportPaths": [ "/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2020-09-22-a.xctoolchain/usr/lib/swift/macosx" ], "runtimeResourcePath": "/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2020-09-22-a.xctoolchain/usr/lib/swift" } } 27
  13. swi$-frontend ͷ৘ใ • Xcode 12 ಉ෧ͷ Swi- ͩͱɺswift -frontend -print-

    target-info Ͱಉ༷ͷ΋ͷ͕ग़ͯ͘Δ • ͨͩ͠ɺͪ͜Β͸ swift-driver Ͱ͸ಈ͔ͳ͍ 28
  14. swift-driver Λىಈ͢Δ (swift build) • ಈ͔͢ʹ͸ swift-frontend ͷ৘ใ͕ඞཁ • ->

    ؀ڥม਺ SWIFT_DRIVER_SWIFT_FRONTEND_EXEC Ͱઌఔ ͷ swift-frontend Λࢦఆͯ͠ run ͢Ε͹ྑ͍ 29
  15. swift-driver Λ Debug ͢Δ • Package.swi, Λ௚઀։͍ͯ࡞ۀͯ͠΋ɺͳ͔ͥ Break Point ͕

    main.swift ͚ͩޮ͔ͳ͍ • ๻ͷ؀ڥ͚͔ͩ΋஌Εͳ͍ɾɾɾɾ • ͜ΕͰ΋ແཧͩͬͨɻଞͷؔ਺Ͱ͸ߦ͚Δ • swift package generate-xcodeprojͰ xcodeproj ্Ͱ࡞ۀ + ্هઃఆͩͱ͏·͘ޮ͘ 31
  16. swift-frontend ͸ͳͥඞཁʁ • ग़ྗ͞Εͨ΋ͷͷ͏ͪɺpathsͷ৘ใʹϑΥʔΧεͯ͠ΈΔ { "runtimeLibraryPaths": [ "/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2020-09-22-a.xctoolchain/usr/lib/swift/macosx", "/usr/lib/swift" ],

    "runtimeLibraryImportPaths": [ "/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2020-09-22-a.xctoolchain/usr/lib/swift/macosx" ], "runtimeResourcePath": "/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2020-09-22-a.xctoolchain/usr/lib/swift" } 32
  17. swift-frontend ͸ͳͥඞཁʁ • ཁ͢ΔʹɺCoreGraphics ͱ͔ Founda2on ͱ͔ͷ dylib ͷύε ΛूΊͨΓ͍ͯ͠Δ

    • ϦϯΧͱ͔ͷδϣϒΛੜ੒͢Δͱ͖ʹɺదٓҾ͖౉͢ • LinkJob.swi9 ͷͱ͖ʹઆ໌ 34
  18. Planning.swi* • υϥΠό (Driver ܕ) ͷঢ়ଶ͔Βɺద੾ͳδϣϒ܈Λฦ͢ planBuild() ͷ࣮૷͕͋Δ • Driver

    ͷ extension • ***Job.swi- ͷதͷؔ਺Λదٓݺͼग़ͯ͠JobΛ࡞ͬͨΓ 39
  19. main.swift import SwiftDriverExecution import SwiftDriver import TSCLibc import TSCBasic import

    TSCUtility var intHandler: InterruptHandler? let diagnosticsEngine = DiagnosticsEngine(handlers: [Driver.stderrDiagnosticsHandler]) do { let processSet = ProcessSet() intHandler = try InterruptHandler { processSet.terminate() } let (mode, arguments) = try Driver.invocationRunMode(forArgs: CommandLine.arguments) if case .subcommand(let subcommand) = mode { // We are running as a subcommand, try to find the subcommand adjacent to the executable we are running as. // If we didn't find the tool there, let the OS search for it. let subcommandPath = Process.findExecutable(arguments[0])?.parentDirectory.appending(component: subcommand) ?? Process.findExecutable(subcommand) if subcommandPath == nil || !localFileSystem.exists(subcommandPath!) { fatalError("cannot find subcommand executable '\(subcommand)'") } // Execute the subcommand. try exec(path: subcommandPath?.pathString ?? "", args: arguments) } let executor = try SwiftDriverExecutor(diagnosticsEngine: diagnosticsEngine, processSet: processSet, fileSystem: localFileSystem, env: ProcessEnv.vars) var driver = try Driver(args: arguments, diagnosticsEngine: diagnosticsEngine, executor: executor) // FIXME: The following check should be at the end of Driver.init, but current // usage of the DiagnosticVerifier in tests makes this difficult. guard !driver.diagnosticEngine.hasErrors else { throw Diagnostics.fatalError } let jobs = try driver.planBuild() try driver.run(jobs: jobs) if driver.diagnosticEngine.hasErrors { exit(EXIT_FAILURE) } } catch Diagnostics.fatalError { exit(EXIT_FAILURE) } catch let diagnosticData as DiagnosticData { diagnosticsEngine.emit(.error(diagnosticData)) exit(EXIT_FAILURE) } catch { print("error: \(error)") exit(EXIT_FAILURE) } 43
  20. main.swift • ·ͣ͸͸͡Ί͔Β var intHandler: InterruptHandler? let diagnosticsEngine = DiagnosticsEngine(handlers:

    [Driver.stderrDiagnosticsHandler]) do { let processSet = ProcessSet() intHandler = try InterruptHandler { processSet.terminate() } ... 45
  21. DiagnosticsEngine var intHandler: InterruptHandler? let diagnosticsEngine = DiagnosticsEngine(handlers: [Driver.stderrDiagnosticsHandler]) //

    ͜Ε do { let processSet = ProcessSet() intHandler = try InterruptHandler { processSet.terminate() } ... • DiagnosticsEngine • ݟͨײ͡ɺerror ΍ warning ͱ͍ͬͨ਍அͷ݁ՌΛϋϯυϦϯά͢Δ • main.swift ͩͱ Driver.stderrDiagnosticsHandler Λ౉͍ͯ͠Δ • swift-driver ͷίʔυͰ͸ͳ͘ɺapple/swi/-tools-support-core ͷίʔυ 46
  22. Driver.stderrDiagnosticsHandler public static let stderrDiagnosticsHandler: DiagnosticsEngine.DiagnosticsHandler = { diagnostic in

    let stream = stderrStream if !(diagnostic.location is UnknownLocation) { stream <<< diagnostic.location.description <<< ": " } switch diagnostic.message.behavior { case .error: stream <<< "error: " case .warning: stream <<< "warning: " ... • error ͱ͔ warning Λ ඪ४Τϥʔग़ྗͱͯ͠ग़͢Α͏ʹϋϯυϦ ϯά͍ͯ͠Δ 47
  23. ProcessSet ͱ InterruptHandler var intHandler: InterruptHandler? // ͜Ε let diagnosticsEngine

    = DiagnosticsEngine(handlers: [Driver.stderrDiagnosticsHandler]) do { let processSet = ProcessSet() intHandler = try InterruptHandler { // ͜Ε processSet.terminate() } ... • InterruptHandler • ׂΓࠐΈγάφϧ (Ctrl + C) ౳ͷγάφϧ͕૸ͬͨͱ͖ͷϋϯυϥ • main.swift Ͱ͸ ProcessSet Λ terminate ͢ΔΑ͏ʹϋϯυϧ͍ͯ͠Δ • swift-driver ͷίʔυͰ͸ͳ͘ɺapple/swi1-tools-support-core ͷίʔυ 48
  24. ProcessSet ͱ InterruptHandler var intHandler: InterruptHandler? let diagnosticsEngine = DiagnosticsEngine(handlers:

    [Driver.stderrDiagnosticsHandler]) do { let processSet = ProcessSet() // ͜Ε intHandler = try InterruptHandler { processSet.terminate() // ͜Ε } ... • ProcessSet • ؆୯ʹݴ͑͹ϓϩηεͷίϨΫγϣϯ • Job ͸࠷ऴతʹ͜ͷίϨΫγϣϯʹϓϩηεͱͯ͠ొ࿥͞ΕΔ • swift-driver ͷίʔυͰ͸ͳ͘ɺapple/swi+-tools-support-core ͷίʔυ 49
  25. Driver.invocationRunMode ~ try exec(... • ࣍͸͔͜͜ΒಡΉ ... let (mode, arguments)

    = try Driver.invocationRunMode(forArgs: CommandLine.arguments) if case .subcommand(let subcommand) = mode { // We are running as a subcommand, try to find the subcommand adjacent to the executable we are running as. // If we didn't find the tool there, let the OS search for it. let subcommandPath = Process.findExecutable(arguments[0])?.parentDirectory.appending(component: subcommand) ?? Process.findExecutable(subcommand) if subcommandPath == nil || !localFileSystem.exists(subcommandPath!) { fatalError("cannot find subcommand executable '\(subcommand)'") } // Execute the subcommand. try exec(path: subcommandPath?.pathString ?? "", args: arguments) } ... 51
  26. Driver.invocationRunMode(forArgs:) ... let (mode, arguments) = try Driver.invocationRunMode(forArgs: CommandLine.arguments) //

    ͜͜ if case .subcommand(let subcommand) = mode { // We are running as a subcommand, try to find the subcommand adjacent to the executable we are running as. // If we didn't find the tool there, let the OS search for it. let subcommandPath = Process.findExecutable(arguments[0])?.parentDirectory.appending(component: subcommand) ?? Process.findExecutable(subcommand) if subcommandPath == nil || !localFileSystem.exists(subcommandPath!) { fatalError("cannot find subcommand executable '\(subcommand)'") } // Execute the subcommand. try exec(path: subcommandPath?.pathString ?? "", args: arguments) } ... 52
  27. Driver.invocationRunMode(forArgs:) • swift ͔ swiftc Ͱݺͼग़͍ͯ͠Δͷ͔ɺͲΜͳΦϓγϣϯ͕ ෇͍͍ͯΔ͔ɺͳͲͰ Driver ͷϞʔυΛมԽ •

    ྫ͑͹ɺ͜͜Ͱ REPL ͔Ͳ͏͔΋൑ఆ͍ͯ͠Δ • αϒίϚϯυΛݟΔϞʔυΛฦ͢͜ͱ΋͋Δ • ྫ) swift build ͱ͔͸αϒίϚϯυΛݟΔର৅ʹͳΔ 53
  28. if case .subcommand(let subcommand) = ... ... let (mode, arguments)

    = try Driver.invocationRunMode(forArgs: CommandLine.arguments) if case .subcommand(let subcommand) = mode { // ͜͜ // We are running as a subcommand, try to find the subcommand adjacent to the executable we are running as. // If we didn't find the tool there, let the OS search for it. let subcommandPath = Process.findExecutable(arguments[0])?.parentDirectory.appending(component: subcommand) ?? Process.findExecutable(subcommand) if subcommandPath == nil || !localFileSystem.exists(subcommandPath!) { fatalError("cannot find subcommand executable '\(subcommand)'") } // Execute the subcommand. try exec(path: subcommandPath?.pathString ?? "", args: arguments) } ... 54
  29. if case .subcommand(let subcommand) = ... • αϒίϚϯυΛ୳ࡧ͢Δɻ • ݟ͔ͭΒͳ͚Ε͹

    error • fatalError("cannot find subcommand ... • ݟ͔ͭͬͨΒαϒίϚϯυΛݺͼग़͢ • try exec(path:, args:) 55
  30. ͜͜·Ͱͷ·ͱΊ • swift-driver ͕ͲͷΑ͏ʹݺ͹ΕΔ͔ௐ΂Δ • swift or swiftc or swift

    + αϒίϚϯυ • αϒίϚϯυ͕͋Ε͹ɺͦͷαϒίϚϯυΛ୳ͯ͠ݺͼग़͢ 56
  31. ࠷ޙͷ͜͜ͷ෦෼ ... let executor = try SwiftDriverExecutor(diagnosticsEngine: diagnosticsEngine, processSet: processSet,

    fileSystem: localFileSystem, env: ProcessEnv.vars) var driver = try Driver(args: arguments, diagnosticsEngine: diagnosticsEngine, executor: executor) // FIXME: The following check should be at the end of Driver.init, but current // usage of the DiagnosticVerifier in tests makes this difficult. guard !driver.diagnosticEngine.hasErrors else { throw Diagnostics.fatalError } let jobs = try driver.planBuild() try driver.run(jobs: jobs) ... 57
  32. ࠷ޙͷ͜͜ͷ෦෼ ... // ͜͜ let executor = try SwiftDriverExecutor(diagnosticsEngine: diagnosticsEngine,

    processSet: processSet, fileSystem: localFileSystem, env: ProcessEnv.vars) var driver = try Driver(args: arguments, diagnosticsEngine: diagnosticsEngine, executor: executor) // FIXME: The following check should be at the end of Driver.init, but current // usage of the DiagnosticVerifier in tests makes this difficult. guard !driver.diagnosticEngine.hasErrors else { throw Diagnostics.fatalError } let jobs = try driver.planBuild() try driver.run(jobs: jobs) ... 58
  33. SwiftDriverExecutor • DriverExecutor ϓϩτίϧʹ४ڌͯ͠Δ • δϣϒΛಈ͔͢͜ͱ͕ϝΠϯͷಇ͖ • ͖ͬ͞ͷ ProcessSet ͱ͔

    DiagnosticsEngineɺ؀ڥม਺ͷ σʔλͳͲΛ౉͍ͯ͠Δ • δϣϒΛϓϩηεʹͯ͠ ProcessSet ʹ౉ͨ͠Γɺerror Λ DiagnosticsEngine Ͱ ϋϯυϦϯάͨ͠Γ͍ͯ͠ΔͬΆ͍ 59
  34. ࠷ޙͷ͜͜ͷ෦෼ ... let executor = try SwiftDriverExecutor(diagnosticsEngine: diagnosticsEngine, processSet: processSet,

    fileSystem: localFileSystem, env: ProcessEnv.vars) // ͜͜ var driver = try Driver(args: arguments, diagnosticsEngine: diagnosticsEngine, executor: executor) // FIXME: The following check should be at the end of Driver.init, but current // usage of the DiagnosticVerifier in tests makes this difficult. guard !driver.diagnosticEngine.hasErrors else { throw Diagnostics.fatalError } let jobs = try driver.planBuild() try driver.run(jobs: jobs) ... 60
  35. ࠷ޙͷ͜͜ͷ෦෼ ... let executor = try SwiftDriverExecutor(diagnosticsEngine: diagnosticsEngine, processSet: processSet,

    fileSystem: localFileSystem, env: ProcessEnv.vars) var driver = try Driver(args: arguments, diagnosticsEngine: diagnosticsEngine, executor: executor) // FIXME: The following check should be at the end of Driver.init, but current // usage of the DiagnosticVerifier in tests makes this difficult. guard !driver.diagnosticEngine.hasErrors else { throw Diagnostics.fatalError } // ͜͜ let jobs = try driver.planBuild() try driver.run(jobs: jobs) ... 62
  36. ࠷ޙͷ͜͜ͷ෦෼ ... let executor = try SwiftDriverExecutor(diagnosticsEngine: diagnosticsEngine, processSet: processSet,

    fileSystem: localFileSystem, env: ProcessEnv.vars) var driver = try Driver(args: arguments, diagnosticsEngine: diagnosticsEngine, executor: executor) // FIXME: The following check should be at the end of Driver.init, but current // usage of the DiagnosticVerifier in tests makes this difficult. guard !driver.diagnosticEngine.hasErrors else { throw Diagnostics.fatalError } let jobs = try driver.planBuild() // ͜͜ try driver.run(jobs: jobs) ... 64
  37. main.swift ΄΅શ෦ಡΊͨʂ if driver.diagnosticEngine.hasErrors { exit(EXIT_FAILURE) } } catch Diagnostics.fatalError

    { exit(EXIT_FAILURE) } catch let diagnosticData as DiagnosticData { diagnosticsEngine.emit(.error(diagnosticData)) exit(EXIT_FAILURE) } catch { print("error: \(error)") exit(EXIT_FAILURE) } • ޙ͸ try catch ͷΤϥʔϋϯυϦϯά͚ͩͰ͢ • આ໌͠ͳͯ͘΋͍͍ͩͨΘ͔Δͱࢥ͍·͢ 67
  38. ࢀߟจݙ • What is a driver, for example, a compiler

    driver? - Quora • h9ps:/ /www.quora.com/What-is-a-driver-for-example-a-compiler-driver • IntroducAon - The LLVM Compiler Driver (llvmc) • h9ps:/ /releases.llvm.org/1.8/docs/CompilerDriver.html • ίϯύΠϥ͸ԿΛ͍ͯ͠Δͷ͔ - େ୍ ݚڀࣨ Ἒ৓େֶ • h9p:/ /nenya.cis.ibaraki.ac.jp/TIPS/compiler.html 70
  39. ࢀߟจݙ • apple/swi*-driver • h0ps:/ /github.com/apple/swi*-driver • Harlan Haskins -

    Twi0er • h0ps:/ /twi0er.com/harlanhaskins/status/1182325909220556800 • Javi - Twi0er • h0ps:/ /twi0er.com/Javi/status/1260793917563256834 71