Skip to content

Commit 0b19b58

Browse files
authored
Merge pull request #70685 from kubamracek/embedded-print-stopgap
[embedded] Add a stop-gap print() for embedded Swift
2 parents 68a1064 + bc36a0c commit 0b19b58

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+260
-175
lines changed

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ FUNCTION(UnexpectedError, swift_unexpectedError, SwiftCC, AlwaysAvailable,
193193
RETURNS(VoidTy),
194194
ARGS(ErrorPtrTy),
195195
ATTRS(NoUnwind, NoReturn),
196-
EFFECT(NoEffect),
196+
EFFECT(NoEffect, Deallocating),
197197
UNKNOWN_MEMEFFECTS)
198198

199199
// void *swift_copyPOD(void *dest, void *src, Metadata *self);

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ endif()
263263
list(APPEND SWIFTLIB_EMBEDDED_SOURCES
264264
EmbeddedRuntime.swift
265265
EmbeddedStubs.swift
266+
EmbeddedPrint.swift
266267
)
267268

268269
set(GROUP_INFO_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/GroupInfo.json)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftShims
14+
15+
// TODO: This is all a stop-gap so that at least some types are printable in
16+
// embedded Swift, in an embedded-programming friendly way (we mainly need
17+
// printing to not need to heap allocate).
18+
19+
@_silgen_name("putchar")
20+
@discardableResult
21+
func putchar(_: CInt) -> CInt
22+
23+
public func print(_ string: StaticString, terminator: StaticString = "\n") {
24+
var p = string.utf8Start
25+
while p.pointee != 0 {
26+
putchar(CInt(p.pointee))
27+
p += 1
28+
}
29+
p = terminator.utf8Start
30+
while p.pointee != 0 {
31+
putchar(CInt(p.pointee))
32+
p += 1
33+
}
34+
}
35+
36+
func printCharacters(_ buf: UnsafeRawBufferPointer) {
37+
for c in buf {
38+
putchar(CInt(c))
39+
}
40+
}
41+
42+
func printCharacters(_ buf: UnsafeBufferPointer<UInt8>) {
43+
printCharacters(UnsafeRawBufferPointer(buf))
44+
}
45+
46+
extension BinaryInteger {
47+
func writeToStdout() {
48+
if self == (0 as Self) {
49+
print("0", terminator: "")
50+
return
51+
}
52+
53+
func _ascii(_ digit: UInt8) -> UInt8 {
54+
UInt8(("0" as Unicode.Scalar).value) + digit
55+
}
56+
let isNegative = Self.isSigned && self < (0 as Self)
57+
var value = magnitude
58+
59+
// Avoid withUnsafeTemporaryAllocation which is not typed-throws ready yet
60+
let byteCount = 64
61+
let stackBuffer = Builtin.stackAlloc(byteCount._builtinWordValue,
62+
1._builtinWordValue, 1._builtinWordValue)
63+
let buffer = UnsafeMutableRawBufferPointer(start: .init(stackBuffer),
64+
count: byteCount)
65+
66+
var index = buffer.count - 1
67+
while value != 0 {
68+
let (quotient, remainder) =
69+
value.quotientAndRemainder(dividingBy: Magnitude(10))
70+
buffer[index] = _ascii(UInt8(truncatingIfNeeded: remainder))
71+
index -= 1
72+
value = quotient
73+
}
74+
if isNegative {
75+
buffer[index] = UInt8(("-" as Unicode.Scalar).value)
76+
index -= 1
77+
}
78+
let start = index + 1
79+
let end = buffer.count - 1
80+
let count = end - start + 1
81+
82+
let pointerToPrint = buffer.baseAddress?.advanced(by: start)
83+
.assumingMemoryBound(to: UInt8.self)
84+
printCharacters(UnsafeBufferPointer(start: pointerToPrint, count: count))
85+
86+
Builtin.stackDealloc(stackBuffer)
87+
}
88+
}
89+
90+
public func print(_ integer: some BinaryInteger, terminator: StaticString = "\n") {
91+
integer.writeToStdout()
92+
print("", terminator: terminator)
93+
}
94+
95+
public func print(_ boolean: Bool, terminator: StaticString = "\n") {
96+
if boolean {
97+
print("true", terminator: terminator)
98+
} else {
99+
print("false", terminator: terminator)
100+
}
101+
}

stdlib/public/core/GroupInfo.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@
248248
"DurationProtocol.swift",
249249
"Instant.swift",
250250
"EmbeddedRuntime.swift",
251-
"EmbeddedStubs.swift"
251+
"EmbeddedStubs.swift",
252+
"EmbeddedPrint.swift"
252253
],
253254
"Result": [
254255
"Result.swift"

stdlib/public/core/LifetimeManager.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public func _withUnprotectedUnsafeMutablePointer<T, Result>(
9999
#endif
100100
}
101101

102+
#if !$Embedded
102103
/// Invokes the given closure with a pointer to the given argument.
103104
///
104105
/// The `withUnsafePointer(to:_:)` function is useful for calling Objective-C
@@ -127,6 +128,17 @@ public func withUnsafePointer<T, Result>(
127128
{
128129
return try body(UnsafePointer<T>(Builtin.addressOfBorrow(value)))
129130
}
131+
#else
132+
// TODO: This should be unified with non-embedded Swift.
133+
@inlinable
134+
public func withUnsafePointer<T, E, Result>(
135+
to value: T,
136+
_ body: (UnsafePointer<T>) throws(E) -> Result
137+
) throws(E) -> Result
138+
{
139+
return try body(UnsafePointer<T>(Builtin.addressOfBorrow(value)))
140+
}
141+
#endif
130142

131143
/// Invokes the given closure with a pointer to the given argument.
132144
///

test/SILOptimizer/devirt_deinits.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// RUN: %target-run-simple-swift(-Xllvm -enable-deinit-devirtualizer -parse-as-library) | %FileCheck -check-prefix CHECK-OUTPUT %s
55

66
// Check if it works in embedded mode.
7-
// RUN: %target-run-simple-swift(%S/../embedded/Inputs/print.swift -enable-experimental-feature Embedded -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck -check-prefix CHECK-OUTPUT %s
7+
// RUN: %target-run-simple-swift(-enable-experimental-feature Embedded -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck -check-prefix CHECK-OUTPUT %s
88

99
// Run without the deinit-devirtualizer to verify that our CHECK-OUTPUT lines are correct.
1010
// TODO: currently disabled because of rdar://118449507

test/embedded/FixedArray.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11

2-
// RUN: %target-run-simple-swift(%S/Inputs/ExperimentalFixedArray.swift %S/Inputs/print.swift -enable-experimental-feature Embedded -enable-experimental-feature FixedArrays -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
3-
// RUN: %target-run-simple-swift(-O %S/Inputs/ExperimentalFixedArray.swift %S/Inputs/print.swift -enable-experimental-feature Embedded -enable-experimental-feature FixedArrays -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
2+
// RUN: %target-run-simple-swift(%S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature Embedded -enable-experimental-feature FixedArrays -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
3+
// RUN: %target-run-simple-swift(-O %S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature Embedded -enable-experimental-feature FixedArrays -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
44

55
// Also test in non-embedded mode
66

7-
// RUN: %target-run-simple-swift(%S/Inputs/ExperimentalFixedArray.swift %S/Inputs/print.swift -enable-experimental-feature FixedArrays -parse-as-library -wmo) | %FileCheck %s
8-
// RUN: %target-run-simple-swift(-O %S/Inputs/ExperimentalFixedArray.swift %S/Inputs/print.swift -enable-experimental-feature FixedArrays -parse-as-library -wmo) | %FileCheck %s
7+
// RUN: %target-run-simple-swift(%S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature FixedArrays -parse-as-library -wmo) | %FileCheck %s
8+
// RUN: %target-run-simple-swift(-O %S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature FixedArrays -parse-as-library -wmo) | %FileCheck %s
99

1010
// REQUIRES: executable_test
1111
// REQUIRES: optimized_stdlib
@@ -37,18 +37,18 @@ struct IntByte: Printable {
3737
let b: Int8
3838

3939
func print() {
40-
main.print(i, terminator: "")
41-
main.print(",", terminator: "")
42-
main.print(b, terminator: "")
40+
Swift.print(i, terminator: "")
41+
Swift.print(",", terminator: "")
42+
Swift.print(b, terminator: "")
4343
}
4444
}
4545

4646
extension Optional: Printable where Wrapped == Int64 {
4747
func print() {
4848
if let x = self {
49-
main.print(x, terminator: "")
49+
Swift.print(x, terminator: "")
5050
} else {
51-
main.print("nil", terminator: "")
51+
Swift.print("nil", terminator: "")
5252
}
5353
}
5454
}
@@ -151,13 +151,13 @@ struct Matrix<T: Printable>: ~Copyable {
151151

152152
func print() {
153153
for r in 0..<rows {
154-
main.print("(", terminator: "")
154+
Swift.print("(", terminator: "")
155155
for c in 0..<columns {
156156
self[r, c].print()
157157
if c < columns - 1 {
158-
main.print(",", terminator: "")
158+
Swift.print(",", terminator: "")
159159
} else {
160-
main.print(")")
160+
Swift.print(")")
161161
}
162162
}
163163
}
@@ -271,7 +271,7 @@ protocol Printable {
271271

272272
extension Int: Printable {
273273
func print() {
274-
main.print(self, terminator: "")
274+
Swift.print(self, terminator: "")
275275
}
276276
}
277277

@@ -290,13 +290,13 @@ final class CheckLifetime: Printable {
290290
}
291291

292292
deinit {
293-
main.print("deinit ", terminator: "")
294-
main.print(x)
293+
Swift.print("deinit ", terminator: "")
294+
Swift.print(x)
295295
}
296296

297297
func print() {
298-
main.print("CheckLifetime(", terminator: "")
299-
main.print(x, terminator: ")")
298+
Swift.print("CheckLifetime(", terminator: "")
299+
Swift.print(x, terminator: ")")
300300
}
301301
}
302302

test/embedded/Inputs/print.swift

Lines changed: 0 additions & 74 deletions
This file was deleted.

test/embedded/array-builtins-exec.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend %s %S/Inputs/print.swift -enable-experimental-feature Embedded -enable-builtin-module -c -o %t/main.o
2+
// RUN: %target-swift-frontend %s -parse-as-library -enable-experimental-feature Embedded -enable-builtin-module -c -o %t/main.o
33
// RUN: %target-clang %t/main.o -o %t/a.out -dead_strip
44
// RUN: %target-run %t/a.out | %FileCheck %s
55

test/embedded/array-to-pointer.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@
1010
// REQUIRES: OS=macosx || OS=linux-gnu
1111

1212
@_silgen_name("putchar")
13-
func putchar(_: UInt8)
13+
@discardableResult
14+
func putchar(_: CInt) -> CInt
1415

1516
public func print(_ s: StaticString, terminator: StaticString = "\n") {
1617
var p = s.utf8Start
1718
while p.pointee != 0 {
18-
putchar(p.pointee)
19+
putchar(CInt(p.pointee))
1920
p += 1
2021
}
2122
p = terminator.utf8Start
2223
while p.pointee != 0 {
23-
putchar(p.pointee)
24+
putchar(CInt(p.pointee))
2425
p += 1
2526
}
2627
}

test/embedded/arrays.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@
1010
// REQUIRES: OS=macosx || OS=linux-gnu
1111

1212
@_silgen_name("putchar")
13-
func putchar(_: UInt8)
13+
@discardableResult
14+
func putchar(_: CInt) -> CInt
1415

1516
public func print(_ s: StaticString, terminator: StaticString = "\n") {
1617
var p = s.utf8Start
1718
while p.pointee != 0 {
18-
putchar(p.pointee)
19+
putchar(CInt(p.pointee))
1920
p += 1
2021
}
2122
p = terminator.utf8Start
2223
while p.pointee != 0 {
23-
putchar(p.pointee)
24+
putchar(CInt(p.pointee))
2425
p += 1
2526
}
2627
}

test/embedded/class-func.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-run-simple-swift(%S/Inputs/print.swift -enable-experimental-feature Embedded -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
1+
// RUN: %target-run-simple-swift(-enable-experimental-feature Embedded -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
22

33
// REQUIRES: swift_in_compiler
44
// REQUIRES: executable_test

test/embedded/classes-arrays.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend %s %S/Inputs/print.swift -enable-experimental-feature Embedded -c -o %t/main.o
2+
// RUN: %target-swift-frontend %s -parse-as-library -enable-experimental-feature Embedded -c -o %t/main.o
33
// RUN: %target-clang %t/main.o -o %t/a.out -dead_strip
44
// RUN: %target-run %t/a.out | %FileCheck %s
55

0 commit comments

Comments
 (0)