From 1972ec604951e4217f07e4f2eadd1f2c37ddc887 Mon Sep 17 00:00:00 2001 From: hufeng Date: Wed, 2 Mar 2022 16:33:16 +0800 Subject: [PATCH 1/4] opt debuginfo Signed-off-by: hufeng Change-Id: I72f9023bb7db08fbaed1d798bf1ae541ec0f151b --- ts2panda/src/debuginfo.ts | 126 ++++++++--------------- ts2panda/src/scope.ts | 21 ++-- ts2panda/src/statement/classStatement.ts | 2 +- ts2panda/src/ts2panda.ts | 12 +-- ts2panda/templates/irnodes.ts.erb | 30 +++++- 5 files changed, 84 insertions(+), 107 deletions(-) diff --git a/ts2panda/src/debuginfo.ts b/ts2panda/src/debuginfo.ts index 0519b3ba20..67f03b09b2 100644 --- a/ts2panda/src/debuginfo.ts +++ b/ts2panda/src/debuginfo.ts @@ -18,7 +18,8 @@ import { CmdOptions } from "./cmdOptions"; import { CalliDynRange, CallRange, - DebugInsPlaceHolder, + DebugInsStartPlaceHolder, + DebugInsEndPlaceHolder, IRNode, Label, VReg @@ -31,11 +32,10 @@ import { } from "./variable"; export class DebugPosInfo { - private bl: number | undefined = 0; // bound left - private br: number | undefined = 0; // bound right + private bl: number | undefined; // bound left + private br: number | undefined; // bound right private l: number = -1; // line number private c: number = -1; // column number - private w: string | undefined = ""; // whole line private nodeKind: NodeKind | undefined = NodeKind.FirstNodeOfFunction; constructor() { } @@ -84,22 +84,7 @@ export class DebugPosInfo { return this.c; } - public setWholeLine(wholeLine: string): void { - this.w = wholeLine; - } - - public getWholeLine(): string | undefined { - return this.w; - } - - public ClearMembersForReleaseBuild(): void { - this.ClearMembersForDebugBuild(); - this.bl = undefined; - this.br = undefined; - } - - public ClearMembersForDebugBuild(): void { - this.w = undefined; + public ClearNodeKind(): void { this.nodeKind = undefined; } } @@ -185,17 +170,14 @@ export class DebugInfo { loc: { line : -1, character : -1 - }, - wholeLineText: "" + } } } pos = node.getStart(); let loc = file.getLineAndCharacterOfPosition(pos); - let wholeLineText = node.getText(); return { - loc: loc, - wholeLineText: wholeLineText + loc: loc } } @@ -208,7 +190,6 @@ export class DebugInfo { } posInfo.setSourecLineNum(res.loc.line); posInfo.setSourecColumnNum(res.loc.character); - posInfo.setWholeLine(res.wholeLineText); } } @@ -229,27 +210,21 @@ export class DebugInfo { let lineNumber = -1; let columnNumber = -1; - let wholeLineText = ""; if (DebugInfo.isNode(node)) { let tsNode = (node); let res = this.searchForPos(tsNode); if (!res) { return; } - wholeLineText = res.wholeLineText; lineNumber = res.loc.line; columnNumber = res.loc.character; } - for (let i = 0; i < insns.length; i++) { - let pos = new DebugPosInfo(); - pos.setSourecLineNum(lineNumber); - pos.setSourecColumnNum(columnNumber); - pos.setWholeLine(wholeLineText); - pos.setDebugPosInfoNodeState(node); - - insns[i].debugPosInfo = pos; - } + insns.forEach(insn => { + insn.debugPosInfo.setSourecLineNum(lineNumber); + insn.debugPosInfo.setSourecColumnNum(columnNumber); + insn.debugPosInfo.setDebugPosInfoNodeState(node); + }) } private static matchFormat(irnode: IRNode): number { @@ -270,7 +245,9 @@ export class DebugInfo { } private static getIRNodeWholeLength(irnode: IRNode): number { - if (irnode instanceof Label || irnode instanceof DebugInsPlaceHolder) { + if (irnode instanceof Label || + irnode instanceof DebugInsStartPlaceHolder || + irnode instanceof DebugInsEndPlaceHolder) { return 0; } let length = 1; @@ -293,49 +270,20 @@ export class DebugInfo { return length; } - private static setVariablesDebugInfoInternal(pandaGen: PandaGen, scope: Scope) { - let insns = pandaGen.getInsns(); - // count variables offset - let startIdx = 0; - let startIns = scope.getScopeStartIns(); - let endIns = scope.getScopeEndIns(); - - for (let i = 0; i < insns.length; i++) { - if (startIns == insns[i]) { - startIdx = i; - } - - if (endIns == insns[i]) { - let name2variable = scope.getName2variable(); - name2variable.forEach((value, key) => { - if (!value.hasAlreadyBinded()) { - return; - } - let variableInfo = new VariableDebugInfo(key, "any", "any", (value.getVreg().num)); - variableInfo.setStart(startIdx); - variableInfo.setLength(i - startIdx + 1); - pandaGen.addDebugVariableInfo(variableInfo); - }); - } - } - } - private static setPosDebugInfo(pandaGen: PandaGen) { - let insns = pandaGen.getInsns(); + let insns: IRNode[] = pandaGen.getInsns(); let offset = 0; + // count pos offset for (let i = 0; i < insns.length; i++) { if (insns[i].debugPosInfo.getDebugPosInfoNodeState() == NodeKind.FirstNodeOfFunction) { DebugInfo.setPosInfoForUninitializeIns(insns[i].debugPosInfo, pandaGen); } - } - // count pos offset - for (let i = 0; i < insns.length; i++) { let insLength = DebugInfo.getIRNodeWholeLength(insns[i]); let insnsDebugPosInfo = insns[i].debugPosInfo; - if (insnsDebugPosInfo) { + if (insnsDebugPosInfo && CmdOptions.isDebugMode()) { insnsDebugPosInfo.setBoundLeft(offset); insnsDebugPosInfo.setBoundRight(offset + insLength); } @@ -348,20 +296,36 @@ export class DebugInfo { } } - private static removeDebugIns(pandaGen: PandaGen) { + private static setVariablesDebugInfo(pandaGen: PandaGen) { let insns = pandaGen.getInsns(); + for (let i = 0; i < insns.length; i++) { - if (insns[i] instanceof DebugInsPlaceHolder) { + if (insns[i] instanceof DebugInsStartPlaceHolder) { + ( insns[i]).getScope().setScopeStartInsIdx(i); + // delete ins placeholder + insns.splice(i, 1); + i--; + } + if (insns[i] instanceof DebugInsEndPlaceHolder) { + ( insns[i]).getScope().setScopeEndInsIdx(i); + // delete ins placeholder insns.splice(i, 1); i--; } } - } - private static setVariablesDebugInfo(pandaGen: PandaGen) { let recordArray = DebugInfo.getScopeArray(); recordArray.forEach(scope => { - DebugInfo.setVariablesDebugInfoInternal(pandaGen, scope); + let name2variable = scope.getName2variable(); + name2variable.forEach((value, key) => { + if (!value.hasAlreadyBinded()) { + return; + } + let variableInfo = new VariableDebugInfo(key, "any", "any", (value.getVreg().num)); + variableInfo.setStart(scope.getScopeStartInsIdx()); + variableInfo.setLength(scope.getScopeEndInsIdx() - scope.getScopeStartInsIdx()); + pandaGen.addDebugVariableInfo(variableInfo); + }); }); } @@ -372,9 +336,6 @@ export class DebugInfo { // set variable debug info DebugInfo.setVariablesDebugInfo(pandaGen); - // delete ins placeholder - DebugInfo.removeDebugIns(pandaGen) - // clear scope array DebugInfo.clearScopeArray(); return; @@ -405,14 +366,15 @@ export class DebugInfo { if (!CmdOptions.isDebugMode()) { return; } + let insns = pandaGen.getInsns(); - let placeHolder = new DebugInsPlaceHolder(); - insns.push(placeHolder); + let placeHolder: IRNode; if (isStart) { - scope.setScopeStartIns(placeHolder); + placeHolder = new DebugInsStartPlaceHolder(scope); DebugInfo.addScope(scope); } else { - scope.setScopeEndIns(placeHolder); + placeHolder = new DebugInsEndPlaceHolder(scope); } + insns.push(placeHolder); } } diff --git a/ts2panda/src/scope.ts b/ts2panda/src/scope.ts index 6de907b653..52cf3bbcde 100644 --- a/ts2panda/src/scope.ts +++ b/ts2panda/src/scope.ts @@ -14,7 +14,6 @@ */ import * as ts from "typescript"; -import { DebugInsPlaceHolder } from "./irnodes"; import { LOGD, LOGE } from "./log"; import { GlobalVariable, @@ -86,8 +85,8 @@ export abstract class Scope { protected decls: Decl[] = []; protected parent: Scope | undefined = undefined; // for debuginfo - protected startIns: DebugInsPlaceHolder = new DebugInsPlaceHolder(); - protected endIns: DebugInsPlaceHolder = new DebugInsPlaceHolder(); + protected startInsIdx: number | undefined; + protected endInsIdx: number | undefined; private callOpt: Set = new Set(); private isArgumentsOrRestargs: boolean = false; @@ -99,20 +98,20 @@ export abstract class Scope { return this.name2variable; } - getScopeStartIns() { - return this.startIns; + getScopeStartInsIdx() { + return this.startInsIdx; } - setScopeStartIns(startIns: DebugInsPlaceHolder) { - this.startIns = startIns; + setScopeStartInsIdx(startInsIdx: number) { + this.startInsIdx = startInsIdx; } - setScopeEndIns(endIns: DebugInsPlaceHolder) { - this.endIns = endIns; + setScopeEndInsIdx(endInsIdx: number) { + this.endInsIdx = endInsIdx; } - getScopeEndIns() { - return this.endIns; + getScopeEndInsIdx() { + return this.endInsIdx; } setParent(parentScope: Scope | undefined) { diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index 26d86846d4..880f4a5f64 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -608,7 +608,7 @@ function generatePropertyFromExpr(node: ts.ClassLikeDeclaration, classFields: Ar let staticItems = properties.slice(properties.length - staticNum) properties = properties.slice(0, properties.length - staticNum); properties = properties.reverse(); - properties = properties.concat(staticItems); + properties.push(...staticItems); if (constructNode) { defineClassMember("constructor", constructNode, PropertyKind.Variable, properties, namedPropertyMap); diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index 34069c20e3..dd1555e4fd 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -14,7 +14,6 @@ */ import { CmdOptions } from "./cmdOptions"; -import { DebugPosInfo } from "./debuginfo"; import { Imm, IRNode, @@ -74,7 +73,6 @@ export class Ts2Panda { let insIds: Array = []; let insImms: Array = []; let insLabel: string = ""; - let insDebugInfo: DebugPosInfo = new DebugPosInfo(); if (insn instanceof Label) { insLabel = Ts2Panda.labelPrefix + insn.id; @@ -104,12 +102,8 @@ export class Ts2Panda { } }); } - insDebugInfo = insn.debugPosInfo; - if (CmdOptions.isDebugMode()) { - insDebugInfo.ClearMembersForDebugBuild(); - } else { - insDebugInfo.ClearMembersForReleaseBuild(); - } + + insn.debugPosInfo.ClearNodeKind(); insns.push(new Ins( insOpcode, @@ -117,7 +111,7 @@ export class Ts2Panda { insIds.length == 0 ? undefined : insIds, insImms.length == 0 ? undefined : insImms, insLabel === "" ? undefined : insLabel, - insDebugInfo, + insn.debugPosInfo, )); }); diff --git a/ts2panda/templates/irnodes.ts.erb b/ts2panda/templates/irnodes.ts.erb index 19b5f1029a..40cbc33f37 100755 --- a/ts2panda/templates/irnodes.ts.erb +++ b/ts2panda/templates/irnodes.ts.erb @@ -173,6 +173,7 @@ import { DebugPosInfo, NodeKind } from "./debuginfo"; +import { Scope } from "./scope"; export enum IRNodeKind { % Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group| @@ -181,7 +182,8 @@ export enum IRNodeKind { VREG, IMM, LABEL, - VIRTUALINS_DYN, + VIRTUALSTARTINS_DYN, + VIRTUALENDINS_DYN, DEFINE_GLOBAL_VAR, } @@ -396,9 +398,29 @@ export class Label extends IRNode { } } -export class DebugInsPlaceHolder extends IRNode { - constructor() { - super(IRNodeKind.VIRTUALINS_DYN, []); +export class DebugInsStartPlaceHolder extends IRNode { + private scope: Scope; + + constructor(scope: Scope) { + super(IRNodeKind.VIRTUALSTARTINS_DYN, []); + this.scope = scope; + } + + getScope() { + return this.scope; + } +} + +export class DebugInsEndPlaceHolder extends IRNode { + private scope: Scope; + + constructor(scope: Scope) { + super(IRNodeKind.VIRTUALENDINS_DYN, []); + this.scope = scope; + } + + getScope() { + return this.scope; } } -- Gitee From 16cf8e3ce5111b803a667f931af70910a0fd074f Mon Sep 17 00:00:00 2001 From: hufeng Date: Thu, 3 Mar 2022 11:38:38 +0800 Subject: [PATCH 2/4] parse piece of json from pipe directly Signed-off-by: hufeng Change-Id: Ie1d0c78c15fe460ce98b8d3e2fdd2f06485a749f --- ts2panda/ts2abc/main.cpp | 7 ++--- ts2panda/ts2abc/ts2abc.cpp | 56 ++++++++++++++++++++++++++++++-------- ts2panda/ts2abc/ts2abc.h | 7 ++--- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/ts2panda/ts2abc/main.cpp b/ts2panda/ts2abc/main.cpp index 724a6536d2..3eaef44c98 100644 --- a/ts2panda/ts2abc/main.cpp +++ b/ts2panda/ts2abc/main.cpp @@ -45,10 +45,6 @@ int Preprocess(const panda::ts2abc::Options &options, const panda::PandArgParser std::cerr << argParser.GetHelpString(); return RETURN_FAILED; } - - if (!ReadFromPipe(data)) { - return RETURN_FAILED; - } } return RETURN_SUCCESS; } @@ -95,7 +91,8 @@ int main(int argc, const char *argv[]) return RETURN_FAILED; } - if (!GenerateProgram(data, output, options.GetOptLevelArg(), options.GetOptLogLevelArg())) { + if (!GenerateProgram(data, output, options.GetCompileByPipeArg(), + options.GetOptLevelArg(), options.GetOptLogLevelArg())) { std::cerr << "call GenerateProgram fail" << std::endl; return RETURN_FAILED; } diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 04e3df954c..45854e6674 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -1011,15 +1011,25 @@ static bool ParseData(const std::string &data, panda::pandasm::Program &prog) return true; } -bool GenerateProgram(const std::string &data, std::string output, int optLevel, std::string optLogLevel) +bool GenerateProgram([[maybe_unused]] const std::string &data, std::string output, bool isParsingFromPipe, + int optLevel, std::string optLogLevel) { panda::pandasm::Program prog = panda::pandasm::Program(); prog.lang = panda::pandasm::extensions::Language::ECMASCRIPT; - if (!ParseData(data, prog)) { - std::cerr << "fail to parse Data!" << std::endl; - return false; + + if (isParsingFromPipe) { + if (!ReadFromPipe(prog)) { + std::cerr << "fail to parse Pipe!" << std::endl; + return false; + } + } else { + if (!ParseData(data, prog)) { + std::cerr << "fail to parse Data!" << std::endl; + return false; + } } + Logd("parsing done, calling pandasm\n"); #ifdef ENABLE_BYTECODE_OPT @@ -1096,8 +1106,10 @@ bool HandleJsonFile(const std::string &input, std::string &data) return true; } -bool ReadFromPipe(std::string &data) +bool ReadFromPipe(panda::pandasm::Program &prog) { + std::string data; + bool isStartDollar = true; const size_t bufSize = 4096; // the parent process open a pipe to this child process with fd of 3 const size_t fd = 3; @@ -1111,14 +1123,36 @@ bool ReadFromPipe(std::string &data) return false; } buff[ret] = '\0'; - data += buff; - } - if (data.empty()) { - std::cerr << "Nothing has been read from pipe" << std::endl; - return false; + uint32_t start_pos = 0; + for (int idx = 0; idx < ret; idx++) { + if (buff[idx] == '$' && + ((idx == 0 && (data.empty() || data.back() != '#')) || (idx != 0 && buff[idx - 1] != '#'))) { + if (isStartDollar) { + start_pos = idx + 1; + isStartDollar = false; + continue; + } + + std::string substr(buff + start_pos, buff + idx); + data += substr; + ReplaceAllDistinct(data, "#$", "$"); + if (ParseSmallPieceJson(data, prog)) { + std::cerr << "fail to parse stringify json" << std::endl; + return false; + } + isStartDollar = true; + // clear data after parsing + data.clear(); + } + } + + if (isStartDollar == false) { + std::string substr(buff + start_pos, buff + ret); + data += substr; + } } - Logd("finish reading from pipe"); + Logd("finish parsing from pipe"); return true; } diff --git a/ts2panda/ts2abc/ts2abc.h b/ts2panda/ts2abc/ts2abc.h index 691e87a0de..708e961f88 100644 --- a/ts2panda/ts2abc/ts2abc.h +++ b/ts2panda/ts2abc/ts2abc.h @@ -46,10 +46,9 @@ enum class OptLevel { }; bool HandleJsonFile(const std::string &input, std::string &data); -bool ReadFromPipe(std::string &data); -bool GenerateProgram(const std::string &data, std::string output, - int optLevel, - std::string optLogLevel); +bool ReadFromPipe(panda::pandasm::Program &prog); +bool GenerateProgram(const std::string &data, std::string output, bool isParsingFromPipe, + int optLevel, std::string optLogLevel); bool GetDebugLog(); void ParseLogEnable(const Json::Value &rootValue); bool GetDebugModeEnabled(); -- Gitee From 7fed8720cd2b9cb0b40466aa213413dbad08d3de Mon Sep 17 00:00:00 2001 From: hufeng Date: Mon, 7 Mar 2022 21:08:44 +0800 Subject: [PATCH 3/4] optmize the regAllocator Signed-off-by: hufeng Change-Id: I87cb31e4a5353f3ed7287faf481a0b084d2930a2 --- ts2panda/src/debuginfo.ts | 5 +--- ts2panda/src/pandagen.ts | 4 +++ ts2panda/src/pass/cacheExpander.ts | 2 +- ts2panda/src/regAllocator.ts | 40 +++++++++++++++--------------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/ts2panda/src/debuginfo.ts b/ts2panda/src/debuginfo.ts index 67f03b09b2..b5f5007684 100644 --- a/ts2panda/src/debuginfo.ts +++ b/ts2panda/src/debuginfo.ts @@ -356,10 +356,7 @@ export class DebugInfo { public static copyDebugInfo(insn: IRNode, expansion: IRNode[]) { - let debugPosInfo = insn.debugPosInfo; - for (let j = 0; j < expansion.length; j++) { - expansion[j].debugPosInfo = debugPosInfo; - } + expansion.forEach(irNode => irNode.debugPosInfo = insn.debugPosInfo); } public static addDebugIns(scope: Scope, pandaGen: PandaGen, isStart: boolean) { diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index 22c11bf961..8a098828cb 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -370,6 +370,10 @@ export class PandaGen { return this.insns; } + setInsns(insns: IRNode[]) { + this.insns = insns; + } + printInsns() { LOGE("function " + this.internalName + "() {"); this.getInsns().forEach(ins => { diff --git a/ts2panda/src/pass/cacheExpander.ts b/ts2panda/src/pass/cacheExpander.ts index cfb0137a90..85dc5bc812 100755 --- a/ts2panda/src/pass/cacheExpander.ts +++ b/ts2panda/src/pass/cacheExpander.ts @@ -32,7 +32,7 @@ export class CacheExpander implements Pass { if (item.isNeeded()) { let expander = item.getExpander(); let expansion = expander(pandaGen); - insns.splice(0, 0, ...expansion); + insns.unshift(...expansion); } } } diff --git a/ts2panda/src/regAllocator.ts b/ts2panda/src/regAllocator.ts index 985262132e..d47c59729a 100644 --- a/ts2panda/src/regAllocator.ts +++ b/ts2panda/src/regAllocator.ts @@ -32,16 +32,13 @@ const MAX_VREGA = 16; const MAX_VREGB = 256; const MAX_VREGC = 65536; -class VRegWithFlag { - constructor(vreg: VReg) { - this.flag = false; - this.vreg = vreg; - } +interface VRegWithFlag { vreg: VReg; flag: boolean; // indicate whether it is used as a temporary register for spill } class RegAllocator { + private newInsns: IRNode[] = []; private spills: VReg[] = []; private vRegsId: number = 0; private usedVreg: VRegWithFlag[] = []; @@ -54,7 +51,7 @@ class RegAllocator { allocIndexForVreg(vreg: VReg) { let num = this.getFreeVreg(); vreg.num = num; - this.usedVreg[num] = new VRegWithFlag(vreg); + this.usedVreg[num] = {vreg: vreg, flag: false}; } findTmpVreg(level: number): VReg { @@ -121,7 +118,7 @@ class RegAllocator { this.tmpVreg.push(this.usedVreg[num]); } - doRealAdjustment(operands: OperandType[], format: Format, index: number, irNodes: IRNode[]): number { + doRealAdjustment(operands: OperandType[], format: Format, index: number, irNodes: IRNode[]) { let head: IRNode[] = []; let tail: IRNode[] = []; let spills: VReg[] = []; @@ -165,14 +162,14 @@ class RegAllocator { DebugInfo.copyDebugInfo(irNodes[index], head); DebugInfo.copyDebugInfo(irNodes[index], tail); - irNodes.splice(index, 0, ...head); - irNodes.splice(index + head.length + 1, 0, ...tail); + this.newInsns.push(...head); + this.newInsns.push(irNodes[index]); + this.newInsns.push(...tail); + for (let j = spills.length - 1; j >= 0; --j) { this.freeSpill(spills[j]); } this.clearVregFlags(); - - return (head.length + tail.length); } checkDynRangeInstruction(irNodes: IRNode[], index: number): boolean { @@ -211,7 +208,7 @@ class RegAllocator { return false; } - adjustDynRangeInstruction(irNodes: IRNode[], index: number): number { + adjustDynRangeInstruction(irNodes: IRNode[], index: number) { let head: IRNode[] = []; let tail: IRNode[] = []; let spills: VReg[] = []; @@ -239,14 +236,13 @@ class RegAllocator { DebugInfo.copyDebugInfo(irNodes[index], head); DebugInfo.copyDebugInfo(irNodes[index], tail); - irNodes.splice(index, 0, ...head); - irNodes.splice(index + head.length + 1, 0, ...tail); + this.newInsns.push(...head); + this.newInsns.push(irNodes[index]); + this.newInsns.push(...tail); for (let i = spills.length - 1; i >= 0; --i) { this.freeSpill(spills[i]); } this.clearVregFlags(); - - return (head.length + tail.length); } adjustInstructionsIfNeeded(irNodes: IRNode[]): void { @@ -255,10 +251,10 @@ class RegAllocator { let formats = irNodes[i].getFormats(); if (isRangeInst(irNodes[i])) { if (this.checkDynRangeInstruction(irNodes, i)) { + this.newInsns.push(irNodes[i]); continue; } - - i += this.adjustDynRangeInstruction(irNodes, i); + this.adjustDynRangeInstruction(irNodes, i); continue; } @@ -272,8 +268,10 @@ class RegAllocator { } } if (min > 0) { - i += this.doRealAdjustment(operands, minFormat, i, irNodes); + this.doRealAdjustment(operands, minFormat, i, irNodes); + continue; } + this.newInsns.push(irNodes[i]); } } @@ -304,8 +302,10 @@ class RegAllocator { for (let i = 0; i < parametersCount; ++i) { let v = new VReg(); this.allocIndexForVreg(v); - irNodes.splice(0, 0, new MovDyn(locals[i], v)); + this.newInsns.unshift(new MovDyn(locals[i], v)); } + + pandaGen.setInsns(this.newInsns); } } -- Gitee From 3c5380dfae9d99c559f3896f0ae20e7a483ddee0 Mon Sep 17 00:00:00 2001 From: hufeng Date: Wed, 9 Mar 2022 09:33:55 +0800 Subject: [PATCH 4/4] fix comma list Signed-off-by: hufeng Change-Id: I18ff037ac092146138b055e2426f2cd0a537a45c --- ts2panda/src/compiler.ts | 6 + .../expression/compileCommaListExpression.ts | 24 ++++ ts2panda/src/regAllocator.ts | 8 +- ts2panda/tests/expression/commalist.test.ts | 121 ++++++++++++++++++ ts2panda/tests/utils/base.ts | 35 +++++ 5 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 ts2panda/src/expression/compileCommaListExpression.ts create mode 100644 ts2panda/tests/expression/commalist.test.ts diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index 39698348e9..4837600458 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -117,6 +117,9 @@ import { VarDeclarationKind, Variable } from "./variable"; +import { + compileCommaListExpression +} from "./expression/compileCommaListExpression" export enum ControlFlowChange { Continue, Break } export class Compiler { @@ -885,6 +888,9 @@ export class Compiler { break; case ts.SyntaxKind.PartiallyEmittedExpression: break; + case ts.SyntaxKind.CommaListExpression: + compileCommaListExpression(this, expr); + break; default: throw new Error("Expression of type " + this.getNodeName(expr) + " is unimplemented"); } diff --git a/ts2panda/src/expression/compileCommaListExpression.ts b/ts2panda/src/expression/compileCommaListExpression.ts new file mode 100644 index 0000000000..4894f99f14 --- /dev/null +++ b/ts2panda/src/expression/compileCommaListExpression.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as ts from "typescript"; +import { Compiler } from "../compiler"; + + +export function compileCommaListExpression(compiler: Compiler, exprList: ts.CommaListExpression) { + exprList.elements.forEach(expr => { + compiler.compileExpression(expr); + }) +} diff --git a/ts2panda/src/regAllocator.ts b/ts2panda/src/regAllocator.ts index d47c59729a..dfcc44b3be 100644 --- a/ts2panda/src/regAllocator.ts +++ b/ts2panda/src/regAllocator.ts @@ -162,9 +162,7 @@ class RegAllocator { DebugInfo.copyDebugInfo(irNodes[index], head); DebugInfo.copyDebugInfo(irNodes[index], tail); - this.newInsns.push(...head); - this.newInsns.push(irNodes[index]); - this.newInsns.push(...tail); + this.newInsns.push(...head, irNodes[index], ...tail); for (let j = spills.length - 1; j >= 0; --j) { this.freeSpill(spills[j]); @@ -236,9 +234,7 @@ class RegAllocator { DebugInfo.copyDebugInfo(irNodes[index], head); DebugInfo.copyDebugInfo(irNodes[index], tail); - this.newInsns.push(...head); - this.newInsns.push(irNodes[index]); - this.newInsns.push(...tail); + this.newInsns.push(...head, irNodes[index], ...tail); for (let i = spills.length - 1; i >= 0; --i) { this.freeSpill(spills[i]); } diff --git a/ts2panda/tests/expression/commalist.test.ts b/ts2panda/tests/expression/commalist.test.ts new file mode 100644 index 0000000000..60f4dba3cc --- /dev/null +++ b/ts2panda/tests/expression/commalist.test.ts @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaReturnundefined, + EcmaStglobalvar, + EcmaTryldglobalbyname, + Imm, + LdaDyn, + MovDyn, + StaDyn, + EcmaDefineclasswithbuffer, + EcmaStclasstoglobalrecord, + EcmaNewobjdynrange, + VReg +} from "../../src/irnodes"; +import { checkInstructions, SnippetCompiler } from "../utils/base"; + +describe("CommaListExpression", function () { + it("computedPropertyName", function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compileAfter(" \ + class Test { \ + #filed1; \ + #filed2; \ + #filed3; \ + #filed4; \ + #filed5; \ + #filed6; \ + #filed7; \ + #filed8; \ + #filed9; \ + #filed10; \ + #filed11; \ + } \ + ", + "test.ts"); + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + new MovDyn(new VReg(), new VReg()), + new EcmaDefineclasswithbuffer("#1#Test", new Imm(0), new Imm(0), new VReg(), new VReg()), + new StaDyn(new VReg()), + new LdaDyn(new VReg()), + new EcmaStclasstoglobalrecord("Test"), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed1'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed2'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed3'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed4'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed5'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed6'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed7'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed8'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed9'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed10'), + new EcmaTryldglobalbyname('WeakMap'), + new StaDyn(new VReg()), + new MovDyn(new VReg(), new VReg()), + new EcmaNewobjdynrange(new Imm(2), [new VReg(), new VReg()]), + new EcmaStglobalvar('_Test_filed11'), + new EcmaReturnundefined() + ] + expect(checkInstructions(insns, expected)).to.be.true; + }); + +}); diff --git a/ts2panda/tests/utils/base.ts b/ts2panda/tests/utils/base.ts index 94b1a99f00..6d505a9c56 100644 --- a/ts2panda/tests/utils/base.ts +++ b/ts2panda/tests/utils/base.ts @@ -170,6 +170,36 @@ export function compileMainSnippet(snippet: string, pandaGen?: PandaGen, scope?: return compileUnits[0].getInsns(); } +export function compileAfterSnippet(snippet: string, name:string) { + let compileUnits = null; + ts.transpileModule( + snippet, + { + compilerOptions : { + "target": ts.ScriptTarget.ES2015 + }, + fileName : name, + transformers : { + after : [ + (ctx: ts.TransformationContext) => { + return (sourceFile: ts.SourceFile) => { + jshelpers.bindSourceFile(sourceFile, {}); + setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(sourceFile, compileOptions)); + let compilerDriver = new CompilerDriver('UnitTest'); + compilerDriver.setCustomPasses([]); + compilerDriver.compileUnitTest(sourceFile, []); + compileUnits = compilerDriver.getCompilationUnits(); + return sourceFile; + } + } + ] + } + } + ); + + return compileUnits; +} + export function getCompileOptions(): ts.CompilerOptions { return compileOptions; } @@ -181,6 +211,11 @@ export class SnippetCompiler { return this.pandaGens; } + compileAfter(snippet: string, name: string, passes?: Pass[], literalBufferArray?: Array) { + this.pandaGens = compileAfterSnippet(snippet, name); + return this.pandaGens; + } + getGlobalInsns(): IRNode[] { let root = this.getPandaGenByName("func_main_0"); if (root) { -- Gitee