stdlib: split topic-focused modules out of StdlibUnittest

The new modules are:

* SwiftUnstable -- assorted additions to the core standard library
  (more algorithms etc.)

* SwiftUnstableDarwinExtras -- proposed additions to the Darwin overlay,
  not yet reviewed by the Darwin team.

* SwiftUnstablePthreadExtras -- wrappers that make it possible to
  use pthread in Swift (they work around the lack of block-based API in
  pthread).  In future these could be possibly folded into the Darwin
  overlay as well.

These APIs are useful without StdlibUnittest for writing automation
tools in Swift.  Just like SwiftExperimental, none of these modules are
exposed to extrenal users.

Also, since these new modules can be compiled with -sil-serialize-all
(unlike StdlibUnittest, where we can't apply the flag because of
compiler bugs), standard library tests that need to run optimized code
(like AtomicInt.swift) are *much* faster now.

Swift SVN r25679
This commit is contained in:
Dmitri Hrybenko
2015-03-02 10:38:42 +00:00
parent 1a7f8f71a3
commit 581dc3c35d
31 changed files with 638 additions and 461 deletions

View File

@@ -120,6 +120,10 @@ MAP_STDLIB_TYPE("u_int16_t", UnsignedInt, 16, "UInt16", All, false, DoNothing)
MAP_STDLIB_TYPE("u_int32_t", UnsignedInt, 32, "UInt32", All, false, DoNothing)
MAP_STDLIB_TYPE("u_int64_t", UnsignedInt, 64, "UInt64", All, false, DoNothing)
// SwiftShims defines its own types.
MAP_STDLIB_TYPE("__swift_ssize_t", SignedWord, 0, "Int", All, false,
DefineOnly)
// stdarg.h types.
// FIXME: why does this not catch va_list on x86_64?
MAP_STDLIB_TYPE("va_list", VaList, 0, "CVaListPointer", All, false, DoNothing)

View File

@@ -0,0 +1,9 @@
add_swift_library(swiftSwiftUnstableDarwinExtras SHARED IS_STDLIB
# This file should be listed the first. Module name is inferred from the
# filename.
SwiftUnstableDarwinExtras.swift
Subprocess.swift
SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
INSTALL_IN_COMPONENT stdlib-experimental)

View File

@@ -10,80 +10,9 @@
//
//===----------------------------------------------------------------------===//
import SwiftUnstable
import Darwin
var _stdlib_FD_SETSIZE: CInt {
return 1024
}
struct _stdlib_fd_set {
var _data: _UnitTestArray<UInt32>
static var _wordBits: Int {
return sizeof(UInt32) * 8
}
init() {
_data = _UnitTestArray<UInt32>(
count: Int(_stdlib_FD_SETSIZE) / _stdlib_fd_set._wordBits,
repeatedValue: 0)
}
func isset(fd: CInt) -> Bool {
let fdInt = Int(fd)
return (
_data[fdInt / _stdlib_fd_set._wordBits] &
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
) != 0
}
mutating func set(fd: CInt) {
let fdInt = Int(fd)
_data[fdInt / _stdlib_fd_set._wordBits] |=
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
}
mutating func clear(fd: CInt) {
let fdInt = Int(fd)
_data[fdInt / _stdlib_fd_set._wordBits] &=
~UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
}
mutating func zero() {
let count = _data.count
return _data.withUnsafeMutableBufferPointer {
(_data) in
for i in 0..<count {
_data[i] = 0
}
return
}
}
}
func _stdlib_select(
inout readfds: _stdlib_fd_set, inout writefds: _stdlib_fd_set,
inout errorfds: _stdlib_fd_set, timeout: UnsafeMutablePointer<timeval>
) -> CInt {
return readfds._data.withUnsafeMutableBufferPointer {
(readfds) in
writefds._data.withUnsafeMutableBufferPointer {
(writefds) in
errorfds._data.withUnsafeMutableBufferPointer {
(errorfds) in
let readAddr = readfds.baseAddress
let writeAddr = writefds.baseAddress
let errorAddr = errorfds.baseAddress
return select(
_stdlib_FD_SETSIZE,
UnsafeMutablePointer(readAddr),
UnsafeMutablePointer(writeAddr),
UnsafeMutablePointer(errorAddr),
timeout)
}
}
}
}
/// Calls POSIX `pipe()`.
func posixPipe() -> (readFD: CInt, writeFD: CInt) {
var fds: _UnitTestArray<CInt> = [ -1, -1 ]
@@ -99,7 +28,7 @@ func posixPipe() -> (readFD: CInt, writeFD: CInt) {
/// Start the same executable as a child process, redirecting its stdout and
/// stderr.
func spawnChild(args: _UnitTestArray<String>)
public func spawnChild(args: _UnitTestArray<String>)
-> (pid: pid_t, stdinFD: CInt, stdoutFD: CInt, stderrFD: CInt) {
var fileActions = posix_spawn_file_actions_t()
if posix_spawn_file_actions_init(&fileActions) != 0 {
@@ -177,7 +106,7 @@ func spawnChild(args: _UnitTestArray<String>)
return (pid, childStdin.writeFD, childStdout.readFD, childStderr.readFD)
}
func readAll(fd: CInt) -> String {
internal func _readAll(fd: CInt) -> String {
var buffer = _UnitTestArray<UInt8>(count: 1024, repeatedValue: 0)
var usedBytes = 0
while true {
@@ -199,7 +128,8 @@ func readAll(fd: CInt) -> String {
UTF8.self, input: buffer[0..<usedBytes]).0
}
func signalToString(signal: Int) -> String {
internal func _signalToString(signal: Int) -> String {
switch CInt(signal) {
case SIGILL: return "SIGILL"
case SIGTRAP: return "SIGTRAP"
@@ -212,30 +142,21 @@ func signalToString(signal: Int) -> String {
}
}
enum ProcessTerminationStatus : Printable {
public enum ProcessTerminationStatus : Printable {
case Exit(Int)
case Signal(Int)
var description: String {
public var description: String {
switch self {
case .Exit(var status):
return "Exit(\(status))"
case .Signal(var signal):
return "Signal(\(signalToString(signal)))"
}
}
var isSwiftTrap: Bool {
switch self {
case .Exit(var status):
return false
case .Signal(var signal):
return CInt(signal) == SIGILL || CInt(signal) == SIGTRAP
return "Signal(\(_signalToString(signal)))"
}
}
}
func posixWaitpid(pid: pid_t) -> ProcessTerminationStatus {
public func posixWaitpid(pid: pid_t) -> ProcessTerminationStatus {
var status: CInt = 0
if waitpid(pid, &status, 0) < 0 {
preconditionFailure("waitpid() failed")
@@ -249,15 +170,15 @@ func posixWaitpid(pid: pid_t) -> ProcessTerminationStatus {
preconditionFailure("did not understand what happened to child process")
}
func runChild(args: _UnitTestArray<String>)
public func runChild(args: _UnitTestArray<String>)
-> (stdout: String, stderr: String, status: ProcessTerminationStatus) {
let (pid, _, stdoutFD, stderrFD) = spawnChild(args)
// FIXME: reading stdout and stderr sequentially can block. Should use
// select(). This is not so simple to implement because of:
// <rdar://problem/17828358> Darwin module is missing fd_set-related macros
let stdout = readAll(stdoutFD)
let stderr = readAll(stderrFD)
let stdout = _readAll(stdoutFD)
let stderr = _readAll(stderrFD)
if close(stdoutFD) != 0 {
preconditionFailure("close() failed")
@@ -269,34 +190,6 @@ func runChild(args: _UnitTestArray<String>)
return (stdout, stderr, status)
}
//
// Functions missing in `Darwin` module.
//
func _WSTATUS(status: CInt) -> CInt {
return status & 0x7f
}
var _WSTOPPED: CInt {
return 0x7f
}
func WIFEXITED(status: CInt) -> Bool {
return _WSTATUS(status) == 0
}
func WIFSIGNALED(status: CInt) -> Bool {
return _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0
}
func WEXITSTATUS(status: CInt) -> CInt {
return (status >> 8) & 0xff
}
func WTERMSIG(status: CInt) -> CInt {
return _WSTATUS(status)
}
@asmname("_NSGetEnviron")
func _NSGetEnviron() -> UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<CChar>>>

View File

@@ -0,0 +1,126 @@
//===--- DarwinExtras.swift -----------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftUnstable
import Darwin
public func _stdlib_mkstemps(inout template: String, suffixlen: CInt) -> CInt {
var utf8 = template.nulTerminatedUTF8
let (fd, fileName) = utf8.withUnsafeMutableBufferPointer {
(utf8) -> (CInt, String) in
let fd = mkstemps(UnsafeMutablePointer(utf8.baseAddress), suffixlen)
let fileName = String.fromCString(UnsafePointer(utf8.baseAddress))!
return (fd, fileName)
}
template = fileName
return fd
}
public var _stdlib_FD_SETSIZE: CInt {
return 1024
}
public struct _stdlib_fd_set {
var _data: _UnitTestArray<UInt32>
static var _wordBits: Int {
return sizeof(UInt32) * 8
}
public init() {
_data = _UnitTestArray<UInt32>(
count: Int(_stdlib_FD_SETSIZE) / _stdlib_fd_set._wordBits,
repeatedValue: 0)
}
public func isset(fd: CInt) -> Bool {
let fdInt = Int(fd)
return (
_data[fdInt / _stdlib_fd_set._wordBits] &
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
) != 0
}
public mutating func set(fd: CInt) {
let fdInt = Int(fd)
_data[fdInt / _stdlib_fd_set._wordBits] |=
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
}
public mutating func clear(fd: CInt) {
let fdInt = Int(fd)
_data[fdInt / _stdlib_fd_set._wordBits] &=
~UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
}
public mutating func zero() {
let count = _data.count
return _data.withUnsafeMutableBufferPointer {
(_data) in
for i in 0..<count {
_data[i] = 0
}
return
}
}
}
public func _stdlib_select(
inout readfds: _stdlib_fd_set, inout writefds: _stdlib_fd_set,
inout errorfds: _stdlib_fd_set, timeout: UnsafeMutablePointer<timeval>
) -> CInt {
return readfds._data.withUnsafeMutableBufferPointer {
(readfds) in
writefds._data.withUnsafeMutableBufferPointer {
(writefds) in
errorfds._data.withUnsafeMutableBufferPointer {
(errorfds) in
let readAddr = readfds.baseAddress
let writeAddr = writefds.baseAddress
let errorAddr = errorfds.baseAddress
return select(
_stdlib_FD_SETSIZE,
UnsafeMutablePointer(readAddr),
UnsafeMutablePointer(writeAddr),
UnsafeMutablePointer(errorAddr),
timeout)
}
}
}
}
//
// Functions missing in `Darwin` module.
//
public func _WSTATUS(status: CInt) -> CInt {
return status & 0x7f
}
public var _WSTOPPED: CInt {
return 0x7f
}
public func WIFEXITED(status: CInt) -> Bool {
return _WSTATUS(status) == 0
}
public func WIFSIGNALED(status: CInt) -> Bool {
return _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0
}
public func WEXITSTATUS(status: CInt) -> CInt {
return (status >> 8) & 0xff
}
public func WTERMSIG(status: CInt) -> CInt {
return _WSTATUS(status)
}

View File

@@ -0,0 +1,10 @@
add_swift_library(swiftSwiftUnstablePthreadExtras SHARED IS_STDLIB
# This file should be listed the first. Module name is inferred from the
# filename.
SwiftUnstablePthreadExtras.swift
PthreadBarriers.swift
SwiftBlockToCFunctionThunks.cpp
SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
INSTALL_IN_COMPONENT stdlib-experimental)

View File

@@ -1,4 +1,4 @@
//===--- PthreadWrappers.swift --------------------------------------------===//
//===--- SwiftUnstablePthreadExtras.swift ---------------------------------===//
//
// This source file is part of the Swift.org open source project
//
@@ -9,13 +9,14 @@
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file contains wrappers for pthread APIs that are less painful to use
// than the C APIs.
//
//===----------------------------------------------------------------------===//
import Darwin
//
// This file contains wrappers for functions in Darwin module.
//
@asmname("swift_stdlib_getExecuteBlockFunctionPtr_VoidPtr_VoidPtr")
func _stdlib_getExecuteBlockFunctionPtr_VoidPtr_VoidPtr()
-> CFunctionPointer<((UnsafeMutablePointer<()>) -> UnsafeMutablePointer<()>)>
@@ -49,7 +50,7 @@ func _stdlib_executeSwiftClosure<Param, Result>(
return result
}
/// Block-based wrapper `pthread_create`.
/// Block-based wrapper for `pthread_create`.
public func _stdlib_pthread_create_block<Argument, Result>(
attr: UnsafePointer<pthread_attr_t>,
start_routine: (Argument) -> Result,
@@ -74,7 +75,7 @@ public func _stdlib_pthread_create_block<Argument, Result>(
}
}
/// Block-based wrapper `pthread_join`.
/// Block-based wrapper for `pthread_join`.
public func _stdlib_pthread_join<Result>(
thread: pthread_t,
resultType: Result.Type
@@ -91,24 +92,6 @@ public func _stdlib_pthread_join<Result>(
}
}
func _stdlib_sysctlbyname_Int32(name: String) -> Int32 {
return name.withCString {
(nameUtf8) -> Int32 in
var resultSize: size_t = 4
var result: Int32 = 0
sysctlbyname(nameUtf8, &result, &resultSize, nil, 0)
return result
}
}
func _stdlib_getHardwareConcurrency() -> Int {
let result = Int(_stdlib_sysctlbyname_Int32("hw.physicalcpu"))
if result < 1 {
fatalError("_stdlib_getHardwareConcurrency(): could not query sysctl")
}
return result
}
public class _stdlib_Barrier {
var _pthreadBarrier: _stdlib_pthread_barrier_t

View File

@@ -41,6 +41,7 @@ add_swift_library(swiftRuntime IS_STDLIB IS_STDLIB_CORE
KnownMetadata.cpp
Metadata.cpp
Reflection.cpp
ShimsChecker.cpp
Stubs.cpp
SwiftObject.cpp
Enum.cpp

View File

@@ -0,0 +1,23 @@
//===--- ShimsChecker.cpp -------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file checks the correctness of certain declarations from SwiftShims.
//
//===----------------------------------------------------------------------===//
#include <type_traits>
#include <unistd.h>
#include "../shims/DarwinShims.h"
static_assert(std::is_same<ssize_t, __swift_ssize_t>::value,
"__swift_ssize_t is wrong");

View File

@@ -318,3 +318,8 @@ extern "C" const char *_swift_strtold(const char * nptr, void *outResult) {
*static_cast<long double*>(outResult) = std::strtold(nptr, &endPtr);
return endPtr;
}
extern "C" int _swift_stdlib_putc_stderr(int C) {
return putc(C, stderr);
}

View File

@@ -19,20 +19,35 @@
#ifndef SWIFT_STDLIB_SHIMS_DARWINSHIMS_H
#define SWIFT_STDLIB_SHIMS_DARWINSHIMS_H
#include "SwiftStdint.h"
#include "SwiftStddef.h"
// This declaration is not universally correct. We verify its correctness for
// the current platform in the runtime code.
typedef long int __swift_ssize_t;
__swift_size_t swift_malloc_size(const void *ptr);
void free(void *);
__swift_size_t strlen(const char *s);
char *strcpy(char *restrict dst, const char *restrict src);
char *strcpy(char *__restrict__ dst, const char *__restrict__ src);
int strcmp(const char *s1, const char *s2);
int memcmp(const void *s1, const void *s2, __swift_size_t n);
int putchar(int c);
double strtod(const char *restrict nptr, char **restrict endptr);
float strtof(const char *restrict nptr, char **restrict endptr);
int putchar(int c);
__swift_ssize_t read(int fildes, void *buf, __swift_size_t nbyte);
__swift_ssize_t write(int fildes, const void *buf, __swift_size_t nbyte);
int close(int fildes);
double strtod(const char *__restrict__ nptr, char **__restrict__ endptr);
float strtof(const char *__restrict__ nptr, char **__restrict__ endptr);
int isspace(int c);
__swift_uint32_t arc4random(void);
__swift_uint32_t arc4random_uniform(__swift_uint32_t upper_bound);
int sysctlbyname(const char *name, void *oldp, __swift_size_t *oldlenp,
void *newp, __swift_size_t newlen);
#endif // SWIFT_STDLIB_SHIMS_DARWINSHIMS_H

View File

@@ -77,6 +77,8 @@ void *_swift_objCMirrorSummary(const void * nsObject);
/// Call strtold, changing arguments so we can operate on Float80
const char *_swift_strtold(const char *nptr, void *outResult);
int _swift_stdlib_putc_stderr(int C);
#ifdef __cplusplus
}} // extern "C", namespace swift
#endif

View File

@@ -3,17 +3,13 @@ add_swift_library(swiftStdlibUnittest SHARED IS_STDLIB
# filename.
StdlibUnittest.swift.gyb
DarwinExtras.swift
GetOSVersion.mm
InterceptTraps.cpp
OpaqueIdentityFunctions.cpp
OpaqueIdentityFunctions.swift
PthreadBarriers.swift
PthreadWrappers.swift
RaceTest.swift
Statistics.swift
StdlibCoreExtras.swift
SwiftBlockToCFunctionThunks.cpp
TestHelpers.swift
LifetimeTracked.swift
@@ -23,7 +19,9 @@ add_swift_library(swiftStdlibUnittest SHARED IS_STDLIB
#
# SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
SWIFT_MODULE_DEPENDS Darwin Foundation
SWIFT_MODULE_DEPENDS
SwiftUnstable SwiftUnstablePthreadExtras SwiftUnstableDarwinExtras
Darwin Foundation
FRAMEWORK_DEPENDS Foundation
INSTALL_IN_COMPONENT stdlib-experimental)

View File

@@ -36,6 +36,8 @@
///
//===----------------------------------------------------------------------===//
import SwiftUnstable
import SwiftUnstablePthreadExtras
import Darwin
#if _runtime(_ObjC)
@@ -401,8 +403,8 @@ func _masterThreadOneTrial<RT : RaceTestWithPerTrialDataType>(
let workerState = _RaceTestWorkerState<RT>()
// Shuffle the data so that threads process it in different order.
let shuffle = _stdlib_randomShuffle(identityShuffle)
workerState.raceData = _stdlib_scatter(sharedState.raceData, shuffle)
let shuffle = randomShuffle(identityShuffle)
workerState.raceData = scatter(sharedState.raceData, shuffle)
workerState.raceDataShuffle = shuffle
workerState.observations = []
@@ -420,9 +422,9 @@ func _masterThreadOneTrial<RT : RaceTestWithPerTrialDataType>(
for i in 0..<racingThreadCount {
let shuffle = sharedState.workerStates[i].raceDataShuffle
sharedState.workerStates[i].raceData =
_stdlib_gather(sharedState.workerStates[i].raceData, shuffle)
gather(sharedState.workerStates[i].raceData, shuffle)
sharedState.workerStates[i].observations =
_stdlib_gather(sharedState.workerStates[i].observations, shuffle)
gather(sharedState.workerStates[i].observations, shuffle)
}
if true {
// FIXME: why doesn't the bracket syntax work?

View File

@@ -1,35 +1,14 @@
import Darwin
public func rand32() -> UInt32 {
return arc4random()
}
public func rand32(#exclusiveUpperBound: UInt32) -> UInt32 {
return arc4random_uniform(exclusiveUpperBound)
}
public func rand64() -> UInt64 {
return (UInt64(arc4random()) << 32) | UInt64(arc4random())
}
public func randInt() -> Int {
#if arch(i386) || arch(arm)
return Int(Int32(bitPattern: rand32()))
#elseif arch(x86_64) || arch(arm64)
return Int(Int64(bitPattern: rand64()))
#else
fatalError("unimplemented")
#endif
}
public func randArray64(count: Int) -> _UnitTestArray<UInt64> {
var result = _UnitTestArray<UInt64>(count: count, repeatedValue: 0)
for i in indices(result) {
result[i] = rand64()
}
return result
}
//===--- Statistics.swift -------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
/// For a given p-value, returns the critical chi-square value for
/// a distribution with 1 degree of freedom.

View File

@@ -10,7 +10,9 @@
//
//===----------------------------------------------------------------------===//
import SwiftUnstable
import Darwin
import SwiftUnstableDarwinExtras
import Foundation
//
@@ -18,62 +20,6 @@ import Foundation
// useful in tests, and stdlib does not have such facilities yet.
//
/// Convert the given numeric value to a hexidecimal string.
public func asHex<T : IntegerType>(x: T) -> String {
return "0x" + String(x.toIntMax(), radix: 16)
}
/// Convert the given sequence of numeric values to a string representing
/// their hexidecimal values.
public func asHex<
S: SequenceType
where
S.Generator.Element : IntegerType
>(x: S) -> String {
return "[ " + ", ".join(lazy(x).map { asHex($0) }) + " ]"
}
/// Compute the prefix sum of `seq`.
func scan<
S : SequenceType, U
>(seq: S, initial: U, combine: (U, S.Generator.Element) -> U) -> _UnitTestArray<U> {
var result = _UnitTestArray<U>()
result.reserveCapacity(underestimateCount(seq))
var runningResult = initial
for element in seq {
runningResult = combine(runningResult, element)
result.append(runningResult)
}
return result
}
public func _stdlib_randomShuffle<T>(a: _UnitTestArray<T>) -> _UnitTestArray<T> {
var result = a
for var i = a.count - 1; i != 0; --i {
// FIXME: 32 bits are not enough in general case!
let j = Int(rand32(exclusiveUpperBound: UInt32(i + 1)))
swap(&result[i], &result[j])
}
return result
}
public func _stdlib_gather<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
var result = _UnitTestArray<T>()
result.reserveCapacity(a.count)
for i in 0..<a.count {
result.append(a[idx[i]])
}
return result
}
public func _stdlib_scatter<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
var result = a
for i in 0..<a.count {
result[idx[i]] = a[i]
}
return result
}
func findSubstring(string: String, substring: String) -> String.Index? {
if substring.isEmpty {
return string.startIndex
@@ -81,90 +27,6 @@ func findSubstring(string: String, substring: String) -> String.Index? {
return string.rangeOfString(substring)?.startIndex
}
func withArrayOfCStrings<R>(
args: _UnitTestArray<String>, body: (Array<UnsafeMutablePointer<CChar>>) -> R
) -> R {
let argsLengths = _UnitTestArray(map(args) { count($0.utf8) + 1 })
let argsOffsets = [ 0 ] + scan(argsLengths, 0, +)
let argsBufferSize = argsOffsets.last!
var argsBuffer = _UnitTestArray<UInt8>()
argsBuffer.reserveCapacity(argsBufferSize)
for arg in args {
argsBuffer.extend(arg.utf8)
argsBuffer.append(0)
}
return argsBuffer.withUnsafeBufferPointer {
(argsBuffer) in
let ptr = UnsafeMutablePointer<CChar>(argsBuffer.baseAddress)
var cStrings = map(argsOffsets) { ptr + $0 }
cStrings[cStrings.count - 1] = nil
return body(cStrings)
}
}
public struct _Stderr : OutputStreamType {
public init() {}
public mutating func write(string: String) {
for c in string.utf8 {
putc(Int32(c), stderr)
}
}
}
struct _FDOutputStream : OutputStreamType {
let fd: CInt
var isClosed: Bool = false
init(fd: CInt) {
self.fd = fd
}
mutating func write(string: String) {
let utf8 = string.nulTerminatedUTF8
utf8.withUnsafeBufferPointer {
(utf8) -> () in
var writtenBytes: size_t = 0
let bufferSize = size_t(utf8.count - 1)
while writtenBytes != bufferSize {
let result = Darwin.write(
self.fd, UnsafePointer(utf8.baseAddress + Int(writtenBytes)),
bufferSize - writtenBytes)
if result < 0 {
fatalError("write() returned an error")
}
writtenBytes += size_t(result)
}
}
}
mutating func close() {
if isClosed {
return
}
let result = Darwin.close(fd)
if result < 0 {
fatalError("close() returned an error")
}
isClosed = true
}
}
func _stdlib_mkstemps(inout template: String, suffixlen: CInt) -> CInt {
var utf8 = template.nulTerminatedUTF8
let (fd, fileName) = utf8.withUnsafeMutableBufferPointer {
(utf8) -> (CInt, String) in
let fd = mkstemps(UnsafeMutablePointer(utf8.baseAddress), suffixlen)
let fileName = String.fromCString(UnsafePointer(utf8.baseAddress))!
return (fd, fileName)
}
template = fileName
return fd
}
public func createTemporaryFile(
fileNamePrefix: String, fileNameSuffix: String, contents: String
) -> String {
@@ -183,65 +45,3 @@ public func createTemporaryFile(
return fileName
}
/// An atomic counter for contended applications.
///
/// This is a struct to prevent extra retains/releases. You are required to
/// call `deinit()` to release the owned memory.
public struct _stdlib_ShardedAtomicCounter {
// Using an array causes retains/releases, which create contention on the
// reference count.
// FIXME: guard every element against false sharing.
var _shardsPtr: UnsafeMutablePointer<Int>
var _shardsCount: Int
public init() {
let hardwareConcurrency = _stdlib_getHardwareConcurrency()
let count = max(8, hardwareConcurrency * hardwareConcurrency)
let shards = UnsafeMutablePointer<Int>.alloc(count)
for var i = 0; i != count; i++ {
(shards + i).initialize(0)
}
self._shardsPtr = shards
self._shardsCount = count
}
public func `deinit`() {
self._shardsPtr.destroy(self._shardsCount)
self._shardsPtr.dealloc(self._shardsCount)
}
public func add(operand: Int, randomInt: Int) {
let shardIndex = Int(UInt(bitPattern: randomInt) % UInt(self._shardsCount))
_swift_stdlib_atomicFetchAddInt(
object: self._shardsPtr + shardIndex, operand: operand)
}
// FIXME: non-atomic as a whole!
public func getSum() -> Int {
var result = 0
let shards = self._shardsPtr
let count = self._shardsCount
for var i = 0; i != count; i++ {
result += _swift_stdlib_atomicLoadInt(object: shards + i)
}
return result
}
public struct PRNG {
var _state: Int
public init() {
_state = Int(Int32(bitPattern: StdlibUnittest.rand32()))
}
public mutating func randomInt() -> Int {
var result = 0
for var i = 0; i != Int._sizeInBits; ++i {
result = (result << 1) | (_state & 1)
_state = (_state >> 1) ^ (-(_state & 1) & Int(bitPattern: 0xD0000001))
}
return result
}
}
}

View File

@@ -10,7 +10,10 @@
//
//===----------------------------------------------------------------------===//
import SwiftUnstable
import SwiftUnstablePthreadExtras
import Darwin
import SwiftUnstableDarwinExtras
import ObjectiveC
public struct SourceLoc {
@@ -393,6 +396,17 @@ public func _setTestSuiteFailedCallback(callback: () -> ()) {
_testSuiteFailedCallback = callback
}
extension ProcessTerminationStatus {
var isSwiftTrap: Bool {
switch self {
case .Exit(var status):
return false
case .Signal(var signal):
return CInt(signal) == SIGILL || CInt(signal) == SIGTRAP
}
}
}
func _stdlib_getline() -> String? {
var result = _UnitTestArray<UInt8>()
while true {
@@ -410,75 +424,6 @@ func _stdlib_getline() -> String? {
}
}
struct _FDInputStream {
let fd: CInt
var isClosed: Bool = false
var isEOF: Bool = false
var _buffer = _UnitTestArray<UInt8>(count: 256, repeatedValue: 0)
var _bufferUsed: Int = 0
init(fd: CInt) {
self.fd = fd
}
mutating func getline() -> String? {
if let newlineIndex =
find(_buffer[0..<_bufferUsed], UInt8(UnicodeScalar("\n").value)) {
var result = String._fromWellFormedCodeUnitSequence(
UTF8.self, input: _buffer[0..<newlineIndex])
_buffer.removeRange(0...newlineIndex)
_bufferUsed -= newlineIndex + 1
return result
}
if isEOF && _bufferUsed > 0 {
var result = String._fromWellFormedCodeUnitSequence(
UTF8.self, input: _buffer[0..<_bufferUsed])
_buffer.removeAll()
_bufferUsed = 0
return result
}
return nil
}
mutating func read() {
let minFree = 128
var bufferFree = _buffer.count - _bufferUsed
if bufferFree < minFree {
_buffer.reserveCapacity(minFree - bufferFree)
while bufferFree < minFree {
_buffer.append(0)
++bufferFree
}
}
let readResult: ssize_t = _buffer.withUnsafeMutableBufferPointer {
(_buffer) in
let fd = self.fd
let addr = _buffer.baseAddress + self._bufferUsed
let size = size_t(bufferFree)
return Darwin.read(fd, addr, size)
}
if readResult == 0 {
isEOF = true
return
}
if readResult < 0 {
fatalError("read() returned error")
}
_bufferUsed += readResult
}
mutating func close() {
if isClosed {
return
}
let result = Darwin.close(fd)
if result < 0 {
fatalError("close() returned an error")
}
isClosed = true
}
}
func _printDebuggingAdvice(fullTestName: String) {
println("To debug, run:")
println("$ \(Process.arguments[0]) " +

View File

@@ -0,0 +1,11 @@
add_swift_library(swiftSwiftUnstable SHARED IS_STDLIB
# This file should be listed the first. Module name is inferred from the
# filename.
SwiftUnstable.swift
IO.swift
PRNG.swift
ShardedAtomicCounter.swift
SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
INSTALL_IN_COMPONENT stdlib-experimental)

131
stdlib/unstable/IO.swift Normal file
View File

@@ -0,0 +1,131 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
public struct _FDInputStream {
public let fd: CInt
public var isClosed: Bool = false
public var isEOF: Bool = false
internal var _buffer = _UnitTestArray<UInt8>(count: 256, repeatedValue: 0)
internal var _bufferUsed: Int = 0
public init(fd: CInt) {
self.fd = fd
}
public mutating func getline() -> String? {
if let newlineIndex =
find(_buffer[0..<_bufferUsed], UInt8(UnicodeScalar("\n").value)) {
var result = String._fromWellFormedCodeUnitSequence(
UTF8.self, input: _buffer[0..<newlineIndex])
_buffer.removeRange(0...newlineIndex)
_bufferUsed -= newlineIndex + 1
return result
}
if isEOF && _bufferUsed > 0 {
var result = String._fromWellFormedCodeUnitSequence(
UTF8.self, input: _buffer[0..<_bufferUsed])
_buffer.removeAll()
_bufferUsed = 0
return result
}
return nil
}
public mutating func read() {
let minFree = 128
var bufferFree = _buffer.count - _bufferUsed
if bufferFree < minFree {
_buffer.reserveCapacity(minFree - bufferFree)
while bufferFree < minFree {
_buffer.append(0)
++bufferFree
}
}
let readResult: __swift_ssize_t = _buffer.withUnsafeMutableBufferPointer {
(_buffer) in
let fd = self.fd
let addr = _buffer.baseAddress + self._bufferUsed
let size = bufferFree
return SwiftShims.read(fd, addr, size)
}
if readResult == 0 {
isEOF = true
return
}
if readResult < 0 {
fatalError("read() returned error")
}
_bufferUsed += readResult
}
public mutating func close() {
if isClosed {
return
}
let result = SwiftShims.close(fd)
if result < 0 {
fatalError("close() returned an error")
}
isClosed = true
}
}
public struct _Stderr : OutputStreamType {
public init() {}
public mutating func write(string: String) {
for c in string.utf8 {
_swift_stdlib_putc_stderr(CInt(c))
}
}
}
public struct _FDOutputStream : OutputStreamType {
public let fd: CInt
public var isClosed: Bool = false
public init(fd: CInt) {
self.fd = fd
}
public mutating func write(string: String) {
let utf8 = string.nulTerminatedUTF8
utf8.withUnsafeBufferPointer {
(utf8) -> () in
var writtenBytes = 0
let bufferSize = utf8.count - 1
while writtenBytes != bufferSize {
let result = SwiftShims.write(
self.fd, UnsafePointer(utf8.baseAddress + Int(writtenBytes)),
bufferSize - writtenBytes)
if result < 0 {
fatalError("write() returned an error")
}
writtenBytes += result
}
}
}
public mutating func close() {
if isClosed {
return
}
let result = SwiftShims.close(fd)
if result < 0 {
fatalError("close() returned an error")
}
isClosed = true
}
}

View File

@@ -0,0 +1,44 @@
//===--- PRNG.swift -------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
public func rand32() -> UInt32 {
return arc4random()
}
public func rand32(#exclusiveUpperBound: UInt32) -> UInt32 {
return arc4random_uniform(exclusiveUpperBound)
}
public func rand64() -> UInt64 {
return (UInt64(arc4random()) << 32) | UInt64(arc4random())
}
public func randInt() -> Int {
#if arch(i386) || arch(arm)
return Int(Int32(bitPattern: rand32()))
#elseif arch(x86_64) || arch(arm64)
return Int(Int64(bitPattern: rand64()))
#else
fatalError("unimplemented")
#endif
}
public func randArray64(count: Int) -> _UnitTestArray<UInt64> {
var result = _UnitTestArray<UInt64>(count: count, repeatedValue: 0)
for i in indices(result) {
result[i] = rand64()
}
return result
}

View File

@@ -0,0 +1,94 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
func _stdlib_sysctlbyname_Int32(name: String) -> Int32 {
return name.withCString {
(nameUtf8) -> Int32 in
var resultSize = 4
var result: Int32 = 0
sysctlbyname(nameUtf8, &result, &resultSize, nil, 0)
return result
}
}
public func _stdlib_getHardwareConcurrency() -> Int {
let result = Int(_stdlib_sysctlbyname_Int32("hw.physicalcpu"))
if result < 1 {
fatalError("_stdlib_getHardwareConcurrency(): could not query sysctl")
}
return result
}
/// An atomic counter for contended applications.
///
/// This is a struct to prevent extra retains/releases. You are required to
/// call `deinit()` to release the owned memory.
public struct _stdlib_ShardedAtomicCounter {
// Using an array causes retains/releases, which create contention on the
// reference count.
// FIXME: guard every element against false sharing.
var _shardsPtr: UnsafeMutablePointer<Int>
var _shardsCount: Int
public init() {
let hardwareConcurrency = _stdlib_getHardwareConcurrency()
let count = max(8, hardwareConcurrency * hardwareConcurrency)
let shards = UnsafeMutablePointer<Int>.alloc(count)
for var i = 0; i != count; i++ {
(shards + i).initialize(0)
}
self._shardsPtr = shards
self._shardsCount = count
}
public func `deinit`() {
self._shardsPtr.destroy(self._shardsCount)
self._shardsPtr.dealloc(self._shardsCount)
}
public func add(operand: Int, randomInt: Int) {
let shardIndex = Int(UInt(bitPattern: randomInt) % UInt(self._shardsCount))
_swift_stdlib_atomicFetchAddInt(
object: self._shardsPtr + shardIndex, operand: operand)
}
// FIXME: non-atomic as a whole!
public func getSum() -> Int {
var result = 0
let shards = self._shardsPtr
let count = self._shardsCount
for var i = 0; i != count; i++ {
result += _swift_stdlib_atomicLoadInt(object: shards + i)
}
return result
}
public struct PRNG {
var _state: Int
public init() {
_state = Int(Int32(bitPattern: rand32()))
}
public mutating func randomInt() -> Int {
var result = 0
for var i = 0; i != Int._sizeInBits; ++i {
result = (result << 1) | (_state & 1)
_state = (_state >> 1) ^ (-(_state & 1) & Int(bitPattern: 0xD0000001))
}
return result
}
}
}

View File

@@ -0,0 +1,94 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
/// Convert the given numeric value to a hexidecimal string.
public func asHex<T : IntegerType>(x: T) -> String {
return "0x" + String(x.toIntMax(), radix: 16)
}
/// Convert the given sequence of numeric values to a string representing
/// their hexidecimal values.
public func asHex<
S: SequenceType
where
S.Generator.Element : IntegerType
>(x: S) -> String {
return "[ " + ", ".join(lazy(x).map { asHex($0) }) + " ]"
}
/// Compute the prefix sum of `seq`.
public func scan<
S : SequenceType, U
>(seq: S, initial: U, combine: (U, S.Generator.Element) -> U) -> _UnitTestArray<U> {
var result = _UnitTestArray<U>()
result.reserveCapacity(underestimateCount(seq))
var runningResult = initial
for element in seq {
runningResult = combine(runningResult, element)
result.append(runningResult)
}
return result
}
public func randomShuffle<T>(a: _UnitTestArray<T>) -> _UnitTestArray<T> {
var result = a
for var i = a.count - 1; i != 0; --i {
// FIXME: 32 bits are not enough in general case!
let j = Int(rand32(exclusiveUpperBound: UInt32(i + 1)))
swap(&result[i], &result[j])
}
return result
}
public func gather<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
var result = _UnitTestArray<T>()
result.reserveCapacity(a.count)
for i in 0..<a.count {
result.append(a[idx[i]])
}
return result
}
public func scatter<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
var result = a
for i in 0..<a.count {
result[idx[i]] = a[i]
}
return result
}
public func withArrayOfCStrings<R>(
args: _UnitTestArray<String>, body: (Array<UnsafeMutablePointer<CChar>>) -> R
) -> R {
let argsLengths = _UnitTestArray(map(args) { count($0.utf8) + 1 })
let argsOffsets = [ 0 ] + scan(argsLengths, 0, +)
let argsBufferSize = argsOffsets.last!
var argsBuffer = _UnitTestArray<UInt8>()
argsBuffer.reserveCapacity(argsBufferSize)
for arg in args {
argsBuffer.extend(arg.utf8)
argsBuffer.append(0)
}
return argsBuffer.withUnsafeBufferPointer {
(argsBuffer) in
let ptr = UnsafeMutablePointer<CChar>(argsBuffer.baseAddress)
var cStrings = map(argsOffsets) { ptr + $0 }
cStrings[cStrings.count - 1] = nil
return body(cStrings)
}
}

View File

@@ -7,6 +7,7 @@
// XFAIL: linux
import Swift
import SwiftUnstable
import StdlibUnittest
final class HeapBool {

View File

@@ -3,6 +3,7 @@
// XFAIL: linux
import Swift
import SwiftUnstable
import StdlibUnittest
var HashingTestSuite = TestSuite("Hashing")

View File

@@ -3,6 +3,7 @@
// XFAIL: linux
import SwiftUnstable
import StdlibUnittest
var HashingTestSuite = TestSuite("Hashing")

View File

@@ -2,6 +2,7 @@
// XFAIL: linux
import SwiftUnstable
import StdlibUnittest
_setOverrideOSVersion(.OSX(major: 10, minor: 9, bugFix: 3))

View File

@@ -4,6 +4,7 @@
import Swift
import StdlibUnittest
import SwiftUnstablePthreadExtras
import Dispatch
var StringTestSuite = TestSuite("String")

View File

@@ -3,6 +3,7 @@
// FIXME: rdar://problem/19648117 Needs splitting objc parts out
// XFAIL: linux
import SwiftUnstable
import StdlibUnittest
import Foundation

View File

@@ -26,6 +26,7 @@ grapheme_cluster_break_property_table = \
}%
import SwiftUnstable
import StdlibUnittest
import Darwin
import Foundation

View File

@@ -3,6 +3,7 @@
// FIXME: rdar://problem/19648117 Needs splitting objc parts out
// XFAIL: linux
import SwiftUnstable
import StdlibUnittest
import Foundation