From 252817131389bf40ab188ee031aaf807993c371b 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() Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I5INW1 Signed-off-by: hufeng Change-Id: I0c101b131fbba62d6ffaac6ed5703d4f77b307ea --- test262/skip_tests.json | 49 +----------------------- ts2panda/scripts/generate_js_bytecode.py | 4 ++ 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 | 15 +++++++- ts2panda/ts2abc/ts2abc.cpp | 10 ++--- 9 files changed, 57 insertions(+), 73 deletions(-) diff --git a/test262/skip_tests.json b/test262/skip_tests.json index e46ee4e350..e8b3a705d7 100644 --- a/test262/skip_tests.json +++ b/test262/skip_tests.json @@ -1035,54 +1035,9 @@ ] }, { - "reason": "Not support function.toString() due to Runtime can not obtain Source Code yet.", + "reason": "js-runtime incorrectly handling", "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" + "built-ins/GeneratorPrototype/constructor.js" ] }, { diff --git a/ts2panda/scripts/generate_js_bytecode.py b/ts2panda/scripts/generate_js_bytecode.py index 5335f46cec..ff99ce8d4a 100755 --- a/ts2panda/scripts/generate_js_bytecode.py +++ b/ts2panda/scripts/generate_js_bytecode.py @@ -42,6 +42,8 @@ def parse_args(): help='whether is module') parser.add_argument("--commonjs", action='store_true', help='whether is commonjs') + parser.add_argument("--functionSourceCode", action='store_true', + help='compile abc with function sourcecode info') arguments = parser.parse_args() return arguments @@ -88,6 +90,8 @@ def gen_abc_info(input_arguments): cmd.insert(4, '-m') if input_arguments.commonjs: cmd.insert(5, '-c') + if input_arguments.functionSourceCode: + cmd.insert(6, '--function-sourcecode') run_command(cmd, path) diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 026287aa0c..fe304a5613 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -45,7 +45,8 @@ const ts2pandaOptions = [ { name: 'dts-type-record', alias: 'q', type: Boolean, defaultValue: false, description: "Record type info for .d.ts files. Default: false" }, { 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: '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()" } ] @@ -275,6 +276,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 45016fe883..f44f9db6d7 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -203,8 +203,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(); @@ -259,20 +259,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 39c62abb7a..2bd1bc846d 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -254,13 +254,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..ace7fc1c21 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,15 @@ 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;}"; + expect(pandaGen.getSourceCode() == expected).to.be.true; + }) +}) diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 5f79472eaa..f585111578 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 ParseSourceFileInfo(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); + ParseSourceFileInfo(function, pandaFunc); ParseFunctionLabels(function, pandaFunc); ParseFunctionCatchTables(function, pandaFunc); // parsing call opt type -- Gitee