Ver Fonte

pastojs: faster concat append for var args

mattias há 3 anos atrás
pai
commit
34605e9cd1
2 ficheiros alterados com 61 adições e 25 exclusões
  1. 14 20
      packages/pastojs/src/fppas2js.pp
  2. 47 5
      packages/pastojs/tests/tcmodules.pas

+ 14 - 20
packages/pastojs/src/fppas2js.pp

@@ -1685,7 +1685,7 @@ type
     function HasAnonymousFunctions(El: TPasImplElement): boolean;
     function GetTopLvlProcScope(El: TPasElement): TPas2JSProcedureScope;
     function ProcCanBePrecompiled(DeclProc: TPasProcedure): boolean; virtual;
-    function IsDirectlyWritable(const ExprResolved: TPasResolverResult): boolean; virtual;
+    function IsReadEqWrite(const ExprResolved: TPasResolverResult): boolean; virtual;
     function IsTObjectFreeMethod(El: TPasExpr): boolean; virtual;
     function IsExternalBracketAccessor(El: TPasElement): boolean;
     function IsExternalClassConstructor(El: TPasElement): boolean;
@@ -7417,13 +7417,14 @@ begin
   until false;
 end;
 
-function TPas2JSResolver.IsDirectlyWritable(const ExprResolved: TPasResolverResult
+function TPas2JSResolver.IsReadEqWrite(const ExprResolved: TPasResolverResult
   ): boolean;
 var
   C: TClass;
-  IdentEl, Setter: TPasElement;
+  IdentEl, Setter, Getter: TPasElement;
   Prop: TPasProperty;
 begin
+  if not (rrfReadable in ExprResolved.Flags) then exit;
   if not (rrfWritable in ExprResolved.Flags) then exit;
   Result:=false;
   IdentEl:=ExprResolved.IdentEl;
@@ -7435,16 +7436,15 @@ begin
       if (C=TPasVariable) or (C=TPasConst) or (C=TPasResultElement) then
         exit(true)
       else if (C=TPasArgument) then
-        begin
-        if TPasArgument(IdentEl).Access=argDefault then
-          exit(true);
-        end
+        exit(true)
       else if (C=TPasProperty) then
         begin
         Prop:=TPasProperty(IdentEl);
+        Getter:=GetPasPropertyGetter(Prop);
+        if not (Getter is TPasVariable) then
+          exit;
         Setter:=GetPasPropertySetter(Prop);
-        if Setter is TPasVariable then
-          exit(true);
+        Result:=Getter=Setter;
         end;
       end;
     end;
@@ -22869,10 +22869,9 @@ begin
           begin
           if (El.Kind<>akDefault) then
             aResolver.RaiseMsg(20201028212754,nIllegalQualifier,sIllegalQualifier,[AssignKindNames[El.Kind]],El);
-          if aResolver.IsDirectlyWritable(AssignContext.LeftResolved) then
+          if aResolver.IsReadEqWrite(AssignContext.LeftResolved) then
             begin
-            Result:=ConvertDirectAssignArrayStatement(El,AssignContext);
-            if Result<>nil then exit;
+            AssignContext.RightSide:=ConvertDirectAssignArrayStatement(El,AssignContext);
             end;
           end;
         end;
@@ -23213,7 +23212,6 @@ var
   LeftRef, ParamRef: TResolvedReference;
   SubParams: TParamsExpr;
   ParentContext: TConvertContext;
-  AssignSt: TJSSimpleAssignStatement;
   Call: TJSCallExpression;
   i: Integer;
   JS: TJSElement;
@@ -23254,23 +23252,19 @@ begin
             exit;
             end;
           // A:=Concat(A,[b,c])  ->  A=rtl.arrayPushN(A,b,c);
-          AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,AssignContext.PasElement));
           try
-            AssignSt.LHS:=ConvertExpression(FirstParam,ParentContext);
             Call:=CreateArrayConcat(AssignContext.LeftResolved.LoTypeEl as TPasArrayType,
-                                             El,ParentContext,true);
-            AssignSt.Expr:=Call;
+                                    El,ParentContext,true);
             Call.AddArg(ConvertExpression(FirstParam,ParentContext));
             for i:=0 to length(SubParams.Params)-1 do
               begin
               JS:=CreateArrayEl(SubParams.Params[i],ParentContext);
               Call.AddArg(JS);
               end;
-
-            Result:=AssignSt;
+            Result:=Call;
           finally
             if Result=nil then
-              AssignSt.Free;
+              Call.Free;
           end;
           end;
         end;

+ 47 - 5
packages/pastojs/tests/tcmodules.pas

@@ -498,6 +498,7 @@ type
     Procedure TestArray_ConstRef;
     Procedure TestArray_Concat;
     Procedure TestArray_Concat_Append;
+    Procedure TestArray_Concat_Append_Var;
     Procedure TestArray_Copy;
     Procedure TestArray_InsertDelete;
     Procedure TestArray_DynArrayConstObjFPC;
@@ -11431,24 +11432,63 @@ begin
     'this.f = {};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.ArrInt;',
+    '$mod.ArrInt = $mod.ArrInt;',
     '$mod.ArrInt = rtl.arrayPushN($mod.ArrInt, 2);',
     '$mod.ArrInt = rtl.arrayPushN($mod.ArrInt, 3, 4);',
-    '$mod.ArrRec;',
+    '$mod.ArrRec = $mod.ArrRec;',
     '$mod.ArrRec = rtl.arrayPush($mod.TRec, $mod.ArrRec, $mod.TRec.$clone($mod.r));',
     '$mod.ArrRec = rtl.arrayPush($mod.TRec, $mod.ArrRec, $mod.TRec.$clone($mod.r), $mod.TRec.$clone($mod.r));',
-    '$mod.ArrSet;',
+    '$mod.ArrSet = $mod.ArrSet;',
     '$mod.ArrSet = rtl.arrayPush("refSet", $mod.ArrSet, rtl.refSet($mod.f));',
     '$mod.ArrSet = rtl.arrayPush("refSet", $mod.ArrSet, rtl.refSet($mod.f), rtl.refSet($mod.f));',
-    '$mod.ArrJSValue;',
+    '$mod.ArrJSValue = $mod.ArrJSValue;',
     '$mod.ArrJSValue = rtl.arrayPushN($mod.ArrJSValue, 11);',
     '$mod.ArrJSValue = rtl.arrayPushN($mod.ArrJSValue, 12, 13);',
-    '$mod.ArrFlag;',
+    '$mod.ArrFlag = $mod.ArrFlag;',
     '$mod.ArrFlag = rtl.arrayPushN($mod.ArrFlag, $mod.TFlag.small);',
     '$mod.ArrFlag = rtl.arrayPushN($mod.ArrFlag, $mod.TFlag.small, $mod.TFlag.big);',
     '']));
 end;
 
+procedure TTestModule.TestArray_Concat_Append_Var;
+begin
+  StartProgram(false);
+  Add([
+  'type',
+  '  TArrInt = array of word;',
+  '',
+  'procedure Fly(a: TArrInt; var b: TArrInt);',
+  'begin',
+  '  a:=concat(a,[2]);',
+  '  b:=concat(b,[2]);',
+  'end;',
+  'var',
+  '  ArrInt: tarrint;',
+  'begin',
+  '  Fly(ArrInt,ArrInt);',
+  '']);
+  ConvertProgram;
+  CheckSource('TestArray_Concat_Append_Var',
+    LinesToStr([ // statements
+    'this.Fly = function (a, b) {',
+    '  a = rtl.arrayPushN(a, 2);',
+    '  b.set(rtl.arrayPushN(b.get(), 2));',
+    '};',
+    'this.ArrInt = [];',
+    '']),
+    LinesToStr([ // $mod.$main
+    '$mod.Fly(rtl.arrayRef($mod.ArrInt), {',
+    '  p: $mod,',
+    '  get: function () {',
+    '      return this.p.ArrInt;',
+    '    },',
+    '  set: function (v) {',
+    '      this.p.ArrInt = v;',
+    '    }',
+    '});',
+    '']));
+end;
+
 procedure TTestModule.TestArray_Copy;
 begin
   StartProgram(false);
@@ -27249,6 +27289,7 @@ begin
   '  Self[1]:=true;',
   '  Self[2]:=not Self[3];',
   '  SetLength(Self,4);',
+  '  Self:=Concat(Self,[true]);',
   'end;',
   'var',
   '  b: TArrOfBool;',
@@ -27265,6 +27306,7 @@ begin
     '    this.get()[1] = true;',
     '    this.get()[2] = !this.get()[3];',
     '    this.set(rtl.arraySetLength(this.get(), false, 4));',
+    '    this.set(rtl.arrayPushN(this.get(), true));',
     '  };',
     '});',
     'this.b = [];',