<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Ok, I see. <div class=""><br class=""></div><div class="">But <b class="">with</b><b class="">MemoryRebound</b> requires a return value. Don’t think there’s any way around that…compiler error<div class=""><span class="">And mainPtr (now typed correctly/safely) needs to access the appropriate data structure mainPassFrameData.</span></div><div class=""><span class="">Hence the external mainPtr.pointee assignment (since I can’t do so safely within the closure -> Swift compiler crashes)</span></div><div class=""><br class=""></div><div class="">Gerard Iglesias crafted another version of this snippet of code using <b class="">assumingMemoryBound </b>but also assigns pointee externally.</div><div class="">So did the original sample code.</div><div class=""><br class=""></div><div class="">Haven’t we achieved the goal of “safely" re-typing raw memory on the fly? To "help the compiler help us" so to speak…</div><div class="">What do you believe is so “unsafe" about the external pointee assignment? Since the compiler won’t let us do so anymore </div><div class="">If the types aren’t all correctly aligned.</div><div class=""><br class=""></div><div class="">Curious to see what Andrew Trick has to say about all of this. Good idea to cc: him</div><div class=""><br class=""></div><div class="">In the meantime, both versions seem to work. Plus am learning a lot about typed versus untyped memory access in Swift...</div><div class=""><br class=""></div><div class="">Best - Patrice</div><div class=""><span class=""><br class="">On Sep 3, 2016, at 9:27 PM, Jacob Bandes-Storch via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:<br class=""><blockquote type="cite" class=""><br class="">I was referring to this:<br class=""><br class=""> let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}<br class=""> mainPtr.pointee = mainPassFrameData<br class=""><br class="">The result of $0 is being returned from the block and used later.<br class=""><br class="">cc'ing Andrew Trick on this conversation because his input would be quite useful :-)<br class=""><br class="">Jacob<br class=""><br class="">On Sat, Sep 3, 2016 at 2:03 PM, Patrice Kouame <<a href="mailto:pkouame@me.com" class="">pkouame@me.com</a>> wrote:<br class=""><br class="">Not sure what you mean? <br class="">The positional arg $0 is never used outside the closure whatever the version...<br class="">No attempt is ever made to save and reuse after withMemoryRebound?<br class="">Why would I use a separate function?<br class=""><br class="">Are we looking at the same code? 🤓<br class=""><br class="">rédigé sur mon iPhone.<br class=""><br class="">On Sep 3, 2016, at 4:16 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:<br class=""><br class=""><blockquote type="cite" class="">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?<br class=""><br class="">On Sat, Sep 3, 2016 at 1:12 PM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:<br class="">Finally Success! I’m seeing my pretty little 3D twirling Metal Renderer cubes again… Here’s how<br class=""><br class="">Snippet of old sample code which no longer compiles in Xcode 8 beta 6 with stricter Swift3 unsafe type casting restrictions <br class="">(in MetalView.swift from # Adopting Metal II: Designing and Implementing a Real-World Metal Renderer)<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>mainPtr.pointee = mainPassFrameData<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))<br class=""><br class="">My conversion attempt that crashes Swift 3 Xcode 8 beta 6 (see RADAR 28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE)<br class=""><br class=""> let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<shadowPassData>.size)<br class=""> let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {<br class=""><span class="Apple-tab-span" style="white-space:pre">                </span>$0.pointee = mainPassFrameData<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""> var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout< ObjectData >.size) {$0}<br class=""><br class="">Latest conversion that make Xcode and Swift 3 smile again...<br class=""><br class=""> let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)<br class=""> let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}<br class=""> mainPtr.pointee = mainPassFrameData<br class=""> var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {$0}<br class=""><br class="">Yes… Xcode/Swift3 SIL generation definitely did NOT like my "$0.pointee = mainPassFrameData" statement. <br class="">Apparently, reassigning the pointee within the closure makes Swift gag out of disgust. Sorry ;-(<br class="">That’s what I get for trying to be fancy…<br class="">And fixed my “capacity” issues thanks to some previous posters.<br class=""><br class="">Hope this helps anyone trying to get the Metal projects to compile again.<br class=""><br class="">At least I got a Radar out of this ;-) Compilers should never burn and crash out like this...<br class=""><br class="">Regards to all, Patrice<br class=""><br class=""><br class=""><blockquote type="cite" class="">On Sep 3, 2016, at 1:22 PM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:<br class=""><br class="">Gerard- <br class=""><br class="">Excellent! Looking forward to seeing your fix (hoping you get your book back soon ;-) )<br class=""><br class="">I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:<br class=""><br class=""> var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {<br class=""> $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {<br class=""> $0.pointee = renderables[0].objectData<br class=""> }<br class=""> }<br class=""><br class="">..but still crashes with no hints.<br class=""><br class="">My bug report also mentions that the Xcode migration/conversion tool is incomplete. <br class="">It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)<br class="">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...<br class=""><br class="">Patrice<br class=""><br class=""><blockquote type="cite" class="">On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:<br class=""><br class="">Ok<br class=""><br class="">For the record I succeeded this transformation phase last week<br class=""><br class="">I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked<br class=""><br class="">But I don't have my MacBook with me, only the phone, the six :)<br class=""><br class="">Gérard <br class=""><br class="">Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com> a écrit :<br class=""><br class=""><blockquote type="cite" class="">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.<br class=""><br class="">Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE<br class="">Should I file a Swift bug too? Would that be helpful?<br class=""><br class="">Regards, Patrice<br class=""><br class=""><blockquote type="cite" class="">On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:<br class=""><br class="">Hello,<br class=""><br class="">I think that it is more secure to use stride in place of size, sometimes it is not the same value.<br class=""><br class="">I use it in my own use of raw bindings <br class=""><br class="">Regards<br class=""><br class="">Gérard <br class=""><br class="">Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org> a écrit :<br class=""><br class=""><blockquote type="cite" class="">Hi Jacob - <br class=""><br class="">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<br class=""><br class=""> let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)<br class=""><br class="">The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this<br class=""><br class=""> let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {<br class=""> $0.pointee = mainPassFrameData<br class=""> }<br class=""><br class="">Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:<br class=""><br class=""> var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><br class="">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.<br class=""><br class="">However, the compiler still segs badly. <br class="">Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.<br class="">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...<br class=""><br class="">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.<br class="">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.<br class=""><br class="">Anyway, back to rtfm … maybe some of the Swift Gods can chime in? ;-) <br class=""><br class="">I must be doing something stupid...Patrice<br class=""><br class=""><blockquote type="cite" class="">On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:<br class=""><br class="">Hi Patrice,<br class="">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:<br class=""><br class="">constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)<br class=""><br class="">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.<br class=""><br class="">More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory<br class=""><br class="">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<br class=""><br class="">Jacob<br class=""><br class="">On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:<br class="">Hi all - <br class=""><br class="">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. <br class="">Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…) <br class="">The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:<br class=""><br class=""> // Grab a pointer to the constant buffer's data store<br class=""> // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer<br class=""> // We need to make a copy of these so the block captures the correct data<br class=""><br class="">// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())<br class=""> let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)<br class=""> shadowPtr.pointee = shadowPassData[0]<br class=""><br class=""> //More Swift specific stuff - advance pointer and cast to MainPass<br class=""><br class="">// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))<br class="">// mainPtr.pointee = mainPassFrameData<br class=""> let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {<br class=""> $0.pointee = mainPassFrameData<br class=""> }<br class=""> <br class=""> //Advance and cast to ObjectData<br class=""> <br class="">// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))<br class=""> var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in<br class=""> }<br class=""><br class=""> let shadowOffset = 0<br class=""> let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset<br class=""> let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset<br class=""><br class=""> // Update position of all the objects<br class=""> if multithreadedUpdate {<br class=""> DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in<br class=""> let thisPtr = ptr.advanced(by: i)<br class=""> _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)<br class=""> }<br class=""> }<br class=""> else {<br class=""> for index in 0..<objectsToRender {<br class=""> ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)<br class=""> }<br class=""> }<br class=""> <br class=""> ptr = ptr.advanced(by: objectsToRender)<br class=""> <br class=""> _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)<br class=""><br class="">Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.<br class=""><br class="">0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45<br class="">1 swift 0x000000010714a3e6 SignalHandler(int) + 470<br class="">2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26<br class="">3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384<br class="">4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51<br class="">5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182<br class="">6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273<br class="">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<br class="">8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195<br class="">9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195<br class="">10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125<br class="">11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169<br class="">12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314<br class="">13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877<br class="">14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626<br class="">15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271<br class="">16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30<br class="">17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795<br class="">18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629<br class="">19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487<br class="">20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029<br class="">21 swift 0x000000010451888d main + 8685<br class="">22 libdyld.dylib 0x00007fff91255255 start + 1<br class=""><br class=""><br class="">Patrice<br class=""><br class=""><br class="">_______________________________________________<br class="">swift-users mailing list<br class="">swift-users@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""><br class=""><br class=""></blockquote><br class=""></blockquote><blockquote type="cite" class="">_______________________________________________<br class="">swift-users mailing list<br class="">swift-users@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></blockquote>_______________________________________________<br class="">swift-users mailing list<br class="">swift-users@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></blockquote><br class=""></blockquote>_______________________________________________<br class="">swift-users mailing list<br class="">swift-users@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></blockquote><br class="">_______________________________________________<br class="">swift-users mailing list<br class="">swift-users@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></blockquote><br class=""><br class="">_______________________________________________<br class="">swift-users mailing list<br class="">swift-users@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""><br class=""><br class=""></blockquote><br class="">_______________________________________________<br class="">swift-users mailing list<br class="">swift-users@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></blockquote><br class=""></span></div></div></body></html>