Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit05ff126

Browse files
committed
Script debugging in VS
See spec athttps://gist.github.com/latkin/cba4187a99db9747d0bfclosesdotnet#225commitb8ea6f6Author: latkin <latkin@microsoft.com>Date: Tue Feb 24 17:12:04 2015 -0800 Touch-ups after rebasecommit26ff245Author: latkin <latkin@microsoft.com>Date: Wed Feb 18 12:54:36 2015 -0800 Add capability to auto-break on first executable linecommit675a272Author: latkin <latkin@microsoft.com>Date: Wed Feb 18 12:53:27 2015 -0800 Change menu text, use more sensible hotkeyscommitab73f78Author: latkin <latkin@microsoft.com>Date: Wed Feb 18 12:52:39 2015 -0800 Small whitespace alignmentcommitf551344Author: latkin <latkin@microsoft.com>Date: Thu Feb 12 19:29:16 2015 -0800 Output symbol info for localscommitd6a0faaAuthor: latkin <latkin@microsoft.com>Date: Thu Feb 12 18:00:14 2015 -0800 Use same whitespace style as existing codecommita4003c1Author: latkin <latkin@microsoft.com>Date: Wed Feb 11 11:06:22 2015 -0800 Add 'detach' item for tool window, and give 'attach'/'detach' smart visibilitycommitc5a6460Author: latkin <latkin@microsoft.com>Date: Wed Feb 11 07:39:34 2015 -0800 Enable basic script debugging
1 parent959b10f commit05ff126

File tree

14 files changed

+361
-202
lines changed

14 files changed

+361
-202
lines changed

‎src/absil/il.fs‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,8 @@ and ILFilterBlock =
11851185
[<NoComparison; NoEquality>]
11861186
typeILLocal=
11871187
{ Type:ILType;
1188-
IsPinned:bool}
1188+
IsPinned:bool;
1189+
DebugInfo:(string* int* int) option}
11891190

11901191
typeILLocals= ILList<ILLocal>
11911192
letemptyILLocals=(ILList.empty: ILLocals)
@@ -3022,9 +3023,10 @@ let mkILReturn ty : ILReturn =
30223023
Type=ty;
30233024
CustomAttrs=emptyILCustomAttrs}
30243025

3025-
letmkILLocal ty=
3026+
letmkILLocal tydbgInfo=
30263027
{ IsPinned=false;
3027-
Type=ty;}
3028+
Type=ty;
3029+
DebugInfo=dbgInfo}
30283030

30293031
typeILFieldSpecwith
30303032
memberfr.ActualType=

‎src/absil/il.fsi‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,8 @@ type ILNativeType =
970970
[<NoComparison; NoEquality>]
971971
typeILLocal=
972972
{ Type:ILType;
973-
IsPinned:bool}
973+
IsPinned:bool;
974+
DebugInfo:(string* int* int) option}
974975

975976

976977
typeILLocals= ILList<ILLocal>
@@ -1955,7 +1956,7 @@ val mkILParam: string option * ILType -> ILParameter
19551956
val mkILParamAnon: ILType-> ILParameter
19561957
val mkILParamNamed: string* ILType-> ILParameter
19571958
val mkILReturn: ILType-> ILReturn
1958-
val mkILLocal: ILType-> ILLocal
1959+
val mkILLocal: ILType->(string* int* int) option->ILLocal
19591960
val mkILLocals: ILLocal list-> ILLocals
19601961
val emptyILLocals: ILLocals
19611962

‎src/absil/ilread.fs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2206,7 +2206,8 @@ and sigptrGetLocal ctxt numtypars bytes sigptr =
22062206
false, sigptr
22072207
lettyp,sigptr= sigptrGetTy ctxt numtypars bytes sigptr
22082208
{ IsPinned= pinned;
2209-
Type= typ}, sigptr
2209+
Type= typ;
2210+
DebugInfo= None}, sigptr
22102211

22112212
andreadBlobHeapAsMethodSig ctxt numtypars blobIdx=
22122213
ctxt.readBlobHeapAsMethodSig(BlobAsMethodSigIdx(numtypars,blobIdx))

‎src/absil/ilreflect.fs‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,11 @@ let emitCode cenv modB emEnv (ilG:ILGenerator) code =
12521252

12531253
letemitLocal cenv emEnv(ilG:ILGenerator)(local:ILLocal)=
12541254
letty= convType cenv emEnv local.Type
1255-
ilG.DeclareLocalAndLog(ty,local.IsPinned)
1255+
letlocBuilder= ilG.DeclareLocalAndLog(ty, local.IsPinned)
1256+
match local.DebugInfowith
1257+
| Some(nm, start, finish)-> locBuilder.SetLocalSymInfo(nm, start, finish)
1258+
| None->()
1259+
locBuilder
12561260

12571261
letemitILMethodBody cenv modB emEnv(ilG:ILGenerator)ilmbody=
12581262
// XXX - REVIEW:

‎src/fsharp/fsi/fsi.fs‎

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,8 @@ type internal FsiDynamicCompilerState =
733733
tcState:Build.TcState
734734
ilxGenerator:Ilxgen.IlxAssemblyGenerator
735735
// Why is this not in FsiOptions?
736-
timing:bool}
736+
timing:bool
737+
debugBreak:bool}
737738

738739
letinternalWithImplicitHome(tcConfigB,dir)f=
739740
letold= tcConfigB.implicitIncludeDir
@@ -986,13 +987,22 @@ type internal FsiDynamicCompiler
986987
letmkBind pat expr= Binding(None, DoBinding,false,(*mutable*)false,[], PreXmlDoc.Empty, SynInfo.emptySynValData, pat, None, expr, m, NoSequencePointAtInvisibleBinding)
987988
letbindingA= mkBind(mkSynPatVar None itID) expr(* let it = <expr>*)// NOTE: the generalizability of 'expr' must not be damaged, e.g. this can't be an application
988989
letsaverPath=["Microsoft";"FSharp";"Compiler";"Interactive";"RuntimeHelpers";"SaveIt"]
989-
letdots= List.replicate(saverPath.Length-1)rangeStdin
990-
letbindingB= mkBind(SynPat.Wild m)(SynExpr.App(ExprAtomicFlag.NonAtomic,false, SynExpr.LongIdent(false, LongIdentWithDots(List.map(mkSynIdrangeStdin) saverPath,dots),None,m), itExp,m))(* let _ = saverPath it*)
990+
letdots= List.replicate(saverPath.Length-1)m
991+
letbindingB= mkBind(SynPat.Wild m)(SynExpr.App(ExprAtomicFlag.NonAtomic,false, SynExpr.LongIdent(false, LongIdentWithDots(List.map(mkSynIdm) saverPath,dots),None,m), itExp,m))(* let _ = saverPath it*)
991992
letdefA= SynModuleDecl.Let(false,[bindingA], m)
992993
letdefB= SynModuleDecl.Let(false,[bindingB], m)
993994

994995
[defA; defB]
995996

997+
// construct an invisible call to Debugger.Break(), in the specified range
998+
member__.CreateDebuggerBreak(m:range)=
999+
letbreakPath=["System";"Diagnostics";"Debugger";"Break"]
1000+
letdots= List.replicate(breakPath.Length-1) m
1001+
letmethCall= SynExpr.LongIdent(false, LongIdentWithDots(List.map(mkSynId m) breakPath, dots), None, m)
1002+
letargs= SynExpr.Const(SynConst.Unit, m)
1003+
letbreakStatement= SynExpr.App(ExprAtomicFlag.Atomic,false, methCall, args, m)
1004+
SynModuleDecl.DoExpr(SequencePointInfoForBinding.NoSequencePointAtDoBinding, breakStatement, m)
1005+
9961006
member__.EvalRequireReference istate m path=
9971007
if Path.IsInvalidPath(path)then
9981008
error(Error(FSIstrings.SR.fsiInvalidAssembly(path),m))
@@ -1080,6 +1090,7 @@ type internal FsiDynamicCompiler
10801090
tcState= tcState;
10811091
ilxGenerator= ilxGenerator;
10821092
timing=false;
1093+
debugBreak=false;
10831094
}
10841095

10851096

@@ -1619,7 +1630,10 @@ type internal FsiInteractionProcessor
16191630
| IHash(ParsedHashDirective("silentCd",[path],m),_)->
16201631
ChangeDirectory path m;
16211632
fsiConsolePrompt.SkipNext();(* "silent" directive*)
1622-
istate,Completed
1633+
istate,Completed
1634+
1635+
| IHash(ParsedHashDirective("dbgbreak",[],_),_)->
1636+
{istatewith debugBreak=true},Completed
16231637

16241638
| IHash(ParsedHashDirective("time",[],_),_)->
16251639
if istate.timingthen
@@ -1678,27 +1692,45 @@ type internal FsiInteractionProcessor
16781692
/// #directive comes through with other definitions as a SynModuleDecl.HashDirective.
16791693
/// We split these out for individual processing.
16801694
let recExecInteractions(exitViaKillThread,tcConfig,istate,action:ParsedFsiInteraction option)=
1681-
letaction,nextAction=
1695+
letaction,nextAction,istate=
16821696
match actionwith
1683-
| None-> None,None
1684-
| Some(IHash_)-> action,None
1685-
| Some(IDefns([],_))-> None,None
1697+
| None-> None,None,istate
1698+
| Some(IHash_)-> action,None,istate
1699+
| Some(IDefns([],_))-> None,None,istate
16861700
| Some(IDefns(SynModuleDecl.HashDirective(hash,mh)::defs,m))->
1687-
Some(IHash(hash,mh)),Some(IDefns(defs,m))
1701+
Some(IHash(hash,mh)),Some(IDefns(defs,m)),istate
16881702

16891703
| Some(IDefns(defs,m))->
16901704
letisDefHash=function SynModuleDecl.HashDirective(_,_)->true|_->false
1705+
letisBreakable def=
1706+
// only add automatic debugger breaks before 'let' or 'do' expressions with sequence points
1707+
match defwith
1708+
| SynModuleDecl.DoExpr(SequencePointInfoForBinding.SequencePointAtBinding_,_,_)
1709+
| SynModuleDecl.Let(_, SynBinding.Binding(_,_,_,_,_,_,_,_,_,_,_, SequencePointInfoForBinding.SequencePointAtBinding_)::_,_)->true
1710+
|_->false
16911711
letdefsA= Seq.takeWhile(isDefHash>>not) defs|> Seq.toList
16921712
letdefsB= Seq.skipWhile(isDefHash>>not) defs|> Seq.toList
16931713

1714+
// If user is debugging their script interactively, inject call
1715+
// to Debugger.Break() at the first "breakable" line.
1716+
// Update istate so that more Break() calls aren't injected when recursing
1717+
letdefsA,istate=
1718+
if istate.debugBreakthen
1719+
letpreBreak= Seq.takeWhile(isBreakable>>not) defsA|> Seq.toList
1720+
letpostBreak= Seq.skipWhile(isBreakable>>not) defsA|> Seq.toList
1721+
match postBreakwith
1722+
| h::_-> preBreak@(fsiDynamicCompiler.CreateDebuggerBreak(h.Range):: postBreak),{ istatewith debugBreak=false}
1723+
|_-> defsA, istate
1724+
else defsA,istate
1725+
16941726
// When the last declaration has a shape of DoExp (i.e., non-binding),
16951727
// transform it to a shape of "let it = <exp>", so we can refer it.
16961728
letdefsA=if defsA.Length<=1|| defsB.Length>0then defsAelse
16971729
match List.headAndTail(List.rev defsA)with
16981730
| SynModuleDecl.DoExpr(_,exp,_), rest->(rest|> List.rev)@(fsiDynamicCompiler.BuildItBinding exp)
16991731
|_-> defsA
17001732

1701-
Some(IDefns(defsA,m)),Some(IDefns(defsB,m))
1733+
Some(IDefns(defsA,m)),Some(IDefns(defsB,m)),istate
17021734

17031735
match actionwith
17041736
| None->assert(nextAction.IsNone); istate,Completed

‎src/fsharp/ilxgen.fs‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ let discardAndReturnVoid = DiscardThen ReturnVoid
15341534
// the bodies of methods in a couple of places
15351535
//-------------------------------------------------------------------------
15361536

1537-
letCodeGenThen mgbuf(zapFirstSeqPointToStart,entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,codeGenFunction,m)=
1537+
letCodeGenThencenvmgbuf(zapFirstSeqPointToStart,entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,codeGenFunction,m)=
15381538
letcgbuf=new CodeGenBuffer(m,mgbuf,methodName,alreadyUsedArgs,alreadyUsedLocals,zapFirstSeqPointToStart)
15391539
letstart= CG.GenerateMark cgbuf"mstart"
15401540
letinnerVals= entryPointInfo|> List.map(fun(v,kind)->(v,(kind,start)))
@@ -1554,7 +1554,21 @@ let CodeGenThen mgbuf (zapFirstSeqPointToStart,entryPointInfo,methodName,eenv,al
15541554
{ locRange=(start.CodeLabel, finish.CodeLabel);
15551555
locInfos=[{ LocalIndex=i; LocalName=nm}]})
15561556

1557-
(List.map(snd>> mkILLocal) locals,
1557+
letilLocals=
1558+
locals
1559+
|> List.map(fun(infos,ty)->
1560+
// in interactive environment, attach name and range info to locals to improve debug experience
1561+
if cenv.opts.isInteractive&& cenv.opts.generateDebugSymbolsthen
1562+
match infoswith
1563+
|[(nm,(start, finish))]-> mkILLocal ty(Some(nm, start.CodeLabel, finish.CodeLabel))
1564+
// REVIEW: what do these cases represent?
1565+
|_::_
1566+
|[]-> mkILLocal ty None
1567+
// if not interactive, don't bother adding this info
1568+
else
1569+
mkILLocal ty None)
1570+
1571+
(ilLocals,
15581572
maxStack,
15591573
computeCodeLabelToPC,
15601574
code,
@@ -1566,7 +1580,7 @@ let CodeGenMethod cenv mgbuf (zapFirstSeqPointToStart,entryPointInfo,methodName,
15661580
(* Codegen the method. REVIEW: change this to generate the AbsIL code tree directly...*)
15671581

15681582
letlocals,maxStack,computeCodeLabelToPC,instrs,exns,localDebugSpecs,hasSequencePoints=
1569-
CodeGenThen mgbuf(zapFirstSeqPointToStart,entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,codeGenFunction,m)
1583+
CodeGenThencenvmgbuf(zapFirstSeqPointToStart,entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,codeGenFunction,m)
15701584

15711585
letdump()=
15721586
instrs|> Array.iteri(fun i instr-> dprintf"%s:%d:%A\n" methodName i instr);

‎src/fsharp/vs/ServiceLexing.fs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ type internal LineTokenizer(text:string,
733733
|true,"I"
734734
|true,"load"
735735
|true,"time"
736+
|true,"dbgbreak"
736737
|true,"cd"
737738
#if DEBUG
738739
|true,"terms"

‎src/ilx/cu_erase.fs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ let rec convInstr cenv (tmps: ILLocalsAllocator) inplab outlab instr =
377377
InstrMorph[ AI_pop;(AI_ldc(DT_I4, ILConst.I40))]
378378
| RuntimeTypes->
379379
letbaseTy= baseTyOfUnionSpec cuspec
380-
letlocn= tmps.AllocLocal(mkILLocal baseTy)
380+
letlocn= tmps.AllocLocal(mkILLocal baseTy None)
381381

382382
letmkCase last inplab cidx failLab=
383383
letalt= altOfUnionSpec cuspec cidx
@@ -495,7 +495,7 @@ let rec convInstr cenv (tmps: ILLocalsAllocator) inplab outlab instr =
495495

496496
match cuspecRepr.DiscriminationTechnique cuspecwith
497497
| RuntimeTypes->
498-
letlocn= tmps.AllocLocal(mkILLocal baseTy)
498+
letlocn= tmps.AllocLocal(mkILLocal baseTy None)
499499
letmkCase _last inplab(cidx,tg)failLab=
500500
letalt= altOfUnionSpec cuspec cidx
501501
letaltTy= tyForAlt cuspec alt

‎src/ilx/pubclo.fs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ let rec convInstr cenv (tmps: ILLocalsAllocator, thisGenParams: ILGenericParamet
226226
| Apps_app(arg,rest)->
227227
letstorers,loaders= unwind rest
228228
letargStorers,argLoaders=
229-
letlocn= tmps.AllocLocal(mkILLocal arg)
229+
letlocn= tmps.AllocLocal(mkILLocal arg None)
230230
[mkStloc locn],[mkLdloc locn]
231231
argStorers:: storers, argLoaders:: loaders
232232
| Apps_done_->
@@ -348,7 +348,7 @@ let mkILFreeVarForParam (p : ILParameter) =
348348
letnm=(match p.Namewith Some x-> x| None-> failwith"closure parameters must be given names")
349349
mkILFreeVar(nm,false,p.Type)
350350

351-
letmkILLocalForFreeVar(p:IlxClosureFreeVar)= mkILLocal p.fvType
351+
letmkILLocalForFreeVar(p:IlxClosureFreeVar)= mkILLocal p.fvType None
352352

353353
letmkILCloFldSpecs _cenv flds=
354354
flds|> Array.map(fun fv->(fv.fvName,fv.fvType))|> Array.toList

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp