Repository: NSExceptional/Runtime
Branch: master
Commit: 1bb33a438f3b
Files: 23
Total size: 62.5 KB
Directory structure:
gitextract_savhqszy/
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── README.md
├── Runtime/
│ ├── Class.swift
│ ├── ClassBuilder.swift
│ ├── DebugDescriptions.swift
│ ├── Ivar.swift
│ ├── Method.swift
│ ├── Object.swift
│ ├── OrderedSet.swift
│ ├── Platform.swift
│ ├── Pointer.swift
│ ├── Property.swift
│ ├── Protocol.swift
│ ├── RootObject.swift
│ ├── Runtime.swift
│ ├── Struct.swift
│ └── Types.swift
├── Runtime.xcodeproj/
│ ├── project.pbxproj
│ └── project.xcworkspace/
│ └── contents.xcworkspacedata
└── RuntimeTests/
├── Info.plist
├── Person.swift
└── RuntimeTests.swift
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [NSExceptional]
================================================
FILE: .gitignore
================================================
# Xcode
.DS_Store
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
!default.xcworkspace
xcuserdata
profile
*.moved-aside
DerivedData
.idea/
*.xcbkptlist
*.xccheckout
*.hmap
*.ipa
*.swp
*.lock
*.xcuserstate
Luna.xcworkspace/xcuserdata/tantan.xcuserdatad/UserInterfaceState.xcuserstate
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
================================================
FILE: README.md
================================================
# Runtime
An Objective-C simulator written in Swift.
## Goals
With few exceptions, this project aims to simulate, in Swift, how Objective-C works under the hood (i.e. calls to `objc_msgSend`, inserted ARC functions, literal class-refs in class method calls, etc), as opposed to mirroring Objective-C style code and dynamism which Swift can accomplish already via `@objc` classes.
This project could theoretically be used as a dynamic runtime backend for a transpiled progamming language, and as such, this framework and its conventions were crafted with this idea in mind. Many of the constructs used here may seem to lack type-safety, but everything is perfectly safe if the code is generated by some other, more type-safe language. In short, this code is not meant to be written by hand if used for anything serious.
## Features
- Dynamic method dispatch
- Method swizzling / replacing
- Creating entire classes at runtime
- Non-fragile ivars
See `Person.Swift` for an examples of everything mentioned in the readme.
## Overview
Runtime metadata types provided by this framework mirrors that of the public Objective-C runtime interface as closely as possible, declaring types such as `Class`, `Ivar`, `Method`, etc, all of which provide about as much information as their Objective-C counterparts.
### Defining classes
A base class, `RootObject`, is provided for other classes to inherit from if they wish. New classes are defined by declaring a `struct` type to enclose the `Class` object in, with the class object itself being declared as a `static let`, followed by method variables.
```swift
struct Person {
static let `class` = Class(
isa: Person_meta.class,
superclass: RootObject.class,
name: "Person",
ivars: [
(name: "_name", type: .string),
(name: "_age", type: .integer)
],
methods: [_init, name, setName_, age, setAge_, description],
properties: [
Property(name: "name", getter: name, setter: setName_),
Property(name: "age", getter: age, setter: setAge_),
],
protocols: []
)
// Methods go here as static vars
static var _init = Method("init", returns: .object("this")) { this, _cmd, args in
func init$(_ this: id, _ _cmd: SEL) -> id {
_msgSend(this, "setName_", ("Bob"))
_msgSend(this, "setAge_", (18))
return msgSend(super: true, this, _cmd)
}
return init$(this, _cmd)
}
static var name = Method("name", returns: .string) ...
...
}
private struct Person_meta {
static let `class` = Class(
isa: nil,
superclass: nil,
name: "Person.meta",
...
)
}
```
It is good practice to declare a struct for the class itself and another for the metaclass, as above, to reduce ambiguity between class members and instance members (methods, properties, etc). The metaclass stores class members.
`isa:` should be the class's metaclass (or `nil` if the class is a metaclass itself). `superclass:` should be the superclass.
#### The Metaclass
Metaclasses inherit from the super-metaclass, not the superclass. It is convention to declare the compile-time variable like `MyClass_meta` and name it `"MyClass.meta"`. So, `Person` inherits from `Object.class`, and `Person_meta` inherits from `Object_meta.class`.
Each metaclass can be looked up by using `Class.named("Foo").isa` or directly by name with `Class.named("Foo.meta")`.
#### Methods
###### Declaration
`Method`s should be defined as `static var/let` as well (as opposed to right inside the `methods:` argument to the `.class` initializer as I have done with `properties:`), in case you need to reference the method as an argument to a `Property` at compile-time. Declaring them inline also makes the initializer very hard to parse visually since method declarations are typically no less than 7 or 8 lines.
###### Method.init() structure
The `Method` initializer takes the name of the method, the return and argument types (`Type`) an implementation (`IMP`). The return and argument types default to `.void` and `[]`. For initializers, it is convention to return `.object("self")` where you would use `instancetype` in Objective-C. You could use `.object("anything you want")`, but I find that `"self"` makes the most sense here. In cases where you return another object of a fixed type, use `.object("ClassName")`. This runtime aims to provide as much metadata for method type signatures as Objective-C does for property type signatures.
###### IMP arguments
Like Objective-C, all methods take two fixed arguments: `this` in place of `self`, and `_cmd`. However, due to limitations in the Swift type system, all method `IMP`s must return the same thing, `Any`, and without using assembly, they must all take `Any` as the variable arguments, even if a method takes no other arguments. An `IMP` is invoked by passing `this`, `_cmd`, and `args` where `args` is a tuple of the non-fixed arguments to the method.
###### Implementation conventions
To counteract the lack of type safety and enhance readability, I find it helpful to declare a function within the scope of the method `IMP` named with a traling `$` to represent the actual type signature of the method (and to hold the non-trivial implementation), like so:
```swift
static var add__ = Method(…) { this, _cmd, args in
// Actual implementation and type signature of method
func add__$(_ this: id, _ _cmd: SEL, a: Int, b: Int) -> Int {
return a + b
}
// Cast out arguments and call method
let args = args as! (Int, Int)
return add__$(this, _cmd, args.0, args.1)
}
```
Arguments must be cast from `Any` to their actual types as a tuple before being used.
###### Overriding methods
To override a method, simply give your subclass another method with the same name as the method you wish to override. If you need to call the `super` implementation, simply pass `super: true` to your call to `msgSend`:
```swift
static var _init = Method("init", ...) { this, _cmd, args in
func init$(_ this: id, _ _cmd: SEL) -> id {
return msgSend(super: true, this, _cmd)
print("init override: \(this)")
}
return init$(this, _cmd)
}
```
###### Init
If you're familiar with Swift, you may know that Swift doesn't allow you to use `self` before all ivars have been initialized. With some exceptions, the same is true here. That said, all ivars are initialized to `0` or `nil`, so it is not necessary to initialize primitive integral types to `nil` or `0`.
> Technically, if a class has no stored complex Swift structures in it (such as `String`), it should be safe to use prior to ivar initialization. I plan to make a wrapper for `String` and `Array`, etc, to counteract these edge cases.
#### Instance variables
Ivars are passed to the `Class` initializer as a tuple of their name and type. Their offset is detremined at runtime, and as a result, classes do not have fragile ivars.
> Metaclasses can not have any instance variables; trying to use ivars on a metaclass is undefined behavior.
#### Properties
Properties take a name and one or two implementations. A property's `type` comes from its `getter`.
--
### Creating objects
Instances of objects are allocated by calling `class.createInstance()`, i.e.:
```swift
let instance1 = Person.class.createInstance()
let instance2 = Class.named("Person").createInstance()
```
### Calling methods
Like Objective-C, this runtime uses dynamic dispatch via the `msgSend` and `_msgSend` functions. `_msgSend` only exists as a shortcut for void-returning methods, or cases where you want to discard the return value.
```swift
let bob: id = msgSend(Person.class.createInstance(), "init")
let name: String = msgSend(bob, "name")
let age: Int = msgSend(bob, "age")
let description: String = msgSend(bob, "description")
```
### Accessing ivars
Ivar access works similarly to how it works in Objective-C. You must retrieve the offset from the runtime and add it to `this` to access the ivar. A lot of casting is involved, and I've provided some operators to ease the pain:
```swift
let offset = this|.getClass.getIvarOffset("_someInt")!
let pointer: Pointer<Int> = ~pointer + offset
let ivarValue = pointer.pointee
```
`this|` is shorthand for `this.pointee`. `~pointer` is shorthand for `unsafeBitCast(pointer, to: T.self)`. Note that the runtime uses its own `Pointer` type, which allows `+` to offset it by bytes at at time.
The above is still pretty convoluted and heavily repeated, so I've provided yet another operator which returns `ivarValue` above:
```swift
let ivarValue: Int = this|"_someInt"
```
In general, `|` provides some form of dereferencing an object pointer. Here is another operator which can be used to set an ivar `_foo` to `5`:
```swift
this |= (5, "_foo")
```
--
### Type system "gotchas"
#### You're stuck with `id`
Since new classes are weakly defined as runtime metadata and not as concrete types in Swift code, you cannot declare a `Pointer` to a custom type directly. That is, all object references are typed as `Pointer<Object>` aka `id`, as defined by `Object.swift` (not to be confused with `RootObject`, which is akin to `NSObject`).
If you really want to declare a `Pointer<Vehicle>` for example, you could declare members on your `Vehicle ` struct like so, alongside the `static let class` declaration:
```swift
struct Vehicle {
let _super: Object
let _capacity: Int
...
static let `class` = Class(isa: ...)
}
/// Vehicle subclass
struct Car {
let _super: Vehicle
let make: String
let model: String
let year: Int
...
static let `class` = Class(isa: ...)
}
```
Now, you could possibly do the following:
```swift
let fiesta: Pointer<Car> = msgSend(
Car.class.createInstance(),
"init",
("Ford", "Fiesta", 2014, ...)
)
fiesta.year = 2017
```
Be sure to continue to declare all ivars and methods inside the `Class` variable. Statically declaring the layout like this is only useful for extra type-safety and direct ivar access if you wish to bypass non-fragile ivar lookup.
#### Using `Class`es as objects
`Class` instances could only be made possible by making `Class` a Swift `class` and not a `struct`, due to limitations in Swift's type system and several abstractions Swift imposes on the user. Therefore, they do not have the same underlying structure as `Object` does (that is, `Class` does not start with the `isa` defined by the `Object` declaration). To call a class method on a class, pass `.ref` as `this`:
```swift
_msgSend(Person.class.ref, "someClassMethod")
```
In general, use `class.ref` whenever you wish to treat a `Class` as an object.
### Other caveats
`Class` objects will not be available via `Class.named(_:)` until they have been accessed statically. You should "load" these classes manually by accessing all classes you define, like so:
```swift
func runtimeInit() {
// Runtime initialization
_ = RootObject.class
_ = Person.class
...
}
```
Ideally this shouldn't be necessary, or should be easier. Please submit a pull request if you have suggestions on how to make this easier or unnecessary!
---
## To-do
- More tests
- Zeroing deallocated references
- Suggestions welcome!
================================================
FILE: Runtime/Class.swift
================================================
//
// Class.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public class Class {
public let isa: Class! // metaclass, nil for metaclasses
let magic: UInt = 0xAAAABBBBCCCCDDDD // for debugging purposes, will be removed
public let superclass: Class! // nil if no superclass
public let name: String
public let instanceSize: Int
/// Instance class property-backing variables
let ivars: [Ivar]
/// Instance or class methods
let methods: [SEL: Method]
/// Instance or class properties
let properties: [Property]
/// Protocols conformed to by instances; not applicable to classes
let protocols: [Protocol]
private static let __swobjSize = 16
/// Used to refer to the class as an object.
/// Temporary workaround since class objects themselves
/// already have an `isa` provided by Swift.
public var ref: id {
var ptr: id = ~self
ptr += Class.__swobjSize
return ptr
}
public init(isa: Class!, superclass: Class?, name: String,
ivars stubs: [Ivar.Stub] = [], methods: [Method] = [], properties: [Property] = [], protocols: [Protocol] = [], extraBytes: Int = 0) {
let offset = superclass?.instanceSize ?? Type.pointer(.class("")).size
self.isa = isa
self.superclass = superclass
self.name = name
self.instanceSize = offset + stubs.map { return $0.type.size }.reduce(0, +) + extraBytes
self.ivars = Ivar.make(from: stubs, offset)
self.properties = properties
self.protocols = protocols
self.methods = {
var dict: [SEL: Method] = [:]
for method in methods {
dict[method.name] = method
}
return dict
}()
Class.classList.append(self)
}
public func createInstance() -> id {
let instance = Pointer<Object>.calloc(self.instanceSize)
instance.pointee.isa = self
return instance
}
public func method(named: String) -> Method! {
return self.methods[named]
}
public func ivar(named name: String) -> Ivar! {
return self.ivars.filter { $0.name == name }.first
}
public func property(named name: String) -> Property! {
return self.properties.filter { $0.name == name }.first
}
public func conforms(to protocol: String) -> Bool {
return !self.protocols.filter { $0.name == name }.isEmpty
}
public func getIvarOffset(_ name: String) -> Int! {
return self.ivar(named: name)?.offset
}
public func getMethodIMP(_ sel: SEL) -> IMP? {
return self.method(named: sel)?.imp
}
public static func isClass(_ object: id) -> Bool {
if object|.isa == nil {
// Metaclass.isa -> nil
return true
} else if object|.isa.isa == nil {
// Class.isa -> metaclass.isa -> nil
return true
} else {
// Object.isa -> Class.isa -> metaclass.isa -> nil
return false
}
}
}
public extension Class {
static var classList: [Class] = []
public static func named(_ name: String) -> Class! {
return Class.classList.filter { $0.name == name }.first
}
}
================================================
FILE: Runtime/ClassBuilder.swift
================================================
//
// ClassBuilder.swift
// Runtime
//
// Created by Tanner on 10/21/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public class ClassBuilder {
public var superclass: Class?
public var name: String
public var extraBytes: Int
private var final = false
private var methods: OrderedSet<Method> = []
private var classMethods: OrderedSet<Method> = []
private var ivars: OrderedSet<IvarStub> = []
private var properties: OrderedSet<Property> = []
private var classProperties: OrderedSet<Property> = []
private var protocols: OrderedSet<Protocol> = []
/// - Warning: returns nil if a class with the given name already exists.
public init?(name: String, superclass: Class? = RootObject.class, extraBytes: Int = 0) {
if Class.named(name) != nil {
return nil
}
self.superclass = superclass
self.name = name
self.extraBytes = extraBytes
}
/// Actually creates the class and adds it to the runtime.
///
/// The class you are constructing cannot be used until it is finalized.
/// - Returns: The newly created class.
public func finalize() -> Class {
let metaclass = Class(
isa: nil,
superclass: self.superclass?.isa,
name: self.name + ".meta",
ivars: [],
methods: self.classMethods.array,
properties: self.classProperties.array,
protocols: []
)
let cls = Class(
isa: metaclass,
superclass: self.superclass,
name: self.name,
ivars: self.ivars.array.map({ $0.stub }),
methods: self.methods.array,
properties: self.properties.array,
protocols: self.protocols.array,
extraBytes: self.extraBytes
)
self.final = true
Class.classList.append(cls)
return cls
}
public func add(_ methods: [Method], toClass: Bool = false) {
if toClass {
self.classMethods.addAll(methods)
} else {
self.methods.addAll(methods)
}
}
public func add(_ ivars: [IvarStub]) {
self.ivars.addAll(ivars)
}
public func add(_ properties: [Property], toClass: Bool = false) {
if toClass {
self.classProperties.addAll(properties)
} else {
self.properties.addAll(properties)
}
}
public func add(_ protocols: [Protocol]) {
self.protocols .addAll(protocols)
}
public struct IvarStub: Hashable {
let name: String
let type: Type
fileprivate var stub: Ivar.Stub { return (name, type) }
public var hashValue: Int {
return self.name.hashValue
}
public static func ==(lhs: IvarStub, rhs: IvarStub) -> Bool {
return lhs.name == rhs.name
}
}
}
================================================
FILE: Runtime/DebugDescriptions.swift
================================================
//
// DebugDescriptions.swift
// Runtime
//
// Created by Tanner on 10/21/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
extension Class: CustomDebugStringConvertible, CustomStringConvertible, CustomPlaygroundQuickLookable {
public var customPlaygroundQuickLook: PlaygroundQuickLook {
return .text(self.name)
}
public var description: String {
return self.name
}
public var debugDescription: String {
var me = self
return """
<Class \(self.name) (\(|me))> {
isa: \(self.isa?.name ?? "nil"),
superclass: \(self.superclass?.name ?? "nil"),
methods: \(self.methods.count),
properties: \(self.properties.count),
protocols: \(self.protocols.count),
}
"""
}
}
================================================
FILE: Runtime/Ivar.swift
================================================
//
// Ivar.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public struct Ivar: Hashable {
public typealias Stub = (name: String, type: Type)
public let name: String
public let type: Type
public let offset: Int
public var hashValue: Int {
return self.name.hashValue
}
public static func ==(lhs: Ivar, rhs: Ivar) -> Bool {
return lhs.name == rhs.name
}
}
extension Ivar {
static func make(from stubs: [Stub], _ offset: Int) -> [Ivar] {
var offsett = offset
return stubs.map { stub -> Ivar in
defer { offsett += stub.type.size }
return Ivar(name: stub.name, type: stub.type, offset: offsett)
}
}
}
================================================
FILE: Runtime/Method.swift
================================================
//
// Method.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public class Method: Hashable {
public typealias Signauture = (returnType: Type, argumentTypes: [Type])
public let name: String
public var imp: IMP
public let returnType: Type
public let argumentTypes: [Type]
public var signature: Signauture {
return (self.returnType, self.argumentTypes)
}
public init(_ name: String, returns: Type = .void, args: [Type] = [], _ imp: @escaping IMP) {
self.name = name
self.returnType = returns
self.argumentTypes = args
self.imp = imp
}
convenience public init(name: String, signature: Signauture = (.void, []), _ imp: @escaping IMP) {
self.init(name, returns: signature.returnType, args: signature.argumentTypes, imp)
}
public var hashValue: Int {
return self.name.hashValue
}
public static func ==(lhs: Method, rhs: Method) -> Bool {
return lhs.name == rhs.name
}
}
================================================
FILE: Runtime/Object.swift
================================================
//
// Object.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public struct Object {
var isa: Class!
public var getClass: Class {
return self.isa
}
public func respondsTo(_ selector: SEL) -> Bool {
return self.isa.getMethodIMP(selector) != nil
}
}
extension Pointer: CustomStringConvertible, CustomDebugStringConvertible {
public var debugDescription: String { return self.description }
public var description: String {
if Pointee.self is Object.Type {
let this: id = ~self
if this|.respondsTo("description") {
return msgSend(this, "description")
} else {
return "<\(this|.getClass) \(self.raw.debugDescription)>"
}
}
return self.raw.debugDescription
}
}
================================================
FILE: Runtime/OrderedSet.swift
================================================
//
// OrderedSet.swift
// Runtime
//
// Created by Tanner on 10/23/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
class OrderedSet<T: Hashable>: ExpressibleByArrayLiteral {
var array: [T] = []
var set: Set<T> = []
init() { }
/// - Returns: true if the element was not already in the set, false otherwise
@discardableResult
func add(_ element: T) -> Bool {
if self.set.insert(element).inserted {
array.append(element)
return true
}
return false
}
/// - Returns: true if all elements were not already in the set, false otherwise
@discardableResult
func addAll(_ elements: [T]) -> Bool {
var allIn = true
for e in elements {
if !self.add(e) {
allIn = false
}
}
return allIn
}
required init(arrayLiteral elements: T...) {
self.addAll(elements)
}
}
================================================
FILE: Runtime/Platform.swift
================================================
//
// Platform.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
struct Platform {
static let is64Bit = MemoryLayout<Int>.size == MemoryLayout<Int64>.size
}
================================================
FILE: Runtime/Pointer.swift
================================================
//
// Pointer.swift
// MirrorKit.swift
//
// Created by Tanner on 8/25/17.
//
import Foundation
extension UnsafeMutableRawPointer {
@inline(__always)
init<T>(to thing: inout T) {
self = withUnsafeMutablePointer(to: &thing) { UnsafeMutableRawPointer($0) }
}
}
prefix operator ~
public prefix func ~<T,U>(thing: T) -> U {
return unsafeBitCast(thing, to: U.self)
}
infix operator |=
/// Shorthand ivar set
public func |=<T>(pointer: id, change: (value: T, ivar: String)) {
let offset = pointer|.getClass.getIvarOffset(change.ivar)!
let pointer: Pointer<T> = ~pointer + offset
pointer.pointee = change.value
}
infix operator |
/// Shorthand ivar get
public func |<T>(pointer: id, ivar: String) -> T {
let offset = pointer|.getClass.getIvarOffset(ivar)!
let ivarPtr: Pointer<T> = ~(pointer + offset)
return ivarPtr.pointee
}
postfix operator |
/// Shorthand for .pointee
public postfix func |<T>(pointer: Pointer<T>) -> T {
return pointer.pointee
}
prefix operator |
/// Shorthand for .pointee
@inline(__always)
public prefix func |<T>(pointee: inout T) -> Pointer<T> {
return Pointer(to: &pointee)
}
public struct Pointer<Pointee>: Strideable, Hashable, Equatable {
// MARK: Public
public let raw: UnsafeMutableRawPointer
public var pointee: Pointee {
get { return self.read() }
nonmutating set { return self.write(newValue) }
}
// Get a Pointer to some variable
public init<T>(to thing: inout T) {
self.raw = UnsafeMutableRawPointer(to: &thing)
}
// Convert some variable, which is already a "pointer" itself, into a Pointer
public init(from pointer: inout Any) {
self.raw = ~pointer
}
public func read<T>(byteOffset: Int = 0) -> T {
return self.raw.load(fromByteOffset: byteOffset, as: T.self)
}
public func write<T>(_ value: T, byteOffset: Int = 0) {
self.raw.storeBytes(of: value, toByteOffset: byteOffset, as: T.self)
}
// MARK: Memory management
public static func alloc(_ count: Int) -> Pointer {
return Pointer(raw: UnsafeMutablePointer.allocate(capacity: count))
}
public static func calloc(_ count: Int) -> Pointer {
#if os(Linux)
return Pointer(raw: Glibc.calloc(count, 1))
#else
return Pointer(raw: Darwin.calloc(count, 1))
#endif
}
public func free() {
#if os(Linux)
Glibc.free(self.raw)
#else
Darwin.free(self.raw)
#endif
}
public func free(_ count: Int) {
self.raw.deallocate(bytes: count, alignedTo: MemoryLayout<Pointee>.alignment)
}
// MARK: Private
init(raw pointer: UnsafeMutableRawPointer) {
self.raw = pointer
}
// MARK: Strideable
public func distance(to other: Pointer) -> Int {
return self.raw.distance(to: other.raw)
}
public func advanced(by n: Int) -> Pointer {
return Pointer(raw: self.raw.advanced(by: n))
}
// MARK: Hashable
public var hashValue: Int {
return self.raw.hashValue
}
// MARK: Convenience
public static func +(lhs: Pointer, rhs: Int) -> Pointer {
return lhs.advanced(by: rhs)
}
public static func -(lhs: Pointer, rhs: Int) -> Pointer {
return lhs.advanced(by: -rhs)
}
public static func +=(lhs: inout Pointer, rhs: Int) {
lhs = lhs.advanced(by: rhs)
}
public static func -=(lhs: inout Pointer, rhs: Int) {
lhs = lhs.advanced(by: -rhs)
}
public static postfix func ++(pointer: inout Pointer) {
pointer = pointer.advanced(by: 1)
}
public static postfix func --(pointer: inout Pointer) {
pointer = pointer.advanced(by: -1)
}
}
================================================
FILE: Runtime/Property.swift
================================================
//
// Property.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public struct Property: Hashable, Equatable {
public let name: String
public let getter: Method
public let setter: Method!
public var type: Type {
return self.getter.returnType
}
public var hashValue: Int {
return self.name.hashValue
}
public static func ==(lhs: Property, rhs: Property) -> Bool {
return lhs.name == rhs.name
}
}
================================================
FILE: Runtime/Protocol.swift
================================================
//
// Protocol.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public class Protocol: Hashable {
public let name: String
public let methods: [Method]
public init(name: String, methods: [Method]) {
self.name = name
self.methods = methods
}
public var hashValue: Int {
return self.name.hashValue
}
public static func ==(lhs: Protocol, rhs: Protocol) -> Bool {
return lhs.name == rhs.name
}
}
public extension Protocol {
static var protocolList: [Protocol] = []
public static func named(_ name: String) -> Protocol! {
return Protocol.protocolList.filter { $0.name == name }.first
}
}
================================================
FILE: Runtime/RootObject.swift
================================================
//
// RootObject.swift
// Runtime
//
// Created by Tanner on 10/19/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
/// New classes are defined as static instances within an extension on Class itself.
/// Methods, ivars, properties, etc for these new classes are defined as below.
public struct RootObject {
static let `class` = Class(
isa: RootObject_meta.class,
superclass: nil,
name: "Object",
ivars: [("isa", .pointer(.class("self"))), ("_retainCount", .integer)],
methods: [_init, retain, retainCount]
)
static var _init = Method("init", returns: .object("self")) { this, _cmd, args in
func init$(_ this: id, _ _cmd: SEL) -> id {
print("\(this|.getClass).init(): \(this)")
return this
}
return init$(this, _cmd)
}
static var retain = Method("retain", returns: .object("self")) { this, _cmd, args in
func retain$(_ this: id, _ _cmd: SEL) -> id {
let newCount: Int = (this|"_retainCount") + 1
this |= (newCount, "_retainCount")
return this
}
return retain$(this, _cmd)
}
static var release = Method("release") { this, _cmd, args in
func release$(_ this: id, _ _cmd: SEL) {
let newCount: Int = (this|"_retainCount") - 1
this |= (newCount, "_retainCount")
if newCount < 1 {
if newCount < 0 {
fatalError("Over-released object at \(this.raw.debugDescription)")
}
this.free()
}
}
release$(this, _cmd)
return ()
}
static var retainCount = Method("retainCount", returns: .integer) { this, _cmd, args in
func retainCount$(_ this: id, _ _cmd: SEL) {
return this|"_retainCount"
}
retainCount$(this, _cmd)
return ()
}
}
public struct RootObject_meta {
static let `class` = Class(
isa: nil,
superclass: nil,
name: "Object.meta"
)
}
================================================
FILE: Runtime/Runtime.swift
================================================
//
// Runtime.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public typealias id = Pointer<Object>
public typealias SEL = String
public typealias IMP = (_ self: id, _ _cmd: SEL, _ args: Any) -> Any
@inline(__always) func prepareMsg(_ target: id, _ _cmd: SEL, super: Bool) -> IMP {
let isClass = Class.isClass(target)
var cls: Class!
if isClass {
cls = `super` ? target|.isa.superclass! : target|.isa
} else {
cls = `super` ? target|.getClass.superclass! : target|.getClass
}
var imp: IMP!
repeat {
imp = cls.getMethodIMP(_cmd)
cls = cls.superclass
} while imp == nil && cls != nil
guard imp != nil else {
let isClass = Class.isClass(target)
let invocation = (isClass ? "+" : "-") + "[\(target|.getClass.name) \(_cmd)]"
fatalError("Unrecognized selector sent to instance \(target.raw): " + invocation)
}
return imp
}
/// Dynamically calls a method on a `Foo` instance given a method name (like objc_msgSend)
public func msgSend<T>(super: Bool = false, _ target: id, _ _cmd: SEL, _ args: Any = ()) -> T {
let imp = prepareMsg(target, _cmd, super: `super`)
return imp(target, _cmd, args) as! T
}
/// Convenience for `Void` or discardable results
public func _msgSend(super: Bool = false, _ target: id, _ _cmd: SEL, _ args: Any = ()) {
let imp = prepareMsg(target, _cmd, super: `super`)
_ = imp(target, _cmd, args)
}
================================================
FILE: Runtime/Struct.swift
================================================
//
// Struct.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
/// As of now, purely for metadata purposes.
/// Provides no way to create and use structs.
/// It may make more sense just to use standard Swift structs
/// alongside instances of `Struct` for reflection purposes.
public class Struct {
let name: String
let instanceSize: Int
let ivars: [Ivar]
let methods: [Method]
let properties: [Property]
public init(name: String, instanceSize: Int, ivars: [Ivar.Stub] = [], methods: [Method] = [], properties: [Property] = []) {
self.name = name
self.instanceSize = instanceSize
self.ivars = Ivar.make(from: ivars, 0)
self.methods = methods
self.properties = properties
}
}
public extension Struct {
static var structList: [Struct] = []
public static func named(_ name: String) -> Struct! {
return Struct.structList.filter { $0.name == name }.first
}
}
public extension Struct {
public var describedAsTuple: String {
return "(" + self.ivars.map({ ivar in
if !ivar.name.isEmpty {
return ivar.name + ": " + ivar.type.description
} else {
return ivar.type.description
}
}).joined(separator: ", ")
}
public var typeEncoding: String {
return ""
}
}
================================================
FILE: Runtime/Types.swift
================================================
//
// Types.swift
// Runtime
//
// Created by Tanner on 10/18/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import Foundation
public indirect enum Type {
case void
case pointer(Type)
case integer
case float
case bool
case string
case tuple(String)
case optional(Type)
case object(String)
case `struct`(String)
case `class`(String)
public var description: String {
switch self {
case .void:
return "Void"
case .pointer(let type):
return "Pointer<\(type)>"
case .integer:
return "Integer"
case .float:
return "Float"
case .bool:
return "Bool"
case .string:
return "String"
case .tuple(let structName):
return structName // TDOO: struct.describedAsTuple
case .optional(let type):
return type.description + "?"
case .object(let name):
return name
case .struct(let name):
return name
case .class(let name):
return name
}
}
public var encoding: String {
switch self {
case .void:
return "v"
case .pointer(let type):
return "^\(type.encoding)"
case .integer:
return Platform.is64Bit ? "q" : "i"
case .float:
return Platform.is64Bit ? "d" : "f"
case .bool:
return "C"
case .string:
return "{11_StringCore}"
case .tuple(let structName):
return Type.struct(structName).encoding
case .optional(let type):
return "?\(type.description.count)\(type.description)"
case .object(_):
return "@"
case .struct(let name):
return "{\(name.count)" + name + "}"
case .class(_):
return "#"
}
}
public var size: Int {
switch self {
case .void:
return 0
case .pointer(_): fallthrough
case .integer:
return MemoryLayout<Int>.size
case .float:
return Platform.is64Bit ? MemoryLayout<Float64>.size : MemoryLayout<Float32>.size
case .bool:
return MemoryLayout<Bool>.size
case .string:
return MemoryLayout<String>.size
case .tuple(let structName):
return Type.struct(structName).size
case .optional(let type):
switch type {
case .pointer(let ptrType):
return ptrType.size
default:
return type.size + 1
}
case .object(let className):
return Class.named(className).instanceSize
case .struct(let name):
return Struct.named(name).instanceSize
case .class(_):
return 0 // You'll never need to know the size of a class in practice
}
}
}
================================================
FILE: Runtime.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
C35AEBBE1F987493008F2988 /* RuntimeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35AEBBD1F987493008F2988 /* RuntimeTests.swift */; };
C35AEBC01F987493008F2988 /* libRuntime.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F59BC81F981B41002494E4 /* libRuntime.a */; };
C37F4B741F9B279E000732E0 /* DebugDescriptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C37F4B731F9B279E000732E0 /* DebugDescriptions.swift */; };
C3BEFCC11F994C7F005AD638 /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BEFCC01F994C7F005AD638 /* Person.swift */; };
C3BEFCC31F994CB9005AD638 /* RootObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BEFCC21F994CB9005AD638 /* RootObject.swift */; };
C3D55DF81F9C4535006DE12F /* ClassBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D55DF71F9C4535006DE12F /* ClassBuilder.swift */; };
C3D55DFA1F9E4642006DE12F /* OrderedSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D55DF91F9E4642006DE12F /* OrderedSet.swift */; };
C3F59BD51F981B8D002494E4 /* Class.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BD41F981B8D002494E4 /* Class.swift */; };
C3F59BD91F981C20002494E4 /* Pointer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BD81F981C20002494E4 /* Pointer.swift */; };
C3F59BDB1F981C4D002494E4 /* Object.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BDA1F981C4D002494E4 /* Object.swift */; };
C3F59BDD1F981D8D002494E4 /* Ivar.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BDC1F981D8D002494E4 /* Ivar.swift */; };
C3F59BDF1F981D93002494E4 /* Method.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BDE1F981D93002494E4 /* Method.swift */; };
C3F59BE11F981D9C002494E4 /* Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BE01F981D9C002494E4 /* Property.swift */; };
C3F59BE31F981DAD002494E4 /* Protocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BE21F981DAD002494E4 /* Protocol.swift */; };
C3F59BE51F981E6F002494E4 /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BE41F981E6F002494E4 /* Types.swift */; };
C3F59BE71F98229C002494E4 /* Struct.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BE61F98229C002494E4 /* Struct.swift */; };
C3F59BE91F9827BD002494E4 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BE81F9827BD002494E4 /* Platform.swift */; };
C3F59BEB1F982B80002494E4 /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F59BEA1F982B80002494E4 /* Runtime.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
C35AEBC11F987493008F2988 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C3F59BC01F981B41002494E4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = C3F59BC71F981B41002494E4;
remoteInfo = Runtime;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
C3F59BC61F981B41002494E4 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
C35AEBBB1F987493008F2988 /* RuntimeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RuntimeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C35AEBBD1F987493008F2988 /* RuntimeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeTests.swift; sourceTree = "<group>"; };
C35AEBBF1F987493008F2988 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C37F4B731F9B279E000732E0 /* DebugDescriptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugDescriptions.swift; sourceTree = "<group>"; };
C3BEFCC01F994C7F005AD638 /* Person.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Person.swift; sourceTree = "<group>"; };
C3BEFCC21F994CB9005AD638 /* RootObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootObject.swift; sourceTree = "<group>"; };
C3D55DF71F9C4535006DE12F /* ClassBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClassBuilder.swift; sourceTree = "<group>"; };
C3D55DF91F9E4642006DE12F /* OrderedSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderedSet.swift; sourceTree = "<group>"; };
C3F59BC81F981B41002494E4 /* libRuntime.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRuntime.a; sourceTree = BUILT_PRODUCTS_DIR; };
C3F59BD41F981B8D002494E4 /* Class.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Class.swift; sourceTree = "<group>"; };
C3F59BD81F981C20002494E4 /* Pointer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pointer.swift; sourceTree = "<group>"; };
C3F59BDA1F981C4D002494E4 /* Object.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Object.swift; sourceTree = "<group>"; };
C3F59BDC1F981D8D002494E4 /* Ivar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ivar.swift; sourceTree = "<group>"; };
C3F59BDE1F981D93002494E4 /* Method.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Method.swift; sourceTree = "<group>"; };
C3F59BE01F981D9C002494E4 /* Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Property.swift; sourceTree = "<group>"; };
C3F59BE21F981DAD002494E4 /* Protocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Protocol.swift; sourceTree = "<group>"; };
C3F59BE41F981E6F002494E4 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; };
C3F59BE61F98229C002494E4 /* Struct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Struct.swift; sourceTree = "<group>"; };
C3F59BE81F9827BD002494E4 /* Platform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = "<group>"; };
C3F59BEA1F982B80002494E4 /* Runtime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Runtime.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C35AEBB81F987493008F2988 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C35AEBC01F987493008F2988 /* libRuntime.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C3F59BC51F981B41002494E4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
C35AEBBC1F987493008F2988 /* RuntimeTests */ = {
isa = PBXGroup;
children = (
C35AEBBD1F987493008F2988 /* RuntimeTests.swift */,
C35AEBBF1F987493008F2988 /* Info.plist */,
C3BEFCC01F994C7F005AD638 /* Person.swift */,
);
path = RuntimeTests;
sourceTree = "<group>";
};
C3F59BBF1F981B41002494E4 = {
isa = PBXGroup;
children = (
C3F59BCA1F981B41002494E4 /* Runtime */,
C35AEBBC1F987493008F2988 /* RuntimeTests */,
C3F59BC91F981B41002494E4 /* Products */,
);
sourceTree = "<group>";
};
C3F59BC91F981B41002494E4 /* Products */ = {
isa = PBXGroup;
children = (
C3F59BC81F981B41002494E4 /* libRuntime.a */,
C35AEBBB1F987493008F2988 /* RuntimeTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
C3F59BCA1F981B41002494E4 /* Runtime */ = {
isa = PBXGroup;
children = (
C3F59BEA1F982B80002494E4 /* Runtime.swift */,
C3F59BE81F9827BD002494E4 /* Platform.swift */,
C3F59BE41F981E6F002494E4 /* Types.swift */,
C3F59BD81F981C20002494E4 /* Pointer.swift */,
C3F59BD41F981B8D002494E4 /* Class.swift */,
C3D55DF71F9C4535006DE12F /* ClassBuilder.swift */,
C3F59BE61F98229C002494E4 /* Struct.swift */,
C3F59BDC1F981D8D002494E4 /* Ivar.swift */,
C3F59BDE1F981D93002494E4 /* Method.swift */,
C3F59BE01F981D9C002494E4 /* Property.swift */,
C3F59BE21F981DAD002494E4 /* Protocol.swift */,
C3F59BDA1F981C4D002494E4 /* Object.swift */,
C3BEFCC21F994CB9005AD638 /* RootObject.swift */,
C37F4B731F9B279E000732E0 /* DebugDescriptions.swift */,
C3D55DF91F9E4642006DE12F /* OrderedSet.swift */,
);
path = Runtime;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C35AEBBA1F987493008F2988 /* RuntimeTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = C35AEBC51F987493008F2988 /* Build configuration list for PBXNativeTarget "RuntimeTests" */;
buildPhases = (
C35AEBB71F987493008F2988 /* Sources */,
C35AEBB81F987493008F2988 /* Frameworks */,
C35AEBB91F987493008F2988 /* Resources */,
);
buildRules = (
);
dependencies = (
C35AEBC21F987493008F2988 /* PBXTargetDependency */,
);
name = RuntimeTests;
productName = RuntimeTests;
productReference = C35AEBBB1F987493008F2988 /* RuntimeTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
C3F59BC71F981B41002494E4 /* Runtime */ = {
isa = PBXNativeTarget;
buildConfigurationList = C3F59BD11F981B41002494E4 /* Build configuration list for PBXNativeTarget "Runtime" */;
buildPhases = (
C3F59BC41F981B41002494E4 /* Sources */,
C3F59BC51F981B41002494E4 /* Frameworks */,
C3F59BC61F981B41002494E4 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = Runtime;
productName = Runtime;
productReference = C3F59BC81F981B41002494E4 /* libRuntime.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C3F59BC01F981B41002494E4 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0900;
LastUpgradeCheck = 0910;
ORGANIZATIONNAME = "Tanner Bennett";
TargetAttributes = {
C35AEBBA1F987493008F2988 = {
CreatedOnToolsVersion = 9.0;
ProvisioningStyle = Automatic;
};
C3F59BC71F981B41002494E4 = {
CreatedOnToolsVersion = 9.0;
LastSwiftMigration = 0900;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = C3F59BC31F981B41002494E4 /* Build configuration list for PBXProject "Runtime" */;
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = C3F59BBF1F981B41002494E4;
productRefGroup = C3F59BC91F981B41002494E4 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C3F59BC71F981B41002494E4 /* Runtime */,
C35AEBBA1F987493008F2988 /* RuntimeTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
C35AEBB91F987493008F2988 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C35AEBB71F987493008F2988 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C3BEFCC11F994C7F005AD638 /* Person.swift in Sources */,
C35AEBBE1F987493008F2988 /* RuntimeTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C3F59BC41F981B41002494E4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C3F59BE91F9827BD002494E4 /* Platform.swift in Sources */,
C3F59BE11F981D9C002494E4 /* Property.swift in Sources */,
C3BEFCC31F994CB9005AD638 /* RootObject.swift in Sources */,
C3F59BDF1F981D93002494E4 /* Method.swift in Sources */,
C37F4B741F9B279E000732E0 /* DebugDescriptions.swift in Sources */,
C3F59BD51F981B8D002494E4 /* Class.swift in Sources */,
C3F59BE71F98229C002494E4 /* Struct.swift in Sources */,
C3F59BE51F981E6F002494E4 /* Types.swift in Sources */,
C3F59BEB1F982B80002494E4 /* Runtime.swift in Sources */,
C3D55DFA1F9E4642006DE12F /* OrderedSet.swift in Sources */,
C3F59BE31F981DAD002494E4 /* Protocol.swift in Sources */,
C3D55DF81F9C4535006DE12F /* ClassBuilder.swift in Sources */,
C3F59BDB1F981C4D002494E4 /* Object.swift in Sources */,
C3F59BD91F981C20002494E4 /* Pointer.swift in Sources */,
C3F59BDD1F981D8D002494E4 /* Ivar.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
C35AEBC21F987493008F2988 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = C3F59BC71F981B41002494E4 /* Runtime */;
targetProxy = C35AEBC11F987493008F2988 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
C35AEBC31F987493008F2988 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = S6N2F22V2Z;
INFOPLIST_FILE = RuntimeTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.nsexceptional.RuntimeTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
C35AEBC41F987493008F2988 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = S6N2F22V2Z;
INFOPLIST_FILE = RuntimeTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.nsexceptional.RuntimeTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
C3F59BCF1F981B41002494E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
C3F59BD01F981B41002494E4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C3F59BD21F981B41002494E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = S6N2F22V2Z;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
C3F59BD31F981B41002494E4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = S6N2F22V2Z;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C35AEBC51F987493008F2988 /* Build configuration list for PBXNativeTarget "RuntimeTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C35AEBC31F987493008F2988 /* Debug */,
C35AEBC41F987493008F2988 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C3F59BC31F981B41002494E4 /* Build configuration list for PBXProject "Runtime" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C3F59BCF1F981B41002494E4 /* Debug */,
C3F59BD01F981B41002494E4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C3F59BD11F981B41002494E4 /* Build configuration list for PBXNativeTarget "Runtime" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C3F59BD21F981B41002494E4 /* Debug */,
C3F59BD31F981B41002494E4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = C3F59BC01F981B41002494E4 /* Project object */;
}
================================================
FILE: Runtime.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Runtime.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: RuntimeTests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: RuntimeTests/Person.swift
================================================
//
// Person.swift
// RuntimeTests
//
// Created by Tanner on 10/19/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
@testable import Runtime
infix operator |=
infix operator |
/// Example subclass of RootObject.
struct Person {
static let `class` = Class(
isa: Person_meta.class,
superclass: RootObject.class,
name: "Person",
ivars: [
(name: "_name", type: .string),
(name: "_age", type: .integer)
],
methods: [_init, name, setName_, age, setAge_, description],
properties: [
Property(name: "name", getter: name, setter: setName_),
Property(name: "age", getter: age, setter: setAge_),
],
protocols: []
)
static var _init = Method("init", returns: .object("self")) { this, _cmd, args in
func init$(_ this: id, _ _cmd: SEL) -> id {
_msgSend(this, "setName_", ("Bob"))
_msgSend(this, "setAge_", (18))
print("init override: \(this)")
return msgSend(super: true, this, _cmd)
}
return init$(this, _cmd)
}
static var name = Method("name", returns: .string) { this, _cmd, args in
func name$(_ this: id, _ _cmd: SEL) -> String {
return this|"_name"
}
return name$(this, _cmd)
}
static var setName_ = Method("setName_", args: [.string]) { this, _cmd, args in
func setName$(_ this: id, _ _cmd: SEL, _ name: String) {
this |= (name, "_name")
}
let args = (args as! (String))
setName$(this, _cmd, args)
return ()
}
static var age = Method("age", returns: .string) { this, _cmd, args in
func age$(_ this: id, _ _cmd: SEL) -> Int {
return this|"_age"
}
return age$(this, _cmd)
}
static var setAge_ = Method("setAge_", args: [.string]) { this, _cmd, args in
func setName$(_ this: id, _ _cmd: SEL, _ age: Int) {
this |= (age, "_age")
}
let args = (args as! (Int))
setName$(this, _cmd, args)
return ()
}
static var description = Method("description", returns: .string) { this, _cmd, args in
func description$(_ this: id, _ _cmd: SEL) -> String {
let name: String = msgSend(this, "name")
let age: Int = msgSend(this, "age")
return """
<\(this|.getClass) \(this.raw.debugDescription)> {
name: \(name),
age: \(age)
}
"""
}
return description$(this, _cmd)
}
}
private struct Person_meta {
static let `class` = Class(
isa: nil,
superclass: nil,
name: "Person.meta",
ivars: [],
methods: [],
properties: [],
protocols: []
)
}
/// For debugging purposes
/// unsafeBitCast(this, to: UnsafePointer<person_>.self).pointee
struct person_ {
let isa: Class
let _retainCount: Int
let _name: String
let _age: Int
}
================================================
FILE: RuntimeTests/RuntimeTests.swift
================================================
//
// RuntimeTests.swift
// RuntimeTests
//
// Created by Tanner on 10/19/17.
// Copyright © 2017 Tanner Bennett. All rights reserved.
//
import XCTest
@testable import Runtime
class Tests: XCTestCase {
typealias id = Runtime.id
override func setUp() {
// Runtime initialization
_ = RootObject.class
_ = Person.class
}
func testPerson() {
let bob: id = msgSend(Person.class.createInstance(), "init")
let name: String = msgSend(bob, "name")
let age: Int = msgSend(bob, "age")
let description: String = msgSend(bob, "description")
XCTAssertEqual("Bob", name)
XCTAssertEqual(18, age)
XCTAssert(description.hasPrefix("\(bob)"))
}
func testPointerAssumptions() {
class Foo {
struct Layout {
let magic: (isa: Int, refCount: Int)
let count: Int
}
let count = 0x72656E6E6174
public init() {}
}
var instance = Foo()
let bitcast = unsafeBitCast(instance, to: Pointer<Foo.Layout>.self)
let unsafe = withUnsafePointer(to: &instance, { $0 })
XCTAssertEqual(bitcast|.count, unsafe.pointee.count)
}
func testClassObjectReferencing() {
var cls = Class.named("Object")!
XCTAssert(cls === RootObject.class)
let ptr: Pointer<Class> = |cls
let unsafePtr = withUnsafePointer(to: &cls, { $0 })
XCTAssertEqual(cls.name, ptr|.name)
XCTAssertEqual(ptr.raw.debugDescription, unsafePtr.debugDescription)
var asObject: id = ~cls
asObject += 16
XCTAssertEqual(cls.name, ptr|.name)
let ref = cls.ref
XCTAssertEqual(asObject, ref)
XCTAssert(ref|.isa === RootObject_meta.class)
}
func testCreateClass() {
XCTAssertNil(Class.named("Foo"))
var counter = 0
let builder = ClassBuilder(name: "Foo")!
let initializer = Method("init", returns: .object("self")) { this, _cmd, args in
func init$(_ this: id, _ _cmd: SEL) -> id {
let this: id = msgSend(super: true, this, _cmd)
counter += 1
return this
}
return init$(this, _cmd)
}
let method = Method("getClassName", returns: .string) { this, _cmd, args in
func getClassName$(_ this: id, _ _cmd: SEL) -> String {
return this|.getClass.name
}
return getClassName$(this, _cmd)
}
builder.add([initializer, method])
let classMethod = Method("instanceCount", returns: .integer) { this, _cmd, args in
func instanceCount$(_ this: id, _ _cmd: SEL) -> Int {
return counter
}
return instanceCount$(this, _cmd)
}
builder.add([classMethod], toClass: true)
let created = builder.finalize()
let asObject = created.ref // TODO: Make this not necessary
XCTAssert(created === Class.named("Foo"))
XCTAssertEqual(0, msgSend(asObject, "instanceCount"))
_msgSend(created.createInstance(), "init")
XCTAssertEqual(1, msgSend(asObject, "instanceCount"))
}
}
gitextract_savhqszy/
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── README.md
├── Runtime/
│ ├── Class.swift
│ ├── ClassBuilder.swift
│ ├── DebugDescriptions.swift
│ ├── Ivar.swift
│ ├── Method.swift
│ ├── Object.swift
│ ├── OrderedSet.swift
│ ├── Platform.swift
│ ├── Pointer.swift
│ ├── Property.swift
│ ├── Protocol.swift
│ ├── RootObject.swift
│ ├── Runtime.swift
│ ├── Struct.swift
│ └── Types.swift
├── Runtime.xcodeproj/
│ ├── project.pbxproj
│ └── project.xcworkspace/
│ └── contents.xcworkspacedata
└── RuntimeTests/
├── Info.plist
├── Person.swift
└── RuntimeTests.swift
Condensed preview — 23 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (69K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 71,
"preview": "# These are supported funding model platforms\n\ngithub: [NSExceptional]\n"
},
{
"path": ".gitignore",
"chars": 634,
"preview": "# Xcode\n.DS_Store\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev"
},
{
"path": "README.md",
"chars": 11353,
"preview": "# Runtime\n\nAn Objective-C simulator written in Swift.\n\n## Goals\n\nWith few exceptions, this project aims to simulate, in "
},
{
"path": "Runtime/Class.swift",
"chars": 3325,
"preview": "//\n// Class.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights res"
},
{
"path": "Runtime/ClassBuilder.swift",
"chars": 2930,
"preview": "//\n// ClassBuilder.swift\n// Runtime\n//\n// Created by Tanner on 10/21/17.\n// Copyright © 2017 Tanner Bennett. All rig"
},
{
"path": "Runtime/DebugDescriptions.swift",
"chars": 792,
"preview": "//\n// DebugDescriptions.swift\n// Runtime\n//\n// Created by Tanner on 10/21/17.\n// Copyright © 2017 Tanner Bennett. Al"
},
{
"path": "Runtime/Ivar.swift",
"chars": 797,
"preview": "//\n// Ivar.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights rese"
},
{
"path": "Runtime/Method.swift",
"chars": 1087,
"preview": "//\n// Method.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights re"
},
{
"path": "Runtime/Object.swift",
"chars": 900,
"preview": "//\n// Object.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights re"
},
{
"path": "Runtime/OrderedSet.swift",
"chars": 971,
"preview": "//\n// OrderedSet.swift\n// Runtime\n//\n// Created by Tanner on 10/23/17.\n// Copyright © 2017 Tanner Bennett. All right"
},
{
"path": "Runtime/Platform.swift",
"chars": 249,
"preview": "//\n// Platform.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights "
},
{
"path": "Runtime/Pointer.swift",
"chars": 3784,
"preview": "//\n// Pointer.swift\n// MirrorKit.swift\n//\n// Created by Tanner on 8/25/17.\n//\n\nimport Foundation\n\nextension UnsafeMut"
},
{
"path": "Runtime/Property.swift",
"chars": 546,
"preview": "//\n// Property.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights "
},
{
"path": "Runtime/Protocol.swift",
"chars": 760,
"preview": "//\n// Protocol.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights "
},
{
"path": "Runtime/RootObject.swift",
"chars": 2100,
"preview": "//\n// RootObject.swift\n// Runtime\n//\n// Created by Tanner on 10/19/17.\n// Copyright © 2017 Tanner Bennett. All right"
},
{
"path": "Runtime/Runtime.swift",
"chars": 1530,
"preview": "//\n// Runtime.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights r"
},
{
"path": "Runtime/Struct.swift",
"chars": 1436,
"preview": "//\n// Struct.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights re"
},
{
"path": "Runtime/Types.swift",
"chars": 2958,
"preview": "//\n// Types.swift\n// Runtime\n//\n// Created by Tanner on 10/18/17.\n// Copyright © 2017 Tanner Bennett. All rights res"
},
{
"path": "Runtime.xcodeproj/project.pbxproj",
"chars": 20622,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 48;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Runtime.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 152,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Runtime.xcodepr"
},
{
"path": "RuntimeTests/Info.plist",
"chars": 701,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "RuntimeTests/Person.swift",
"chars": 3086,
"preview": "//\n// Person.swift\n// RuntimeTests\n//\n// Created by Tanner on 10/19/17.\n// Copyright © 2017 Tanner Bennett. All righ"
},
{
"path": "RuntimeTests/RuntimeTests.swift",
"chars": 3251,
"preview": "//\n// RuntimeTests.swift\n// RuntimeTests\n//\n// Created by Tanner on 10/19/17.\n// Copyright © 2017 Tanner Bennett. Al"
}
]
About this extraction
This page contains the full source code of the NSExceptional/Runtime GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 23 files (62.5 KB), approximately 18.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.