@jhlagado/azm 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -70
- package/dist/{src → legacy-root-azm/src}/formats/index.d.ts +1 -1
- package/dist/{src → legacy-root-azm/src}/formats/index.js +1 -1
- package/dist/{src → legacy-root-azm/src}/formats/types.d.ts +67 -7
- package/dist/{src → legacy-root-azm/src}/formats/writeHex.d.ts +0 -1
- package/dist/{src → legacy-root-azm/src}/formats/writeHex.js +0 -1
- package/dist/{src → legacy-root-azm/src}/pipeline.d.ts +3 -5
- package/dist/legacy-root-azm/src/z80/effects.d.ts +3 -0
- package/dist/legacy-root-azm/src/z80/effects.js +516 -0
- package/dist/legacy-root-azm/src/z80/encode.d.ts +10 -0
- package/dist/legacy-root-azm/src/z80/encode.js +412 -0
- package/dist/src/api-compile.d.ts +49 -8
- package/dist/src/api-compile.js +313 -3
- package/dist/src/api-tooling.d.ts +7 -25
- package/dist/src/api-tooling.js +3 -21
- package/dist/src/assembly/address-planning.d.ts +19 -0
- package/dist/src/assembly/address-planning.js +268 -0
- package/dist/src/assembly/assemble-program.d.ts +13 -0
- package/dist/src/assembly/assemble-program.js +34 -0
- package/dist/src/assembly/fixup-emission.d.ts +10 -0
- package/dist/src/assembly/fixup-emission.js +247 -0
- package/dist/src/assembly/placement.d.ts +26 -0
- package/dist/src/assembly/placement.js +79 -0
- package/dist/src/assembly/program-emission.d.ts +13 -0
- package/dist/src/assembly/program-emission.js +268 -0
- package/dist/src/cli/parse-args.d.ts +29 -0
- package/dist/src/cli/parse-args.js +372 -0
- package/dist/src/cli/run.d.ts +2 -0
- package/dist/src/cli/run.js +35 -0
- package/dist/src/cli/write-artifacts.d.ts +21 -0
- package/dist/src/cli/write-artifacts.js +175 -0
- package/dist/src/cli.d.ts +1 -30
- package/dist/src/cli.js +20 -524
- package/dist/src/core/compile-artifacts.d.ts +26 -0
- package/dist/src/core/compile-artifacts.js +17 -0
- package/dist/src/core/compile.d.ts +26 -0
- package/dist/src/core/compile.js +164 -0
- package/dist/src/diagnostics/format.d.ts +4 -0
- package/dist/src/diagnostics/format.js +9 -0
- package/dist/src/expansion/op-expansion.d.ts +96 -0
- package/dist/src/expansion/op-expansion.js +913 -0
- package/dist/src/index.d.ts +14 -3
- package/dist/src/index.js +7 -2
- package/dist/src/model/diagnostic.d.ts +50 -0
- package/dist/src/model/diagnostic.js +29 -0
- package/dist/src/model/expression.d.ts +51 -0
- package/dist/src/model/expression.js +1 -0
- package/dist/src/model/fixup.d.ts +18 -0
- package/dist/src/model/fixup.js +1 -0
- package/dist/src/model/source-item.d.ts +87 -0
- package/dist/src/model/source-item.js +1 -0
- package/dist/src/model/symbol.d.ts +1 -0
- package/dist/src/model/symbol.js +1 -0
- package/dist/src/node/source-host.d.ts +19 -0
- package/dist/src/node/source-host.js +146 -0
- package/dist/src/outputs/hex.d.ts +1 -0
- package/dist/src/outputs/hex.js +75 -0
- package/dist/src/outputs/index.d.ts +3 -0
- package/dist/src/outputs/index.js +13 -0
- package/dist/src/outputs/range.d.ts +3 -0
- package/dist/src/outputs/range.js +31 -0
- package/dist/src/outputs/types.d.ts +182 -0
- package/dist/src/outputs/types.js +1 -0
- package/dist/src/outputs/write-asm80.d.ts +7 -0
- package/dist/src/outputs/write-asm80.js +666 -0
- package/dist/src/outputs/write-bin.d.ts +2 -0
- package/dist/src/outputs/write-bin.js +27 -0
- package/dist/src/outputs/write-d8.d.ts +2 -0
- package/dist/src/outputs/write-d8.js +257 -0
- package/dist/src/outputs/write-hex.d.ts +2 -0
- package/dist/src/outputs/write-hex.js +53 -0
- package/dist/src/outputs/write-listing.d.ts +2 -0
- package/dist/src/outputs/write-listing.js +79 -0
- package/dist/src/register-care/accept-output.d.ts +2 -0
- package/dist/src/register-care/accept-output.js +35 -0
- package/dist/src/register-care/analyze.d.ts +26 -0
- package/dist/src/register-care/analyze.js +115 -0
- package/dist/src/register-care/annotate.d.ts +11 -0
- package/dist/src/register-care/annotate.js +76 -0
- package/dist/src/register-care/annotations.d.ts +8 -0
- package/dist/src/register-care/annotations.js +41 -0
- package/dist/src/register-care/boundaryHints.d.ts +2 -0
- package/dist/src/register-care/boundaryHints.js +11 -0
- package/dist/src/register-care/carriers.d.ts +2 -0
- package/dist/src/register-care/carriers.js +78 -0
- package/dist/src/register-care/controlFlow.d.ts +5 -0
- package/dist/src/register-care/controlFlow.js +38 -0
- package/dist/src/register-care/fix.d.ts +11 -0
- package/dist/src/register-care/fix.js +130 -0
- package/dist/src/register-care/instruction-shape.d.ts +11 -0
- package/dist/src/register-care/instruction-shape.js +129 -0
- package/dist/src/register-care/liveness.d.ts +3 -0
- package/dist/src/register-care/liveness.js +197 -0
- package/dist/src/register-care/profiles.d.ts +9 -0
- package/dist/src/register-care/profiles.js +47 -0
- package/dist/src/register-care/programModel.d.ts +3 -0
- package/dist/src/register-care/programModel.js +188 -0
- package/dist/src/register-care/report.d.ts +5 -0
- package/dist/src/register-care/report.js +139 -0
- package/dist/src/register-care/routine-summaries.d.ts +6 -0
- package/dist/src/register-care/routine-summaries.js +89 -0
- package/dist/src/register-care/smartComments.d.ts +5 -0
- package/dist/src/register-care/smartComments.js +243 -0
- package/dist/src/register-care/sourceText.d.ts +8 -0
- package/dist/src/register-care/sourceText.js +15 -0
- package/dist/src/register-care/summaries.d.ts +12 -0
- package/dist/src/register-care/summaries.js +121 -0
- package/dist/src/register-care/summary.d.ts +3 -0
- package/dist/src/register-care/summary.js +474 -0
- package/dist/src/{registerCare → register-care}/tooling.d.ts +7 -6
- package/dist/src/{registerCare → register-care}/tooling.js +17 -6
- package/dist/src/register-care/types.d.ts +170 -0
- package/dist/src/register-care/types.js +1 -0
- package/dist/src/semantics/expression-evaluation.d.ts +29 -0
- package/dist/src/semantics/expression-evaluation.js +409 -0
- package/dist/src/source/logical-lines.d.ts +7 -0
- package/dist/src/source/logical-lines.js +11 -0
- package/dist/src/source/source-file.d.ts +5 -0
- package/dist/src/source/source-file.js +3 -0
- package/dist/src/source/source-span.d.ts +5 -0
- package/dist/src/source/source-span.js +1 -0
- package/dist/src/source/strip-line-comment.d.ts +6 -0
- package/dist/src/source/strip-line-comment.js +53 -0
- package/dist/src/syntax/directive-aliases.d.ts +10 -0
- package/dist/src/syntax/directive-aliases.js +199 -0
- package/dist/src/syntax/parse-diagnostics.d.ts +12 -0
- package/dist/src/syntax/parse-diagnostics.js +18 -0
- package/dist/src/syntax/parse-expression.d.ts +3 -0
- package/dist/src/syntax/parse-expression.js +551 -0
- package/dist/src/syntax/parse-line.d.ts +12 -0
- package/dist/src/syntax/parse-line.js +382 -0
- package/dist/src/tooling/api.d.ts +42 -0
- package/dist/src/tooling/api.js +42 -0
- package/dist/src/tooling/case-style.d.ts +8 -0
- package/dist/src/tooling/case-style.js +163 -0
- package/dist/src/z80/effects.d.ts +3 -3
- package/dist/src/z80/effects.js +349 -302
- package/dist/src/z80/encode.d.ts +2 -10
- package/dist/src/z80/encode.js +951 -374
- package/dist/src/z80/instruction.d.ts +226 -0
- package/dist/src/z80/instruction.js +1 -0
- package/dist/src/z80/parse-instruction.d.ts +7 -0
- package/dist/src/z80/parse-instruction.js +1068 -0
- package/docs/reference/tooling-api.md +68 -9
- package/package.json +22 -3
- /package/dist/{src → legacy-root-azm/src}/analysis.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/analysis.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/compile.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/compile.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/compileShared.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/compileShared.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/diagnosticTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/diagnosticTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/range.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/range.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/types.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeAsm80.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeAsm80.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeBin.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeBin.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeD8m.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeD8m.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeListing.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeListing.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/asmLine.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/asmLine.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/parseAsmRawValues.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/parseAsmRawValues.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/quoteScan.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/quoteScan.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/ast.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/ast.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/directiveAliases.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/directiveAliases.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/grammarData.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/grammarData.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/immExprUtils.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/immExprUtils.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmFlatDirectiveLine.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmFlatDirectiveLine.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmInstruction.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmInstruction.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStatements.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStatements.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStream.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStream.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmTopLevel.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmTopLevel.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseDiagnostics.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseDiagnostics.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseEnum.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseEnum.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseImm.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseImm.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseLogicalLines.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseLogicalLines.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOp.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOp.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOpHeader.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOpHeader.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOperands.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOperands.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParams.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParams.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserRecovery.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserRecovery.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserShared.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserShared.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectiveStart.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectiveStart.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectives.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectives.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRecordFieldDecl.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRecordFieldDecl.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemDispatch.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemDispatch.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemTable.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemTable.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTopLevelCommon.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTopLevelCommon.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parser.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parser.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/source.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/source.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/sourceExtensions.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/sourceExtensions.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lintCaseStyle.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lintCaseStyle.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveTraversal.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveTraversal.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmEquResolution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmEquResolution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLdHelpers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLdHelpers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionStream.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionStream.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringBranchCall.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringBranchCall.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringHost.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringHost.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringLd.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringLd.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRangeLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRangeLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRawDataLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRawDataLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceEmitter.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceEmitter.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceInstructionLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceInstructionLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmUtils.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmUtils.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerFlowSetup.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerFlowSetup.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContextSplit.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContextSplit.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringPhases.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringPhases.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/bytePlacement.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/bytePlacement.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/capabilities.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/capabilities.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/eaResolution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/eaResolution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emissionCore.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emissionCore.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emit.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emit.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitContextBuilder.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitContextBuilder.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalization.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalization.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalizationSetup.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalizationSetup.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1BuildProgramLoweringContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1BuildProgramLoweringContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Helpers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Helpers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Types.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Types.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1WirePipeline.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1WirePipeline.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Workspace.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Workspace.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPipeline.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPipeline.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitProgramContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitProgramContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitState.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitState.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupBaseResolution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupBaseResolution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupEmission.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupEmission.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/immMath.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/immMath.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/inputAssets.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/inputAssets.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncoding.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncoding.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncodingRegMemHelpers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncodingRegMemHelpers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldFormSelection.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldFormSelection.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmByteEmission.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmByteEmission.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmPlacement.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmPlacement.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmStreamRecording.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmStreamRecording.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredFormat.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredFormat.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredItemSize.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredItemSize.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringDiagnostics.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringDiagnostics.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opCandidateRegistry.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opCandidateRegistry.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionExecution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionExecution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionOrchestration.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionOrchestration.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionStream.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionStream.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opMatching.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opMatching.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opSubstitution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opSubstitution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/prescanTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/prescanTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringDeclarations.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringDeclarations.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringFinalize.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringFinalize.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringTraversal.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringTraversal.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programPrescan.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programPrescan.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/traceFormat.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/traceFormat.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/packageInfo.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/packageInfo.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/pathCompare.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/pathCompare.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/pipeline.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/analyze.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/analyze.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/annotate.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/annotate.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/boundaryHints.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/boundaryHints.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/carriers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/carriers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/controlFlow.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/controlFlow.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/fix.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/fix.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/liveness.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/liveness.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/profiles.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/profiles.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/programModel.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/programModel.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/report.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/report.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/smartComments.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/smartComments.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/sourceText.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/sourceText.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/summary.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/summary.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/types.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/types.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/declVisitor.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/declVisitor.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/env.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/env.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layout.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layout.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layoutCastFold.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layoutCastFold.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/semanticsDiagnostics.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/semanticsDiagnostics.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/typeQueries.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/typeQueries.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludeExpansion.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludeExpansion.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludePaths.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludePaths.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceLoader.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceLoader.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeAlu.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeAlu.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeBitOps.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeBitOps.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeControl.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeControl.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeCoreOps.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeCoreOps.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeIo.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeIo.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeLd.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeLd.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encoderRegistry.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encoderRegistry.js +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RegisterCareAnnotationFile, RegisterCareOutputCandidate, RegisterCareRoutine, RoutineSummary } from './types.js';
|
|
2
|
+
export declare function buildAnnotations(loaded: {
|
|
3
|
+
sourceTexts: ReadonlyMap<string, string>;
|
|
4
|
+
}, programRoutines: readonly RegisterCareRoutine[], summariesByName: ReadonlyMap<string, RoutineSummary>, outputCandidates: readonly RegisterCareOutputCandidate[], options: {
|
|
5
|
+
fixOutputCandidates: boolean;
|
|
6
|
+
outputCandidateFixability: ReadonlyMap<string, boolean>;
|
|
7
|
+
outputCandidateKey: (file: string, line: number, column: number) => string;
|
|
8
|
+
}): readonly RegisterCareAnnotationFile[];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { annotateRegisterCareContracts } from './annotate.js';
|
|
2
|
+
import { applyExpectOutFixesToSource, findExpectOutFixesForCandidates, } from './fix.js';
|
|
3
|
+
export function buildAnnotations(loaded, programRoutines, summariesByName, outputCandidates, options) {
|
|
4
|
+
const routines = programRoutines
|
|
5
|
+
.filter((routine) => summariesByName.has(routine.name))
|
|
6
|
+
.map((routine) => ({
|
|
7
|
+
routine,
|
|
8
|
+
summary: summariesByName.get(routine.name),
|
|
9
|
+
}));
|
|
10
|
+
const annotated = annotateRegisterCareContracts(loaded.sourceTexts, routines);
|
|
11
|
+
if (!options.fixOutputCandidates) {
|
|
12
|
+
return annotated.map((file) => ({ path: file.path, text: file.text }));
|
|
13
|
+
}
|
|
14
|
+
const autoFixableCandidates = outputCandidates.filter((candidate) => options.outputCandidateFixability.get(options.outputCandidateKey(candidate.file, candidate.line, candidate.column)) === true);
|
|
15
|
+
const fixes = findExpectOutFixesForCandidates([...programRoutines], autoFixableCandidates);
|
|
16
|
+
if (fixes.length === 0) {
|
|
17
|
+
return annotated.map((file) => ({ path: file.path, text: file.text }));
|
|
18
|
+
}
|
|
19
|
+
const workingTexts = new Map(loaded.sourceTexts);
|
|
20
|
+
for (const file of annotated) {
|
|
21
|
+
workingTexts.set(file.path, file.text);
|
|
22
|
+
}
|
|
23
|
+
const out = [];
|
|
24
|
+
const fixesByFile = new Map();
|
|
25
|
+
for (const fix of fixes) {
|
|
26
|
+
const items = fixesByFile.get(fix.file) ?? [];
|
|
27
|
+
items.push(fix);
|
|
28
|
+
fixesByFile.set(fix.file, items);
|
|
29
|
+
}
|
|
30
|
+
for (const [path, text] of workingTexts) {
|
|
31
|
+
const reference = loaded.sourceTexts.get(path);
|
|
32
|
+
if (reference === undefined)
|
|
33
|
+
continue;
|
|
34
|
+
const fileFixes = fixesByFile.get(path) ?? [];
|
|
35
|
+
const nextText = fileFixes.length > 0 ? applyExpectOutFixesToSource(text, fileFixes, reference) : text;
|
|
36
|
+
if (nextText !== reference) {
|
|
37
|
+
out.push({ path, text: nextText });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return out.sort((left, right) => left.path.localeCompare(right.path));
|
|
41
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function precedingCServiceName(item) {
|
|
2
|
+
const instruction = item?.instruction;
|
|
3
|
+
if (!instruction || instruction.mnemonic !== 'ld')
|
|
4
|
+
return undefined;
|
|
5
|
+
if (instruction.target?.kind !== 'reg8' || instruction.target.register !== 'c')
|
|
6
|
+
return undefined;
|
|
7
|
+
if (instruction.source.kind === 'imm' && instruction.source.expression.kind === 'symbol') {
|
|
8
|
+
return instruction.source.expression.name;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const FLAG_UNITS = ['carry', 'zero', 'sign', 'parity', 'halfCarry'];
|
|
2
|
+
const SINGLE_UNITS = new Set([
|
|
3
|
+
'A',
|
|
4
|
+
'B',
|
|
5
|
+
'C',
|
|
6
|
+
'D',
|
|
7
|
+
'E',
|
|
8
|
+
'H',
|
|
9
|
+
'L',
|
|
10
|
+
'IXH',
|
|
11
|
+
'IXL',
|
|
12
|
+
'IYH',
|
|
13
|
+
'IYL',
|
|
14
|
+
'SPH',
|
|
15
|
+
'SPL',
|
|
16
|
+
'carry',
|
|
17
|
+
'zero',
|
|
18
|
+
'sign',
|
|
19
|
+
'parity',
|
|
20
|
+
'halfCarry',
|
|
21
|
+
]);
|
|
22
|
+
const PAIRS = {
|
|
23
|
+
AF: ['A', ...FLAG_UNITS],
|
|
24
|
+
BC: ['B', 'C'],
|
|
25
|
+
DE: ['D', 'E'],
|
|
26
|
+
HL: ['H', 'L'],
|
|
27
|
+
IX: ['IXH', 'IXL'],
|
|
28
|
+
IY: ['IYH', 'IYL'],
|
|
29
|
+
SP: ['SPH', 'SPL'],
|
|
30
|
+
};
|
|
31
|
+
const FLAG_ALIASES = {
|
|
32
|
+
CARRY: 'carry',
|
|
33
|
+
ZERO: 'zero',
|
|
34
|
+
Z: 'zero',
|
|
35
|
+
SIGN: 'sign',
|
|
36
|
+
S: 'sign',
|
|
37
|
+
PARITY: 'parity',
|
|
38
|
+
PV: 'parity',
|
|
39
|
+
'P/V': 'parity',
|
|
40
|
+
HALFCARRY: 'halfCarry',
|
|
41
|
+
HFLAG: 'halfCarry',
|
|
42
|
+
};
|
|
43
|
+
function normalizeCarrierName(raw) {
|
|
44
|
+
const trimmed = raw.trim();
|
|
45
|
+
const upper = trimmed.toUpperCase();
|
|
46
|
+
const flag = FLAG_ALIASES[upper];
|
|
47
|
+
if (flag !== undefined)
|
|
48
|
+
return flag;
|
|
49
|
+
if (SINGLE_UNITS.has(upper))
|
|
50
|
+
return upper;
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
function expandCarrier(raw) {
|
|
54
|
+
const upper = raw.trim().toUpperCase();
|
|
55
|
+
if (upper === 'F')
|
|
56
|
+
return FLAG_UNITS;
|
|
57
|
+
const pair = PAIRS[upper];
|
|
58
|
+
if (pair !== undefined)
|
|
59
|
+
return pair;
|
|
60
|
+
const single = normalizeCarrierName(raw);
|
|
61
|
+
return single !== undefined ? [single] : undefined;
|
|
62
|
+
}
|
|
63
|
+
export function expandCarrierList(raw) {
|
|
64
|
+
const out = [];
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
for (const item of raw) {
|
|
67
|
+
const expanded = expandCarrier(item);
|
|
68
|
+
if (expanded === undefined)
|
|
69
|
+
return undefined;
|
|
70
|
+
for (const unit of expanded) {
|
|
71
|
+
if (seen.has(unit))
|
|
72
|
+
continue;
|
|
73
|
+
seen.add(unit);
|
|
74
|
+
out.push(unit);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { InstructionEffect, RegisterCareRoutine } from './types.js';
|
|
2
|
+
export declare function labelIndex(routine: RegisterCareRoutine): Map<string, number>;
|
|
3
|
+
export declare function instructionSuccessors(routine: RegisterCareRoutine, index: number, effect: InstructionEffect, labels: ReadonlyMap<string, number>, options?: {
|
|
4
|
+
boundaryFallthrough?: boolean;
|
|
5
|
+
}): number[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function unique(items) {
|
|
2
|
+
return [...new Set(items)];
|
|
3
|
+
}
|
|
4
|
+
export function labelIndex(routine) {
|
|
5
|
+
const out = new Map();
|
|
6
|
+
routine.instructions.forEach((item, index) => {
|
|
7
|
+
for (const label of item.labels)
|
|
8
|
+
out.set(label, index);
|
|
9
|
+
});
|
|
10
|
+
return out;
|
|
11
|
+
}
|
|
12
|
+
function localTargetIndex(labels, target) {
|
|
13
|
+
if (!target)
|
|
14
|
+
return undefined;
|
|
15
|
+
return labels.get(target);
|
|
16
|
+
}
|
|
17
|
+
export function instructionSuccessors(routine, index, effect, labels, options = {}) {
|
|
18
|
+
const next = index + 1 < routine.instructions.length ? index + 1 : undefined;
|
|
19
|
+
if (effect.control.kind === 'fallthrough' ||
|
|
20
|
+
(options.boundaryFallthrough &&
|
|
21
|
+
(effect.control.kind === 'call' || effect.control.kind === 'rst'))) {
|
|
22
|
+
return next === undefined ? [] : [next];
|
|
23
|
+
}
|
|
24
|
+
if (effect.control.kind === 'jump') {
|
|
25
|
+
const target = localTargetIndex(labels, effect.control.target);
|
|
26
|
+
if (effect.control.conditional) {
|
|
27
|
+
return unique([
|
|
28
|
+
...(target === undefined ? [] : [target]),
|
|
29
|
+
...(next === undefined ? [] : [next]),
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
return target === undefined ? [] : [target];
|
|
33
|
+
}
|
|
34
|
+
if (effect.control.kind === 'return') {
|
|
35
|
+
return effect.control.conditional && next !== undefined ? [next] : [];
|
|
36
|
+
}
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RegisterCareOutputCandidate, RegisterCareRoutine, RegisterCareUnit } from './types.js';
|
|
2
|
+
export interface RegisterCareExpectOutFix {
|
|
3
|
+
file: string;
|
|
4
|
+
line: number;
|
|
5
|
+
column: number;
|
|
6
|
+
routine: string;
|
|
7
|
+
carriers: RegisterCareUnit[];
|
|
8
|
+
}
|
|
9
|
+
export declare function findExpectOutFixesForCandidates(routines: RegisterCareRoutine[], candidates: RegisterCareOutputCandidate[]): RegisterCareExpectOutFix[];
|
|
10
|
+
export declare function autoFixableCandidateKeys(routines: RegisterCareRoutine[], candidates: RegisterCareOutputCandidate[]): Set<string>;
|
|
11
|
+
export declare function applyExpectOutFixesToSource(source: string, fixes: RegisterCareExpectOutFix[], referenceSource?: string): string;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { getZ80InstructionEffect } from '../z80/effects.js';
|
|
2
|
+
import { instructionSuccessors, labelIndex } from './controlFlow.js';
|
|
3
|
+
import { contractCarrierList } from './report.js';
|
|
4
|
+
import { joinSourceLines, splitSourceLines } from './sourceText.js';
|
|
5
|
+
function sameLocation(a, b) {
|
|
6
|
+
return a.file === b.file && a.line === b.line && a.column === b.column;
|
|
7
|
+
}
|
|
8
|
+
function isUnconditionalDirectCall(item) {
|
|
9
|
+
const effect = getZ80InstructionEffect(item.instruction);
|
|
10
|
+
return (effect.control.kind === 'call' &&
|
|
11
|
+
effect.control.target !== undefined &&
|
|
12
|
+
!effect.control.conditional);
|
|
13
|
+
}
|
|
14
|
+
function continuationReads(routine, callIndex, carriers) {
|
|
15
|
+
const labels = labelIndex(routine);
|
|
16
|
+
const confirmed = new Set();
|
|
17
|
+
const work = callIndex + 1 < routine.instructions.length
|
|
18
|
+
? [{ index: callIndex + 1, pending: [...new Set(carriers)] }]
|
|
19
|
+
: [];
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
let steps = 0;
|
|
22
|
+
while (work.length > 0 && steps < 512) {
|
|
23
|
+
steps += 1;
|
|
24
|
+
const state = work.pop();
|
|
25
|
+
const pending = state.pending.filter((unit) => !confirmed.has(unit));
|
|
26
|
+
if (pending.length === 0)
|
|
27
|
+
continue;
|
|
28
|
+
const key = `${state.index}:${pending.join(',')}`;
|
|
29
|
+
if (seen.has(key))
|
|
30
|
+
continue;
|
|
31
|
+
seen.add(key);
|
|
32
|
+
const item = routine.instructions[state.index];
|
|
33
|
+
if (!item)
|
|
34
|
+
continue;
|
|
35
|
+
const effect = getZ80InstructionEffect(item.instruction);
|
|
36
|
+
const reads = new Set(effect.reads);
|
|
37
|
+
const writes = new Set(effect.writes);
|
|
38
|
+
const remaining = [];
|
|
39
|
+
for (const unit of pending) {
|
|
40
|
+
if (reads.has(unit)) {
|
|
41
|
+
confirmed.add(unit);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (!writes.has(unit))
|
|
45
|
+
remaining.push(unit);
|
|
46
|
+
}
|
|
47
|
+
if (remaining.length === 0)
|
|
48
|
+
continue;
|
|
49
|
+
for (const next of instructionSuccessors(routine, state.index, effect, labels)) {
|
|
50
|
+
work.push({ index: next, pending: remaining });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return carriers.filter((unit) => confirmed.has(unit));
|
|
54
|
+
}
|
|
55
|
+
function findExpectOutFixes(routines, candidates) {
|
|
56
|
+
const out = [];
|
|
57
|
+
for (const routine of routines) {
|
|
58
|
+
for (let index = 0; index < routine.instructions.length; index += 1) {
|
|
59
|
+
const item = routine.instructions[index];
|
|
60
|
+
if (!isUnconditionalDirectCall(item))
|
|
61
|
+
continue;
|
|
62
|
+
const candidate = candidates.find((entry) => sameLocation(item, entry));
|
|
63
|
+
if (!candidate)
|
|
64
|
+
continue;
|
|
65
|
+
const carriers = continuationReads(routine, index, candidate.carriers);
|
|
66
|
+
if (carriers.length === 0)
|
|
67
|
+
continue;
|
|
68
|
+
out.push({ ...candidate, carriers });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
export function findExpectOutFixesForCandidates(routines, candidates) {
|
|
74
|
+
return findExpectOutFixes(routines, candidates);
|
|
75
|
+
}
|
|
76
|
+
export function autoFixableCandidateKeys(routines, candidates) {
|
|
77
|
+
const fixes = findExpectOutFixes(routines, candidates);
|
|
78
|
+
const out = new Set();
|
|
79
|
+
for (const fix of fixes) {
|
|
80
|
+
out.add(`${fix.file}:${fix.line}:${fix.column}`);
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function isExpectOutLine(line) {
|
|
85
|
+
return /^\s*;\s*expects\s+out\b/i.test(line);
|
|
86
|
+
}
|
|
87
|
+
function expectedCallLine(originalLines, fix) {
|
|
88
|
+
return originalLines[fix.line - 1]?.trim();
|
|
89
|
+
}
|
|
90
|
+
function findCallLineIndex(lines, originalLines, fix) {
|
|
91
|
+
const expected = expectedCallLine(originalLines, fix);
|
|
92
|
+
if (!expected)
|
|
93
|
+
return undefined;
|
|
94
|
+
const preferred = fix.line - 1;
|
|
95
|
+
if (lines[preferred]?.trim() === expected)
|
|
96
|
+
return preferred;
|
|
97
|
+
let best;
|
|
98
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
99
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
100
|
+
if (lines[index]?.trim() !== expected)
|
|
101
|
+
continue;
|
|
102
|
+
const distance = Math.abs(index - preferred);
|
|
103
|
+
if (distance < bestDistance) {
|
|
104
|
+
best = index;
|
|
105
|
+
bestDistance = distance;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return best;
|
|
109
|
+
}
|
|
110
|
+
function indentation(line) {
|
|
111
|
+
return line.match(/^\s*/)?.[0] ?? '';
|
|
112
|
+
}
|
|
113
|
+
export function applyExpectOutFixesToSource(source, fixes, referenceSource = source) {
|
|
114
|
+
if (fixes.length === 0)
|
|
115
|
+
return source;
|
|
116
|
+
const originalLines = referenceSource.split(/\r?\n/);
|
|
117
|
+
const sourceLines = splitSourceLines(source);
|
|
118
|
+
const { lines } = sourceLines;
|
|
119
|
+
const sorted = [...fixes].sort((a, b) => b.line - a.line || b.column - a.column);
|
|
120
|
+
for (const fix of sorted) {
|
|
121
|
+
const index = findCallLineIndex(lines, originalLines, fix);
|
|
122
|
+
if (index === undefined)
|
|
123
|
+
continue;
|
|
124
|
+
if (index > 0 && isExpectOutLine(lines[index - 1] ?? ''))
|
|
125
|
+
continue;
|
|
126
|
+
const prefix = indentation(lines[index] ?? '');
|
|
127
|
+
lines.splice(index, 0, `${prefix}; expects out ${contractCarrierList(fix.carriers)}`);
|
|
128
|
+
}
|
|
129
|
+
return joinSourceLines(sourceLines);
|
|
130
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Z80Instruction, Z80Operand } from '../z80/instruction.js';
|
|
2
|
+
import type { RegisterCareInstruction } from './types.js';
|
|
3
|
+
export declare function instructionHead(item: RegisterCareInstruction): string;
|
|
4
|
+
export declare function regName(operand: Z80Operand | undefined): string | undefined;
|
|
5
|
+
export declare function instructionOperandCount(instruction: Z80Instruction): number;
|
|
6
|
+
export declare function instructionOperand(instruction: Z80Instruction, index: number): Z80Operand | undefined;
|
|
7
|
+
export declare function isUnconditionalReturnInstruction(item: RegisterCareInstruction): boolean;
|
|
8
|
+
export declare function isPureTokenTransferInstruction(item: RegisterCareInstruction): boolean;
|
|
9
|
+
export declare function isAccumulatorSelfOperand(item: RegisterCareInstruction): boolean;
|
|
10
|
+
export declare function isImmediateZeroOperand(item: RegisterCareInstruction): boolean;
|
|
11
|
+
export declare function isRegisterOperand(item: RegisterCareInstruction | undefined, index: number, name: string): boolean;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
export function instructionHead(item) {
|
|
2
|
+
return item.instruction.mnemonic.toLowerCase();
|
|
3
|
+
}
|
|
4
|
+
export function regName(operand) {
|
|
5
|
+
if (operand === undefined)
|
|
6
|
+
return undefined;
|
|
7
|
+
switch (operand.kind) {
|
|
8
|
+
case 'reg8':
|
|
9
|
+
return operand.register.toUpperCase();
|
|
10
|
+
case 'reg16':
|
|
11
|
+
return operand.register.toUpperCase();
|
|
12
|
+
case 'reg-index16':
|
|
13
|
+
return operand.register.toUpperCase();
|
|
14
|
+
case 'reg-half-index':
|
|
15
|
+
return operand.register.toUpperCase();
|
|
16
|
+
default:
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function immValue(operand) {
|
|
21
|
+
if (operand?.kind !== 'imm')
|
|
22
|
+
return undefined;
|
|
23
|
+
const expression = operand.expression;
|
|
24
|
+
return expression.kind === 'number' ? expression.value : undefined;
|
|
25
|
+
}
|
|
26
|
+
export function instructionOperandCount(instruction) {
|
|
27
|
+
switch (instruction.mnemonic) {
|
|
28
|
+
case 'ret':
|
|
29
|
+
case 'ret-cc':
|
|
30
|
+
return instruction.mnemonic === 'ret' ? 0 : 1;
|
|
31
|
+
case 'ld':
|
|
32
|
+
return 2;
|
|
33
|
+
case 'ex':
|
|
34
|
+
return 2;
|
|
35
|
+
case 'jp':
|
|
36
|
+
case 'jp-cc':
|
|
37
|
+
case 'jr':
|
|
38
|
+
case 'jr-cc':
|
|
39
|
+
case 'djnz':
|
|
40
|
+
case 'call':
|
|
41
|
+
case 'call-cc':
|
|
42
|
+
return 1;
|
|
43
|
+
case 'add':
|
|
44
|
+
case 'adc':
|
|
45
|
+
case 'sbc':
|
|
46
|
+
return 'target' in instruction ? 2 : 1;
|
|
47
|
+
case 'sub':
|
|
48
|
+
case 'and':
|
|
49
|
+
case 'or':
|
|
50
|
+
case 'xor':
|
|
51
|
+
case 'cp':
|
|
52
|
+
return 1;
|
|
53
|
+
default:
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function instructionOperand(instruction, index) {
|
|
58
|
+
switch (instruction.mnemonic) {
|
|
59
|
+
case 'ld':
|
|
60
|
+
return index === 0 ? instruction.target : index === 1 ? instruction.source : undefined;
|
|
61
|
+
case 'ex': {
|
|
62
|
+
if (index === 0) {
|
|
63
|
+
return instruction.form === 'de-hl'
|
|
64
|
+
? { kind: 'reg16', register: 'de' }
|
|
65
|
+
: instruction.form === 'af-af'
|
|
66
|
+
? { kind: 'reg16', register: 'af' }
|
|
67
|
+
: undefined;
|
|
68
|
+
}
|
|
69
|
+
if (index === 1) {
|
|
70
|
+
return instruction.form === 'de-hl'
|
|
71
|
+
? { kind: 'reg16', register: 'hl' }
|
|
72
|
+
: undefined;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
case 'add':
|
|
77
|
+
case 'adc':
|
|
78
|
+
case 'sbc':
|
|
79
|
+
if ('target' in instruction) {
|
|
80
|
+
return index === 0 ? instruction.target : index === 1 ? instruction.source : undefined;
|
|
81
|
+
}
|
|
82
|
+
return index === 0 ? instruction.source : undefined;
|
|
83
|
+
case 'sub':
|
|
84
|
+
case 'and':
|
|
85
|
+
case 'or':
|
|
86
|
+
case 'xor':
|
|
87
|
+
case 'cp':
|
|
88
|
+
return index === 0 ? instruction.source : undefined;
|
|
89
|
+
default:
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function isUnconditionalReturnInstruction(item) {
|
|
94
|
+
const head = instructionHead(item);
|
|
95
|
+
if (head === 'ret')
|
|
96
|
+
return item.instruction.mnemonic === 'ret';
|
|
97
|
+
return head === 'retn' || head === 'reti';
|
|
98
|
+
}
|
|
99
|
+
export function isPureTokenTransferInstruction(item) {
|
|
100
|
+
const head = instructionHead(item);
|
|
101
|
+
if (head === 'ex')
|
|
102
|
+
return true;
|
|
103
|
+
if (head !== 'ld' || instructionOperandCount(item.instruction) !== 2)
|
|
104
|
+
return false;
|
|
105
|
+
const dst = instructionOperand(item.instruction, 0);
|
|
106
|
+
const src = instructionOperand(item.instruction, 1);
|
|
107
|
+
if (regName(dst) === undefined)
|
|
108
|
+
return false;
|
|
109
|
+
return regName(src) !== undefined || src?.kind === 'imm';
|
|
110
|
+
}
|
|
111
|
+
export function isAccumulatorSelfOperand(item) {
|
|
112
|
+
const inst = item.instruction;
|
|
113
|
+
if (inst.mnemonic === 'or' || inst.mnemonic === 'and' || inst.mnemonic === 'xor') {
|
|
114
|
+
return inst.source.kind === 'reg8' && inst.source.register === 'a';
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
export function isImmediateZeroOperand(item) {
|
|
119
|
+
const inst = item.instruction;
|
|
120
|
+
if (inst.mnemonic !== 'cp')
|
|
121
|
+
return false;
|
|
122
|
+
return immValue(inst.source) === 0;
|
|
123
|
+
}
|
|
124
|
+
export function isRegisterOperand(item, index, name) {
|
|
125
|
+
if (item === undefined)
|
|
126
|
+
return false;
|
|
127
|
+
const operand = instructionOperand(item.instruction, index);
|
|
128
|
+
return regName(operand) === name.toUpperCase();
|
|
129
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LocatedSmartComment, RegisterCareConflict, RegisterCareOutputCandidate, RegisterCareRoutine, RoutineSummary } from './types.js';
|
|
2
|
+
export declare function findRegisterCareConflicts(routine: RegisterCareRoutine, summaries: Map<string, RoutineSummary>, hints: LocatedSmartComment[]): RegisterCareConflict[];
|
|
3
|
+
export declare function findCallerOutputCandidateObservations(routines: RegisterCareRoutine[], summaries: Map<string, RoutineSummary>): RegisterCareOutputCandidate[];
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { getZ80InstructionEffect } from '../z80/effects.js';
|
|
2
|
+
import { precedingCServiceName } from './boundaryHints.js';
|
|
3
|
+
import { instructionSuccessors, labelIndex } from './controlFlow.js';
|
|
4
|
+
import { rstServiceTargetName, rstTargetName } from './profiles.js';
|
|
5
|
+
function unique(units) {
|
|
6
|
+
return [...new Set(units)];
|
|
7
|
+
}
|
|
8
|
+
function boundaryTarget(routine, index, effect) {
|
|
9
|
+
const item = routine.instructions[index];
|
|
10
|
+
if (effect.control.kind === 'call' && effect.control.target) {
|
|
11
|
+
return {
|
|
12
|
+
targets: [effect.control.target],
|
|
13
|
+
conditional: effect.control.conditional,
|
|
14
|
+
subject: `CALL ${effect.control.target}`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (effect.control.kind === 'jump' &&
|
|
18
|
+
item?.instruction.mnemonic === 'jp' &&
|
|
19
|
+
!effect.control.conditional &&
|
|
20
|
+
effect.control.target &&
|
|
21
|
+
!effect.control.target.startsWith('.')) {
|
|
22
|
+
return {
|
|
23
|
+
targets: [effect.control.target],
|
|
24
|
+
conditional: false,
|
|
25
|
+
subject: `JP ${effect.control.target}`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (effect.control.kind === 'rst' && effect.control.vector !== undefined) {
|
|
29
|
+
const target = rstTargetName(effect.control.vector);
|
|
30
|
+
const service = precedingCServiceName(routine.instructions[index - 1]);
|
|
31
|
+
const targets = service
|
|
32
|
+
? [rstServiceTargetName(effect.control.vector, service), target]
|
|
33
|
+
: [target];
|
|
34
|
+
return { targets, conditional: false, subject: target };
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
function summaryForBoundary(boundary, summaries) {
|
|
39
|
+
for (const target of boundary.targets) {
|
|
40
|
+
const summary = summaries.get(target);
|
|
41
|
+
if (summary)
|
|
42
|
+
return { target, summary };
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
function hintUnitsForLine(hints, file, callLine) {
|
|
47
|
+
const prior = hints.find((hint) => hint.file === file && hint.line === callLine - 1 && hint.comment.kind === 'expectOut');
|
|
48
|
+
return prior?.comment.kind === 'expectOut' ? unique(prior.comment.carriers) : [];
|
|
49
|
+
}
|
|
50
|
+
function outputUnits(summary) {
|
|
51
|
+
return unique(summary.valueRelations.flatMap((relation) => relation.out));
|
|
52
|
+
}
|
|
53
|
+
function setEqual(left, right) {
|
|
54
|
+
if (left.size !== right.size)
|
|
55
|
+
return false;
|
|
56
|
+
for (const item of left)
|
|
57
|
+
if (!right.has(item))
|
|
58
|
+
return false;
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
function unionLive(sets) {
|
|
62
|
+
const out = new Set();
|
|
63
|
+
for (const set of sets) {
|
|
64
|
+
for (const unit of set)
|
|
65
|
+
out.add(unit);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
function transferLiveBefore(item, effect, boundary, summary, liveAfter, hints) {
|
|
70
|
+
const live = new Set(liveAfter);
|
|
71
|
+
if (boundary && summary) {
|
|
72
|
+
const accepted = new Set();
|
|
73
|
+
for (const unit of hintUnitsForLine(hints, item.file, item.line))
|
|
74
|
+
accepted.add(unit);
|
|
75
|
+
for (const unit of outputUnits(summary))
|
|
76
|
+
accepted.add(unit);
|
|
77
|
+
if (!boundary.conditional) {
|
|
78
|
+
for (const unit of summary.mayWrite)
|
|
79
|
+
live.delete(unit);
|
|
80
|
+
for (const unit of accepted)
|
|
81
|
+
live.delete(unit);
|
|
82
|
+
}
|
|
83
|
+
for (const unit of summary.mayRead)
|
|
84
|
+
live.add(unit);
|
|
85
|
+
}
|
|
86
|
+
const instructionWritesAreConditional = effect.control.kind === 'call' && effect.control.conditional;
|
|
87
|
+
if (!instructionWritesAreConditional) {
|
|
88
|
+
for (const unit of effect.writes)
|
|
89
|
+
live.delete(unit);
|
|
90
|
+
}
|
|
91
|
+
for (const unit of effect.reads)
|
|
92
|
+
live.add(unit);
|
|
93
|
+
return live;
|
|
94
|
+
}
|
|
95
|
+
function liveSetsForRoutine(routine, summaries, hints = []) {
|
|
96
|
+
const labels = labelIndex(routine);
|
|
97
|
+
const effects = routine.instructions.map((item) => getZ80InstructionEffect(item.instruction));
|
|
98
|
+
const boundaries = effects.map((effect, index) => boundaryTarget(routine, index, effect));
|
|
99
|
+
const resolvedSummaries = boundaries.map((boundary) => boundary ? summaryForBoundary(boundary, summaries)?.summary : undefined);
|
|
100
|
+
const successorIndexes = effects.map((effect, index) => instructionSuccessors(routine, index, effect, labels, { boundaryFallthrough: true }));
|
|
101
|
+
const liveIn = routine.instructions.map(() => new Set());
|
|
102
|
+
const liveOut = routine.instructions.map(() => new Set());
|
|
103
|
+
let changed = true;
|
|
104
|
+
let passes = 0;
|
|
105
|
+
while (changed && passes < Math.max(8, routine.instructions.length * 4)) {
|
|
106
|
+
changed = false;
|
|
107
|
+
passes += 1;
|
|
108
|
+
for (let index = routine.instructions.length - 1; index >= 0; index -= 1) {
|
|
109
|
+
const nextOut = unionLive(successorIndexes[index].map((successor) => liveIn[successor]));
|
|
110
|
+
const nextIn = transferLiveBefore(routine.instructions[index], effects[index], boundaries[index], resolvedSummaries[index], nextOut, hints);
|
|
111
|
+
if (!setEqual(nextOut, liveOut[index])) {
|
|
112
|
+
liveOut[index] = nextOut;
|
|
113
|
+
changed = true;
|
|
114
|
+
}
|
|
115
|
+
if (!setEqual(nextIn, liveIn[index])) {
|
|
116
|
+
liveIn[index] = nextIn;
|
|
117
|
+
changed = true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { liveIn, liveOut };
|
|
122
|
+
}
|
|
123
|
+
function resolvedBoundariesForRoutine(routine, summaries) {
|
|
124
|
+
const out = [];
|
|
125
|
+
for (let index = 0; index < routine.instructions.length; index += 1) {
|
|
126
|
+
const item = routine.instructions[index];
|
|
127
|
+
const effect = getZ80InstructionEffect(item.instruction);
|
|
128
|
+
const boundary = boundaryTarget(routine, index, effect);
|
|
129
|
+
if (!boundary)
|
|
130
|
+
continue;
|
|
131
|
+
const resolved = summaryForBoundary(boundary, summaries);
|
|
132
|
+
if (!resolved)
|
|
133
|
+
continue;
|
|
134
|
+
out.push({ item, index, boundary, target: resolved.target, summary: resolved.summary });
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
export function findRegisterCareConflicts(routine, summaries, hints) {
|
|
139
|
+
const conflicts = [];
|
|
140
|
+
const { liveOut } = liveSetsForRoutine(routine, summaries, hints);
|
|
141
|
+
for (const { item, index, boundary, target, summary } of resolvedBoundariesForRoutine(routine, summaries)) {
|
|
142
|
+
const accepted = new Set();
|
|
143
|
+
for (const unit of hintUnitsForLine(hints, item.file, item.line))
|
|
144
|
+
accepted.add(unit);
|
|
145
|
+
for (const unit of outputUnits(summary))
|
|
146
|
+
accepted.add(unit);
|
|
147
|
+
const carriers = unique(summary.mayWrite.filter((unit) => liveOut[index].has(unit) && !accepted.has(unit)));
|
|
148
|
+
if (carriers.length > 0) {
|
|
149
|
+
conflicts.push({
|
|
150
|
+
file: item.file,
|
|
151
|
+
line: item.line,
|
|
152
|
+
column: item.column,
|
|
153
|
+
callTarget: target,
|
|
154
|
+
carriers,
|
|
155
|
+
message: `${boundary.subject} may modify ${carriers.join(',')}, but the pre-call value is used later.`,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return conflicts;
|
|
160
|
+
}
|
|
161
|
+
function candidateMessage(boundary, units) {
|
|
162
|
+
const carriers = units.join(',');
|
|
163
|
+
const expectation = units.length === 1 ? units[0] : `{${carriers}}`;
|
|
164
|
+
return `${boundary.subject} writes ${carriers} and caller reads it later; review the call site and add \`; expects out ${expectation}\` above the call if this is intentional.`;
|
|
165
|
+
}
|
|
166
|
+
export function findCallerOutputCandidateObservations(routines, summaries) {
|
|
167
|
+
const out = [];
|
|
168
|
+
for (const routine of routines) {
|
|
169
|
+
const { liveOut } = liveSetsForRoutine(routine, summaries);
|
|
170
|
+
for (const { item, index, boundary, target, summary } of resolvedBoundariesForRoutine(routine, summaries)) {
|
|
171
|
+
const intentionalOutputs = new Set(outputUnits(summary));
|
|
172
|
+
const carrierSources = [];
|
|
173
|
+
for (const unit of summary.mayWrite) {
|
|
174
|
+
if (liveOut[index].has(unit) && !intentionalOutputs.has(unit)) {
|
|
175
|
+
carrierSources.push(unit);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const unit of intentionalOutputs) {
|
|
179
|
+
if (liveOut[index].has(unit)) {
|
|
180
|
+
carrierSources.push(unit);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const carriers = unique(carrierSources);
|
|
184
|
+
if (carriers.length > 0) {
|
|
185
|
+
out.push({
|
|
186
|
+
file: item.file,
|
|
187
|
+
line: item.line,
|
|
188
|
+
column: item.column,
|
|
189
|
+
routine: target,
|
|
190
|
+
carriers,
|
|
191
|
+
message: candidateMessage(boundary, carriers),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
}
|