Swift-rooted class hierarchies don't permit the replacement of "self",
so it's guaranteed that the 'self' returned from a 'super.init'
invocation is identical to the previous self. Elide the unconditional
checked downcast (that manifests as a call to
swift_dynamicCastClassUnconditional in the runtime) by putting in the
moral equivalent of a bitcast.
For Objective-C-rooted hierarchies, 'self' can be replaced, so memory
safety dictates that we use the unconditional checked downcast. Note
that this path is still unsafe against nil returns.
Swift SVN r12401
We need to model the difference between Objective-C- and Swift-rooted
class hierarchies in SIL. IRGen is too late to handle nil returns.
This reverts commit 549db981ea0136a67aee3029aefe18a05d3c8833.
Swift SVN r12400
No functional difference from the unconditional checked downcast we
had before, but this gives IRGen the chance to specialize the
implementation.
Swift SVN r12382
When we decide to emit a separate ivar initializer method (via the
Objective-C entry point -.cxx_construct), we no longer initialize the
ivars within the initializer. This only happens for derived classes,
so teach DI about uninitialized 'self' values that require a
super.init call but don't require the ivars to be initialized.
Swift SVN r12240
- constify the Initialization::getAddressOrNull/hasAddress functions.
- Teach the initialization logic that 'let' initializations can be
split into tuple subelements by address (i.e. i
getSubInitializationsForTuple works on them) when the let decl has
a backing memory allocation.
- Teach LetValueInitialization to produce a backing memory object
for address-only tuple arguments, since they are passed as multiple
SILArguments and need some place in memory to reassemble them.
The collection fixes a bad miscompilation where the RValue logic emitted
a temporary (through getSingleValue) which we then accidentally lifetime
extended for the duration of the argument. This led to bad things when
the temporary got destroyed too early.
Thanks to MichaelG for helping narrow down this problem, it initially looked
like a sil optimizer bug.
Swift SVN r12234
RValue::forwardInto. While this isn't directly related to my
current problem, it is obvious goodness. This avoids materializing
"as a single value" the argument values, which means that we don't
create a temporary holding the value when we have tuple elements,
allowing us to generate more efficient code (particularly for
address-only tuple).
Swift SVN r12233
so merge them. ArgumentInitVisitor is very very similar to
InitializeTupleValues, so start using RValue::forwardInto in
ArgumentInitVisitor for some cases instead of duplciating logic. This
gives ArgumentInitVisitor some extra magic for lets which I'll be using
in a bit.
Swift SVN r12231
Doing so makes it plain that the empty tuple case doesn't need to
synthesize a tupleinst to return. Eliminating this gets rid of the
weird dead empty tuple you may have seen get dropped in the prolog
of functions taking no arguments.
Also, push around RValue handling a bit in ArgumentInitVisitor, NFC
for this part.
Swift SVN r12230
When a class that will be allocated by the Objective-C runtime also
requires all of its stored properties have initial values, move that
complete initialization of the object into -.cxx_construct, which is
invoked by the runtime after +alloc.
Definite initialization doesn't like the resulting initializers (which
don't initialize any of their ivars) at all, so no end-to-end testing yet.
Swift SVN r12229
When we're using Objective-C's memory allocation, emit .cxx_construct
methods whenever we have instance variables with in-class
initializers. Presently, these methods are just empty stubs.
Swift SVN r12211
Instance variable destruction is handled separately by -.cxx_destruct,
and the message send to the superclass's -dealloc is handled by the
Objective-C runtime, so we only need to emit a -dealloc if there is
any user code in it.
Swift SVN r12210
The Objective-C runtime executes the .cxx_destruct method after the
last -dealloc has executed when destroying an object, allowing the
instance variables to remain live even after the subclass's
destructor/-dealloc has executed, which is important for memory
safety. This fixes the majority of <rdar://problem/15136592>.
Note that IRGenModule::getAddrOfIVarDestroyer() contains an egregious
hack to find the ivar destructor SIL function via a linear
search. We need a better way to find SIL functions that we know exist,
because LinkEntity does not suffice.
Swift SVN r12206
The Swift entry point is required for the Swift metadata, while the
Objective-C entry point goes into the Objective-C metadata. As part of
this, stop emitting the destroying destructor for classes that use
Objective-C allocation: it won't work anyway.
Swift SVN r12199
Right now I unconditionally generate these, because silgen doesn't have
easy access to whether "-g" is passed or not. We can either make SILGen
know about this, or we can have optimizations strip these uses out.
Opinions welcome!
As an example, something like:
protocol P { func bonk() }
func foo(let a : Int, let b : P) -> Int {
let x = a
b.bonk()
return x
}
compiles into:
sil @_TF1t3fooFT1aSi1bPS_1P__Si : $@thin (Int64, @in P) -> Int64 {
bb0(%0 : $Int64, %1 : $*P):
debug_value %0 : $Int64 // let a // id: %2
debug_value_addr %1 : $*P // let b // id: %3
debug_value %0 : $Int64 // let x // id: %4
%5 = project_existential %1 : $*P to $*@sil_self P // user: %7
%6 = protocol_method %1 : $*P, #P.bonk!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %7
%7 = apply %6(%5) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
destroy_addr %1 : $*P // id: %8
return %0 : $Int64 // id: %9
}
Swift SVN r12193
Because Objective-C doesn't have the notion of a destroying
destructor, this is a matter of cleanliness rather than
correctness. Still, it's better not to lie.
Swift SVN r12160
takes the archetype as an rvalue, not an lvalue. This defines away the need
for MaterializeExpr at sema time, reusing the existing temporary mechanics in
SILGen. This also opens future optimizations.
Swift SVN r12123
SILDeclRef was previously storing the ClassDecl for this case, because
semantic analysis didn't guarantee that a DestructorDecl was always
present. It is now, and this representation makes more sense.
Swift SVN r12122
to non-@mutating methods work in the AST: now the base expression is
always computed as an rvalue, instead of computing them as an lvalue. The
optimization that we were accidentally getting before is now explicitly
modeled, and the non-optimized case is now handled by standard temporary
emission in SILGen instead of with MaterializeExpr. The upshot of this
carefully choreographed step is that there is no change in generated code (!).
Archetype member references still need to be switched over to this new
scheme (at which point materializeexpr is dead), and the optimization
needs to be replicated for 'let' bases (at which point arguments
becoming 'let' is only gated on debug info).
Swift SVN r12120
Teach SILGen to emit a -dealloc method that runs user code, destroys
instance variables, and then calls up to the superclass dealloc. Teach
IRGen to deal with Objective-C destructor methods and add -dealloc to
the instance method table.
There are a few things still wrong here: we're emitting both a Swift
destructor and -dealloc, even though only one of them should ever
actually be used. Additionally, instance variables shouldn't be
destroyed in -dealloc, but in .cxx_destruct, so they persist until the
last of the -dealloc methods is invoked.
Swift SVN r12115
We use Objective-C allocation for classes whose root was defined in
Objective-C. Any Swift class whose root is defined in Swift will use
Swift's allocation routines instead.
Plus some minor cleanup in advance of implementing -dealloc.
Swift SVN r12104
General compiler support is missing for 'type' properties on classes, and lets don't
work either, but at least we have a nice diagnostic now.
also, rename static -> type in a few internal diagnostic names.
Swift SVN r12102