From 2735e18dfaefd2d5aefaae8da670f3f35f7cc0d1 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Tue, 2 Nov 2021 16:10:05 +0800 Subject: [PATCH 01/11] add calltype Signed-off-by: zhangrengao Change-Id: I27f00cde8b4e620ebbcfbbc41cbf3f6f6278fe92 --- ts2panda/src/compiler.ts | 58 ++++++++++++++++++++++++ ts2panda/src/expression/metaProperty.ts | 3 ++ ts2panda/src/pandagen.ts | 20 ++++++++ ts2panda/src/pandasm.ts | 3 ++ ts2panda/src/scope.ts | 18 ++++++++ ts2panda/src/statement/classStatement.ts | 2 + ts2panda/src/ts2panda.ts | 2 + ts2panda/ts2abc/ts2abc.cpp | 15 ++++++ 8 files changed, 121 insertions(+) diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index b87ad4cc6a..58f4642ff0 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -74,6 +74,7 @@ import { } from "./pandagen"; import { Recorder } from "./recorder"; import { + FunctionScope, GlobalScope, LoopScope, ModuleScope, @@ -155,6 +156,7 @@ export class Compiler { this.compileSourceFileOrBlock(this.rootNode); } else { this.compileFunctionLikeDeclaration(this.rootNode); + this.callOpt(); } } @@ -170,6 +172,43 @@ export class Compiler { return this.envUnion[this.envUnion.length - 1]; } + private callOpt() { + let CallMap: Map = new Map([ + ["this", 1], + ["4newTarget", 2], + ["argumentsOrRestargs", 4] + ]); + let callType = 0; + let scope = this.pandaGen.getScope(); + + if (scope instanceof FunctionScope) { + let tempLocals: VReg[] = []; + let count = 0; + // 4funcObj/newTarget/this + for (let i = 0; i < 3; i++) { + if (scope.getCallOpt().has(scope.getParameters()[i].getName())) { + tempLocals.push(this.pandaGen.getLocals()[i]); + callType += CallMap.get(scope.getParameters()[i].getName()) ?? 0; + } else { + count++; + } + } + // acutal parameters + for (let i = 3; i < this.pandaGen.getLocals().length; i++) { + tempLocals.push(this.pandaGen.getLocals()[i]); + } + + this.pandaGen.setLocals(tempLocals); + this.pandaGen.setParametersCount(this.pandaGen.getParametersCount()-count); + + if (scope.getArgumentsOrRestargs()) { + callType += CallMap.get("argumentsOrRestargs") ?? 0; + } + + this.pandaGen.setCallType(callType); + } + } + private compileLexicalBindingForArrowFunction() { let rootNode = this.rootNode; @@ -283,6 +322,10 @@ export class Compiler { let paramReg = pandaGen.getVregForVariable(variable!); if (param.dotDotDotToken) { + let scope = this.pandaGen.getScope(); + if (scope instanceof FunctionScope) { + scope.setArgumentsOrRestargs(); + } pandaGen.copyRestArgs(param, index); pandaGen.storeAccumulator(param, paramReg); } @@ -886,6 +929,9 @@ export class Compiler { checkValidUseSuperBeforeSuper(this, node); let { scope, level, v } = this.scope.find("this"); + + this.setCallOpt(scope, "this") + if (!v) { throw new Error("\"this\" not found"); } @@ -1293,6 +1339,9 @@ export class Compiler { let scope = thisInfo.scope; let level = thisInfo.level; let v = thisInfo.v; + + this.setCallOpt(scope, "this") + if (scope && level >= 0) { let needSetLexVar: boolean = false; while (curScope != scope) { @@ -1320,6 +1369,9 @@ export class Compiler { setThis(node: ts.Node) { let pandaGen = this.pandaGen; let thisInfo = this.getCurrentScope().find("this"); + + this.setCallOpt(thisInfo.scope, "this") + if (thisInfo.v!.isLexVar) { let slot = (thisInfo.v).idxLex; let value = pandaGen.getTemp(); @@ -1331,6 +1383,12 @@ export class Compiler { } } + setCallOpt(scope: Scope | undefined, callOptStr: String) { + if (scope instanceof FunctionScope) { + scope.setCallOpt(callOptStr); + } + } + getPandaGen() { return this.pandaGen; } diff --git a/ts2panda/src/expression/metaProperty.ts b/ts2panda/src/expression/metaProperty.ts index 103755473d..dfc44034ff 100644 --- a/ts2panda/src/expression/metaProperty.ts +++ b/ts2panda/src/expression/metaProperty.ts @@ -22,6 +22,9 @@ export function compileMetaProperty(expr: ts.MetaProperty, compiler: Compiler) { let id = jshelpers.getTextOfIdentifierOrLiteral(expr.name); if (id == "target") { let { scope, level, v } = curScope.find("4newTarget"); + + compiler.setCallOpt(scope, "4newTarget"); + if (!v) { throw new Error("fail to access new.target"); } else { diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index e823a72174..1b56905a96 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -201,6 +201,7 @@ export class PandaGen { private sourceFileDebugInfo: string = ""; private sourceCodeDebugInfo: string | undefined; private icSize: number = 0; + private callType: number = 0; private static literalArrayBuffer: Array = []; @@ -211,6 +212,14 @@ export class PandaGen { this.vregisterCache = new VregisterCache(); } + public setCallType(callType: number) { + this.callType = callType; + } + + public getCallType(): number { + return this.callType; + } + public getSourceCodeDebugInfo() { return this.sourceCodeDebugInfo; } @@ -348,10 +357,18 @@ export class PandaGen { return this.totalRegsNum; } + setParametersCount(count: number) { + this.parametersCount = count; + } + getParametersCount(): number { return this.parametersCount; } + setLocals(locals: VReg[]) { + this.locals = locals; + } + getLocals(): VReg[] { return this.locals; } @@ -367,6 +384,9 @@ export class PandaGen { loadAccFromArgs(node: ts.Node) { if ((this.scope).getUseArgs()) { let v = this.scope!.findLocal("arguments"); + if (this.scope instanceof FunctionScope) { + this.scope.setArgumentsOrRestargs(); + } if (v) { let paramVreg = this.getVregForVariable(v); this.getUnmappedArgs(node); diff --git a/ts2panda/src/pandasm.ts b/ts2panda/src/pandasm.ts index f4ca2651ae..c523f7fa87 100644 --- a/ts2panda/src/pandasm.ts +++ b/ts2panda/src/pandasm.ts @@ -72,6 +72,7 @@ export class Function { public variables: Array | undefined; public sourceFile: string; public sourceCode: string | undefined; + public callType: number; constructor( name: string, @@ -82,6 +83,7 @@ export class Function { variables: Array | undefined = undefined, sourceFile: string = "", sourceCode: string | undefined = undefined, + callType: number = 0 ) { this.name = name; this.signature = signature; @@ -93,6 +95,7 @@ export class Function { this.variables = variables; this.sourceFile = sourceFile; this.sourceCode = sourceCode; + this.callType = callType; } } diff --git a/ts2panda/src/scope.ts b/ts2panda/src/scope.ts index e2aa29a062..e70888f569 100644 --- a/ts2panda/src/scope.ts +++ b/ts2panda/src/scope.ts @@ -408,6 +408,8 @@ export class ModuleScope extends VariableScope { export class FunctionScope extends VariableScope { private parameterLength: number = 0; private funcName: string = ""; + private callOpt: Set = new Set(); + private isArgumentsOrRestargs: boolean = false; constructor(parent?: Scope, node?: ts.FunctionLikeDeclaration) { super(); this.parent = parent ? parent : undefined; @@ -430,6 +432,22 @@ export class FunctionScope extends VariableScope { return this.funcName; } + public getCallOpt() { + return this.callOpt; + } + + public setCallOpt(key: String) { + this.callOpt.add(key); + } + + public setArgumentsOrRestargs() { + this.isArgumentsOrRestargs = true; + } + + public getArgumentsOrRestargs() { + return this.isArgumentsOrRestargs; + } + getParent(): Scope | undefined { return this.parent; } diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index 1163c9e0b8..d3f2105859 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -282,6 +282,8 @@ export function compileSuperCall(compiler: Compiler, node: ts.CallExpression, ar let curScope = compiler.getCurrentScope(); let { scope, level, v } = curScope.find("this"); + compiler.setCallOpt(scope, "this"); + if (scope && level >= 0) { let tmpScope = curScope; let needSetLexVar: boolean = false; diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index 58e7765b79..e3b60b281e 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -170,6 +170,7 @@ export class Ts2Panda { let funcSignature = Ts2Panda.getFuncSignature(pg); let funcInsnsAndRegsNum = Ts2Panda.getFuncInsnsAndRegsNum(pg); let sourceFile = pg.getSourceFileDebugInfo(); + let callType = pg.getCallType(); let variables, sourceCode; if (CmdOptions.isDebugMode()) { @@ -189,6 +190,7 @@ export class Ts2Panda { variables, sourceFile, sourceCode, + callType ); let catchTables = generateCatchTables(pg.getCatchMap()); catchTables.forEach((catchTable) => { diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 8f131798fb..37aac83ec5 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -594,6 +594,19 @@ static void ParseFunctionCatchTables(const Json::Value &function, panda::pandasm } } +static void ParseFunctionCallType(const Json::Value &function, panda::pandasm::Function &pandaFunc) +{ + uint8_t callType = 0; + if (function.isMember("callType") && function["callType"].isInt()) { + callType = function["callType"].asInt() + } + panda::pandasm::AnnotationData callTypeAnnotation("_ESCallTypeAnnotation"); + std::string annotationName = "callType"; + panda::pandasm::AnnotationElement callTypeAnnotationElement(annotationName, std::make_unique(panda::pandasm::ScalarValue::Create(call_type))); + callTypeAnnotation.AddElement(std::move(callTypeAnnotationElement)); + const_cast&>(pandaFunc.metadata->GetAnnotations()).push_back(std::move(callTypeAnnotation)); +} + static panda::pandasm::Function ParseFunction(const Json::Value &function) { auto pandaFunc = GetFunctionDefintion(function); @@ -607,6 +620,8 @@ static panda::pandasm::Function ParseFunction(const Json::Value &function) ParseFunctionLabels(function, pandaFunc); // parsing catch blocks ParseFunctionCatchTables(function, pandaFunc); + // parsing call opt type + ParseFunctionCallType(function, pandaFunc); return pandaFunc; } -- Gitee From 7b545266b311029d9aa445abdffffcd919e0c714 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Fri, 5 Nov 2021 14:39:53 +0800 Subject: [PATCH 02/11] add record Change-Id: Ice5c16a819407c62763244ea0d3c3073b8cfcbd0 --- ts2panda/ts2abc/ts2abc.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 37aac83ec5..2836ef6d2e 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -598,11 +598,11 @@ static void ParseFunctionCallType(const Json::Value &function, panda::pandasm::F { uint8_t callType = 0; if (function.isMember("callType") && function["callType"].isInt()) { - callType = function["callType"].asInt() + callType = function["callType"].asInt(); } panda::pandasm::AnnotationData callTypeAnnotation("_ESCallTypeAnnotation"); std::string annotationName = "callType"; - panda::pandasm::AnnotationElement callTypeAnnotationElement(annotationName, std::make_unique(panda::pandasm::ScalarValue::Create(call_type))); + panda::pandasm::AnnotationElement callTypeAnnotationElement(annotationName, std::make_unique(panda::pandasm::ScalarValue::Create(callType))); callTypeAnnotation.AddElement(std::move(callTypeAnnotationElement)); const_cast&>(pandaFunc.metadata->GetAnnotations()).push_back(std::move(callTypeAnnotation)); } @@ -626,6 +626,14 @@ static panda::pandasm::Function ParseFunction(const Json::Value &function) return pandaFunc; } +static void GenerateESCallTypeAnnotationRecord(panda::pandasm::Program &prog) +{ + auto callTypeAnnotationRecord = panda::pandasm::Record("_ESCallTypeAnnotation", LANG_EXT); + callTypeAnnotationRecord.metadata->SetAttribute("external"); + callTypeAnnotationRecord.metadata->SetAccessFlags(panda::ACC_ANNOTATION); + prog.record_table.emplace(callTypeAnnotationRecord.name, std::move(callTypeAnnotationRecord)); +} + static void GenrateESModuleModeRecord(panda::pandasm::Program &prog, bool moduleMode) { auto ecmaModuleModeRecord = panda::pandasm::Record("_ESModuleMode", LANG_EXT); @@ -720,6 +728,7 @@ static void ReplaceAllDistinct(std::string &str, const std::string &oldValue, co static void ParseOptions(const Json::Value &rootValue, panda::pandasm::Program &prog) { + GenerateESCallTypeAnnotationRecord(prog); ParseModuleMode(rootValue, prog); ParseLogEnable(rootValue); ParseDebugMode(rootValue); -- Gitee From 49dd494226825ebe2f5d9211667100cbaf1d07d0 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Tue, 16 Nov 2021 09:50:35 +0800 Subject: [PATCH 03/11] delete main callType annotation Change-Id: I060c10cba7c5f86f080a403dfe07869b49b0e7f9 --- ts2panda/ts2abc/ts2abc.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 2836ef6d2e..36698096e2 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -596,6 +596,14 @@ static void ParseFunctionCatchTables(const Json::Value &function, panda::pandasm static void ParseFunctionCallType(const Json::Value &function, panda::pandasm::Function &pandaFunc) { + std::string funcName = ""; + if (function.isMember("name") && function["name"].isString()) { + funcName = function["name"].asString(); + } + if (funcName == "func_main_0") { + return ; + } + uint8_t callType = 0; if (function.isMember("callType") && function["callType"].isInt()) { callType = function["callType"].asInt(); -- Gitee From e3ab431a60c4d6b3dbdf9c6b302b93379f6a667f Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Tue, 16 Nov 2021 16:54:46 +0800 Subject: [PATCH 04/11] creategenerator set undefine Change-Id: I17f2baf3689b775716bd09fe484c857a5fd2ec00 --- ts2panda/src/function/generatorFunctionBuilder.ts | 5 ++--- ts2panda/ts2abc/ts2abc.cpp | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ts2panda/src/function/generatorFunctionBuilder.ts b/ts2panda/src/function/generatorFunctionBuilder.ts index 85d1d18c19..37d11b187d 100755 --- a/ts2panda/src/function/generatorFunctionBuilder.ts +++ b/ts2panda/src/function/generatorFunctionBuilder.ts @@ -47,10 +47,9 @@ export class GeneratorFunctionBuilder { prepare(node: ts.Node, recorder: Recorder) { let pandaGen = this.pandaGen; - let scope = recorder.getScopeOfNode(node); - let funcObj = scope.getName2variable().get('4funcObj')!.getVreg(); - pandaGen.createGeneratorObj(node, funcObj); + // backend handle funcobj, frontend set undefined + pandaGen.createGeneratorObj(node, getVregisterCache(pandaGen, CacheList.undefined)); pandaGen.storeAccumulator(node, this.genObj); pandaGen.suspendGenerator(node, this.genObj, getVregisterCache(pandaGen, CacheList.undefined)); pandaGen.resumeGenerator(node, this.genObj); diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 36698096e2..d9c3cc4540 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -604,13 +604,13 @@ static void ParseFunctionCallType(const Json::Value &function, panda::pandasm::F return ; } - uint8_t callType = 0; + uint32_t callType = 0; if (function.isMember("callType") && function["callType"].isInt()) { - callType = function["callType"].asInt(); + callType = function["callType"].asUInt(); } panda::pandasm::AnnotationData callTypeAnnotation("_ESCallTypeAnnotation"); std::string annotationName = "callType"; - panda::pandasm::AnnotationElement callTypeAnnotationElement(annotationName, std::make_unique(panda::pandasm::ScalarValue::Create(callType))); + panda::pandasm::AnnotationElement callTypeAnnotationElement(annotationName, std::make_unique(panda::pandasm::ScalarValue::Create(callType))); callTypeAnnotation.AddElement(std::move(callTypeAnnotationElement)); const_cast&>(pandaFunc.metadata->GetAnnotations()).push_back(std::move(callTypeAnnotation)); } -- Gitee From 1d3e9e292560ef96d1464a361e71ddb11b6398a7 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Wed, 17 Nov 2021 09:37:08 +0800 Subject: [PATCH 05/11] funcobj to undefined Change-Id: If1f61cb7c2f9ceab9f0b62a9992186ce9fc43826 --- ts2panda/src/compiler.ts | 8 +++++++- ts2panda/src/function/generatorFunctionBuilder.ts | 2 ++ ts2panda/src/statement/classStatement.ts | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index 58f4642ff0..eeca0770f7 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -243,8 +243,14 @@ export class Compiler { let v = variableInfo.v; if (v && v.isLexVar) { + if ((arg === "this" || arg === "4newTarget") && variableInfo.scope instanceof FunctionScope) { + variableInfo.scope.setCallOpt(arg); + } + if (arg === "arguments" && variableInfo.scope instanceof FunctionScope) { + variableInfo.scope.setArgumentsOrRestargs(); + } let pandaGen = this.pandaGen; - let vreg = pandaGen.getVregForVariable(variableInfo.v); + let vreg = "4funcObj" === arg ? getVregisterCache(pandaGen, CacheList.undefined) : pandaGen.getVregForVariable(variableInfo.v); let slot = (variableInfo.v).idxLex; pandaGen.storeLexicalVar(this.rootNode, variableInfo.level, slot, vreg); } diff --git a/ts2panda/src/function/generatorFunctionBuilder.ts b/ts2panda/src/function/generatorFunctionBuilder.ts index 37d11b187d..d0433352a2 100755 --- a/ts2panda/src/function/generatorFunctionBuilder.ts +++ b/ts2panda/src/function/generatorFunctionBuilder.ts @@ -47,6 +47,8 @@ export class GeneratorFunctionBuilder { prepare(node: ts.Node, recorder: Recorder) { let pandaGen = this.pandaGen; + let scope = recorder.getScopeOfNode(node); + let funcObj = scope.getName2variable().get('4funcObj')!.getVreg(); // backend handle funcobj, frontend set undefined pandaGen.createGeneratorObj(node, getVregisterCache(pandaGen, CacheList.undefined)); diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index d3f2105859..79acb275ad 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -332,7 +332,7 @@ function loadCtorObj(node: ts.CallExpression, compiler: Compiler) { if (ts.isConstructorDeclaration(nearestFunc)) { let funcObj = nearestFuncScope.findLocal("4funcObj"); - pandaGen.loadAccumulator(node, pandaGen.getVregForVariable(funcObj)); + pandaGen.loadAccumulator(node, getVregisterCache(pandaGen, CacheList.undefined)); } else { let outerFunc = jshelpers.getContainingFunction(nearestFunc); let outerFuncScope = recorder.getScopeOfNode(outerFunc); -- Gitee From ca06faef19bcd3df59c4be0838e540c948182313 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Wed, 17 Nov 2021 18:35:09 +0800 Subject: [PATCH 06/11] switch undefined to hole Change-Id: Idff0888337bb19dec0e9c94a42b1315081cf4a1e --- ts2panda/src/compiler.ts | 2 +- ts2panda/src/function/generatorFunctionBuilder.ts | 4 ++-- ts2panda/src/lexenv.ts | 6 +++++- ts2panda/src/statement/classStatement.ts | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index eeca0770f7..6aef2b9c91 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -250,7 +250,7 @@ export class Compiler { variableInfo.scope.setArgumentsOrRestargs(); } let pandaGen = this.pandaGen; - let vreg = "4funcObj" === arg ? getVregisterCache(pandaGen, CacheList.undefined) : pandaGen.getVregForVariable(variableInfo.v); + let vreg = "4funcObj" === arg ? getVregisterCache(pandaGen, CacheList.HOLE) : pandaGen.getVregForVariable(variableInfo.v); let slot = (variableInfo.v).idxLex; pandaGen.storeLexicalVar(this.rootNode, variableInfo.level, slot, vreg); } diff --git a/ts2panda/src/function/generatorFunctionBuilder.ts b/ts2panda/src/function/generatorFunctionBuilder.ts index d0433352a2..cf879e3561 100755 --- a/ts2panda/src/function/generatorFunctionBuilder.ts +++ b/ts2panda/src/function/generatorFunctionBuilder.ts @@ -48,10 +48,10 @@ export class GeneratorFunctionBuilder { prepare(node: ts.Node, recorder: Recorder) { let pandaGen = this.pandaGen; let scope = recorder.getScopeOfNode(node); - let funcObj = scope.getName2variable().get('4funcObj')!.getVreg(); + let funcObj = scope.getName2variable().get("4funcObj")!.getVreg(); // backend handle funcobj, frontend set undefined - pandaGen.createGeneratorObj(node, getVregisterCache(pandaGen, CacheList.undefined)); + pandaGen.createGeneratorObj(node, getVregisterCache(pandaGen, CacheList.HOLE)); pandaGen.storeAccumulator(node, this.genObj); pandaGen.suspendGenerator(node, this.genObj, getVregisterCache(pandaGen, CacheList.undefined)); pandaGen.resumeGenerator(node, this.genObj); diff --git a/ts2panda/src/lexenv.ts b/ts2panda/src/lexenv.ts index 3193042838..e73212718f 100644 --- a/ts2panda/src/lexenv.ts +++ b/ts2panda/src/lexenv.ts @@ -93,7 +93,11 @@ export class VariableAccessLoad extends VariableAccessBase { pandaGen.freeTemps(holeReg); return insns; } - insns.push(loadAccumulator(bindVreg)); + if (v.getName() === "4funcObj") { + insns.push(loadAccumulator(getVregisterCache(pandaGen, CacheList.HOLE))); + } else { + insns.push(loadAccumulator(bindVreg)); + } return insns; } diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index 79acb275ad..a4a9dd822d 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -332,7 +332,7 @@ function loadCtorObj(node: ts.CallExpression, compiler: Compiler) { if (ts.isConstructorDeclaration(nearestFunc)) { let funcObj = nearestFuncScope.findLocal("4funcObj"); - pandaGen.loadAccumulator(node, getVregisterCache(pandaGen, CacheList.undefined)); + pandaGen.loadAccumulator(node, getVregisterCache(pandaGen, CacheList.HOLE)); } else { let outerFunc = jshelpers.getContainingFunction(nearestFunc); let outerFuncScope = recorder.getScopeOfNode(outerFunc); -- Gitee From efe154627089ff1edb511a5b76db27bf48a1f399 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Thu, 18 Nov 2021 20:10:54 +0800 Subject: [PATCH 07/11] supercall add newTarget Change-Id: I1d7a5575af0bc19187f2c30c3e318ca065250460 --- ts2panda/src/statement/classStatement.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index a4a9dd822d..f76fb039f3 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -283,6 +283,7 @@ export function compileSuperCall(compiler: Compiler, node: ts.CallExpression, ar let { scope, level, v } = curScope.find("this"); compiler.setCallOpt(scope, "this"); + compiler.setCallOpt(scope, "4newTarget"); if (scope && level >= 0) { let tmpScope = curScope; -- Gitee From 60fa2d17401b36b0ccfae1381f8f20fff96662e8 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Fri, 19 Nov 2021 10:58:34 +0800 Subject: [PATCH 08/11] 0newTarget for arrowfunction supercall Change-Id: I255e0a5b6b4ee7a7402f2af7e96370ee33f407ac --- ts2panda/src/compiler.ts | 1 + ts2panda/src/statement/classStatement.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index 6aef2b9c91..c7c00d7721 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -176,6 +176,7 @@ export class Compiler { let CallMap: Map = new Map([ ["this", 1], ["4newTarget", 2], + ["0newTarget", 2], ["argumentsOrRestargs", 4] ]); let callType = 0; diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index f76fb039f3..4619b16236 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -299,6 +299,9 @@ export function compileSuperCall(compiler: Compiler, node: ts.CallExpression, ar if (needSetLexVar) { scope.setLexVar(v, curScope); } + if (needSetLexVar && curScope instanceof FunctionScope) { + curScope.setCallOpt("0newTarget"); + } } if (hasSpread) { -- Gitee From ad40e46a14bd39d6dc84207e8f2aab9b11b5750e Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Sat, 20 Nov 2021 16:29:24 +0800 Subject: [PATCH 09/11] add ldfunc Change-Id: Ie1a352d5c833044cdaa5b5872d27cc6f3243a420 --- ts2panda/src/base/builtIn.ts | 11 ++++++++++- ts2panda/src/base/vregisterCache.ts | 5 ++++- ts2panda/src/compiler.ts | 2 +- ts2panda/src/function/generatorFunctionBuilder.ts | 2 +- ts2panda/src/lexenv.ts | 2 +- ts2panda/src/statement/classStatement.ts | 2 +- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ts2panda/src/base/builtIn.ts b/ts2panda/src/base/builtIn.ts index 61afcb3ecd..170536a81c 100755 --- a/ts2panda/src/base/builtIn.ts +++ b/ts2panda/src/base/builtIn.ts @@ -25,7 +25,8 @@ import { EcmaLdsymbol, EcmaLdtrue, EcmaLdundefined, - StaDyn + StaDyn, + EcmaLdfunc } from "../irnodes"; import { CacheList, getVregisterCache } from "./vregisterCache"; @@ -99,4 +100,12 @@ export function expandFalse(pandaGen: PandaGen): IRNode[] { new EcmaLdfalse(), new StaDyn(vreg) ]; +} + +export function expandFunc(pandaGen: PandaGen): IRNode[] { + let vreg = getVregisterCache(pandaGen, CacheList.FUNC); + return [ + new EcmaLdfunc(), + new StaDyn(vreg) + ]; } \ No newline at end of file diff --git a/ts2panda/src/base/vregisterCache.ts b/ts2panda/src/base/vregisterCache.ts index a48db661b3..7d7965db01 100755 --- a/ts2panda/src/base/vregisterCache.ts +++ b/ts2panda/src/base/vregisterCache.ts @@ -33,7 +33,8 @@ import { // expandString, expandSymbol, expandTrue, - expandUndefined + expandUndefined, + expandFunc } from "./builtIn"; import { expandLexEnv } from "./lexEnv"; export enum CacheList { @@ -56,6 +57,7 @@ export enum CacheList { True, False, MAX, + FUNC } let cacheExpandHandlers = new Map([ [CacheList.HOLE, expandHole], @@ -75,6 +77,7 @@ let cacheExpandHandlers = new Map([ [CacheList.LexEnv, expandLexEnv], [CacheList.True, expandTrue], [CacheList.False, expandFalse], + [CacheList.FUNC, expandFunc], ]); class CacheItem { diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index c7c00d7721..be0e8bb51e 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -251,7 +251,7 @@ export class Compiler { variableInfo.scope.setArgumentsOrRestargs(); } let pandaGen = this.pandaGen; - let vreg = "4funcObj" === arg ? getVregisterCache(pandaGen, CacheList.HOLE) : pandaGen.getVregForVariable(variableInfo.v); + let vreg = "4funcObj" === arg ? getVregisterCache(pandaGen, CacheList.FUNC) : pandaGen.getVregForVariable(variableInfo.v); let slot = (variableInfo.v).idxLex; pandaGen.storeLexicalVar(this.rootNode, variableInfo.level, slot, vreg); } diff --git a/ts2panda/src/function/generatorFunctionBuilder.ts b/ts2panda/src/function/generatorFunctionBuilder.ts index cf879e3561..73a26c6be4 100755 --- a/ts2panda/src/function/generatorFunctionBuilder.ts +++ b/ts2panda/src/function/generatorFunctionBuilder.ts @@ -51,7 +51,7 @@ export class GeneratorFunctionBuilder { let funcObj = scope.getName2variable().get("4funcObj")!.getVreg(); // backend handle funcobj, frontend set undefined - pandaGen.createGeneratorObj(node, getVregisterCache(pandaGen, CacheList.HOLE)); + pandaGen.createGeneratorObj(node, getVregisterCache(pandaGen, CacheList.FUNC)); pandaGen.storeAccumulator(node, this.genObj); pandaGen.suspendGenerator(node, this.genObj, getVregisterCache(pandaGen, CacheList.undefined)); pandaGen.resumeGenerator(node, this.genObj); diff --git a/ts2panda/src/lexenv.ts b/ts2panda/src/lexenv.ts index e73212718f..fbdbb2a5fb 100644 --- a/ts2panda/src/lexenv.ts +++ b/ts2panda/src/lexenv.ts @@ -94,7 +94,7 @@ export class VariableAccessLoad extends VariableAccessBase { return insns; } if (v.getName() === "4funcObj") { - insns.push(loadAccumulator(getVregisterCache(pandaGen, CacheList.HOLE))); + insns.push(loadAccumulator(getVregisterCache(pandaGen, CacheList.FUNC))); } else { insns.push(loadAccumulator(bindVreg)); } diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index 4619b16236..bf5aaaaf8a 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -336,7 +336,7 @@ function loadCtorObj(node: ts.CallExpression, compiler: Compiler) { if (ts.isConstructorDeclaration(nearestFunc)) { let funcObj = nearestFuncScope.findLocal("4funcObj"); - pandaGen.loadAccumulator(node, getVregisterCache(pandaGen, CacheList.HOLE)); + pandaGen.loadAccumulator(node, getVregisterCache(pandaGen, CacheList.FUNC)); } else { let outerFunc = jshelpers.getContainingFunction(nearestFunc); let outerFuncScope = recorder.getScopeOfNode(outerFunc); -- Gitee From 7a666f676d543315b85f1ff02acb9c89bd90d955 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Sat, 20 Nov 2021 17:10:34 +0800 Subject: [PATCH 10/11] add func Change-Id: Ie687fadf82fad4f6216ba7a87cd87586744aacbe --- ts2panda/src/base/vregisterCache.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ts2panda/src/base/vregisterCache.ts b/ts2panda/src/base/vregisterCache.ts index 7d7965db01..83bfcea12e 100755 --- a/ts2panda/src/base/vregisterCache.ts +++ b/ts2panda/src/base/vregisterCache.ts @@ -41,6 +41,7 @@ export enum CacheList { MIN, NaN = MIN, HOLE, + FUNC, Infinity, undefined, // Boolean, @@ -56,8 +57,7 @@ export enum CacheList { LexEnv, // Lex Env must come before True and False, because LexEnv depends on True and False True, False, - MAX, - FUNC + MAX } let cacheExpandHandlers = new Map([ [CacheList.HOLE, expandHole], -- Gitee From 81935a885ddb427c750422e5067ddca48fbb0c45 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Sat, 20 Nov 2021 17:19:52 +0800 Subject: [PATCH 11/11] amend func name Change-Id: Ifccbd0add466affc06ac91f8fc199f505e4e2dee --- ts2panda/src/base/builtIn.ts | 4 ++-- ts2panda/src/base/vregisterCache.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ts2panda/src/base/builtIn.ts b/ts2panda/src/base/builtIn.ts index 170536a81c..160b5f9d2a 100755 --- a/ts2panda/src/base/builtIn.ts +++ b/ts2panda/src/base/builtIn.ts @@ -26,7 +26,7 @@ import { EcmaLdtrue, EcmaLdundefined, StaDyn, - EcmaLdfunc + EcmaLdfunction } from "../irnodes"; import { CacheList, getVregisterCache } from "./vregisterCache"; @@ -105,7 +105,7 @@ export function expandFalse(pandaGen: PandaGen): IRNode[] { export function expandFunc(pandaGen: PandaGen): IRNode[] { let vreg = getVregisterCache(pandaGen, CacheList.FUNC); return [ - new EcmaLdfunc(), + new EcmaLdfunction(), new StaDyn(vreg) ]; } \ No newline at end of file diff --git a/ts2panda/src/base/vregisterCache.ts b/ts2panda/src/base/vregisterCache.ts index 83bfcea12e..e4b3082acf 100755 --- a/ts2panda/src/base/vregisterCache.ts +++ b/ts2panda/src/base/vregisterCache.ts @@ -41,7 +41,7 @@ export enum CacheList { MIN, NaN = MIN, HOLE, - FUNC, + FUNC, // load function Infinity, undefined, // Boolean, -- Gitee