mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Runtime] Add a function pointer for intercepting swift_willThrow calls.
rdar://problem/53400364
This commit is contained in:
@@ -27,6 +27,7 @@ add_swift_target_library(swiftStdlibUnittest ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES}
|
|||||||
Statistics.swift
|
Statistics.swift
|
||||||
StdlibCoreExtras.swift
|
StdlibCoreExtras.swift
|
||||||
StringConvertible.swift
|
StringConvertible.swift
|
||||||
|
SymbolLookup.swift
|
||||||
TestHelpers.swift
|
TestHelpers.swift
|
||||||
TypeIndexed.swift
|
TypeIndexed.swift
|
||||||
|
|
||||||
|
|||||||
49
stdlib/private/StdlibUnittest/SymbolLookup.swift
Normal file
49
stdlib/private/StdlibUnittest/SymbolLookup.swift
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//===--- SymbolLookup.swift -----------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
import Darwin
|
||||||
|
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku)
|
||||||
|
import Glibc
|
||||||
|
#elseif os(Windows)
|
||||||
|
import MSVCRT
|
||||||
|
import WinSDK
|
||||||
|
#else
|
||||||
|
#error("Unsupported platform")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
|
||||||
|
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
|
||||||
|
#elseif os(Linux)
|
||||||
|
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0)
|
||||||
|
#elseif os(Android)
|
||||||
|
#if arch(arm)
|
||||||
|
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0xffffffff as UInt)
|
||||||
|
#elseif arch(arm64)
|
||||||
|
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0)
|
||||||
|
#else
|
||||||
|
#error("Unsupported platform")
|
||||||
|
#endif
|
||||||
|
#elseif os(Windows)
|
||||||
|
let hStdlibCore: HMODULE = GetModuleHandleA("swiftCore.dll")!
|
||||||
|
#else
|
||||||
|
#error("Unsupported platform")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public func pointerToSwiftCoreSymbol(name: String) -> UnsafeMutableRawPointer? {
|
||||||
|
#if os(Windows)
|
||||||
|
return unsafeBitCast(GetProcAddress(hStdlibCore, name),
|
||||||
|
to: UnsafeMutableRawPointer?.self)
|
||||||
|
#else
|
||||||
|
return dlsym(RTLD_DEFAULT, name)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ set(swift_runtime_sources
|
|||||||
CygwinPort.cpp
|
CygwinPort.cpp
|
||||||
Demangle.cpp
|
Demangle.cpp
|
||||||
Enum.cpp
|
Enum.cpp
|
||||||
|
ErrorObjectCommon.cpp
|
||||||
ErrorObjectConstants.cpp
|
ErrorObjectConstants.cpp
|
||||||
ErrorObjectNative.cpp
|
ErrorObjectNative.cpp
|
||||||
Errors.cpp
|
Errors.cpp
|
||||||
|
|||||||
@@ -598,12 +598,5 @@ swift::swift_errorRelease(SwiftError *error) {
|
|||||||
return objc_release((id)error);
|
return objc_release((id)error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Breakpoint hook for debuggers.
|
|
||||||
SWIFT_CC(swift) void
|
|
||||||
swift::swift_willThrow(SWIFT_CONTEXT void *unused,
|
|
||||||
SWIFT_ERROR_RESULT SwiftError **error) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
38
stdlib/public/runtime/ErrorObjectCommon.cpp
Normal file
38
stdlib/public/runtime/ErrorObjectCommon.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
//===--- ErrorObjectCommon.cpp - Recoverable error object -----------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This implements the parts of the standard Error protocol type which are
|
||||||
|
// shared between the ObjC-interoperable implementation and the native
|
||||||
|
// implementation. The parts specific to each implementation can be found in
|
||||||
|
// ErrorObject.mm (for the ObjC-interoperable parts) and ErrorObjectNative.cpp.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "swift/Runtime/Concurrent.h"
|
||||||
|
#include "swift/Runtime/Config.h"
|
||||||
|
#include "ErrorObject.h"
|
||||||
|
#include "ErrorObjectTestSupport.h"
|
||||||
|
|
||||||
|
using namespace swift;
|
||||||
|
|
||||||
|
void (*swift::_swift_willThrow)(SwiftError *error);
|
||||||
|
|
||||||
|
/// Breakpoint hook for debuggers, and calls _swift_willThrow if set.
|
||||||
|
SWIFT_CC(swift) void
|
||||||
|
swift::swift_willThrow(SWIFT_CONTEXT void *unused,
|
||||||
|
SWIFT_ERROR_RESULT SwiftError **error) {
|
||||||
|
// Cheap check to bail out early, since we expect there to be no callbacks
|
||||||
|
// the vast majority of the time.
|
||||||
|
if (SWIFT_LIKELY(!_swift_willThrow))
|
||||||
|
return;
|
||||||
|
_swift_willThrow(*error);
|
||||||
|
}
|
||||||
@@ -106,11 +106,4 @@ swift::swift_getErrorValue(const SwiftError *errorObject,
|
|||||||
out->errorConformance = errorObject->errorConformance;
|
out->errorConformance = errorObject->errorConformance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Breakpoint hook for debuggers.
|
|
||||||
SWIFT_CC(swift) void
|
|
||||||
swift::swift_willThrow(SWIFT_CONTEXT void *unused,
|
|
||||||
SWIFT_ERROR_RESULT SwiftError **error) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
26
stdlib/public/runtime/ErrorObjectTestSupport.h
Normal file
26
stdlib/public/runtime/ErrorObjectTestSupport.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//===--- ErrorObjectTestSupport.h - Support for Instruments.app -*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Swift runtime support for tests involving errors.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef SWIFT_RUNTIME_ERROROBJECT_TEST_SUPPORT_H
|
||||||
|
#define SWIFT_RUNTIME_ERROROBJECT_TEST_SUPPORT_H
|
||||||
|
|
||||||
|
namespace swift {
|
||||||
|
|
||||||
|
SWIFT_RUNTIME_EXPORT void (*_swift_willThrow)(SwiftError *error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -191,5 +191,23 @@ ErrorTests.test("test dealloc empty error box") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errors: [Error] = []
|
||||||
|
ErrorTests.test("willThrow") {
|
||||||
|
typealias WillThrow = @convention(c) (Error) -> Void
|
||||||
|
let willThrow = pointerToSwiftCoreSymbol(name: "_swift_willThrow")!
|
||||||
|
willThrow.storeBytes(of: { errors.append($0) }, as: WillThrow.self)
|
||||||
|
expectTrue(errors.isEmpty)
|
||||||
|
do {
|
||||||
|
throw UnsignedError.negativeOne
|
||||||
|
} catch {}
|
||||||
|
expectEqual(UnsignedError.self, type(of: errors.last!))
|
||||||
|
|
||||||
|
do {
|
||||||
|
throw SillyError.JazzHands
|
||||||
|
} catch {}
|
||||||
|
expectEqual(2, errors.count)
|
||||||
|
expectEqual(SillyError.self, type(of: errors.last!))
|
||||||
|
}
|
||||||
|
|
||||||
runAllTests()
|
runAllTests()
|
||||||
|
|
||||||
|
|||||||
@@ -592,39 +592,9 @@ Runtime.test("Struct layout with reference storage types") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Runtime.test("SwiftError layout constants for LLDB") {
|
Runtime.test("SwiftError layout constants for LLDB") {
|
||||||
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
|
let offsetof_SwiftError_typeMetadata = pointerToSwiftCoreSymbol(name: "_swift_lldb_offsetof_SwiftError_typeMetadata")!
|
||||||
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
|
let sizeof_SwiftError = pointerToSwiftCoreSymbol(name: "_swift_lldb_sizeof_SwiftError")!
|
||||||
#elseif os(Linux)
|
|
||||||
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0)
|
|
||||||
#elseif os(Android)
|
|
||||||
#if arch(arm)
|
|
||||||
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0xffffffff as UInt)
|
|
||||||
#elseif arch(arm64)
|
|
||||||
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0)
|
|
||||||
#else
|
|
||||||
_UnimplementedError()
|
|
||||||
#endif
|
|
||||||
#elseif os(Windows)
|
|
||||||
let hStdlibCore: HMODULE = GetModuleHandleA("swiftCore.dll")!
|
|
||||||
#else
|
|
||||||
_UnimplementedError()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if os(Windows)
|
|
||||||
let offsetof_SwiftError_typeMetadata: UnsafeRawPointer =
|
|
||||||
unsafeBitCast(GetProcAddress(hStdlibCore,
|
|
||||||
"_swift_lldb_offsetof_SwiftError_typeMetadata")!,
|
|
||||||
to: UnsafeRawPointer.self)
|
|
||||||
let sizeof_SwiftError: UnsafeRawPointer =
|
|
||||||
unsafeBitCast(GetProcAddress(hStdlibCore,
|
|
||||||
"_swift_lldb_sizeof_SwiftError")!,
|
|
||||||
to: UnsafeRawPointer.self)
|
|
||||||
#else
|
|
||||||
let offsetof_SwiftError_typeMetadata =
|
|
||||||
dlsym(RTLD_DEFAULT, "_swift_lldb_offsetof_SwiftError_typeMetadata")!
|
|
||||||
let sizeof_SwiftError =
|
|
||||||
dlsym(RTLD_DEFAULT, "_swift_lldb_sizeof_SwiftError")!
|
|
||||||
#endif
|
|
||||||
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
|
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
|
||||||
#if arch(i386) || arch(arm)
|
#if arch(i386) || arch(arm)
|
||||||
expectEqual(20, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
|
expectEqual(20, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
|
||||||
|
|||||||
Reference in New Issue
Block a user