Browse Source

pas2js: parse $optimization

git-svn-id: trunk@45587 -
Mattias Gaertner 5 years ago
parent
commit
17850b3bb7

+ 71 - 18
packages/pastojs/src/fppas2js.pp

@@ -407,6 +407,8 @@ Works:
 - async procedure modifier
 - async procedure modifier
 - function await(const expr: T): T
 - function await(const expr: T): T
 - function await(T; p: TJSPromise): T
 - function await(T; p: TJSPromise): T
+- constref
+- generics
 
 
 ToDos:
 ToDos:
 - range check:
 - range check:
@@ -420,7 +422,6 @@ ToDos:
 - $OPTIMIZATION ON|OFF
 - $OPTIMIZATION ON|OFF
 - $optimization REMOVEEMPTYPROCS
 - $optimization REMOVEEMPTYPROCS
 - $optimization REMOVEEMPTYPROCS,RemoveNotUsedDeclarations-
 - $optimization REMOVEEMPTYPROCS,RemoveNotUsedDeclarations-
-- setlength(dynarray)  modeswitch to not create a copy
 - static arrays
 - static arrays
   - clone multi dim static array
   - clone multi dim static array
 - RTTI
 - RTTI
@@ -436,7 +437,6 @@ ToDos:
 - call array of proc element without ()
 - call array of proc element without ()
 - enums with custom values
 - enums with custom values
 - library
 - library
-- constref
 - option overflow checking -Co
 - option overflow checking -Co
   +, -, *, Succ, Pred, Inc, Dec
   +, -, *, Succ, Pred, Inc, Dec
   -CO   : Check for possible overflow of integer operations
   -CO   : Check for possible overflow of integer operations
@@ -444,7 +444,6 @@ ToDos:
 - optimizations:
 - optimizations:
   see https://wiki.lazarus.freepascal.org/Pas2js_optimizations
   see https://wiki.lazarus.freepascal.org/Pas2js_optimizations
 - objects
 - objects
-- generics
 - operator overloading
 - operator overloading
   - operator enumerator
   - operator enumerator
 - inline
 - inline
@@ -1316,6 +1315,25 @@ const
     proMethodAddrAsPointer,
     proMethodAddrAsPointer,
     proSafecallAllowsDefault
     proSafecallAllowsDefault
     ];
     ];
+
+type
+  TPasToJsConverterOption = (
+    coLowerCase, // lowercase all identifiers, except conflicts with JS reserved words
+    coSwitchStatement, // convert case-of into switch instead of if-then-else
+    coEnumNumbers, // use enum numbers instead of names
+    coUseStrict,   // insert 'use strict'
+    coNoTypeInfo,  // do not generate RTTI
+    coEliminateDeadCode,  // skip code that is never executed
+    coStoreImplJS,  // store references to JS code in procscopes
+    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
+    coAliaslobals // use short alias variables for global identifiers
+    );
+  TPasToJsConverterOptions = set of TPasToJsConverterOption;
+const
+  DefaultPasToJSOptions = [coLowerCase];
+
 type
 type
   TPas2JSResolver = class;
   TPas2JSResolver = class;
 
 
@@ -1329,7 +1347,10 @@ type
     FTargetProcessor: TPasToJsProcessor;
     FTargetProcessor: TPasToJsProcessor;
   protected
   protected
     function HandleInclude(const Param: String): TToken; override;
     function HandleInclude(const Param: String): TToken; override;
+    procedure DoHandleOptimization(OptName, OptValue: string); override;
   public
   public
+    GlobalConvOptsEnabled: TPasToJsConverterOptions;
+    GlobalConvOptsDisabled: TPasToJsConverterOptions;
     function ReadNonPascalTillEndToken(StopAtLineEnd: boolean): TToken;
     function ReadNonPascalTillEndToken(StopAtLineEnd: boolean): TToken;
       override;
       override;
     property CompilerVersion: string read FCompilerVersion write FCompilerVersion;
     property CompilerVersion: string read FCompilerVersion write FCompilerVersion;
@@ -1680,22 +1701,7 @@ type
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 // TPasToJSConverter
 // TPasToJSConverter
-type
-  TPasToJsConverterOption = (
-    coLowerCase, // lowercase all identifiers, except conflicts with JS reserved words
-    coSwitchStatement, // convert case-of into switch instead of if-then-else
-    coEnumNumbers, // use enum numbers instead of names
-    coUseStrict,   // insert 'use strict'
-    coNoTypeInfo,  // do not generate RTTI
-    coEliminateDeadCode,  // skip code that is never executed
-    coStoreImplJS,  // store references to JS code in procscopes
-    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
-    );
-  TPasToJsConverterOptions = set of TPasToJsConverterOption;
 const
 const
-  DefaultPasToJSOptions = [coLowerCase];
   DefaultJSWriterOptions = [
   DefaultJSWriterOptions = [
     {$IFDEF FPC_HAS_CPSTRING}
     {$IFDEF FPC_HAS_CPSTRING}
     woUseUTF8,
     woUseUTF8,
@@ -2630,6 +2636,45 @@ begin
   Result:=inherited HandleInclude(Param);
   Result:=inherited HandleInclude(Param);
 end;
 end;
 
 
+procedure TPas2jsPasScanner.DoHandleOptimization(OptName, OptValue: string);
+
+  procedure HandleBoolean(o: TPasToJsConverterOption; IsGlobalSwitch: boolean);
+  var
+    Enable: Boolean;
+  begin
+    Enable:=false;
+    case lowercase(OptValue) of
+    '','on','+': Enable:=true;
+    'off','-': Enable:=false;
+    else
+      Error(nErrWrongSwitchToggle,SErrWrongSwitchToggle,[]);
+    end;
+    if IsGlobalSwitch and SkipGlobalSwitches then
+      begin
+      DoLog(mtWarning,nMisplacedGlobalCompilerSwitch,SMisplacedGlobalCompilerSwitch,[]);
+      exit;
+      end;
+    if Enable then
+      begin
+      Include(GlobalConvOptsEnabled,o);
+      Exclude(GlobalConvOptsDisabled,o);
+      end
+    else
+      begin
+      Include(GlobalConvOptsDisabled,o);
+      Exclude(GlobalConvOptsEnabled,o);
+      end;
+  end;
+
+begin
+  case lowercase(OptName) of
+  'aliasglobals':
+    HandleBoolean(coAliaslobals,true);
+  else
+    DoLog(mtWarning,nWarnIllegalCompilerDirectiveX,sWarnIllegalCompilerDirectiveX,['optimization '+OptName]);
+  end;
+end;
+
 function TPas2jsPasScanner.ReadNonPascalTillEndToken(StopAtLineEnd: boolean
 function TPas2jsPasScanner.ReadNonPascalTillEndToken(StopAtLineEnd: boolean
   ): TToken;
   ): TToken;
 var
 var
@@ -24838,9 +24883,17 @@ function TPasToJSConverter.ConvertPasElement(El: TPasElement;
   Resolver: TPas2JSResolver): TJSElement;
   Resolver: TPas2JSResolver): TJSElement;
 var
 var
   aContext: TRootContext;
   aContext: TRootContext;
+  Scanner: TPas2jsPasScanner;
 begin
 begin
   if FGlobals=nil then
   if FGlobals=nil then
     FGlobals:=TPasToJSConverterGlobals.Create(Self);
     FGlobals:=TPasToJSConverterGlobals.Create(Self);
+  if (Resolver<>nil)
+      and (Resolver.CurrentParser<>nil)
+      and (Resolver.CurrentParser.Scanner is TPas2jsPasScanner) then
+    begin
+    Scanner:=TPas2jsPasScanner(Resolver.CurrentParser.Scanner);
+    Options:=Options+Scanner.GlobalConvOptsEnabled-Scanner.GlobalConvOptsDisabled;
+    end;
   aContext:=TRootContext.Create(El,nil,nil);
   aContext:=TRootContext.Create(El,nil,nil);
   try
   try
     aContext.Resolver:=Resolver;
     aContext.Resolver:=Resolver;

+ 2 - 1
packages/pastojs/src/pas2jsfiler.pp

@@ -252,7 +252,8 @@ const
     'StoreImplJS',
     'StoreImplJS',
     'RTLVersionCheckMain',
     'RTLVersionCheckMain',
     'RTLVersionCheckSystem',
     'RTLVersionCheckSystem',
-    'RTLVersionCheckUnit'
+    'RTLVersionCheckUnit',
+    'AliasGlobals'
     );
     );
 
 
   PCUDefaultTargetPlatform = PlatformBrowser;
   PCUDefaultTargetPlatform = PlatformBrowser;

+ 58 - 0
packages/pastojs/tests/tcoptimizations.pas

@@ -56,6 +56,10 @@ type
 
 
   TTestOptimizations = class(TCustomTestOptimizations)
   TTestOptimizations = class(TCustomTestOptimizations)
   published
   published
+    // unit optimization: aliasglobals
+    procedure TestOptAliasGlobals_Program; // ToDo
+    // ToDo: procedure TestOptAliasGlobals_Unit;
+
     // Whole Program Optimization
     // Whole Program Optimization
     procedure TestWPO_OmitLocalVar;
     procedure TestWPO_OmitLocalVar;
     procedure TestWPO_OmitLocalProc;
     procedure TestWPO_OmitLocalProc;
@@ -187,6 +191,60 @@ end;
 
 
 { TTestOptimizations }
 { TTestOptimizations }
 
 
+procedure TTestOptimizations.TestOptAliasGlobals_Program;
+begin
+  exit;
+
+  StartProgram(true,[supTObject]);
+  AddModuleWithIntfImplSrc('UnitA.pas',
+  LinesToStr([
+    'const',
+    '  cWidth = 17;',
+    'type',
+    '  TBird = class',
+    '  public',
+    '    const c = 3;',
+    '    class function Run(w: word): word; virtual; abstract;',
+    '  end;',
+    '  TRec = record',
+    '    x: word;',
+    '  end;',
+    'var b: TBird;',
+    '']),
+  LinesToStr([
+    '']));
+  Add([
+  '{$optimization AliasGlobals}',
+  '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;',
+  'begin',
+  '  b:=TBird.Create;',
+  '  r.x:=TBird.c;',
+  '  r.x:=b.c;',
+  '  r.x:=e.Run;',
+  '  r.x:=e.Run();',
+  '  r.x:=e.Run(4);',
+  '']);
+  ConvertProgram;
+  CheckSource('TestOptAliasGlobals_Program',
+    LinesToStr([
+    'this.DoIt = function () {',
+    '};',
+    '']),
+    LinesToStr([
+    '$mod.DoIt();',
+    '']));
+end;
+
 procedure TTestOptimizations.TestWPO_OmitLocalVar;
 procedure TTestOptimizations.TestWPO_OmitLocalVar;
 begin
 begin
   StartProgram(false);
   StartProgram(false);