Files
swift-mirror/stdlib/public/runtime/ErrorObjectNative.cpp
Dario Rexin a8d4d57f11 [IRGen] Generate compressed representation of value witnesses (#63813)
rdar://105837040

* WIP: Store layout string in type metadata

* WIP: More cases working

* WIP: Layout strings almost working

* Add layout string pointer to struct metadata

* Fetch bytecode layout strings from metadata in runtime

* More efficient bytecode layout

* Add support for interpreted generics in layout strings

* Layout string instantiation, take and more

* Remove duplicate information from layout strings

* Include size of previous object in next objects offset to reduce number of increments at runtime

* Add support for existentials

* Build type layout strings with StructBuilder to support target sizes and metadata pointers

* Add support for resilient types

* Properly cache layout strings in compiler

* Generic resilient types working

* Non-generic resilient types working

* Instantiate resilient type in layout when possible

* Fix a few issues around alignment and signing

* Disable generics, fix static alignment

* Fix MultiPayloadEnum size when no extra tag is necessary

* Fixes after rebase

* Cleanup

* Fix most tests

* Fix objcImplementattion and non-Darwin builds

* Fix BytecodeLayouts on non-Darwin

* Fix Linux build

* Fix sizes in linux tests

* Sign layout string pointers

* Use nullptr instead of debug value
2023-02-24 15:40:28 -08:00

118 lines
3.8 KiB
C++

//===--- ErrorObjectNative.cpp - Recoverable error object -----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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 object representation of the standard Error
// protocol type, which represents recoverable errors in the language. This
// implementation is used when ObjC interop is disabled; the ObjC-interoperable
// version is implemented in ErrorObject.mm.
//
//===----------------------------------------------------------------------===//
#include "swift/Runtime/Config.h"
#if !SWIFT_OBJC_INTEROP
#include <stdio.h>
#include "swift/Runtime/Debug.h"
#include "ErrorObject.h"
#include "Private.h"
using namespace swift;
/// Determine the size and alignment of an Error box containing the given
/// type.
static std::pair<size_t, size_t>
_getErrorAllocatedSizeAndAlignmentMask(const Metadata *type) {
// The value is tail-allocated after the SwiftError record with the
// appropriate alignment.
auto vw = type->getValueWitnesses();
size_t size = sizeof(SwiftError);
unsigned valueAlignMask = vw->getAlignmentMask();
size = (size + valueAlignMask) & ~(size_t)valueAlignMask;
size += vw->getSize();
size_t alignMask = (alignof(SwiftError) - 1) | valueAlignMask;
return {size, alignMask};
}
/// Destructor for an Error box.
static SWIFT_CC(swift) void _destroyErrorObject(SWIFT_CONTEXT HeapObject *obj) {
auto error = static_cast<SwiftError *>(obj);
// Destroy the value inside.
auto type = error->type;
type->vw_destroy(error->getValue());
// Deallocate the buffer.
auto sizeAndAlign = _getErrorAllocatedSizeAndAlignmentMask(type);
swift_deallocObject(obj, sizeAndAlign.first, sizeAndAlign.second);
}
/// Heap metadata for Error boxes.
static const FullMetadata<HeapMetadata> ErrorMetadata{
HeapMetadataHeader{{nullptr}, {_destroyErrorObject}, {&VALUE_WITNESS_SYM(Bo)}},
HeapMetadata(MetadataKind::ErrorObject),
};
BoxPair
swift::swift_allocError(const swift::Metadata *type,
const swift::WitnessTable *errorConformance,
OpaqueValue *initialValue,
bool isTake) {
auto sizeAndAlign = _getErrorAllocatedSizeAndAlignmentMask(type);
auto allocated = swift_allocObject(&ErrorMetadata,
sizeAndAlign.first, sizeAndAlign.second);
auto error = reinterpret_cast<SwiftError*>(allocated);
error->type = type;
error->errorConformance = errorConformance;
// If an initial value was given, copy or take it in.
auto valuePtr = error->getValue();
if (initialValue) {
if (isTake)
type->vw_initializeWithTake(valuePtr, initialValue);
else
type->vw_initializeWithCopy(valuePtr, initialValue);
}
return BoxPair{allocated, valuePtr};
}
void
swift::swift_deallocError(SwiftError *error, const Metadata *type) {
auto sizeAndAlign = _getErrorAllocatedSizeAndAlignmentMask(type);
swift_deallocUninitializedObject(error, sizeAndAlign.first, sizeAndAlign.second);
}
void
swift::swift_getErrorValue(const SwiftError *errorObject,
void **scratch,
ErrorValueResult *out) {
out->value = errorObject->getValue();
out->type = errorObject->type;
out->errorConformance = errorObject->errorConformance;
}
SwiftError *swift::swift_errorRetain(SwiftError *error) {
return static_cast<SwiftError*>(swift_retain(error));
}
void swift::swift_errorRelease(SwiftError *error) {
swift_release(error);
}
#endif