Ok, I see. 

But withMemoryRebound requires a return value. Don’t think there’s any way 
around that…compiler error
And mainPtr (now typed correctly/safely) needs to access the appropriate data 
structure mainPassFrameData.
Hence the external mainPtr.pointee assignment (since I can’t do so safely 
within the closure -> Swift compiler crashes)

Gerard Iglesias crafted another version of this snippet of code using 
assumingMemoryBound but also assigns pointee externally.
So did the original sample code.

Haven’t we achieved the goal of “safely" re-typing raw memory on the fly? To 
"help the compiler help us" so to speak…
What do you believe is so “unsafe" about the external pointee assignment? Since 
the compiler won’t let us do so anymore 
If the types aren’t all correctly aligned.

Curious to see what Andrew Trick has to say about all of this. Good idea to cc: 
him

In the meantime, both versions seem to work. Plus am learning a lot about typed 
versus untyped memory access in Swift...

Best - Patrice

On Sep 3, 2016, at 9:27 PM, Jacob Bandes-Storch via swift-users 
<swift-users@swift.org> wrote:
> 
> I was referring to this:
> 
>         let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 
> 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
>         mainPtr.pointee = mainPassFrameData
> 
> The result of $0 is being returned from the block and used later.
> 
> cc'ing Andrew Trick on this conversation because his input would be quite 
> useful :-)
> 
> Jacob
> 
> On Sat, Sep 3, 2016 at 2:03 PM, Patrice Kouame <pkou...@me.com> wrote:
> 
> Not sure what you mean? 
> The positional arg $0 is never used outside the closure whatever the 
> version...
> No attempt is ever made to save and reuse after withMemoryRebound?
> Why would I use a separate function?
> 
> Are we looking at the same code? 🤓
> 
> rédigé sur mon iPhone.
> 
> On Sep 3, 2016, at 4:16 PM, Jacob Bandes-Storch <jtban...@gmail.com> wrote:
> 
>> Yikes! That's unsafe! When using withMemoryRebound, I think you're only 
>> supposed to use the argument $0 inside the block. Saving it and using it 
>> after withMemoryRebound is probably undefined behavior. But maybe you can 
>> move your ".pointee = x" into a separate function rather than using a 
>> closure?
>> 
>> On Sat, Sep 3, 2016 at 1:12 PM, Patrice Kouame via swift-users 
>> <swift-users@swift.org> wrote:
>> Finally Success!  I’m seeing my pretty little 3D twirling Metal Renderer 
>> cubes again… Here’s how
>> 
>> Snippet of old  sample code which no longer compiles in Xcode 8 beta 6 with 
>> stricter Swift3 unsafe type casting restrictions 
>> (in MetalView.swift from # Adopting Metal II: Designing and Implementing a 
>> Real-World Metal Renderer)
>> 
>>      let shadowPtr = 
>> UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
>>      let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
>>      mainPtr.pointee = mainPassFrameData
>>      var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
>> 
>> My conversion attempt that crashes Swift 3 Xcode 8 beta 6 (see  RADAR 
>> 28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and 
>> IDE)
>> 
>>         let shadowPtr = constantBufferForFrame.contents().bindMemory(to: 
>> ShadowPass.self, capacity: MemoryLayout<shadowPassData>.size)
>>         let mainPtr : UnsafeMutablePointer<MainPass> = 
>> shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
>>              $0.pointee = mainPassFrameData
>>      }
>>         var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 
>> 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout< ObjectData 
>> >.size) {$0}
>> 
>> Latest conversion that make Xcode and Swift 3 smile again...
>> 
>>         let shadowPtr = constantBufferForFrame.contents().bindMemory(to: 
>> ShadowPass.self, capacity: shadowPassData.count)
>>         let mainPtr : UnsafeMutablePointer<MainPass> = 
>> shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) 
>> {$0}
>>         mainPtr.pointee = mainPassFrameData
>>         var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 
>> 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {$0}
>> 
>> Yes… Xcode/Swift3 SIL generation definitely did NOT like my "$0.pointee = 
>> mainPassFrameData" statement. 
>> Apparently, reassigning the pointee within the closure makes Swift gag out 
>> of disgust. Sorry ;-(
>> That’s what I get for trying to be fancy…
>> And fixed my “capacity” issues thanks to some previous posters.
>> 
>> Hope this helps anyone trying to get the Metal projects to compile again.
>> 
>> At least I got a Radar out of this ;-) Compilers should never burn and crash 
>> out like this...
>> 
>> Regards to all, Patrice
>> 
>> 
>>> On Sep 3, 2016, at 1:22 PM, Patrice Kouame via swift-users 
>>> <swift-users@swift.org> wrote:
>>> 
>>> Gerard- 
>>> 
>>> Excellent!  Looking forward to seeing your fix (hoping you get your book 
>>> back soon ;-) )
>>> 
>>> I think Xcode/Swift gags on the last ptr advance to objectData.  I recently 
>>> tried another variant using withUnsafeMutablePointer like this:
>>> 
>>>         var ptr : UnsafeMutablePointer<ObjectData>  = 
>>> withUnsafeMutablePointer(to: &mainPtr) {
>>>             $0.withMemoryRebound(to: ObjectData.self, capacity: 
>>> objectsToRender) {
>>>                 $0.pointee = renderables[0].objectData
>>>             }
>>>         }
>>> 
>>> ..but still crashes with no hints.
>>> 
>>> My bug report also mentions that the Xcode migration/conversion tool is 
>>> incomplete.  
>>> It handles the “simpler" UnsafeMutableRawPointer<X> to 
>>> UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to 
>>> mind the capacity value though)
>>> In all fairness, migrating/converting automagically in these cases is 
>>> always a little bit tricky - the proposed Xcode fixes should always be 
>>> reviewed by a human...
>>> 
>>> Patrice
>>> 
>>>> On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users 
>>>> <swift-users@swift.org> wrote:
>>>> 
>>>> Ok
>>>> 
>>>> For the record I succeeded this transformation phase last week
>>>> 
>>>> I remember the tedious stuff to advance pointer from one struct to the 
>>>> other kind of struct... it worked
>>>> 
>>>> But I don't have my MacBook with me, only the phone, the six :)
>>>> 
>>>> Gérard 
>>>> 
>>>> Le 3 sept. 2016 à 18:22, Patrice Kouame <pkou...@me.com> a écrit :
>>>> 
>>>>> Indeed. There is a difference between stride and size, but I interpreted 
>>>>> capacity incorrectly for my purposes.  It should indicate the number of 
>>>>> <T> elements (not their size - right?) and the snippets below should work.
>>>>> 
>>>>> Still, compiler crashes and Xcode IDE is left in inconsistent state.  So 
>>>>> I filed this Apple radar against Developer Tools.
>>>>> 
>>>>>   28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler 
>>>>> and IDE
>>>>> Should I file a Swift bug too? Would that be helpful?
>>>>> 
>>>>> Regards, Patrice
>>>>> 
>>>>>> On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users 
>>>>>> <swift-users@swift.org> wrote:
>>>>>> 
>>>>>> Hello,
>>>>>> 
>>>>>> I think that it is more secure to use stride in place of size, sometimes 
>>>>>> it is not the same value.
>>>>>> 
>>>>>> I use it in my own use of raw bindings 
>>>>>> 
>>>>>> Regards
>>>>>> 
>>>>>> Gérard 
>>>>>> 
>>>>>> Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users 
>>>>>> <swift-users@swift.org> a écrit :
>>>>>> 
>>>>>>> Hi Jacob - 
>>>>>>> 
>>>>>>> I think you’re right. “capacity” should be the count of type T elements 
>>>>>>> in my buffer.  So in my case that line should read
>>>>>>> 
>>>>>>>         let shadowPtr = 
>>>>>>> constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, 
>>>>>>> capacity: shadowPassData.count)
>>>>>>> 
>>>>>>> The withMemoryRebound calls need similar adjustments. The pointer to 
>>>>>>> MainPass is actually a single structure to it should be safe to do this
>>>>>>> 
>>>>>>>         let mainPtr : UnsafeMutablePointer<MainPass> = 
>>>>>>> shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, 
>>>>>>> capacity: 1) {
>>>>>>>             $0.pointee = mainPassFrameData
>>>>>>>         }
>>>>>>> 
>>>>>>> Whereas the unsafe pointer to <ObjectData> is actually a buffer of 
>>>>>>> renderable objects, so this should work:
>>>>>>> 
>>>>>>>         var ptr : UnsafeMutablePointer<ObjectData> = 
>>>>>>> mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, 
>>>>>>> capacity: objectsToRender) {_ in
>>>>>>>         }
>>>>>>> 
>>>>>>> There are surely ways to refactor and simplify this, but I’m trying to 
>>>>>>> retain as much of the original sample code approach as possible.
>>>>>>> 
>>>>>>> However, the compiler still segs badly. 
>>>>>>> Xcode also borks an internal error often. Only cleaning or restarting 
>>>>>>> the project can clear up that state.
>>>>>>> Compilers (or Playgrounds for that matter) should never crash, and I’m 
>>>>>>> not sure where to file this bug : Swift or Apple radar against Xcode or 
>>>>>>> both? I now Xcode 8 is beta but…it’s been doing this for quite a while 
>>>>>>> now...
>>>>>>> 
>>>>>>> In both our “close to the metal” (no pun intended) cases, it seems like 
>>>>>>> a lot of churning for very little gain. Don’t you think? The easier, 
>>>>>>> but “unsafe” casting afforded previously did the trick with the normal 
>>>>>>> caveats.
>>>>>>> Don’t get me wrong, I love Swift and “get" all the neat type safety 
>>>>>>> features. Guess we can’t have our cake and eat it too, especially when 
>>>>>>> interfacing with “unsafe” C APIs.
>>>>>>> 
>>>>>>> Anyway, back to rtfm … maybe some of the Swift Gods can chime in?  ;-) 
>>>>>>> 
>>>>>>> I must be doing something stupid...Patrice
>>>>>>> 
>>>>>>>> On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtban...@gmail.com> 
>>>>>>>> wrote:
>>>>>>>> 
>>>>>>>> Hi Patrice,
>>>>>>>> I don't have a solution for you, but I just wanted to point out what I 
>>>>>>>> think may be an error with your use of the new UnsafeRawPointer APIs:
>>>>>>>> 
>>>>>>>> constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, 
>>>>>>>> capacity: MemoryLayout<ShadowPass>.size)
>>>>>>>> 
>>>>>>>> I believe the `capacity` should actually be the number of ShadowPass 
>>>>>>>> elements in the buffer, not the size of each element. Using 
>>>>>>>> `bindMemory(to: ShadowPass.self` already implies that 
>>>>>>>> MemoryLayout<ShadowPass>.size is the size of each element.
>>>>>>>> 
>>>>>>>> More info at 
>>>>>>>> https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory
>>>>>>>> 
>>>>>>>> I just updated a small Metal project of mine to Swift 3. I ran into 
>>>>>>>> some compiler (playground) crashes, but it does seem to work most of 
>>>>>>>> the time. Although I only have 1 buffer :-) 
>>>>>>>> https://github.com/jtbandes/Metalbrot.playground
>>>>>>>> 
>>>>>>>> Jacob
>>>>>>>> 
>>>>>>>> On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users 
>>>>>>>> <swift-users@swift.org> wrote:
>>>>>>>> Hi all - 
>>>>>>>> 
>>>>>>>> I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and 
>>>>>>>> Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the 
>>>>>>>> latest UnsafeMutablePointer API for untyped memory access.  
>>>>>>>> Changes are necessary in MetalView.swift (Apple hasn’t updated their 
>>>>>>>> sample code for the latest beta yet…) 
>>>>>>>> The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:
>>>>>>>> 
>>>>>>>>         // Grab a pointer to the constant buffer's data store
>>>>>>>>         // Since we are using Swift, it is easier to cast the pointer 
>>>>>>>> to the ShadowPass type to fill the constant buffer
>>>>>>>>         // We need to make a copy of these so the block captures the 
>>>>>>>> correct data
>>>>>>>> 
>>>>>>>> //      let shadowPtr = 
>>>>>>>> UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
>>>>>>>>         let shadowPtr = 
>>>>>>>> constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, 
>>>>>>>> capacity: MemoryLayout<ShadowPass>.size)
>>>>>>>>         shadowPtr.pointee = shadowPassData[0]
>>>>>>>> 
>>>>>>>>         //More Swift specific stuff - advance pointer and cast to 
>>>>>>>> MainPass
>>>>>>>> 
>>>>>>>> //      let mainPtr = 
>>>>>>>> UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
>>>>>>>> //      mainPtr.pointee = mainPassFrameData
>>>>>>>>         let mainPtr : UnsafeMutablePointer<MainPass>  = 
>>>>>>>> shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, 
>>>>>>>> capacity: MemoryLayout<MainPass>.size) {
>>>>>>>>             $0.pointee = mainPassFrameData
>>>>>>>>         }
>>>>>>>>         
>>>>>>>>         //Advance and cast to ObjectData
>>>>>>>>         
>>>>>>>> //      var ptr = 
>>>>>>>> UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
>>>>>>>>         var ptr : UnsafeMutablePointer<ObjectData> = 
>>>>>>>> mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, 
>>>>>>>> capacity: MemoryLayout<ObjectData>.size) {_ in
>>>>>>>>         }
>>>>>>>> 
>>>>>>>>         let shadowOffset = 0
>>>>>>>>         let mainPassOffset = MemoryLayout<ShadowPass>.size + 
>>>>>>>> shadowOffset
>>>>>>>>         let objectDataOffset = MemoryLayout<MainPass>.size + 
>>>>>>>> mainPassOffset
>>>>>>>> 
>>>>>>>>         // Update position of all the objects
>>>>>>>>         if multithreadedUpdate {
>>>>>>>>             DispatchQueue.concurrentPerform(iterations: 
>>>>>>>> objectsToRender) { i in
>>>>>>>>                 let thisPtr = ptr.advanced(by: i)
>>>>>>>>                 _ = self.renderables[i].UpdateData(ptr, deltaTime: 
>>>>>>>> 1.0/60.0)
>>>>>>>>             }
>>>>>>>>         }
>>>>>>>>         else {
>>>>>>>>             for index in 0..<objectsToRender {
>>>>>>>>                 ptr = renderables[index].UpdateData(ptr, deltaTime: 
>>>>>>>> 1.0/60.0)
>>>>>>>>             }
>>>>>>>>         }
>>>>>>>>         
>>>>>>>>         ptr = ptr.advanced(by: objectsToRender)
>>>>>>>>         
>>>>>>>>         _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)
>>>>>>>> 
>>>>>>>> Any help is appreciated.  I have the latest Xcode log handy if 
>>>>>>>> necessary.  Here’s a clip of the stack trace.
>>>>>>>> 
>>>>>>>> 0  swift                    0x000000010714a99d 
>>>>>>>> PrintStackTraceSignalHandler(void*) + 45
>>>>>>>> 1  swift                    0x000000010714a3e6 SignalHandler(int) + 470
>>>>>>>> 2  libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
>>>>>>>> 3  libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
>>>>>>>> 4  swift                    0x00000001047207b3 (anonymous 
>>>>>>>> namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
>>>>>>>> 5  swift                    0x0000000104723ace (anonymous 
>>>>>>>> namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
>>>>>>>> 6  swift                    0x0000000104711cc1 
>>>>>>>> prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
>>>>>>>> 7  swift                    0x00000001047624e7 
>>>>>>>> swift::ASTVisitor<(anonymous namespace)::RValueEmitter, 
>>>>>>>> swift::Lowering::RValue, void, void, void, void, void, 
>>>>>>>> swift::Lowering::SGFContext>::visit(swift::Expr*, 
>>>>>>>> swift::Lowering::SGFContext) + 103
>>>>>>>> 8  swift                    0x0000000104762313 
>>>>>>>> swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, 
>>>>>>>> swift::Lowering::Initialization*) + 195
>>>>>>>> 9  swift                    0x000000010474fbc3 
>>>>>>>> swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*,
>>>>>>>>  unsigned int) + 195
>>>>>>>> 10 swift                    0x00000001047077bd 
>>>>>>>> swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, 
>>>>>>>> void, void, void>::visit(swift::Decl*) + 125
>>>>>>>> 11 swift                    0x00000001047c0019 
>>>>>>>> swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, 
>>>>>>>> void, void, void, void>::visit(swift::Stmt*) + 4169
>>>>>>>> 12 swift                    0x00000001047809ba 
>>>>>>>> swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
>>>>>>>> 13 swift                    0x00000001046fd775 
>>>>>>>> swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*)
>>>>>>>>  const + 1877
>>>>>>>> 14 swift                    0x00000001046fc322 
>>>>>>>> swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
>>>>>>>> 15 swift                    0x00000001047c7007 (anonymous 
>>>>>>>> namespace)::SILGenType::emitType() + 1271
>>>>>>>> 16 swift                    0x00000001047c6a9e 
>>>>>>>> swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*)
>>>>>>>>  + 30
>>>>>>>> 17 swift                    0x0000000104709093 
>>>>>>>> swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, 
>>>>>>>> unsigned int) + 1795
>>>>>>>> 18 swift                    0x000000010470ad4d 
>>>>>>>> swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, 
>>>>>>>> swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
>>>>>>>> 19 swift                    0x00000001045621bf 
>>>>>>>> performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, 
>>>>>>>> llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
>>>>>>>> 20 swift                    0x000000010455b2c5 
>>>>>>>> swift::performFrontend(llvm::ArrayRef<char const*>, char const*, 
>>>>>>>> void*, swift::FrontendObserver*) + 17029
>>>>>>>> 21 swift                    0x000000010451888d main + 8685
>>>>>>>> 22 libdyld.dylib            0x00007fff91255255 start + 1
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Patrice
>>>>>>>> 
>>>>>>>> 
>>>>>>>> _______________________________________________
>>>>>>>> swift-users mailing list
>>>>>>>> swift-users@swift.org
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>>>>> _______________________________________________
>>>>>>> swift-users mailing list
>>>>>>> swift-users@swift.org
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>>> _______________________________________________
>>>>>> swift-users mailing list
>>>>>> swift-users@swift.org
>>>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>> 
>>>> _______________________________________________
>>>> swift-users mailing list
>>>> swift-users@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>> 
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>> 
>> 
>> _______________________________________________
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>> 
>> 
> 
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to