From 363c27139b64e2be0fea954ffe5ec74efcdd2f42 Mon Sep 17 00:00:00 2001 From: hufeng Date: Tue, 5 Jul 2022 11:43:29 +0800 Subject: [PATCH] Support function Object's [toString] property Description: Write the function's sourceCode when the [switch] is ON to Support function's toString() Signed-off-by: hufeng Change-Id: I0c101b131fbba62d6ffaac6ed5703d4f77b307ea --- test262/skip_tests.json | 51 --------------------------------- ts2panda/src/cmdOptions.ts | 10 ++++++- ts2panda/src/compilerDriver.ts | 8 ++++++ ts2panda/src/debuginfo.ts | 7 ++--- ts2panda/src/pandagen.ts | 16 +++++------ ts2panda/src/ts2panda.ts | 11 +++---- ts2panda/tests/builtIns.test.ts | 16 ++++++++++- ts2panda/ts2abc/ts2abc.cpp | 10 +++---- 8 files changed, 52 insertions(+), 77 deletions(-) diff --git a/test262/skip_tests.json b/test262/skip_tests.json index e46ee4e350..db99a85e09 100644 --- a/test262/skip_tests.json +++ b/test262/skip_tests.json @@ -1034,57 +1034,6 @@ "built-ins/DataView/prototype/setBigInt64/detached-buffer-after-bigint-value.js" ] }, - { - "reason": "Not support function.toString() due to Runtime can not obtain Source Code yet.", - "files": [ - "built-ins/RegExp/prototype/exec/S15.10.6.2_A1_T9.js", - "built-ins/RegExp/prototype/test/S15.10.6.3_A1_T9.js", - "built-ins/String/prototype/trim/15.5.4.20-2-46.js", - "built-ins/GeneratorPrototype/constructor.js", - "language/expressions/new.target/value-via-reflect-construct.js", - "language/expressions/new.target/asi.js", - "language/expressions/new.target/value-via-new.js", - "language/expressions/new.target/value-via-call.js", - "language/expressions/addition/S11.6.1_A2.2_T3.js", - "language/expressions/addition/S11.6.1_A3.2_T1.2.js", - "language/expressions/bitwise-and/S11.10.1_A3_T1.5.js", - "language/expressions/bitwise-not/S11.4.8_A3_T5.js", - "language/expressions/bitwise-or/S11.10.3_A3_T1.5.js", - "language/expressions/bitwise-xor/S11.10.2_A3_T1.5.js", - "language/expressions/division/S11.5.2_A3_T1.5.js", - "language/expressions/greater-than/S11.8.2_A3.2_T1.2.js", - "language/expressions/greater-than-or-equal/S11.8.4_A3.2_T1.2.js", - "language/expressions/left-shift/S11.7.1_A3_T1.5.js", - "language/expressions/less-than/S11.8.1_A3.2_T1.2.js", - "language/expressions/less-than-or-equal/S11.8.3_A3.2_T1.2.js", - "language/expressions/modulus/S11.5.3_A3_T1.5.js", - "language/expressions/multiplication/S11.5.1_A3_T1.5.js", - "language/expressions/postfix-decrement/S11.3.2_A3_T5.js", - "language/expressions/postfix-decrement/S11.3.2_A4_T5.js", - "language/expressions/postfix-increment/S11.3.1_A3_T5.js", - "language/expressions/postfix-increment/S11.3.1_A4_T5.js", - "language/expressions/prefix-decrement/S11.4.5_A3_T5.js", - "language/expressions/prefix-decrement/S11.4.5_A4_T5.js", - "language/expressions/prefix-increment/S11.4.4_A3_T5.js", - "language/expressions/prefix-increment/S11.4.4_A4_T5.js", - "language/rest-parameters/with-new-target.js", - "language/expressions/right-shift/S11.7.2_A3_T1.5.js", - "language/expressions/subtraction/S11.6.2_A3_T1.5.js", - "language/expressions/unary-minus/S11.4.7_A3_T5.js", - "language/expressions/unary-plus/S11.4.6_A3_T5.js", - "language/expressions/unsigned-right-shift/S11.7.3_A3_T1.5.js", - "language/module-code/eval-gtbndng-indirect-update-dflt.js", - "language/statements/switch/S12.11_A1_T4.js", - "language/statements/switch/S12.11_A1_T4.js", - "built-ins/Promise/resolve/ctx-ctor.js", - "built-ins/Promise/reject/ctx-ctor.js", - "built-ins/Promise/race/ctx-ctor.js", - "built-ins/Promise/all/ctx-ctor.js", - "built-ins/TypedArrayConstructors/ctors/length-arg/use-custom-proto-if-object.js", - "built-ins/TypedArrayConstructors/ctors/no-args/use-custom-proto-if-object.js", - "built-ins/TypedArrayConstructors/ctors/object-arg/use-custom-proto-if-object.js" - ] - }, { "reason": "AnnexB Feature Supported, Support must be aligned with the ACE", "files": [ diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 4e108670db..7b0f65fab9 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -46,7 +46,8 @@ const ts2pandaOptions = [ { name: 'debug-type', alias: 'g', type: Boolean, defaultValue: false, description: "Print type-related log. Default: false" }, { name: 'output-type', type: Boolean, defaultValue: false, description: "set output type."}, { name: 'enable-typeinfo', type: Boolean, defaultValue: false, description: "Enable typeinfo of pairs of instruction orders and types" }, - { name: 'display-typeinfo', type: Boolean, defaultValue: false, description: "Display typeinfo of pairs of instruction orders and types when enable-typeinfo is true" } + { name: 'display-typeinfo', type: Boolean, defaultValue: false, description: "Display typeinfo of pairs of instruction orders and types when enable-typeinfo is true" }, + { name: 'function-sourcecode', type: Boolean, defaultValue: false, description: "Record functions' sourceCode to support the feature of [function].toString()" } ] @@ -271,6 +272,13 @@ export class CmdOptions { return this.options["debug-type"]; } + static needRecordSourceCode(): boolean { + if (!this.options) { + return false; + } + return this.options["function-sourcecode"]; + } + // @ts-ignore static parseUserCmd(args: string[]): ts.ParsedCommandLine | undefined { this.options = commandLineArgs(ts2pandaOptions, { partial: true }); diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index a5b3543ef5..66747fbe58 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -216,6 +216,11 @@ export class CompilerDriver { private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder): void { let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); + + if (CmdOptions.needRecordSourceCode() && !ts.isSourceFile(node)) { + // souceCode of [ts.sourceFile] will be record in debugInfo later. + pandaGen.setSourceCode(node.getText()); + } // for debug info DebugInfo.addDebugIns(scope, pandaGen, true); @@ -262,6 +267,9 @@ export class CompilerDriver { private compileUnitTestImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder) { let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); + if (CmdOptions.needRecordSourceCode() && !ts.isSourceFile(node)) { + pandaGen.setSourceCode(node.getText()); + } let compiler = new Compiler(node, pandaGen, this, recorder); hoisting(node, pandaGen, recorder, compiler); diff --git a/ts2panda/src/debuginfo.ts b/ts2panda/src/debuginfo.ts index 982b92334a..3df1f37ba5 100644 --- a/ts2panda/src/debuginfo.ts +++ b/ts2panda/src/debuginfo.ts @@ -354,11 +354,8 @@ export class DebugInfo { let sourceFile = jshelpers.getSourceFileOfNode(node); pandaGen.setSourceFileDebugInfo(sourceFile.fileName); - if (CmdOptions.isDebugMode()) { - if (ts.isSourceFile(node)) { - pandaGen.setSourceCodeDebugInfo(node.text); - } - return; + if (CmdOptions.isDebugMode() && ts.isSourceFile(node)) { + pandaGen.setSourceCode(node.text); } } diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index 0db314b6bd..a51dda46dc 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -202,8 +202,8 @@ export class PandaGen { // for debug info private variableDebugInfoArray: VariableDebugInfo[] = []; private firstStmt: ts.Statement | undefined; - private sourceFileDebugInfo: string = ""; - private sourceCodeDebugInfo: string | undefined; + private sourceFile: string = ""; + private sourceCode: string | undefined = undefined; private callType: number = 0; private static literalArrayBuffer: Array = new Array(); @@ -258,20 +258,20 @@ export class PandaGen { } } - public getSourceCodeDebugInfo() { - return this.sourceCodeDebugInfo; + public getSourceCode(): string | undefined { + return this.sourceCode; } - public setSourceCodeDebugInfo(code: string) { - this.sourceCodeDebugInfo = code; + public setSourceCode(code: string) { + this.sourceCode = code; } public getSourceFileDebugInfo() { - return this.sourceFileDebugInfo; + return this.sourceFile; } public setSourceFileDebugInfo(sourceFile: string) { - this.sourceFileDebugInfo = sourceFile; + this.sourceFile = sourceFile; } static getLiteralArrayBuffer() { diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index 52c1823865..bd157fbcaa 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -255,13 +255,14 @@ export class Ts2Panda { ); } - let variables, sourceCode; + let variables = undefined, sourceCode = undefined; + if (CmdOptions.needRecordSourceCode() || CmdOptions.isDebugMode()) { + // function's sourceCode will be undefined in debugMode + // if we don't need to record function-sourceCode + sourceCode = pg.getSourceCode(); + } if (CmdOptions.isDebugMode()) { variables = pg.getVariableDebugInfoArray(); - sourceCode = pg.getSourceCodeDebugInfo(); - } else { - variables = undefined; - sourceCode = undefined; } let catchTableArr; diff --git a/ts2panda/tests/builtIns.test.ts b/ts2panda/tests/builtIns.test.ts index 2484fba12f..39f483e1e7 100644 --- a/ts2panda/tests/builtIns.test.ts +++ b/ts2panda/tests/builtIns.test.ts @@ -22,7 +22,8 @@ import { LdaDyn, VReg } from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; +import { checkInstructions, compileMainSnippet, SnippetCompiler } from "./utils/base"; +import { CmdOptions } from '../src/cmdOptions'; describe("BuiltInsTest", function () { it("Global Value Properties", function () { @@ -37,3 +38,16 @@ describe("BuiltInsTest", function () { expect(checkInstructions(insns, expected)).to.be.true; }); }); + +describe("FunctionToStringTest", function () { + it("func.toString()", function () { + CmdOptions.needRecordSourceCode = () => {return true}; + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compileAfter(`function foo() {return 123;}\nfunction bar() {return 321;}\n`, 'toStringTest.js'); + CmdOptions.needRecordSourceCode = () => {return false}; + let pandaGen = snippetCompiler.getPandaGenByName('foo'); + let expected = "function foo() {return 123;}"; + console.log(pandaGen.getSourceCode()); + expect(pandaGen.getSourceCode() == expected).to.be.true; + }) +}) diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index f66e50ce9f..efb2b90adc 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -477,16 +477,14 @@ static int ParseVariablesDebugInfo(const Json::Value &function, panda::pandasm:: return RETURN_SUCCESS; } -static int ParseSourceFileDebugInfo(const Json::Value &function, panda::pandasm::Function &pandaFunc) +static int ParseSourceFile(const Json::Value &function, panda::pandasm::Function &pandaFunc) { if (function.isMember("sf") && function["sf"].isString()) { pandaFunc.source_file = function["sf"].asString(); } - if (GetDebugModeEnabled()) { - if (function.isMember("sc") && function["sc"].isString()) { - pandaFunc.source_code = function["sc"].asString(); - } + if (function.isMember("sc") && function["sc"].isString()) { + pandaFunc.source_code = function["sc"].asString(); } return RETURN_SUCCESS; @@ -770,7 +768,7 @@ static panda::pandasm::Function ParseFunction(const Json::Value &function) auto pandaFunc = GetFunctionDefintion(function); ParseFunctionInstructions(function, pandaFunc); ParseVariablesDebugInfo(function, pandaFunc); - ParseSourceFileDebugInfo(function, pandaFunc); + ParseSourceFile(function, pandaFunc); ParseFunctionLabels(function, pandaFunc); ParseFunctionCatchTables(function, pandaFunc); // parsing call opt type -- Gitee