From 05c47722dd5bd09e8a7c3dd43fee47c0392ff873 Mon Sep 17 00:00:00 2001 From: mattias Date: Wed, 30 Mar 2022 11:40:13 +0200 Subject: [PATCH] pastojs: added option ObfuscateLocalIdentifiers --- packages/pastojs/src/fppas2js.pp | 5 +- packages/pastojs/src/pas2jscompiler.pp | 13 ++++- packages/pastojs/src/pas2jsfiler.pp | 3 +- packages/pastojs/tests/tcmodules.pas | 45 +++++++++++++++ packages/pastojs/tests/tcoptimizations.pas | 66 +++++++++++++++++++++- 5 files changed, 127 insertions(+), 5 deletions(-) diff --git a/packages/pastojs/src/fppas2js.pp b/packages/pastojs/src/fppas2js.pp index 36cb958cfa..cd33446f7c 100644 --- a/packages/pastojs/src/fppas2js.pp +++ b/packages/pastojs/src/fppas2js.pp @@ -1417,7 +1417,8 @@ type coRTLVersionCheckMain, // insert rtl version check into main coRTLVersionCheckSystem, // insert rtl version check into system unit init coRTLVersionCheckUnit, // insert rtl version check into every unit init - coShortRefGlobals // use short local variables for global identifiers + coShortRefGlobals, // use short local variables for global identifiers + coObfuscateLocalIdentifiers // use auto generated names for private and local Pascal identifiers ); TPasToJsConverterOptions = set of TPasToJsConverterOption; const @@ -3014,6 +3015,8 @@ begin HandleBoolean(coUseStrict,true); 'jsshortrefglobals': HandleBoolean(coShortRefGlobals,true); + 'jsobfuscatelocalidentifiers': + HandleBoolean(coObfuscateLocalIdentifiers,true); else DoLog(mtWarning,nWarnIllegalCompilerDirectiveX,sWarnIllegalCompilerDirectiveX,['optimization '+OptName]); end; diff --git a/packages/pastojs/src/pas2jscompiler.pp b/packages/pastojs/src/pas2jscompiler.pp index 36eb2bbef4..220adafc56 100644 --- a/packages/pastojs/src/pas2jscompiler.pp +++ b/packages/pastojs/src/pas2jscompiler.pp @@ -139,6 +139,7 @@ type coKeepNotUsedPrivates, // -O- coKeepNotUsedDeclarationsWPO, // -O- coShortRefGlobals, // -O2 + coObfuscateLocalIdentifiers, // -O2 // source map coSourceMapCreate, coSourceMapInclude, @@ -163,10 +164,11 @@ const DefaultResourceMode = rmHTML; coShowAll = [coShowErrors..coShowDebug]; - coAllOptimizations = [coEnumValuesAsNumbers..coShortRefGlobals]; + coAllOptimizations = [coEnumValuesAsNumbers..coObfuscateLocalIdentifiers]; coO0 = [coKeepNotUsedPrivates,coKeepNotUsedDeclarationsWPO]; coO1 = [coEnumValuesAsNumbers]; - coO2 = coO1+[coShortRefGlobals]; + coO2 = coO1+[coShortRefGlobals + {$IFDEF EnableObfuscateIdentifiers},coObfuscateLocalIdentifiers{$ENDIF}]; p2jscoCaption: array[TP2jsCompilerOption] of string = ( // only used by experts or programs parsing the pas2js output, no need for resourcestrings @@ -200,6 +202,7 @@ const 'Keep not used private declarations', 'Keep not used declarations (WPO)', 'Create short local variables for globals', + 'Obfuscate local identifiers', 'Create source map', 'Include Pascal sources in source map', 'Do not shorten filenames in source map', @@ -1066,6 +1069,8 @@ begin Include(Result,fppas2js.coEnumNumbers); if (coShortRefGlobals in Compiler.Options) or IsUnitReadFromPCU then Include(Result,fppas2js.coShortRefGlobals); + if coObfuscateLocalIdentifiers in Compiler.Options then + Include(Result,fppas2js.coObfuscateLocalIdentifiers); if coLowerCase in Compiler.Options then Include(Result,fppas2js.coLowerCase) @@ -3827,6 +3832,7 @@ begin 'removenotusedprivates': SetOption(coKeepNotUsedPrivates,not Enable); 'removenotuseddeclarations': SetOption(coKeepNotUsedDeclarationsWPO,not Enable); 'shortrefglobals': SetOption(coShortRefGlobals,Enable); + 'obfuscatelocalidentifiers': SetOption(coObfuscateLocalIdentifiers,Enable); else Log.LogMsgIgnoreFilter(nUnknownOptimizationOption,[QuoteStr(aValue)]); end; @@ -4833,6 +4839,9 @@ begin w(' -OoRemoveNotUsedDeclarations[-]: Default enabled for programs with -Jc'); w(' -OoRemoveNotUsedPublished[-] : Default is disabled'); w(' -OoShortRefGlobals[-]: Insert JS local var for types, modules and static functions. Default enabled in -O2'); + {$IFDEF EnableObfuscateIdentifiers} + w(' -OoObfuscateLocalIdentifiers[-]: Use auto generated names for private and local Pascal identifiers. Default enabled in -O2'); + {$ENDIF} w(' -P : Set target processor. Case insensitive:'); w(' -Pecmascript5: default'); w(' -Pecmascript6'); diff --git a/packages/pastojs/src/pas2jsfiler.pp b/packages/pastojs/src/pas2jsfiler.pp index d686c240d1..2814b8b0e9 100644 --- a/packages/pastojs/src/pas2jsfiler.pp +++ b/packages/pastojs/src/pas2jsfiler.pp @@ -261,7 +261,8 @@ const 'RTLVersionCheckMain', 'RTLVersionCheckSystem', 'RTLVersionCheckUnit', - 'ShortRefGlobals' + 'ShortRefGlobals', + 'ObfuscateLocalIdentifiers' ); PCUDefaultTargetPlatform = PlatformBrowser; diff --git a/packages/pastojs/tests/tcmodules.pas b/packages/pastojs/tests/tcmodules.pas index 5338a01d09..b29096b04b 100644 --- a/packages/pastojs/tests/tcmodules.pas +++ b/packages/pastojs/tests/tcmodules.pas @@ -946,6 +946,7 @@ type Procedure TestAWait_Result; Procedure TestAWait_ResultPromiseMissingTypeFail; // await(AsyncCallResultPromise) needs T Procedure TestAsync_AnonymousProc; + Procedure TestAsync_AnonymousProc_PassAsyncAsArg; // ToDo Procedure TestAsync_ProcType; Procedure TestAsync_ProcTypeAsyncModMismatchFail; Procedure TestAsync_Inherited; @@ -34736,6 +34737,50 @@ begin CheckResolverUnexpectedHints(); end; +procedure TTestModule.TestAsync_AnonymousProc_PassAsyncAsArg; +begin + exit; + + StartProgram(false); + Add([ + '{$mode objfpc}', + '{$modeswitch externalclass}', + 'type', + ' TJSPromise = class external name ''Promise''', + ' end;', + 'type', + ' TFunc = reference to function(x: double): word; async;', + 'function Crawl: jsvalue; async;', + 'begin', + 'end;', + 'begin', + ' function(c:double):word async begin', + ' Result:=await(Crawl(c));', + ' end;', + ' Func:=function(c:double):word async assembler asm', + ' end;', + ' ']); + ConvertProgram; + CheckSource('TestAsync_AnonymousProc', + LinesToStr([ // statements + 'this.Crawl = async function (d) {', + ' var Result = 0;', + ' return Result;', + '};', + 'this.Func = null;', + '']), + LinesToStr([ + '$mod.Func = async function (c) {', + ' var Result = 0;', + ' Result = await $mod.Crawl(c);', + ' return Result;', + '};', + '$mod.Func = async function (c) {', + '};', + ''])); + CheckResolverUnexpectedHints(); +end; + procedure TTestModule.TestAsync_ProcType; begin StartProgram(false); diff --git a/packages/pastojs/tests/tcoptimizations.pas b/packages/pastojs/tests/tcoptimizations.pas index f7f319aacb..781465ca62 100644 --- a/packages/pastojs/tests/tcoptimizations.pas +++ b/packages/pastojs/tests/tcoptimizations.pas @@ -75,7 +75,10 @@ type procedure TestOptShortRefGlobals_SameUnit_RecordType; procedure TestOptShortRefGlobals_Unit_InitNoImpl; - // Whole Program Optimization + // Obfuscate Identifiers + procedure TestObfuscateLocalIdentifiers_Program; // ToDo + + // Whole Program Optimization - omit not used elements procedure TestWPO_OmitLocalVar; procedure TestWPO_OmitLocalProc; procedure TestWPO_OmitLocalProcForward; @@ -1595,6 +1598,67 @@ begin ''])); end; +procedure TTestOptimizations.TestObfuscateLocalIdentifiers_Program; +begin + exit; + + StartProgram(true,[supTObject]); + Add([ + '{$optimization JSObfuscateLocalIdentifiers}', + 'uses unita;', + 'type', + ' TEagle = class(TBird)', + ' class function Run(w: word = 5): word; override;', + ' end;', + 'class function TEagle.Run(w: word): word;', + 'begin', + 'end;', + 'var', + ' e: TEagle;', + ' r: TRec;', + ' c: TColors;', + 'begin', + ' e:=TEagle.Create;', + ' b:=TBird.Create;', + ' e.c:=e.c+1;', + ' r.x:=TBird.c;', + ' r.x:=b.c;', + ' r.x:=e.Run;', + ' r.x:=e.Run();', + ' r.x:=e.Run(4);', + ' c:=cRedBlue;', + '']); + ConvertProgram; + CheckSource('TestOptShortRefGlobals_Program', + LinesToStr([ + 'var $lt = null;', + 'var $lm = pas.UnitA;', + 'var $lt1 = $lm.TBird;', + 'var $lt2 = $lm.TRec;', + 'rtl.createClass(this, "TEagle", $lt1, function () {', + ' $lt = this;', + ' this.Run = function (w) {', + ' var Result = 0;', + ' return Result;', + ' };', + '});', + 'this.e = null;', + 'this.r = $lt2.$new();', + 'this.c = {};', + '']), + LinesToStr([ + '$mod.e = $lt.$create("Create");', + '$lm.b = $lt1.$create("Create");', + '$lt1.c = $mod.e.c + 1;', + '$mod.r.x = $lt1.c;', + '$mod.r.x = $lm.b.c;', + '$mod.r.x = $mod.e.$class.Run(5);', + '$mod.r.x = $mod.e.$class.Run(5);', + '$mod.r.x = $mod.e.$class.Run(4);', + '$mod.c = rtl.refSet($lm.cRedBlue);', + ''])); +end; + procedure TTestOptimizations.TestWPO_OmitLocalVar; begin StartProgram(false);