Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mock a runtime type system & other changes #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ let package = Package(
.target(
name: "SwiftTypeSystem",
dependencies: []),
.target(
name: "SwiftRuntime",
dependencies: ["SwiftTypeSystem"]),
.testTarget(
name: "SwiftTypeSystemTests",
dependencies: ["SwiftTypeSystem"]),
Expand Down
40 changes: 40 additions & 0 deletions Sources/SwiftRuntime/Metadata.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import SwiftTypeSystem

public struct Metadata: TypeProtocol, Layout {
public typealias System = Runtime
typealias Layout = Kind

let pointer: UnsafeRawPointer

init(_ ptr: UnsafeRawPointer) {
self.pointer = ptr
}
}

extension Metadata {
public var kind: Kind {
layout
}
}

extension Metadata {
/// The structure of the type, which mirrors the spelling of the type as
/// written in the language.
public var structure: StructuralType<Metadata> {
switch kind {
case .tuple:
let elts = TupleMetadata(pointer).map {
TupleTypeElement<Runtime>(
// We can technically dig this out from the labels string in tuple.
name: nil,
type: $0.type
)
}

return .tuple(elts)

default:
return .placeholder
}
}
}
114 changes: 114 additions & 0 deletions Sources/SwiftRuntime/MetadataValues.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
extension Metadata {
public struct Kind {
let value: Int

init(_ value: Int) {
self.value = value
}

static var isRuntimePrivate: Int {
0x100
}

static var isNonHeap: Int {
0x200
}

static var isNonType: Int {
0x400
}

public static var `class`: Kind {
Kind(0x0)
}

public static var `struct`: Kind {
Kind(0x0 | isNonHeap)
}

public static var `enum`: Kind {
Kind(0x1 | isNonHeap)
}

public static var optional: Kind {
Kind(0x2 | isNonHeap)
}

public static var foreignClass: Kind {
Kind(0x3 | isNonHeap)
}

public static var foreignReferenceType: Kind {
Kind(0x4 | isNonHeap)
}

public static var opaque: Kind {
Kind(0x0 | isRuntimePrivate | isNonHeap)
}

public static var tuple: Kind {
Kind(0x1 | isRuntimePrivate | isNonHeap)
}

public static var function: Kind {
Kind(0x2 | isRuntimePrivate | isNonHeap)
}

public static var existential: Kind {
Kind(0x3 | isRuntimePrivate | isNonHeap)
}

public static var metatype: Kind {
Kind(0x4 | isRuntimePrivate | isNonHeap)
}

public static var objcClassWrapper: Kind {
Kind(0x5 | isRuntimePrivate | isNonHeap)
}

public static var existentialMetatype: Kind {
Kind(0x6 | isRuntimePrivate | isNonHeap)
}

public static var extendedExistential: Kind {
Kind(0x7 | isRuntimePrivate | isNonHeap)
}

public static var heapLocalVariable: Kind {
Kind(0x0 | isNonType)
}

public static var heapGenericLocalVariable: Kind {
Kind(0x0 | isRuntimePrivate | isNonType)
}

public static var errorObject: Kind {
Kind(0x1 | isRuntimePrivate | isNonType)
}

public static var task: Kind {
Kind(0x2 | isRuntimePrivate | isNonType)
}

public static var job: Kind {
Kind(0x3 | isRuntimePrivate | isNonType)
}
}
}

extension Metadata.Kind: Equatable {
public static func ==(_ lhs: Metadata.Kind, _ rhs: Metadata.Kind) -> Bool {
// On Darwin platforms, the metadata kind for class types is the ObjC isa
// pointer value which is guaranteed to be >= 0x800.
switch (lhs.value, rhs.value) {
case (0x800..., 0x0):
return true
case (0x0, 0x800...):
return true
case (0x800..., 0x800...):
return true
default:
return lhs.value == rhs.value
}
}
}
15 changes: 15 additions & 0 deletions Sources/SwiftRuntime/Misc.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
protocol Layout {
associatedtype Layout

var pointer: UnsafeRawPointer { get }
}

extension Layout {
var layout: Layout {
pointer.load(as: Layout.self)
}

var trailing: UnsafeRawPointer {
pointer + MemoryLayout<Layout>.size
}
}
49 changes: 49 additions & 0 deletions Sources/SwiftRuntime/Runtime.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import SwiftTypeSystem

public struct Runtime: TypeSystem {
public typealias Context = ()
public typealias TypeRef = Metadata
public typealias ResolvedNameBaggage = Never

/// Bind the names of a type in the given context, resolving names to the
/// kind of entity (and associated baggage) providing resolved names for each
/// identifier.
public func bind(_ type: TypeRef, in context: Context) -> TypeRef {
type
}

/// Resolve a type in context, binding any names, checking generic arguments,
/// and producing complete substitution maps (for example).
///
/// Note: we need some way of producing errors.
public func resolve(_ type: TypeRef, in context: Context) -> TypeRef {
type
}

/// Canonicalize a type in context, producing an equivalent type that
/// reduces all syntactic sugar (including, e.g., type aliases,
/// array/dictionary/optional sugar, parentheses, and so on).
///
/// The canonical type produced from this operation is the language's notion
/// of the type, which provides complete information for identifying the type
/// independent of any context. A canonical type can be reasonably
/// interpreted within any type system, without consulting system-specific
/// baggage.
///
/// Comparing two canonical types for equality determines whether
/// the two types are semantic equivalent according to the language
/// definition.
public func canonicalize(_ type: TypeRef, in context: Context) -> TypeRef {
type
}

/// Apply the given set of `substitutions` to the provided `type`, replacing
/// each occurrence of a generic parameter within the type with its
/// corresponding generic argument.
public func substitute(
in type: TypeRef,
with substitutions: SubstitutionMap<Self>
) -> TypeRef {
type
}
}
47 changes: 47 additions & 0 deletions Sources/SwiftRuntime/TupleMetadata.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
public struct TupleMetadata: Layout {
typealias Layout = (
base: Metadata.Layout,
numberOfElements: Int,
labels: UnsafePointer<CChar>?
)

let pointer: UnsafeRawPointer

init(_ ptr: UnsafeRawPointer) {
self.pointer = ptr
}
}

extension TupleMetadata: RandomAccessCollection {
public struct Element {
let storage: (Metadata, Int)

public var type: Metadata {
storage.0
}

public var offset: Int {
storage.1
}
}

public var startIndex: Int {
0
}

public var endIndex: Int {
layout.numberOfElements
}

public func index(after i: Int) -> Int {
i + 1
}

public func index(before i: Int) -> Int {
i - 1
}

public subscript(position: Int) -> Element {
(trailing + position * MemoryLayout<Element>.size).load(as: Element.self)
}
}
13 changes: 6 additions & 7 deletions Sources/SwiftTypeSystem/FunctionTypes.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

extension Type {
public struct FunctionType<System: TypeSystem> {
/// The calling convention used for a function.
public enum FunctionConvention {
public enum Convention {
/// The normal Swift calling convention.
///
/// This is the default calling convention for Swift functions, which is
Expand All @@ -26,7 +25,7 @@ extension Type {
}

/// Attributes provided for a function.
public struct FunctionAttributes {
public struct Attributes {
/// Whether this function is asynchronous.
public var `async`: Bool

Expand All @@ -40,10 +39,10 @@ extension Type {
public var `sendable`: Bool

/// The calling convention for the function.
public var convention: FunctionConvention = .swift
public var convention: Convention = .swift

/// The global actor, such as `@MainActor`, on which this function runs.
public var globalActor: Type?
public var globalActor: System.Type?
}

/// The convention used to pass a parameter.
Expand All @@ -61,7 +60,7 @@ extension Type {
}

/// A parameter within a function type.
public struct FunctionTypeParameter {
public struct Parameter {
/// The argument label used when calling the function.
///
/// Note: this is in the language grammar, but must either be omitted or
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftTypeSystem/GenericArgument.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/// A generic argument.
public enum GenericArgument<System: TypeSystem> {
case type(Type<System>)
case type(System.Type)
}
2 changes: 0 additions & 2 deletions Sources/SwiftTypeSystem/GenericParameter.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
public enum GenericParameter<System: TypeSystem> {
public typealias TypeRef = Type<System>

/// A generic type parameter, e.g., <T>.
case type(
name: Identifier?,
Expand Down
11 changes: 4 additions & 7 deletions Sources/SwiftTypeSystem/GenericRequirement.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/// A constraint on the layout of a type, e.g., it is known to be a class,
/// or be trivial with a fixed size.
public enum LayoutConstraint {
Expand Down Expand Up @@ -30,22 +29,20 @@ public enum LayoutConstraint {
/// A generic requirement that is part of the generic signature of a type,
/// e.g., `C: Collection` or `C.Element == C2.Element`.
public enum GenericRequirement<System: TypeSystem> {
public typealias TypeRef = Type<System>

/// A type bound such as `C: Collection` or `T: SomeSuperclass`.
case typeBound(TypeRef, TypeRef)
case typeBound(System.Type, System.Type)

/// A same-type constraint such as `C.Element == C2.Element`.
case sameType(TypeRef, TypeRef)
case sameType(System.Type, System.Type)

/// A same-shape constraint that ensures that two parameter packs have the
/// same shape.
///
/// Note: this does not have a spelling in the surface language.
case sameShape(TypeRef, TypeRef)
case sameShape(System.Type, System.Type)

/// A layout constraint that states that a given type
case layout(TypeRef, LayoutConstraint)
case layout(System.Type, LayoutConstraint)

/// A pack expansion of a generic requirement, e.g.,
/// `T.Element = U.Element...`.
Expand Down
1 change: 1 addition & 0 deletions Sources/SwiftTypeSystem/Misc.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public typealias Identifier = String
Loading