Browse Source

pastojs: filer: store generic procedure body

git-svn-id: trunk@43853 -
Mattias Gaertner 5 years ago
parent
commit
0a9048a9a4
3 changed files with 616 additions and 390 deletions
  1. 9 9
      packages/pastojs/src/fppas2js.pp
  2. 541 367
      packages/pastojs/src/pas2jsfiler.pp
  3. 66 14
      packages/pastojs/tests/tcfiler.pas

+ 9 - 9
packages/pastojs/src/fppas2js.pp

@@ -1455,7 +1455,7 @@ type
     function ProcHasImplElements(Proc: TPasProcedure): boolean; override;
     function ProcHasImplElements(Proc: TPasProcedure): boolean; override;
     function HasAnonymousFunctions(El: TPasImplElement): boolean;
     function HasAnonymousFunctions(El: TPasImplElement): boolean;
     function GetTopLvlProcScope(El: TPasElement): TPas2JSProcedureScope;
     function GetTopLvlProcScope(El: TPasElement): TPas2JSProcedureScope;
-    function ProcCanBePrecompiled(Proc: TPasProcedure): boolean; virtual;
+    function ProcCanBePrecompiled(DeclProc: TPasProcedure): boolean; virtual;
     function IsTObjectFreeMethod(El: TPasExpr): boolean; virtual;
     function IsTObjectFreeMethod(El: TPasExpr): boolean; virtual;
     function IsExternalBracketAccessor(El: TPasElement): boolean;
     function IsExternalBracketAccessor(El: TPasElement): boolean;
     function IsExternalClassConstructor(El: TPasElement): boolean;
     function IsExternalClassConstructor(El: TPasElement): boolean;
@@ -5940,30 +5940,30 @@ begin
     end;
     end;
 end;
 end;
 
 
-function TPas2JSResolver.ProcCanBePrecompiled(Proc: TPasProcedure): boolean;
+function TPas2JSResolver.ProcCanBePrecompiled(DeclProc: TPasProcedure): boolean;
 var
 var
   El: TPasElement;
   El: TPasElement;
   TemplTypes: TFPList;
   TemplTypes: TFPList;
   ProcScope: TPas2JSProcedureScope;
   ProcScope: TPas2JSProcedureScope;
   GenScope: TPasGenericScope;
   GenScope: TPasGenericScope;
 begin
 begin
-  if GetProcTemplateTypes(Proc)<>nil then
-    exit(false); // generic proc
-  ProcScope:=Proc.CustomData as TPas2JSProcedureScope;
+  if GetProcTemplateTypes(DeclProc)<>nil then
+    exit(false); // generic DeclProc
+  ProcScope:=DeclProc.CustomData as TPas2JSProcedureScope;
   if ProcScope.SpecializedFromItem<>nil then
   if ProcScope.SpecializedFromItem<>nil then
-    exit(false); // specialized generic proc
-  El:=Proc;
+    exit(false); // specialized generic DeclProc
+  El:=DeclProc;
   repeat
   repeat
     El:=El.Parent;
     El:=El.Parent;
     if El=nil then
     if El=nil then
       exit(true); // ok
       exit(true); // ok
     if El is TPasProcedure then
     if El is TPasProcedure then
-      exit(false); // Proc is a local proc
+      exit(false); // DeclProc is a local DeclProc
     if El is TPasGenericType then
     if El is TPasGenericType then
       begin
       begin
       TemplTypes:=TPasGenericType(El).GenericTemplateTypes;
       TemplTypes:=TPasGenericType(El).GenericTemplateTypes;
       if (TemplTypes<>nil) and (TemplTypes.Count>0) then
       if (TemplTypes<>nil) and (TemplTypes.Count>0) then
-        exit(false); // not fully specialized
+        exit(false); // method of a generic class/record type
       GenScope:=El.CustomData as TPasGenericScope;
       GenScope:=El.CustomData as TPasGenericScope;
       if GenScope.SpecializedFromItem<>nil then
       if GenScope.SpecializedFromItem<>nil then
         exit(false); // method of a specialized class/record type
         exit(false); // method of a specialized class/record type

File diff suppressed because it is too large
+ 541 - 367
packages/pastojs/src/pas2jsfiler.pp


+ 66 - 14
packages/pastojs/tests/tcfiler.pas

@@ -56,6 +56,7 @@ type
     procedure StartParsing; override;
     procedure StartParsing; override;
     function CheckRestoredObject(const Path: string; Orig, Rest: TObject): boolean; virtual;
     function CheckRestoredObject(const Path: string; Orig, Rest: TObject): boolean; virtual;
     procedure CheckRestoredJS(const Path, Orig, Rest: string); virtual;
     procedure CheckRestoredJS(const Path, Orig, Rest: string); virtual;
+    procedure CheckRestoredStringList(const Path: string; Orig, Rest: TStrings); virtual;
     // check restored parser+resolver
     // check restored parser+resolver
     procedure CheckRestoredResolver(Original, Restored: TPas2JSResolver); virtual;
     procedure CheckRestoredResolver(Original, Restored: TPas2JSResolver); virtual;
     procedure CheckRestoredDeclarations(const Path: string; Orig, Rest: TPasDeclarations); virtual;
     procedure CheckRestoredDeclarations(const Path: string; Orig, Rest: TPasDeclarations); virtual;
@@ -125,7 +126,9 @@ type
     procedure CheckRestoredProcNameParts(const Path: string; Orig, Rest: TPasProcedure); virtual;
     procedure CheckRestoredProcNameParts(const Path: string; Orig, Rest: TPasProcedure); virtual;
     procedure CheckRestoredProcedure(const Path: string; Orig, Rest: TPasProcedure); virtual;
     procedure CheckRestoredProcedure(const Path: string; Orig, Rest: TPasProcedure); virtual;
     procedure CheckRestoredOperator(const Path: string; Orig, Rest: TPasOperator); virtual;
     procedure CheckRestoredOperator(const Path: string; Orig, Rest: TPasOperator); virtual;
+    procedure CheckRestoredProcedureBody(const Path: string; Orig, Rest: TProcedureBody); virtual;
     procedure CheckRestoredAttributes(const Path: string; Orig, Rest: TPasAttributes); virtual;
     procedure CheckRestoredAttributes(const Path: string; Orig, Rest: TPasAttributes); virtual;
+    procedure CheckRestoredImplBeginBlock(const Path: string; Orig, Rest: TPasImplBeginBlock); virtual;
   public
   public
     property Analyzer: TPas2JSAnalyzer read FAnalyzer;
     property Analyzer: TPas2JSAnalyzer read FAnalyzer;
     property RestAnalyzer: TPas2JSAnalyzer read FRestAnalyzer;
     property RestAnalyzer: TPas2JSAnalyzer read FRestAnalyzer;
@@ -173,7 +176,7 @@ type
     procedure TestPC_Attributes;
     procedure TestPC_Attributes;
 
 
     procedure TestPC_GenericClassSkip; // ToDo
     procedure TestPC_GenericClassSkip; // ToDo
-    procedure TestPC_GenericFunctionSkip;
+    procedure TestPC_GenericFunction;
 
 
     procedure TestPC_UseUnit;
     procedure TestPC_UseUnit;
     procedure TestPC_UseUnit_Class;
     procedure TestPC_UseUnit_Class;
@@ -486,7 +489,6 @@ end;
 procedure TCustomTestPrecompile.CheckRestoredJS(const Path, Orig, Rest: string);
 procedure TCustomTestPrecompile.CheckRestoredJS(const Path, Orig, Rest: string);
 var
 var
   OrigList, RestList: TStringList;
   OrigList, RestList: TStringList;
-  i: Integer;
 begin
 begin
   if Orig=Rest then exit;
   if Orig=Rest then exit;
   writeln('TCustomTestPrecompile.CheckRestoredJS ORIG START--------------');
   writeln('TCustomTestPrecompile.CheckRestoredJS ORIG START--------------');
@@ -500,20 +502,31 @@ begin
   try
   try
     OrigList.Text:=Orig;
     OrigList.Text:=Orig;
     RestList.Text:=Rest;
     RestList.Text:=Rest;
-    for i:=0 to OrigList.Count-1 do
-      begin
-      if i>=RestList.Count then
-        Fail(Path+' missing: '+OrigList[i]);
-      writeln('  ',i,': '+OrigList[i]);
-      end;
-    if OrigList.Count<RestList.Count then
-      Fail(Path+' too much: '+RestList[OrigList.Count]);
+    CheckRestoredStringList(Path,OrigList,RestList);
  finally
  finally
     OrigList.Free;
     OrigList.Free;
     RestList.Free;
     RestList.Free;
   end;
   end;
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredStringList(const Path: string;
+  Orig, Rest: TStrings);
+var
+  i: Integer;
+begin
+  CheckRestoredObject(Path,Orig,Rest);
+  if Orig=nil then exit;
+  if Orig.Text=Rest.Text then exit;
+  for i:=0 to Orig.Count-1 do
+    begin
+    if i>=Rest.Count then
+      Fail(Path+' missing: '+Orig[i]);
+    writeln('  ',i,': '+Orig[i]);
+    end;
+  if Orig.Count<Rest.Count then
+    Fail(Path+' too much: '+Rest[Orig.Count]);
+end;
+
 procedure TCustomTestPrecompile.CheckRestoredResolver(Original,
 procedure TCustomTestPrecompile.CheckRestoredResolver(Original,
   Restored: TPas2JSResolver);
   Restored: TPas2JSResolver);
 var
 var
@@ -1200,6 +1213,8 @@ begin
   else if (C=TPasOperator)
   else if (C=TPasOperator)
       or (C=TPasClassOperator) then
       or (C=TPasClassOperator) then
     CheckRestoredOperator(Path,TPasOperator(Orig),TPasOperator(Rest))
     CheckRestoredOperator(Path,TPasOperator(Orig),TPasOperator(Rest))
+  else if (C=TPasImplBeginBlock) then
+    CheckRestoredImplBeginBlock(Path,TPasImplBeginBlock(Orig),TPasImplBeginBlock(Rest))
   else if (C=TPasModule)
   else if (C=TPasModule)
         or (C=TPasProgram)
         or (C=TPasProgram)
         or (C=TPasLibrary) then
         or (C=TPasLibrary) then
@@ -1617,8 +1632,11 @@ end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredProcedure(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredProcedure(const Path: string;
   Orig, Rest: TPasProcedure);
   Orig, Rest: TPasProcedure);
+const
+  ImplMods = [pmInline,pmAssembler,pmNoReturn];
 var
 var
   RestScope, OrigScope: TPas2JSProcedureScope;
   RestScope, OrigScope: TPas2JSProcedureScope;
+  DeclProc: TPasProcedure;
 begin
 begin
   CheckRestoredObject(Path+'.CustomData',Orig.CustomData,Rest.CustomData);
   CheckRestoredObject(Path+'.CustomData',Orig.CustomData,Rest.CustomData);
   OrigScope:=Orig.CustomData as TPas2JSProcedureScope;
   OrigScope:=Orig.CustomData as TPas2JSProcedureScope;
@@ -1628,8 +1646,10 @@ begin
   CheckRestoredReference(Path+'.CustomData[TPas2JSProcedureScope].DeclarationProc',
   CheckRestoredReference(Path+'.CustomData[TPas2JSProcedureScope].DeclarationProc',
     OrigScope.DeclarationProc,RestScope.DeclarationProc);
     OrigScope.DeclarationProc,RestScope.DeclarationProc);
   AssertEquals(Path+'.CustomData[TPas2JSProcedureScope].ResultVarName',OrigScope.ResultVarName,RestScope.ResultVarName);
   AssertEquals(Path+'.CustomData[TPas2JSProcedureScope].ResultVarName',OrigScope.ResultVarName,RestScope.ResultVarName);
-  if RestScope.DeclarationProc=nil then
+  DeclProc:=RestScope.DeclarationProc;
+  if DeclProc=nil then
     begin
     begin
+    DeclProc:=Rest;
     CheckRestoredProcNameParts(Path,Orig,Rest);
     CheckRestoredProcNameParts(Path,Orig,Rest);
     CheckRestoredElement(Path+'.ProcType',Orig.ProcType,Rest.ProcType);
     CheckRestoredElement(Path+'.ProcType',Orig.ProcType,Rest.ProcType);
     CheckRestoredElement(Path+'.PublicName',Orig.PublicName,Rest.PublicName);
     CheckRestoredElement(Path+'.PublicName',Orig.PublicName,Rest.PublicName);
@@ -1646,8 +1666,25 @@ begin
   else
   else
     begin
     begin
     // ImplProc
     // ImplProc
+    if Orig.Modifiers*ImplMods<>Rest.Modifiers*ImplMods then
+      Fail(Path+'.Impl-Modifiers');
     end;
     end;
-  // ToDo: Body
+  // Body
+  if Orig.Body<>nil then
+    begin
+    if Engine.ProcCanBePrecompiled(DeclProc) then
+      begin
+      AssertEquals(Path+'.EmptyJS',OrigScope.EmptyJS,RestScope.EmptyJS);
+      CheckRestoredJS(Path+'.BodyJS',OrigScope.BodyJS,RestScope.BodyJS);
+      CheckRestoredStringList(Path+'.GlobalJS',OrigScope.GlobalJS,RestScope.GlobalJS);
+      end
+    else
+      begin
+      CheckRestoredProcedureBody(Path+'.Body',Orig.Body,Rest.Body);
+      end;
+    end
+  else if Rest.Body<>nil then
+    Fail(Path+'.Body<>nil, expected =nil');
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredOperator(const Path: string; Orig,
 procedure TCustomTestPrecompile.CheckRestoredOperator(const Path: string; Orig,
@@ -1659,12 +1696,27 @@ begin
   CheckRestoredProcedure(Path,Orig,Rest);
   CheckRestoredProcedure(Path,Orig,Rest);
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredProcedureBody(const Path: string;
+  Orig, Rest: TProcedureBody);
+begin
+  CheckRestoredObject(Path+'.CustomData',Orig.CustomData,Rest.CustomData);
+  CheckRestoredDeclarations(Path,Orig,Rest);
+  CheckRestoredElement(Path+'.Body',Orig.Body,Rest.Body);
+end;
+
 procedure TCustomTestPrecompile.CheckRestoredAttributes(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredAttributes(const Path: string;
   Orig, Rest: TPasAttributes);
   Orig, Rest: TPasAttributes);
 begin
 begin
   CheckRestoredPasExprArray(Path+'.Calls',Orig.Calls,Rest.Calls);
   CheckRestoredPasExprArray(Path+'.Calls',Orig.Calls,Rest.Calls);
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredImplBeginBlock(const Path: string;
+  Orig, Rest: TPasImplBeginBlock);
+begin
+  CheckRestoredObject(Path+'.CustomData',Orig.CustomData,Rest.CustomData);
+  CheckRestoredElementList(Path,Orig.Elements,Rest.Elements);
+end;
+
 { TTestPrecompile }
 { TTestPrecompile }
 
 
 procedure TTestPrecompile.Test_Base256VLQ;
 procedure TTestPrecompile.Test_Base256VLQ;
@@ -2431,7 +2483,7 @@ begin
   WriteReadUnit;
   WriteReadUnit;
 end;
 end;
 
 
-procedure TTestPrecompile.TestPC_GenericFunctionSkip;
+procedure TTestPrecompile.TestPC_GenericFunction;
 begin
 begin
   StartUnit(false);
   StartUnit(false);
   Add([
   Add([
@@ -2441,7 +2493,7 @@ begin
   'generic function Run<T>(a: T): T;',
   'generic function Run<T>(a: T): T;',
   'var b: T;',
   'var b: T;',
   'begin',
   'begin',
-  '  b:=a; Result:=b;',
+  //'  b:=a; Result:=b;',
   'end;',
   'end;',
   '']);
   '']);
   WriteReadUnit;
   WriteReadUnit;

Some files were not shown because too many files changed in this diff