Vogel
February 14, 2019, 11:59pm
1
Hello!
I've been trying to investigate how the standard library works and I've found something that I don't fully understand.
It appears as if everything eventually boils down to "Builtin" stuff that's not actually declared anywhere, but just assumed to exist within the stdlib.
For example, a Bool is really just a wrapped for a Builtin.Int1.
Now I would like to know: Where do I find the declaration of this Int1? Or, even more interesting: Where do I find a list of all the Builtin types?
Thank you in advance,
Best regards, Vogel.
1 Like
scanon
(Steve Canon)
February 15, 2019, 12:04am
2
Builtins generally expand to LLVM IR types and operations. The mappings are defined directly in the compiler (mostly include/swift/AST/Builtins.def
and lib/AST/Builtins.cpp
--for example, the Builtin.Int${N}
types like Builtin.Int1
are defined via the machinery starting on line 102).
11 Likes
Pogosito
(Pogos)
September 30, 2023, 11:59am
3
Hi, thanks for reply.
Can you explain where find implementation of Builtin.NativeObject.
I already use your answer and found that Builtin.NativeObject mapped to TheNativeObjectType (in Builtins.cpp). It maps by context ASTContext
But there is no mention TheNativeObjectType in ASTContext.cpp ASTContext.h
I try to google TheNativeObjectType in context of LLVM and did not find it.
Could you give more information where find implementation of Builtin type and operations ?
Thanks
AFAIU, most if not all Builtin
functions map to LLVM IR instructions, which you can look up in the LLVM language reference .
Pogosito
(Pogos)
September 30, 2023, 4:26pm
5
Thank you very much for your reply.
I already viewed this page and did not find definition of Builtin.NativeObject
With Respect
Pogos
Alejandro
(Alejandro Alonso)
September 30, 2023, 6:04pm
6
The type is defined here in ASTContext.h:
// Type manipulation routines.
//===--------------------------------------------------------------------===//
// Builtin type and simple types that are used frequently.
const CanType TheErrorType; /// This is the ErrorType singleton.
const CanType TheUnresolvedType; /// This is the UnresolvedType singleton.
const CanType TheEmptyTupleType; /// This is '()', aka Void
const CanType TheEmptyPackType;
const CanType TheAnyType; /// This is 'Any', the empty protocol composition
#define SINGLETON_TYPE(SHORT_ID, ID) \
const CanType The##SHORT_ID##Type;
#include "swift/AST/TypeNodes.def"
const CanType TheIEEE32Type; /// 32-bit IEEE floating point
const CanType TheIEEE64Type; /// 64-bit IEEE floating point
// Target specific types.
const CanType TheIEEE16Type; /// 16-bit IEEE floating point
const CanType TheIEEE80Type; /// 80-bit IEEE floating point
const CanType TheIEEE128Type; /// 128-bit IEEE floating point
const CanType ThePPC128Type; /// 128-bit PowerPC 2xDouble
and in TypeNodes.def:
//===--- TypeNodes.def - Swift Type AST Metaprogramming ---------*- C++ -*-===//
//
// 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 file defines macros used for macro-metaprogramming with types.
//
//===----------------------------------------------------------------------===//
/// TYPE(id, parent)
/// If the type node is not abstract, its enumerator value is
/// TypeKind::id. The node's class name is 'id##Type', and the name of
/// its base class (in the Type hierarchy) is 'parent' (including
This file has been truncated. show original
The actual type definition for this type is:
public:
static bool classof(const TypeBase *T) {
return T->getKind() == TypeKind::BuiltinPackIndex;
}
};
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinPackIndexType, BuiltinType)
/// BuiltinNativeObjectType - The builtin opaque object-pointer type.
/// Useful for keeping an object alive when it is otherwise being
/// manipulated via an unsafe pointer type.
class BuiltinNativeObjectType : public BuiltinType {
friend class ASTContext;
BuiltinNativeObjectType(const ASTContext &C)
: BuiltinType(TypeKind::BuiltinNativeObject, C) {}
public:
static bool classof(const TypeBase *T) {
return T->getKind() == TypeKind::BuiltinNativeObject;
}
};
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinNativeObjectType, BuiltinType)
2 Likes
Pogosito
(Pogos)
September 30, 2023, 6:14pm
7
Thank you very much, I should have read the sources more carefully, thank you
Pogosito
(Pogos)
October 7, 2023, 6:16am
8
Sorry to bother you again.
Could you tell me if I understood correctly that BuiltinNativeObjectType is just a "universal" pointer to any object?
And even somehow embarrassingly, I again could not find the implementation of Builtin functions, for example cancel.
I find only a '.def' file in which most of the functions I'm interested in are wrapped in BUILTIN_MISC_OPERATION_WITH_SILGEN, but the description of what does (and what is it) this is completely incomprehensible to me
Judging by the description, these functions should be generated at the SIL stage, I tried to look at the implementation of the cancel method, generated SIL and got
// Task.cancel()
sil [available 12.0.0] @$sScT6cancelyyF : $@convention(method) <Ο_0_0, Ο_0_1 where Ο_0_0 : Sendable, Ο_0_1 : Error> (@guaranteed Task<Ο_0_0, Ο_0_1>) -> ()
which does not give any ideas for further steps
1 Like
ktoso
(Konrad 'ktoso' Malawski ππ΄ββ οΈ)
November 20, 2023, 1:27am
9
Task.cancel is not a builtin:
First go to Task.swift
and find cancel:
public func cancel() {
_taskCancel(_task)
}
find that function in the same file:
@available(SwiftStdlib 5.1, *)
@_silgen_name("swift_task_cancel")
public func _taskCancel(_ task: Builtin.NativeObject)
Then find:
SWIFT_CC(swift)
static void swift_task_cancelImpl(AsyncTask *task)
in TaskStatus.cpp.
Builtins like creating groups etc are declared in Builtins.def
BUILTIN_MISC_OPERATION_WITH_SILGEN(GetCurrentExecutor, "getCurrentExecutor", "", Special)
and then the signature is in Builtins.cpp
:
case BuiltinValueKind::GetCurrentExecutor:
return getGetCurrentExecutor(Context, Id);
and implementation in GenBuiltin.cpp
:
// emitGetCurrentExecutor has no arguments.
if (Builtin.ID == BuiltinValueKind::GetCurrentExecutor) {
emitGetCurrentExecutor(IGF, out);
return;
}
The above emit forms a call to a runtime function, which eventually ends up in plain runtime function (declared in RuntimeFunctions.def
):
SWIFT_CC(swift)
static SerialExecutorRef swift_task_getCurrentExecutorImpl() { ... }
Basically keep looking where GetCurrentExecutor
is used, and you'll find all important places -- there's quite a few.
Hope this helps,
3 Likes