Add checks for metadata state (#375)
* Add checks for metadata state Type metadata actually *is* mutable, is updated by the runtime, and we need to be careful when reading from it. * Add a precondition for type metadata state * Replace `precondition` with an `assert` * Add missing license headers
This commit is contained in:
parent
9a79548312
commit
d75b185553
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2021 Tokamak contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
enum MetadataState: UInt {
|
||||
case complete = 0x00
|
||||
case nonTransitiveComplete = 0x01
|
||||
case layoutComplete = 0x3F
|
||||
case abstract = 0xFF
|
||||
}
|
||||
|
||||
private let isBlockingMask: UInt = 0x100
|
||||
|
||||
struct MetadataRequest {
|
||||
private let bits: UInt
|
||||
|
||||
init(desiredState: MetadataState, isBlocking: Bool) {
|
||||
if isBlocking {
|
||||
bits = desiredState.rawValue | isBlockingMask
|
||||
} else {
|
||||
bits = desiredState.rawValue & ~isBlockingMask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MetadataResponse {
|
||||
let metadata: UnsafePointer<StructMetadata>
|
||||
let state: MetadataState
|
||||
}
|
||||
|
||||
@_silgen_name("swift_checkMetadataState")
|
||||
func _checkMetadataState(_ request: MetadataRequest, _ type: StructMetadata) -> MetadataResponse
|
|
@ -129,5 +129,15 @@ struct StructMetadata {
|
|||
extension StructMetadata {
|
||||
init(type: Any.Type) {
|
||||
self = Self(pointer: unsafeBitCast(type, to: UnsafePointer<StructMetadataLayout>.self))
|
||||
assert(
|
||||
_checkMetadataState(
|
||||
.init(desiredState: .layoutComplete, isBlocking: false),
|
||||
self
|
||||
).state.rawValue < MetadataState.layoutComplete.rawValue,
|
||||
"""
|
||||
Struct metadata for \(type) is in incomplete state, \
|
||||
proceeding would result in an undefined behavior.
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,26 @@
|
|||
// Copyright 2021 Tokamak contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import Benchmark
|
||||
import TokamakCore
|
||||
|
||||
private let bigType = NavigationView<HStack<VStack<Button<Text>>>>.self
|
||||
|
||||
benchmark("mangledName Runtime") {
|
||||
_ = typeInfo(of: bigType)!.mangledName
|
||||
}
|
||||
|
||||
benchmark("typeConstructorName TokamakCore") {
|
||||
_ = typeConstructorName(bigType)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
// Copyright 2021 Tokamak contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import Benchmark
|
||||
import TokamakStaticHTML
|
||||
|
||||
|
|
Loading…
Reference in New Issue