                         # if there were bound args we have to fall back to the runtime invoke method (since we can't
                         # guarantee enough room in our scratch area -- should we inline a check here or pass the length
                         # of the scratch area to decompose?  perhaps...FIXME)
-                        # 
-                        ir.setInsertPoint runtime_invoke_bb
-                        calltmp = @createCall @ejs_runtime.invoke_closure, argv, "calltmp"
-                        store = ir.createStore calltmp, call_result
-                        ir.createBr invoke_merge_bb
+                        #
+                        @doInsideBlock runtime_invoke_bb, =>
+                                calltmp = @createCall @ejs_runtime.invoke_closure, argv, "calltmp"
+                                store = ir.createStore calltmp, call_result
+                                ir.createBr invoke_merge_bb
 
                         # in the successful case we modify our argv with the responses and directly invoke the closure func
-                        ir.setInsertPoint direct_invoke_bb
-                        direct_args = [ (@createLoad env_alloca, "env"), (@createLoad this_alloca, "this"), argv[2], argv[3] ]
-                        calltmp = @createCall (@createLoad func_alloca, "func"), direct_args, "calltmp"
-                        store = ir.createStore calltmp, call_result
-                        ir.createBr invoke_merge_bb
+                        @doInsideBlock direct_invoke_bb, =>
+                                direct_args = [ (@createLoad env_alloca, "env"), (@createLoad this_alloca, "this"), argv[2], argv[3] ]
+                                calltmp = @createCall (@createLoad func_alloca, "func"), direct_args, "calltmp"
+                                store = ir.createStore calltmp, call_result
+                                ir.createBr invoke_merge_bb
 
                         ir.setInsertPoint invoke_merge_bb
                 else

                merge_bb = new llvm.BasicBlock "while_merge", insertFunc

                ir.createBr while_bb
                ir.setInsertPoint while_bb
                
                cond_truthy = @createCall @ejs_runtime.truthy, [@visit(n.test)], "cond_truthy"
                cmp = ir.createICmpEq cond_truthy, consts.false(), "cmpresult"
                
                ir.createCondBr cmp, merge_bb, body_bb

                scope = new LoopExitableScope n.label, while_bb, merge_bb
                scope.enter()
                
                ir.setInsertPoint body_bb
                @visit n.body
                ir.createBr while_bb

                scope.leave()
                                

                # 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"
                        @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?
                        @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
                        
                                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
