diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f8ff86b0296..736169849aa1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,9 @@ on: push: # Empty configuration means use default (ie. test all branches) branches-ignore: + # Everything would have passed bors before going into devel + - devel + # Bors temporary branches - staging.tmp - trying.tmp - staging-squash-merge.tmp @@ -265,24 +268,22 @@ jobs: - name: Build docs run: | - branch=${{ github.ref }} - # Remove refs/heads/ prefix - branch=${branch##*/} - ./koch.py doc \ --git.url:'https://github.com/${{ github.repository }}' \ --git.commit:'${{ github.sha }}' \ - --git.devel:"$branch" + --git.devel:devel + + # Remove leftover nimcache + rm -rf doc/html/nimcache - - name: Publish - if: | - github.event_name == 'push' && github.ref == 'refs/heads/devel' && - matrix.target.publish_docs - uses: crazy-max/ghaction-github-pages@v2.6.0 + - name: Publish to artifacts + if: matrix.target.publish_docs + uses: actions/upload-artifact@v2.3.1 with: - build_dir: doc/html - env: - GITHUB_TOKEN: ${{ github.token }} + # If this name is updated, tweak publisher.yml + name: Generated docs + path: doc/html/ + if-no-files-found: error passed: name: All check passed diff --git a/.github/workflows/publisher.yml b/.github/workflows/publisher.yml new file mode 100644 index 000000000000..d6bbb83adba6 --- /dev/null +++ b/.github/workflows/publisher.yml @@ -0,0 +1,39 @@ +name: Publish built artifacts +on: + push: + branches: + - devel + +# Run every script actions in bash +defaults: + run: + shell: bash + +# Since we will be pushing, make sure that only one instance can run at a time. +concurrency: publisher + +jobs: + publisher: + runs-on: ubuntu-latest + + steps: + # Publish action needs a checkout + - uses: actions/checkout@v2.4.0 + + # Download the latest instance of generated documentation from the build + # during bors staging. + - name: Download generated docs + uses: dawidd6/action-download-artifact@v2.16.0 + with: + workflow: ci.yml + workflow_conclusion: completed + commit: ${{ github.event.after }} + # Keep up-to-date with ci.yml + name: Generated docs + path: doc/html + + - name: Publish docs + uses: JamesIves/github-pages-deploy-action@v4.2.2 + with: + branch: gh-pages + folder: doc/html diff --git a/compiler/ast/lineinfos.nim b/compiler/ast/lineinfos.nim index 78a305f426db..ba0d8a7a17ed 100644 --- a/compiler/ast/lineinfos.nim +++ b/compiler/ast/lineinfos.nim @@ -58,9 +58,13 @@ proc computeNotesVerbosity(): tuple[ # debug report for transition of the configuration options result.base.incl {rdbgOptionsPush, rdbgOptionsPop} - when defined(nimVMDebug): + when defined(nimVMDebugExecute): + result.base.incl { + rdbgVmExecTraceFull # execution of the generated code listings + } + + when defined(nimVMDebugGenerate): result.base.incl { - rdbgVmExecTraceFull, # execution of the generated code listings rdbgVmCodeListing # immediately generated code listings } diff --git a/compiler/front/cli_reporter.nim b/compiler/front/cli_reporter.nim index aab7936854c4..34f583f8d356 100644 --- a/compiler/front/cli_reporter.nim +++ b/compiler/front/cli_reporter.nim @@ -19,7 +19,8 @@ import strformat, tables, intsets, - json + json, + strtabs ], ast/[ lineinfos, @@ -101,7 +102,7 @@ proc formatPath(conf: ConfigRef, path: string): string = when compileOption"excessiveStackTrace": # instLoc(), when `--excessiveStackTrace` is used, generates full # paths that /might/ need to be filtered if `--filenames:canonical`. - const compilerRoot = currentSourcePath().parentDir() + const compilerRoot = currentSourcePath().parentDir().parentDir() if conf.filenameOption == foCanonical and path.startsWith(compilerRoot): result = path[(compilerRoot.len + 1) .. ^1] @@ -3170,43 +3171,60 @@ proc reportBody*(conf: ConfigRef, r: DebugReport): string = result = "cfg trace '" & r.str & "'" of rdbgVmCodeListing: + result.add "Code listing" + let l = r.vmgenListing + if not l.sym.isNil(): + result.addf( + " for the '$#' $#\n\n", + l.sym.name.s, + conf.toStr(l.sym.info)) + + else: + result.add "\n\n" + for e in r.vmgenListing.entries: if e.isTarget: - result.add("L:\n", e.pc) + result.add("L:", e.pc, "\n") + func `$<`[T](arg: T): string = alignLeft($arg, 5) + func `$<`(opc: TOpcode): string = alignLeft(opc.toStr, 12) + + var line: string case e.opc: of {opcIndCall, opcIndCallAsgn}: - result.addf("\t$#\tr$#, r$#, nargs:$#", e.opc, e.ra, e.rb, e.rc) + line.addf(" $# r$# r$# #$#", $>] trace start + #0]> semExpr @ sem/semexprs.nim(2948, 21) from sem/semstmts.nim(2446, 1) + #1] > semOverloadedCallAnalyseEffects @ sem/semexprs.nim(941, 21) from sem/semexprs.nim(1133, 1) + #2] > semOverloadedCall @ sem/semcall.nim(569, 21) from sem/semexprs.nim(950, 1) + #3] > semExpr @ sem/semexprs.nim(2948, 21) from sem/semexprs.nim(43, 1) + #4] > semTypeNode @ sem/semtypes.nim(1903, 21) from sem/semobjconstr.nim(469, 1) + #4] < semTypeNode @ sem/semtypes.nim(1903, 21) from sem/semobjconstr.nim(469, 1) + #3] < semExpr @ sem/semexprs.nim(2948, 21) from sem/semexprs.nim(43, 1) + #2] < semOverloadedCall @ sem/semcall.nim(569, 21) from sem/semexprs.nim(950, 1) + #1] < semOverloadedCallAnalyseEffects @ sem/semexprs.nim(941, 21) from sem/semexprs.nim(1133, 1) + #0]< semExpr @ sem/semexprs.nim(2948, 21) from sem/semstmts.nim(2446, 1) + #0]> semExpr @ sem/semexprs.nim(2948, 21) from sem/semstmts.nim(2446, 1) + <<] trace end + +Formatting of the report is implemented in the `cli_reporter.nim` as well +(all debug reports are also transferred using regular reporting pipeline). +It has a lot of information, but general parts for each call parts are: + +.. code-block:: literal + + #2] < semOverloadedCall @ sem/semcall.nim(569, 21) from sem/semexprs.nim(950, 1) + ^ ^ ^ ^ ^ + | | | | Where proc has been called from + | | | Location of the `addInNimDebugUtils()` - the proc itsemf + | | Name of the proc + | Whether proc has been entered or exited + Depth of the traced call tree + + + +VM codegen and execution +------------------------ + +VM code generation prints all of the generated procedures. If this is not +needed (which would be the majority of use cases) you can add +`--define:expandVmListing=vmTarget` and only code for the specific proc +would be printed. For example (generated listing might not match exactly) + +.. code-block:: nim + + type + Obj = object + charField: char + intField: int + + proc vmTarget(arg: Obj) = + echo arg.charField.int + arg.intField + + static: + vmTarget(Obj()) + + +.. code-block:: cmd + + nim c --filenames:canonical --define:expandVmListing=vmTarget file.nim + + +.. code-block:: literal + + Code listing for the 'vmTarget' file.nim(6, 6) + + LdConst r3 $ 1279 system.nim(2005, 30) + LdObj r6 r1 r0 file.nim(7, 11) + NodeToReg r5 r6 r0 file.nim(7, 11) + Conv r6 r5 int char file.nim(7, 21) + LdObj r7 r1 r1 file.nim(7, 31) + NodeToReg r5 r7 r0 file.nim(7, 31) + AddInt r4 r6 r5 file.nim(7, 26) + IndCallAsgn r2 r3 #2 file.nim(7, 26) + Echo r2 r1 r0 file.nim(7, 26) + Ret r0 r0 r0 file.nim(7, 8) + Eof r0 r0 r0 file.nim(7, 8) + Runtimes ========