                 # at the end of the try block branch to our branch_target (either the finally block or the merge block after the try{}) with REASON_FALLOFF
                 scope.exitAft false
 
+                scope.leave()
+
                 if scope.landing_pad_block?
                         # the scope's landingpad block is created if needed by @createCall (using that function we pass in as the last argument to TryExitableScope's ctor.)
                         # if a try block includes no calls, there's no need for an landing pad block as nothing can throw, and we don't bother generating any code for the
                         # catch clause.
                         console.log "have a landing pad block"
-                        ir.setInsertPoint scope.landing_pad_block
-
-                        # XXX is it an error to have multiple catch handlers, as JS doesn't allow you to filter by type?
-                        clause_count = if n.handlers.length > 0 then 1 else 0
-                        
-                        casted_personality = ir.createPointerCast @ejs_runtime.personality, types.int8Pointer, "personality"
-                        caught_result = ir.createLandingPad types.EjsValue.pointerTo(), casted_personality, clause_count, "caught_result"
-                        caught_result.addClause types.EjsValue.pointerTo() # this used to be '@ejs_runtime.exception_typeinfo'
-                        caught_result.setCleanup true
-                
-                        # if we have a catch clause, create catch_bb
-                        if n.handlers.length > 0
-                                catch_block = new llvm.BasicBlock "catch_bb", insertFunc
-                                ir.setInsertPoint catch_block
-
-                                # call _ejs_begin_catch
-                                catchval = ir.createCall @ejs_runtime.begin_catch, [(ir.createPointerCast caught_result, types.int8Pointer, "")], "catchval"
-
-                                # create a new scope which maps the catch parameter name (the "e" in try { } catch (e) { }) to catchval
-                                catch_scope = Object.create null
-                                if n.handlers[0].param?.name?
-                                        catch_name = n.handlers[0].param.name
-                                        alloca = @createAlloca @currentFunction, types.EjsValue, "local_catch_#{catch_name}"
-                                        catch_scope[catch_name] = alloca
-                                        ir.createStore catchval, alloca
-
-                                # and visit the handler with this scope active
-                                @visitWithScope catch_scope, [n.handlers[0]]
-
-                                # unsure about this one - we should likely call end_catch if another exception is thrown from the catch block?
-                                ir.createCall @ejs_runtime.end_catch, [], ""
-
-                                # if we make it to the end of the catch block, branch unconditionally to the branch target (either this try's
-                                # finally block or the merge pointer after the try)
-                                ir.createBr branch_target
-
-                        # Unwind Resume Block (calls _Unwind_Resume)
-                        unwind_resume_block = new llvm.BasicBlock "unwind_resume", insertFunc
-                        ir.setInsertPoint unwind_resume_block
-                        ir.createResume caught_result
-
-                        if catch_block?
-                                ir.createBr catch_block
-                        else if finally_block?
-                                ir.createBr finally_block
-                        else
-                                throw "this shouldn't happen.  a try{} without either a catch{} or finally{}"
-
-                scope.leave()
+                        @doInsideBlock scope.landing_pad_block, =>
+
+                                # XXX is it an error to have multiple catch handlers, as JS doesn't allow you to filter by type?
+                                clause_count = if n.handlers.length > 0 then 1 else 0
+                        
+                                casted_personality = ir.createPointerCast @ejs_runtime.personality, types.int8Pointer, "personality"
+                                caught_result = ir.createLandingPad types.EjsValue.pointerTo(), casted_personality, clause_count, "caught_result"
+                                caught_result.addClause @ejs_runtime.exception_typeinfo
+                                caught_result.setCleanup true
+
+                                # if we have a catch clause, create catch_bb
+                                if n.handlers.length > 0
+                                        catch_block = new llvm.BasicBlock "catch_bb", insertFunc
+                                        @doInsideBlock catch_block, =>
+                                                # call _ejs_begin_catch to return the actual exception
+                                                catchval = @beginCatch caught_result
+                                
+                                                # create a new scope which maps the catch parameter name (the "e" in "try { } catch (e) { }") to catchval
+                                                catch_scope = Object.create null
+                                                if n.handlers[0].param?.name?
+                                                        catch_name = n.handlers[0].param.name
+                                                        alloca = @createAlloca @currentFunction, types.EjsValue, "local_catch_#{catch_name}"
+                                                        catch_scope[catch_name] = alloca
+                                                        ir.createStore catchval, alloca
+
+                                                @visitWithScope catch_scope, [n.handlers[0]]
+
+                                                # unsure about this one - we should likely call end_catch if another exception is thrown from the catch block?
+                                                @endCatch()
+
+                                                # if we make it to the end of the catch block, branch unconditionally to the branch target (either this try's
+                                                # finally block or the merge pointer after the try)
+                                                ir.createBr branch_target
+
+                                ###
+                                # Unwind Resume Block (calls _Unwind_Resume)
+                                unwind_resume_block = new llvm.BasicBlock "unwind_resume", insertFunc
+                                @doInsideBlock unwind_resume_block, =>
+                                        ir.createResume caught_result
+                                ###
+
+                                if catch_block?
+                                        ir.createBr catch_block
+                                else if finally_block?
+                                        ir.createBr finally_block
+                                else
+                                        throw "this shouldn't happen.  a try{} without either a catch{} or finally{}"
 
                 # Finally Block
                 if n.finalizer?
-                        ir.setInsertPoint finally_block
-                        @visit n.finalizer
-
-                        cleanup_reason = @createLoad @currentFunction.cleanup_reason, "cleanup_reason_load"
-
-                        if @returnValueAlloca?
-                                return_tramp = new llvm.BasicBlock "return_tramp", insertFunc
-                                ir.setInsertPoint return_tramp
+                        @doInsideBlock finally_block, =>
+                                @visit n.finalizer
+
+                                cleanup_reason = @createLoad @currentFunction.cleanup_reason, "cleanup_reason_load"
+
+                                if @returnValueAlloca?
+                                        return_tramp = new llvm.BasicBlock "return_tramp", insertFunc
+                                        @doInsideBlock return_tramp, =>
                                 
-                                if @finallyStack.length > 0
-                                        ir.createStore (consts.int32 ExitableScope.REASON_RETURN), @currentFunction.cleanup_reason
-                                        ir.createBr @finallyStack[0]
-                                else
-                                        rv = @createLoad @returnValueAlloca, "rv"
-                                        ir.createRet rv
-                        
-                        ir.setInsertPoint finally_block
-                        switch_stmt = ir.createSwitch cleanup_reason, merge_block, scope.destinations.length + 1
-                        if @returnValueAlloca?
-                                switch_stmt.addCase (consts.int32 ExitableScope.REASON_RETURN), return_tramp
+                                        if @finallyStack.length > 0
+                                                ir.createStore (consts.int32 ExitableScope.REASON_RETURN), @currentFunction.cleanup_reason
+                                                ir.createBr @finallyStack[0]
+                                        else
+                                                rv = @createLoad @returnValueAlloca, "rv"
+                                                ir.createRet rv
+                        
+                                switch_stmt = ir.createSwitch cleanup_reason, merge_block, scope.destinations.length + 1
+                                if @returnValueAlloca?
+                                        switch_stmt.addCase (consts.int32 ExitableScope.REASON_RETURN), return_tramp
                         
                 console.log "done with try block"
                 ir.setInsertPoint merge_block

                                        num_alloca = @currentFunction.literalAllocas[literal_key]
                                else
                                        # only create 1 instance of num literals used in a function, and allocate them in the entry block
                                        insertBlock = ir.getInsertBlock()

                                        ir.setInsertPoint @currentFunction.entry_bb
                                        num_alloca = ir.createAlloca types.EjsValue, "num-alloca-#{n.value}"
                                        c = llvm.ConstantFP.getDouble n.value
                                        call = @createCall @ejs_runtime.number_new, [c], "numconst-#{n.value}"
                                        ir.createStore call, num_alloca
                                        @currentFunction.literalAllocas[literal_key] = num_alloca
                                        
                                        ir.setInsertPoint insertBlock
                                
                                numload = @createLoad num_alloca, "%num_alloca"
                        numload.literal = n
                        debug.log -> "numload = #{numload}"

                merge_bb  = new llvm.BasicBlock "forin_merge", insertFunc
                                
                ir.createBr forin_bb

                @doInsideBlock forin_bb, =>
                        moreleft = @createCall @ejs_runtime.prop_iterator_next, [iterator, consts.true()], "moreleft"
                        cmp = ir.createICmpEq moreleft, consts.false(), "cmpmoreleft"
                        ir.createCondBr cmp, merge_bb, body_bb

                @doInsideBlock body_bb, =>
                        current = @createCall @ejs_runtime.prop_iterator_current, [iterator], "iterator_current"
                        @storeValueInDest current, lhs
                        @visit n.body
                        ir.createBr forin_bb

                ir.setInsertPoint merge_bb
                merge_bb
