Instead of immediately creating closures for local function declarations and treating them directly as capturable values, break function captures down and transitively capture the storage necessary to invoke the captured functions. Change the way SILGen emits calls to closures and local functions so that it treats the capture list as the first curry level of an invocation, so that full applications of closure literals or nested functions don't require a partial apply at all. This allows references among local functions with captures to work within the existing confines of partial_apply, and also has the nice benefit that circular references would work without creating reference cycles (though Sema unfortunately rejects them; something we arguably ought to fix.)
This fixes rdar://problem/11266246 and improves codegen of local functions. Full applications of functions, or immediate applications of closure literals like { }(), now never need to allocate a closure.
Swift SVN r28112
preserve the original method name.
This heuristic is based on the Objective-C selector and therefore
doesn't really handle factory methods that would conflict with
initializers, but we can hope that those simply don't come up in
the wild.
It's not clear that this is the best thing to do --- it tends to
promote the non-throwing API over what's probably a newer, throwing
API --- but it's significantly easier, and it unblocks code without
creating deployment problems.
Swift SVN r28066
results when finding bridged types, rather than reinventing
(well, pre-inventing) the same thing elsewhere.
Doing this apparently forces AbstractionPattern to deal
with ObjC protocol methods for the first time, which are
generic and therefore require even the Clang-based
abstraction patterns to propagate generic signatures.
Use this infrastructure to allow foreign error conventions
to suppress the wrapping of nonnull bridged collection results
in a level of optionality. We can't treat nil results as
an empty collection while simultaneously treating them as
an error signal.
Swift SVN r28022
Preparation to fix <rdar://problem/18151694> Add Builtin.checkUnique
to avoid lost Array copies.
This adds the following new builtins:
isUnique : <T> (inout T[?]) -> Int1
isUniqueOrPinned : <T> (inout T[?]) -> Int1
These builtins take an inout object reference and return a
boolean. Passing the reference inout forces the optimizer to preserve
a retain distinct from what’s required to maintain lifetime for any of
the reference's source-level copies, because the called function is
allowed to replace the reference, thereby releasing the referent.
Before this change, the API entry points for uniqueness checking
already took an inout reference. However, after full inlining, it was
possible for two source-level variables that reference the same object
to appear to be the same variable from the optimizer's perspective
because an address to the variable was longer taken at the point of
checking uniqueness. Consequently the optimizer could remove
"redundant" copies which were actually needed to implement
copy-on-write semantics. With a builtin, the variable whose reference
is being checked for uniqueness appears mutable at the level of an
individual SIL instruction.
The kind of reference count checking that Builtin.isUnique performs
depends on the argument type:
- Native object types are directly checked by reading the
strong reference count:
(Builtin.NativeObject, known native class reference)
- Objective-C object types require an additional check that the
dynamic object type uses native swift reference counting:
(Builtin.UnknownObject, unknown class reference, class existential)
- Bridged object types allow the dymanic object type check to be
bypassed based on the pointer encoding:
(Builtin.BridgeObject)
Any of the above types may also be wrapped in an optional. If the
static argument type is optional, then a null check is also performed.
Thus, isUnique only returns true for non-null, native swift object
references with a strong reference count of one.
isUniqueOrPinned has the same semantics as isUnique except that it
also returns true if the object is marked pinned regardless of the
reference count. This allows for simultaneous non-structural
modification of multiple subobjects.
In some cases, the standard library can dynamically determine that it
has a native reference even though the static type is a bridge or
unknown object. Unsafe variants of the builtin are available to allow
the additional pointer bit mask and dynamic class lookup to be
bypassed in these cases:
isUnique_native : <T> (inout T[?]) -> Int1
isUniqueOrPinned_native : <T> (inout T[?]) -> Int1
These builtins perform an implicit cast to NativeObject before
checking uniqueness. There’s no way at SIL level to cast the address
of a reference, so we need to encapsulate this operation as part of
the builtin.
Swift SVN r27887
emit{StrongRelease,ReleaseValue} => emit{StrongRelease,ReleaseValue}AndFold.
Then introduce a new method emit{StrongRelease,ReleaseValue} that returns a
PointerUnion containing the increment to be deleted if it exists. This obviates
the need for the callback.
Swift SVN r27804
Handle recursions by replacing the apply to the callee with an apply to the newly specialized function, but only if substitutions are the same.
rdar://20676434
Swift SVN r27671
Replace the 'ignoreMissing' boolean flag with a new option set type,
SubstOptions, which is easier to extend. It is not an OptionSet<>
because a follow-on commit will introduce a non-trivial option that
will require more storage.
Also eliminate the LazyResolver parameter, which is no longer
needed. Eliminate the silly TypeChecker::substType(), whose only
purpose was to provide the resolver.
Swift SVN r27656
Keep track of a second set of "direct method reference" curry thunks that don't end in a dynamic dispatch in order to properly implement a partial application such as 'let foo = super.foo'. Fixes rdar://problem/20598526.
Swift SVN r27538
reference to something of class type. This is required to model
RebindSelfInConstructorExpr correctly to DI, since in the class case,
self.init and super.init *take* a value out of class box so that it
can pass the +1 value without performing an extra retain. Nothing
else in the compiler uninitializes a DI-controlled memory object
like this, so nothing else needs this. DI really doesn't like something
going from initialized to uninitialized.
Yes, I feel super-gross about this and am really unhappy about it. I
may end up reverting this if I can find an alternate solution to this
problem.
Swift SVN r27525
We still don't actually handle these correctly, but at least
we have sensible information for them now.
Also, remember that we're working with canonical generic
signatures in more places.
Swift SVN r27388
@objc protocols aren't supported with an ObjC runtime, but we still want values of AnyObject type to be word-sized. Handle this by turning the binary "needsWitnessTable" condition into a "dispatch strategy" enum, so we can recognize the condition "has no methods, so neither swift nor objc dispatch" as distinct from either swift or ObjC protocol representations. Assign this dispatch strategy when we lower AnyObject. Should be NFC for the ObjC-enabled build.
(It would also be beneficial for the ObjC-runtime-enabled version of Swift if AnyObject weren't an @objc protocol; that would mean we could give it a canonical protocol descriptor in the standard library, among other things. There are fairly deep assumptions in Sema that AnyObject is @objc, though, and it's not worth disturbing those assumptions right now.)
Reapplying with updates to the runtime unit tests.
Swift SVN r27341
@objc protocols aren't supported with an ObjC runtime, but we still want values of AnyObject type to be word-sized. Handle this by turning the binary "needsWitnessTable" condition into a "dispatch strategy" enum, so we can recognize the condition "has no methods, so neither swift nor objc dispatch" as distinct from either swift or ObjC protocol representations. Assign this dispatch strategy when we lower AnyObject. Should be NFC for the ObjC-enabled build.
(It would also be beneficial for the ObjC-runtime-enabled version of Swift if AnyObject weren't an @objc protocol; that would mean we could give it a canonical protocol descriptor in the standard library, among other things. There are fairly deep assumptions in Sema that AnyObject is @objc, though, and it's not worth disturbing those assumptions right now.)
Swift SVN r27338
The protocol_lookup testcase from Interpreter test-cases exposed a bug when compiled with -O:
- SILCloner was generating an open_existential_ref from an open_existential_metatype instruction during cloning even if the existential in question was not a class existential.
Swift SVN r27266
The protocol_lookup the testcase from Interpreter test-cases exposed two bugs, once I tried to compiler with with -O:
- SILCloner was generating an open_existential_ref from an open_existential_metatype instruction during cloning even if the existential in question was not a class existential.
- DynamicCasts was not considering the fact that subclasses of a given class may implement a protocol, even if the class does not implement it.
Swift SVN r27260
The two ways functions are created currently is via the two
SILModule::getOrCreateFunction(). One of the methods, takes in a raw mangled
name and uses that to create the function. The other takes in a SILDeclRef to
generate the mangled name. Most function emission (besides some thunk creation
functions) goes through the latter. For now we update the map there. This is ok,
since this map will only be used to provide extra verification that guaranteed
self is occuring everywhere that it is supposed to (since constructors and
destructors still have @owned self).
Swift SVN r27240
Previous attempts to update the callgraph explicitly after calls to
linkFunction() weren't completely effective because we can deserialize
deeply and introduce multiple new function bodies in the process.
This gets us a bit closer, but only adds new call graph nodes. It does
not currently add edges for everything that gets deserialized (and this
is not fatal, so it is a step forward).
Swift SVN r27120
This API is more convenient than using the old getOrCreate API, which requires 9 parameters to be provided.
I'm going to use this API in the subsequent commits.
Swift SVN r27097
These aren't really orthogonal concerns--you'll never have a @thick @cc(objc_method), or an @objc_block @cc(witness_method)--and we have gross decision trees all over the codebase that try to hopscotch between the subset of combinations that make sense. Stop the madness by eliminating AbstractCC and folding its states into SILFunctionTypeRepresentation. This cleans up a ton of code across the compiler.
I couldn't quite eliminate AbstractCC's information from AST function types, since SIL type lowering transiently created AnyFunctionTypes with AbstractCCs set, even though these never occur at the source level. To accommodate type lowering, allow AnyFunctionType::ExtInfo to carry a SILFunctionTypeRepresentation, and arrange for the overlapping representations to share raw values.
In order to avoid disturbing test output, AST and SILFunctionTypes are still printed and parsed using the existing @thin/@thick/@objc_block and @cc() attributes, which is kind of gross, but lets me stage in the real source-breaking change separately.
Swift SVN r27095