From 99f2aad0827e5b4ee460236250029f0a27e0fc2d Mon Sep 17 00:00:00 2001 From: zgy-ian Date: Wed, 22 Dec 2021 14:50:21 +0800 Subject: [PATCH 1/2] merge abc files Signed-off-by: zgy-ian --- ts2panda/src/base/util.ts | 14 +- ts2panda/src/cmdOptions.ts | 12 +- ts2panda/src/compiler.ts | 2 +- ts2panda/src/compilerDriver.ts | 253 +++++++++++++++-------- ts2panda/src/debuginfo.ts | 2 +- ts2panda/src/index.ts | 117 ++++++++--- ts2panda/src/pandagen.ts | 20 +- ts2panda/src/pandasm.ts | 17 +- ts2panda/src/statement/classStatement.ts | 9 +- ts2panda/src/ts2panda.ts | 35 +++- ts2panda/ts2abc/ts2abc.cpp | 37 +--- 11 files changed, 332 insertions(+), 186 deletions(-) diff --git a/ts2panda/src/base/util.ts b/ts2panda/src/base/util.ts index c9a2177cad..747e15a0d4 100755 --- a/ts2panda/src/base/util.ts +++ b/ts2panda/src/base/util.ts @@ -28,6 +28,7 @@ import * as jshelpers from "../jshelpers"; import { LOGD } from "../log"; import { ModuleScope, Scope } from "../scope"; import { isFunctionLikeDeclaration } from "../syntaxCheckHelper"; +import { CmdOptions } from "../cmdOptions"; export function containSpreadElement(args?: ts.NodeArray): boolean { if (!args) { @@ -196,7 +197,7 @@ export function initiateTs2abc(args: Array) { args.unshift("--compile-by-pipe"); var spawn = require('child_process').spawn; let child = spawn(js2abc, [...args], { - stdio: ['pipe', 'inherit', 'inherit', 'pipe'] + stdio: ['pipe', 'inherit', 'pipe', 'pipe'] }); return child; @@ -206,10 +207,19 @@ export function terminateWritePipe(ts2abc: any) { if (!ts2abc) { LOGD("ts2abc is not a valid object"); } - ts2abc.stdio[3].end(); } +export function initiateTs2abcChildProcess(outputFileName: string): any { + let ts2abcProcess; + if (!CmdOptions.isAssemblyMode()) { + ts2abcProcess = initiateTs2abc([outputFileName]); + listenChildExit(ts2abcProcess); + listenErrorEvent(ts2abcProcess); + } + return ts2abcProcess; +} + export function listenChildExit(child: any) { if (!child) { LOGD("child is not a valid object"); diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 6a14324b7f..618f76ebdb 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -36,7 +36,8 @@ const ts2pandaOptions = [ 2: other bytecode optimizations, unimplemented yet"}, { name: 'help', alias: 'h', type: Boolean, description: "Show usage guide."}, { name: 'bc-version', alias: 'v', type: Boolean, defaultValue: false, description: "Print ark bytecode version"}, - { name: 'bc-min-version', type: Boolean, defaultValue: false, description: "Print ark bytecode minimum supported version"} + { name: 'bc-min-version', type: Boolean, defaultValue: false, description: "Print ark bytecode minimum supported version"}, + { name: 'merge-abc-files', alias: 'e', type: Boolean, defaultValue: false, description: "Merge multiple abc files into one" } ] export class CmdOptions { @@ -113,7 +114,7 @@ export class CmdOptions { return inputFile; } - static getOutputBinName(): string { + static getOutputFileName(): string { let outputFile = this.options.output; if (outputFile == "") { outputFile = CmdOptions.getInputFileName() + ".abc"; @@ -165,6 +166,13 @@ export class CmdOptions { return this.options["bc-min-version"]; } + static isMergeAbcFiles(): boolean { + if (!this.options) { + return false; + } + return this.options["merge-abc-files"]; + } + static parseUserCmd(args: string[]): ts.ParsedCommandLine | undefined { this.options = commandLineArgs(ts2pandaOptions, { partial: true }); if (this.options.help) { diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index c9230ee088..44536d189e 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -760,7 +760,7 @@ export class Compiler { compileExpression(expr: ts.Expression) { // Please keep order of cases the same as in types.ts - LOGD(this.debugTag, "compile expr:" + expr.kind); + LOGD(this.debugTag, "compile expr:" + this.getNodeName(expr)); switch (expr.kind) { case ts.SyntaxKind.NumericLiteral: // line 34 compileNumericLiteral(this.pandaGen, expr); diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index 46a1533d01..311d10eb8b 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -17,11 +17,9 @@ import { writeFileSync } from "fs"; import * as ts from "typescript"; import { addVariableToScope } from "./addVariable2Scope"; import { AssemblyDumper } from "./assemblyDumper"; -import { initiateTs2abc, listenChildExit, listenErrorEvent, terminateWritePipe } from "./base/util"; +import { initiateTs2abcChildProcess, terminateWritePipe } from "./base/util"; import { CmdOptions } from "./cmdOptions"; -import { - Compiler -} from "./compiler"; +import { Compiler } from "./compiler"; import { CompilerStatistics } from "./compilerStatistics"; import { DebugInfo } from "./debuginfo"; import { hoisting } from "./hoisting"; @@ -57,7 +55,7 @@ export class PendingCompilationUnit { * It handles all dependencies and run passes. */ export class CompilerDriver { - private fileName: string; + private outputfileName: string; private passes: Pass[]; private compilationUnits: PandaGen[]; pendingCompilationUnits: PendingCompilationUnit[]; @@ -66,31 +64,34 @@ export class CompilerDriver { private statistics: CompilerStatistics; private needDumpHeader: boolean = true; private ts2abcProcess: any = undefined; + private sourceFileName: string; - constructor(fileName: string) { - this.fileName = fileName; + constructor(outputFileName: string, ts2abcProc: any, sourceFileName: string) { + this.outputfileName = outputFileName; // register passes here this.passes = [ new CacheExpander(), new IntrinsicExpander(), - new RegAlloc() + new RegAlloc(), ]; this.compilationUnits = []; this.pendingCompilationUnits = []; this.statistics = new CompilerStatistics(); - } - - initiateTs2abcChildProcess() { - this.ts2abcProcess = initiateTs2abc([this.fileName]); + this.ts2abcProcess = ts2abcProc; + this.sourceFileName = sourceFileName; } getTs2abcProcess(): any { if (this.ts2abcProcess === undefined) { - throw new Error("ts2abc hasn't been initiated") + throw new Error("ts2abc hasn't been initiated"); } return this.ts2abcProcess; } + setTs2abcProcess(ts2abcProc: any) { + this.ts2abcProcess = ts2abcProc; + } + getStatistics() { return this.statistics; } @@ -99,7 +100,15 @@ export class CompilerDriver { this.passes = passes; } - addCompilationUnit(decl: ts.FunctionLikeDeclaration, scope: Scope, recorder: Recorder): string { + getSourceFileName(): string { + return this.sourceFileName; + } + + addCompilationUnit( + decl: ts.FunctionLikeDeclaration, + scope: Scope, + recorder: Recorder + ): string { let internalName = this.getFuncInternalName(decl, recorder); this.pendingCompilationUnits.push( new PendingCompilationUnit(decl, scope, internalName) @@ -116,10 +125,10 @@ export class CompilerDriver { } getASTStatistics(node: ts.Node, statics: number[]) { - node.forEachChild(childNode => { + node.forEachChild((childNode) => { statics[childNode.kind] = statics[childNode.kind] + 1; this.getASTStatistics(childNode, statics); - }) + }); } // sort all function in post order @@ -144,68 +153,94 @@ export class CompilerDriver { } compile(node: ts.SourceFile): void { - if (CmdOptions.showASTStatistics()) { - let statics: number[] = new Array(ts.SyntaxKind.Count).fill(0); - - this.getASTStatistics(node, statics); - statics.forEach((element, idx) => { - if (element > 0) { - LOGD(this.kind2String(idx) + " = " + element); - } - }); + this.showASTStatistics(node); + if (!CmdOptions.isMergeAbcFiles()) { + let ts2abcProc: any = initiateTs2abcChildProcess(this.outputfileName); + this.setTs2abcProcess(ts2abcProc); } - let recorder = this.compilePrologue(node); + let recorder: Recorder; + try { + recorder = this.compilePrologue(node); + } catch (err) { + terminateWritePipe(this.getTs2abcProcess()); + throw err; + } - // initiate ts2abc if (!CmdOptions.isAssemblyMode()) { - this.initiateTs2abcChildProcess(); - let ts2abcProc = this.getTs2abcProcess(); - listenChildExit(ts2abcProc); - listenErrorEvent(ts2abcProc); - try { - Ts2Panda.dumpCmdOptions(ts2abcProc); - - for (let i = 0; i < this.pendingCompilationUnits.length; i++) { - let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); + this.prePendingCompilationUnits(recorder); + + if (!CmdOptions.isMergeAbcFiles()) { + Ts2Panda.dumpCmdOptions(this.getTs2abcProcess()); + Ts2Panda.dumpStringsArray(this.getTs2abcProcess()); + Ts2Panda.dumpConstantPool(this.getTs2abcProcess()); + + terminateWritePipe(this.getTs2abcProcess()); + if (CmdOptions.isEnableDebugLog()) { + let jsonFileName = this.outputfileName + .substring(0, this.outputfileName.lastIndexOf(".")) + .concat(".json"); + writeFileSync(jsonFileName, Ts2Panda.jsonString); + LOGD("Successfully generate ", `${jsonFileName}`); + } + + Ts2Panda.clearDumpData(); } - - Ts2Panda.dumpStringsArray(ts2abcProc); - Ts2Panda.dumpConstantPool(ts2abcProc); - - terminateWritePipe(ts2abcProc); - if (CmdOptions.isEnableDebugLog()) { - let jsonFileName = this.fileName.substring(0, this.fileName.lastIndexOf(".")).concat(".json"); - writeFileSync(jsonFileName, Ts2Panda.jsonString); - LOGD("Successfully generate ", `${jsonFileName}`); - } - - Ts2Panda.clearDumpData(); } catch (err) { - terminateWritePipe(ts2abcProc); + terminateWritePipe(this.getTs2abcProcess()); throw err; } } else { - for (let i = 0; i < this.pendingCompilationUnits.length; i++) { - let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); - } + this.prePendingCompilationUnits(recorder); } - PandaGen.clearLiteralArrayBuffer(); + if (!CmdOptions.isMergeAbcFiles()) { + PandaGen.clearLiteralArrayBuffer(); + } } - private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, - internalName: string, recorder: Recorder): void { - let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); + private showASTStatistics(node: ts.SourceFile): void { + if (CmdOptions.showASTStatistics()) { + let statics: number[] = new Array(ts.SyntaxKind.Count).fill(0); + + this.getASTStatistics(node, statics); + statics.forEach((element, idx) => { + if (element > 0) { + LOGD(this.kind2String(idx) + " = " + element); + } + }); + } + } + + private prePendingCompilationUnits(recorder: Recorder): void { + for (let i = 0; i < this.pendingCompilationUnits.length; i++) { + let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; + this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); + } + } + + private compileImpl( + node: ts.SourceFile | ts.FunctionLikeDeclaration, + scope: Scope, + internalName: string, + recorder: Recorder + ): void { + let pandaGen = new PandaGen( + internalName, + this.getParametersCount(node), + scope + ); // for debug info DebugInfo.addDebugIns(scope, pandaGen, true); let compiler = new Compiler(node, pandaGen, this, recorder); - if (CmdOptions.isModules() && ts.isSourceFile(node) && scope instanceof ModuleScope) { + if ( + CmdOptions.isModules() && + ts.isSourceFile(node) && + scope instanceof ModuleScope + ) { setImport(recorder.getImportStmts(), scope, pandaGen); setExportBinding(recorder.getExportStmts(), scope, pandaGen); } @@ -232,23 +267,46 @@ export class CompilerDriver { } } + compileForSyntaxCheck(node: ts.SourceFile): void { + let recorder = this.compilePrologue(node); + checkDuplicateDeclaration(recorder); + checkExportEntries(recorder); + } + compileUnitTest(node: ts.SourceFile): void { let recorder = this.compilePrologue(node); for (let i = 0; i < this.pendingCompilationUnits.length; i++) { let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileUnitTestImpl(unit.decl, unit.scope, unit.internalName, recorder); + this.compileUnitTestImpl( + unit.decl, + unit.scope, + unit.internalName, + recorder + ); } PandaGen.clearLiteralArrayBuffer(); } - private compileUnitTestImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, - internalName: string, recorder: Recorder) { - let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); + private compileUnitTestImpl( + node: ts.SourceFile | ts.FunctionLikeDeclaration, + scope: Scope, + internalName: string, + recorder: Recorder + ) { + let pandaGen = new PandaGen( + internalName, + this.getParametersCount(node), + scope + ); let compiler = new Compiler(node, pandaGen, this, recorder); - if (CmdOptions.isModules() && ts.isSourceFile(node) && scope instanceof ModuleScope) { + if ( + CmdOptions.isModules() && + ts.isSourceFile(node) && + scope instanceof ModuleScope + ) { setImport(recorder.getImportStmts(), scope, pandaGen); setExportBinding(recorder.getExportStmts(), scope, pandaGen); } @@ -278,7 +336,11 @@ export class CompilerDriver { let postOrderVariableScopes = this.postOrderAnalysis(topLevelScope); for (let variableScope of postOrderVariableScopes) { - this.addCompilationUnit(variableScope.getBindingNode(), variableScope, recorder); + this.addCompilationUnit( + variableScope.getBindingNode(), + variableScope, + recorder + ); } return recorder; @@ -294,7 +356,9 @@ export class CompilerDriver { } } - getFuncId(node: ts.SourceFile | ts.FunctionLikeDeclaration | ts.ClassLikeDeclaration): number { + getFuncId( + node: ts.SourceFile | ts.FunctionLikeDeclaration | ts.ClassLikeDeclaration + ): number { if (this.funcIdMap.has(node)) { return this.funcIdMap.get(node)!; } @@ -310,11 +374,22 @@ export class CompilerDriver { return idx; } + getRecoderFuncName(funcName: string): string { + if (CmdOptions.isMergeAbcFiles()) { + let recoderName: string = this.sourceFileName.substring(0, this.sourceFileName.lastIndexOf(".")); + funcName = `${recoderName}.${funcName}` + } + return funcName; + } + /** * Internal name is used to indentify a function in panda file * Runtime uses this name to bind code and a Function object */ - getFuncInternalName(node: ts.SourceFile | ts.FunctionLikeDeclaration, recorder: Recorder): string { + getFuncInternalName( + node: ts.SourceFile | ts.FunctionLikeDeclaration, + recorder: Recorder + ): string { let name: string; if (ts.isSourceFile(node)) { name = "func_main_0"; @@ -324,36 +399,34 @@ export class CompilerDriver { } else { let funcNode = node; name = (recorder.getScopeOfNode(funcNode)).getFuncName(); - if (name == '') { - return `#${this.getFuncId(funcNode)}#`; - } - - if (name == "func_main_0") { - return `#${this.getFuncId(funcNode)}#${name}`; - } - - let funcNameMap = recorder.getFuncNameMap(); - if (funcNameMap.has(name)) { - let freq = funcNameMap.get(name); - if (freq > 1) { - name = `#${this.getFuncId(funcNode)}#${name}`; - } + if (name == "") { + name = `#${this.getFuncId(funcNode)}#`; + } else if (name == "func_main_0") { + name = `#${this.getFuncId(funcNode)}#${name}`; } else { - throw new Error("the function name is missing from the name map"); - } + let funcNameMap = recorder.getFuncNameMap(); + if (funcNameMap.has(name)) { + let freq = funcNameMap.get(name); + if (freq > 1) { + name = `#${this.getFuncId(funcNode)}#${name}`; + } + } else { + throw new Error("the function name is missing from the name map"); + } - if (name.lastIndexOf(".") != -1) { - name = `#${this.getFuncId(funcNode)}#` + if (name.lastIndexOf(".") != -1) { + name = `#${this.getFuncId(funcNode)}#`; + } } } - return name; + return this.getRecoderFuncName(name); } getInternalNameForCtor(node: ts.ClassLikeDeclaration) { let name = getClassNameForConstructor(node); - name = `#${this.getFuncId(node)}#${name}` + name = `#${this.getFuncId(node)}#${name}`; if (name.lastIndexOf(".") != -1) { - name = `#${this.getFuncId(node)}#` + name = `#${this.getFuncId(node)}#`; } return name; } @@ -366,7 +439,9 @@ export class CompilerDriver { new AssemblyDumper(pandaGen).dump(); } - private getParametersCount(node: ts.SourceFile | ts.FunctionLikeDeclaration): number { + private getParametersCount( + node: ts.SourceFile | ts.FunctionLikeDeclaration + ): number { // each function and global scope accepts three parameters - funcObj + newTarget + this. // the runtime passes these to global scope when calls it let parametersCount = 3; diff --git a/ts2panda/src/debuginfo.ts b/ts2panda/src/debuginfo.ts index 527b8f0d50..a0a7b01fa2 100644 --- a/ts2panda/src/debuginfo.ts +++ b/ts2panda/src/debuginfo.ts @@ -349,7 +349,7 @@ export class DebugInfo { public static setSourceFileDebugInfo(pandaGen: PandaGen, node: ts.SourceFile | ts.FunctionLikeDeclaration) { let sourceFile = jshelpers.getSourceFileOfNode(node); - pandaGen.setSourceFileDebugInfo(sourceFile.fileName); + pandaGen.setSourceFileName(sourceFile.fileName); if (CmdOptions.isDebugMode()) { if (ts.isSourceFile(node)) { diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index f778f0a75e..c786777bd8 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -13,61 +13,66 @@ * limitations under the License. */ +import { writeFileSync } from "fs"; import * as ts from "typescript"; +import { initiateTs2abcChildProcess, terminateWritePipe } from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { CompilerDriver } from "./compilerDriver"; import * as diag from "./diagnostic"; import { LOGD, LOGE } from "./log"; +import { PandaGen } from "./pandagen"; +import { Record } from "./pandasm"; import { Pass } from "./pass"; import { CacheExpander } from "./pass/cacheExpander"; import { ICPass } from "./pass/ICPass"; import { RegAlloc } from "./regAllocator"; import { setGlobalStrict } from "./strictMode"; +import { Ts2Panda } from "./ts2panda"; import jshelpers = require("./jshelpers"); function main(fileNames: string[], options: ts.CompilerOptions) { - let program = ts.createProgram(fileNames, options); + let program: ts.Program = ts.createProgram(fileNames, options); + let outputFileName: string = CmdOptions.getOutputFileName(); + + let ts2abcProc: any + if (CmdOptions.isMergeAbcFiles()) { + ts2abcProc = initiateTs2abcChildProcess(outputFileName); + } + let emitResult = program.emit( - undefined, - undefined, - undefined, - undefined, + undefined, undefined, undefined, undefined, { before: [ (ctx: ts.TransformationContext) => { return (node: ts.SourceFile) => { - let outputBinName = CmdOptions.getOutputBinName(); - let fileName = node.fileName.substring(0, node.fileName.lastIndexOf('.')); - if (fileName != CmdOptions.getInputFileName()) { - outputBinName = fileName + ".abc"; - } - let compilerDriver = new CompilerDriver(outputBinName); - setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); - if (CmdOptions.isVariantBytecode()) { - LOGD("variant bytecode dump"); - let passes: Pass[] = [ - new CacheExpander(), - new ICPass(), - new RegAlloc() - ]; - compilerDriver.setCustomPasses(passes); - } - compilerDriver.compile(node); - compilerDriver.showStatistics(); - return node; + return ts2abcTransform(node, outputFileName, options, ts2abcProc); } } ] } ); - let allDiagnostics = ts - .getPreEmitDiagnostics(program) - .concat(emitResult.diagnostics); + if (preDiagnostics(program, emitResult)) { + return; + } - allDiagnostics.forEach(diagnostic => { - diag.printDiagnostic(diagnostic); - }); + if (!CmdOptions.isAssemblyMode()) { + if (CmdOptions.isMergeAbcFiles()) { + Ts2Panda.dumpCmdOptions(ts2abcProc); + Ts2Panda.dumpStringsArray(ts2abcProc); + Ts2Panda.dumpConstantPool(ts2abcProc); + Ts2Panda.dumpRecoder(ts2abcProc); + + terminateWritePipe(ts2abcProc); + if (CmdOptions.isEnableDebugLog()) { + let jsonFileName = outputFileName.substring(0, outputFileName.lastIndexOf(".")).concat(".json"); + writeFileSync(jsonFileName, Ts2Panda.jsonString); + LOGD("Successfully generate ", `${jsonFileName}`); + } + Ts2Panda.clearDumpData(); + PandaGen.clearLiteralArrayBuffer(); + } + } } namespace Compiler { @@ -86,6 +91,53 @@ namespace Compiler { } } +function ts2abcTransform(node: ts.SourceFile, + outputFileName: string, + options: ts.CompilerOptions, + ts2abcProc: any): ts.SourceFile { + let sourceFileName: string = node.fileName; + let name: string = sourceFileName.substring(0, sourceFileName.lastIndexOf(".")); + let recoder: Record = new Record(name, sourceFileName); + let recoders: Array = PandaGen.getRecoders(); + recoders.push(recoder); + let newOutputFileName: string = getOutputFileName(node, outputFileName); + let compilerDriver = new CompilerDriver(newOutputFileName, ts2abcProc, sourceFileName); + setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); + if (CmdOptions.isVariantBytecode()) { + LOGD("variant bytecode dump"); + let passes: Pass[] = [ + new CacheExpander(), + new ICPass(), + new RegAlloc() + ]; + compilerDriver.setCustomPasses(passes); + } + compilerDriver.compile(node); + compilerDriver.showStatistics(); + return node; +} + +function preDiagnostics(program: ts.Program, emitResult: ts.EmitResult): boolean { + let hasDiagnostics: boolean = false; + let allDiagnostics: ts.Diagnostic[] = ts + .getPreEmitDiagnostics(program) + .concat(emitResult.diagnostics); + + allDiagnostics.forEach((diagnostic: ts.Diagnostic) => { + diag.printDiagnostic(diagnostic); + hasDiagnostics = true; + }); + return hasDiagnostics; +} + +function getOutputFileName(node: ts.SourceFile, outputFileName: string): string { + let fileName = node.fileName.substring(0, node.fileName.lastIndexOf('.')); + if (fileName != CmdOptions.getInputFileName()) { + outputFileName = fileName + ".abc"; + } + return outputFileName; +} + function run(args: string[], options?: ts.CompilerOptions): void { let parsed = CmdOptions.parseUserCmd(args); if (!parsed) { @@ -101,9 +153,10 @@ function run(args: string[], options?: ts.CompilerOptions): void { main(parsed.fileNames, parsed.options); } catch (err) { if (err instanceof diag.DiagnosticError) { - let diagnostic = diag.getDiagnostic(err.code); + let diagError: diag.DiagnosticError = err; + let diagnostic = diag.getDiagnostic(diagError.code); if (diagnostic != undefined) { - let diagnosticLog = diag.createDiagnostic(err.file, err.irnode, diagnostic, ...err.args); + let diagnosticLog = diag.createDiagnostic(diagError.file, diagError.irnode, diagnostic, ...diagError.args); diag.printDiagnostic(diagnosticLog); } } else if (err instanceof SyntaxError) { diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index 1b56905a96..ad839941b3 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -173,6 +173,7 @@ import { VariableAcessStore } from "./lexenv"; import { LOGE } from "./log"; +import { Record } from "./pandasm"; import { FunctionScope, LoopScope, @@ -198,12 +199,13 @@ export class PandaGen { // for debug info private variableDebugInfoArray: VariableDebugInfo[] = []; private firstStmt: ts.Statement | undefined; - private sourceFileDebugInfo: string = ""; + private sourceFileName: string = ""; private sourceCodeDebugInfo: string | undefined; private icSize: number = 0; private callType: number = 0; private static literalArrayBuffer: Array = []; + private static recoders: Array = []; constructor(internalName: string, parametersCount: number, scope: Scope | undefined = undefined) { this.internalName = internalName; @@ -228,12 +230,12 @@ export class PandaGen { this.sourceCodeDebugInfo = code; } - public getSourceFileDebugInfo() { - return this.sourceFileDebugInfo; + public getSourceFileName() { + return this.sourceFileName; } - public setSourceFileDebugInfo(sourceFile: string) { - this.sourceFileDebugInfo = sourceFile; + public setSourceFileName(sourceFile: string) { + this.sourceFileName = sourceFile; } static getLiteralArrayBuffer() { @@ -244,6 +246,14 @@ export class PandaGen { PandaGen.literalArrayBuffer = []; } + static getRecoders() { + return PandaGen.recoders; + } + + static clearRecoders() { + PandaGen.recoders = []; + } + getParameterLength() { if (this.scope instanceof FunctionScope) { return this.scope.getParameterLength(); diff --git a/ts2panda/src/pandasm.ts b/ts2panda/src/pandasm.ts index c523f7fa87..8f0f7156dc 100644 --- a/ts2panda/src/pandasm.ts +++ b/ts2panda/src/pandasm.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { DebugPosInfo, VariableDebugInfo } from "./debuginfo"; import { LiteralBuffer } from "./base/literal"; +import { DebugPosInfo, VariableDebugInfo } from "./debuginfo"; export class Metadata { public attribute: string; @@ -101,25 +101,16 @@ export class Function { export class Record { public name: string; - public whole_line: string; - public bound_left: number; - public bound_right: number; - public line_number: number; public metadata: Metadata; + public source_file: string; constructor( name: string, - whole_line: string, - bound_left: number, - bound_right: number, - line_number: number + source_file: string ) { this.name = name; - this.whole_line = whole_line; - this.bound_left = bound_left; - this.bound_right = bound_right; - this.line_number = line_number; this.metadata = new Metadata(); + this.source_file = source_file; } } diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index d346350f80..296b9394d1 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -13,7 +13,6 @@ * limitations under the License. */ -import { Ts2Panda } from "src/ts2panda"; import * as ts from "typescript"; import { Literal, LiteralBuffer, LiteralTag } from "../base/literal"; import { LReference } from "../base/lreference"; @@ -26,6 +25,7 @@ import { } from "../base/properties"; import { getParameterLength4Ctor, getParamLengthOfFunc, isUndefinedIdentifier } from "../base/util"; import { CacheList, getVregisterCache } from "../base/vregisterCache"; +import { CmdOptions } from "../cmdOptions"; import { Compiler } from "../compiler"; import { createArrayFromElements } from "../expression/arrayLiteralExpression"; import { createMethodOrAccessor } from "../expression/objectLiteralExpression"; @@ -238,6 +238,11 @@ function createClassLiteralBuf(compiler: Compiler, classBuffer: LiteralBuffer, let classLiteralBuf = PandaGen.getLiteralArrayBuffer(); let buffIdx = classLiteralBuf.length; let internalName = compiler.getCompilerDriver().getInternalNameForCtor(stmt); + if (CmdOptions.isMergeAbcFiles()) { + let sourceFileName: string = compiler.getCompilerDriver().getSourceFileName(); + let recoderName: string = sourceFileName.substring(0, sourceFileName.lastIndexOf(".")); + internalName = `${recoderName}.${internalName}` + } classLiteralBuf.push(classBuffer); let parameterLength = getParameterLength4Ctor(stmt); @@ -651,7 +656,7 @@ function scalarArrayEquals(node1: ts.Node | undefined, node2: ts.Node | undefine let val1Modifs = node1.modifiers; let val2Modifs = node2.modifiers; if (val1Modifs && val2Modifs) { - return val1Modifs.length == val2Modifs.length && val1Modifs.every(function(v, i) { return v === val2Modifs![i] });; + return val1Modifs.length == val2Modifs.length && val1Modifs.every(function (v, i) { return v === val2Modifs![i] });; } if (!val1Modifs && !val2Modifs) { diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index e3b60b281e..a85d1ef899 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -13,6 +13,7 @@ * limitations under the License. */ +import { escapeUnicode, getRangeStartVregPos, isRangeInst } from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { DebugPosInfo } from "./debuginfo"; import { @@ -24,9 +25,8 @@ import { } from "./irnodes"; import { LOGD } from "./log"; import { PandaGen } from "./pandagen"; -import { CatchTable, Function, Ins, Signature } from "./pandasm"; +import { CatchTable, Function, Ins, Record, Signature } from "./pandasm"; import { generateCatchTables } from "./statement/tryStatement"; -import { escapeUnicode, isRangeInst, getRangeStartVregPos } from "./base/util"; const dollarSign: RegExp = /\$/g; @@ -119,7 +119,7 @@ export class Ts2Panda { Ts2Panda.jsonString += escapeUnicode(JSON.stringify(strings_arr, null, 2)); } - strings_arr.forEach(function(str){ + strings_arr.forEach(function (str: string) { let strObject = { "type": JsonType.string, "string": str @@ -133,22 +133,39 @@ export class Ts2Panda { static dumpConstantPool(ts2abc: any): void { let literalArrays = PandaGen.getLiteralArrayBuffer(); - if (CmdOptions.isEnableDebugLog()) { - Ts2Panda.jsonString += escapeUnicode(JSON.stringify(literalArrays, null, 2)); - } - literalArrays.forEach(function(literalArray){ + literalArrays.forEach(function (literalArray) { let literalArrayObject = { "type": JsonType.literal_arr, "literalArray": literalArray } let jsonLiteralArrUnicode = escapeUnicode(JSON.stringify(literalArrayObject, null, 2)); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonLiteralArrUnicode; + } jsonLiteralArrUnicode = "$" + jsonLiteralArrUnicode.replace(dollarSign, '#$') + "$"; ts2abc.stdio[3].write(jsonLiteralArrUnicode + '\n'); }); } - static dumpCmdOptions(ts2abc: any): void { + static dumpRecoder(ts2abc: any): void { + let recoders: Record[] = PandaGen.getRecoders(); + + recoders.forEach(function (recoder: Record) { + let recoderObject = { + "type": JsonType.record, + "rec_body": recoder + } + let jsonRecoderUnicode = escapeUnicode(JSON.stringify(recoderObject, null, 2)); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonRecoderUnicode; + } + jsonRecoderUnicode = "$" + jsonRecoderUnicode.replace(dollarSign, '#$') + "$"; + ts2abc.stdio[3].write(jsonRecoderUnicode + '\n'); + }); + } + + static dumpCmdOptions(ts2abc: any): void { let options = { "type": JsonType.options, "module_mode": CmdOptions.isModules(), @@ -169,7 +186,7 @@ export class Ts2Panda { let funcName = pg.internalName; let funcSignature = Ts2Panda.getFuncSignature(pg); let funcInsnsAndRegsNum = Ts2Panda.getFuncInsnsAndRegsNum(pg); - let sourceFile = pg.getSourceFileDebugInfo(); + let sourceFile = pg.getSourceFileName(); let callType = pg.getCallType(); let variables, sourceCode; diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 0e72bf4f5e..5fdfe75ee5 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -71,17 +71,11 @@ namespace { } // pandasm hellpers -static panda::pandasm::Record MakeRecordDefinition(const std::string &name, const std::string &wholeLine, - size_t boundLeft, size_t boundRight, size_t lineNumber) +static panda::pandasm::Record MakeRecordDefinition(const std::string &name) { auto record = panda::pandasm::Record( name, - LANG_EXT, - boundLeft, - boundRight, - wholeLine, - IS_DEFINED, - lineNumber); + LANG_EXT); return record; } @@ -275,28 +269,7 @@ static panda::pandasm::Record ParseRecord(const Json::Value &record) recordName = record["name"].asString(); } - std::string wholeLine = ""; - if (record.isMember("whole_line") && record["whole_line"].isString()) { - wholeLine = ParseString(record["whole_line"].asString()); - } - - int boundLeft = -1; - if (record.isMember("bound_left") && record["bound_left"].isInt()) { - boundLeft = record["bound_left"].asInt(); - } - - int boundRight = -1; - if (record.isMember("bound_right") && record["bound_right"].isInt()) { - boundRight = record["bound_right"].asInt(); - } - - int lineNumber = -1; - if (record.isMember("line_number") && record["line_number"].isInt()) { - lineNumber = record["line_number"].asInt(); - } - - auto pandaRecord = MakeRecordDefinition(recordName, wholeLine, static_cast(boundLeft), - static_cast(boundRight), static_cast(lineNumber)); + auto pandaRecord = MakeRecordDefinition(recordName); if (record.isMember("metadata") && record["metadata"].isObject()) { auto metadata = record["metadata"]; @@ -308,6 +281,10 @@ static panda::pandasm::Record ParseRecord(const Json::Value &record) } } + if (record.isMember("source_file") && record["source_file"].isString()) { + pandaRecord.source_file = record["source_file"].asString(); + } + return pandaRecord; } -- Gitee From 32871864a4442b732f1064b90976fe7cad50cc53 Mon Sep 17 00:00:00 2001 From: zgy-ian Date: Fri, 7 Jan 2022 10:33:30 +0800 Subject: [PATCH 2/2] merge abc files Signed-off-by: zgy-ian --- ts2panda/src/compilerDriver.ts | 21 ++++++--------------- ts2panda/src/index.ts | 17 +++-------------- ts2panda/src/ts2panda.ts | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index 311d10eb8b..38b02e126a 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -13,11 +13,13 @@ * limitations under the License. */ -import { writeFileSync } from "fs"; import * as ts from "typescript"; import { addVariableToScope } from "./addVariable2Scope"; import { AssemblyDumper } from "./assemblyDumper"; -import { initiateTs2abcChildProcess, terminateWritePipe } from "./base/util"; +import { + initiateTs2abcChildProcess, + terminateWritePipe +} from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { Compiler } from "./compiler"; import { CompilerStatistics } from "./compilerStatistics"; @@ -172,19 +174,7 @@ export class CompilerDriver { this.prePendingCompilationUnits(recorder); if (!CmdOptions.isMergeAbcFiles()) { - Ts2Panda.dumpCmdOptions(this.getTs2abcProcess()); - Ts2Panda.dumpStringsArray(this.getTs2abcProcess()); - Ts2Panda.dumpConstantPool(this.getTs2abcProcess()); - - terminateWritePipe(this.getTs2abcProcess()); - if (CmdOptions.isEnableDebugLog()) { - let jsonFileName = this.outputfileName - .substring(0, this.outputfileName.lastIndexOf(".")) - .concat(".json"); - writeFileSync(jsonFileName, Ts2Panda.jsonString); - LOGD("Successfully generate ", `${jsonFileName}`); - } - + Ts2Panda.dumpCommonFields(this.getTs2abcProcess(), this.outputfileName); Ts2Panda.clearDumpData(); } } catch (err) { @@ -196,6 +186,7 @@ export class CompilerDriver { } if (!CmdOptions.isMergeAbcFiles()) { + PandaGen.clearRecoders(); PandaGen.clearLiteralArrayBuffer(); } } diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index c786777bd8..29be3ae1f8 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -13,9 +13,8 @@ * limitations under the License. */ -import { writeFileSync } from "fs"; import * as ts from "typescript"; -import { initiateTs2abcChildProcess, terminateWritePipe } from "./base/util"; +import { initiateTs2abcChildProcess } from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { CompilerDriver } from "./compilerDriver"; import * as diag from "./diagnostic"; @@ -58,18 +57,8 @@ function main(fileNames: string[], options: ts.CompilerOptions) { if (!CmdOptions.isAssemblyMode()) { if (CmdOptions.isMergeAbcFiles()) { - Ts2Panda.dumpCmdOptions(ts2abcProc); - Ts2Panda.dumpStringsArray(ts2abcProc); - Ts2Panda.dumpConstantPool(ts2abcProc); - Ts2Panda.dumpRecoder(ts2abcProc); - - terminateWritePipe(ts2abcProc); - if (CmdOptions.isEnableDebugLog()) { - let jsonFileName = outputFileName.substring(0, outputFileName.lastIndexOf(".")).concat(".json"); - writeFileSync(jsonFileName, Ts2Panda.jsonString); - LOGD("Successfully generate ", `${jsonFileName}`); - } - Ts2Panda.clearDumpData(); + Ts2Panda.dumpCommonFields(ts2abcProc, outputFileName); + PandaGen.clearRecoders(); PandaGen.clearLiteralArrayBuffer(); } } diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index a85d1ef899..bb9b772344 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -13,7 +13,13 @@ * limitations under the License. */ -import { escapeUnicode, getRangeStartVregPos, isRangeInst } from "./base/util"; +import { writeFileSync } from "fs"; +import { + escapeUnicode, + getRangeStartVregPos, + isRangeInst, + terminateWritePipe +} from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { DebugPosInfo } from "./debuginfo"; import { @@ -25,7 +31,13 @@ import { } from "./irnodes"; import { LOGD } from "./log"; import { PandaGen } from "./pandagen"; -import { CatchTable, Function, Ins, Record, Signature } from "./pandasm"; +import { + CatchTable, + Function, + Ins, + Record, + Signature +} from "./pandasm"; import { generateCatchTables } from "./statement/tryStatement"; const dollarSign: RegExp = /\$/g; @@ -143,6 +155,7 @@ export class Ts2Panda { if (CmdOptions.isEnableDebugLog()) { Ts2Panda.jsonString += jsonLiteralArrUnicode; } + jsonLiteralArrUnicode = "$" + jsonLiteralArrUnicode.replace(dollarSign, '#$') + "$"; ts2abc.stdio[3].write(jsonLiteralArrUnicode + '\n'); }); @@ -240,4 +253,19 @@ export class Ts2Panda { Ts2Panda.strings.clear(); Ts2Panda.jsonString = ""; } + + static dumpCommonFields(ts2abcProc: any, outputFileName: string) { + Ts2Panda.dumpCmdOptions(ts2abcProc); + Ts2Panda.dumpStringsArray(ts2abcProc); + Ts2Panda.dumpConstantPool(ts2abcProc); + Ts2Panda.dumpRecoder(ts2abcProc); + + terminateWritePipe(ts2abcProc); + if (CmdOptions.isEnableDebugLog()) { + let jsonFileName = outputFileName.substring(0, outputFileName.lastIndexOf(".")).concat(".json"); + writeFileSync(jsonFileName, Ts2Panda.jsonString); + LOGD("Successfully generate ", `${jsonFileName}`); + } + Ts2Panda.clearDumpData(); + } } -- Gitee