Skip to content

Commit

Permalink
pastojs: faster concat append for var args
Browse files Browse the repository at this point in the history
  • Loading branch information
Felzomah committed Jun 10, 2022
1 parent 4149562 commit 34605e9
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 25 deletions.
34 changes: 14 additions & 20 deletions packages/pastojs/src/fppas2js.pp
Original file line number Diff line number Diff line change
Expand Up @@ -1685,7 +1685,7 @@ TPRFindExtSystemClass = record
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;
Expand Down Expand Up @@ -7417,13 +7417,14 @@ function TPas2JSResolver.ProcCanBePrecompiled(DeclProc: TPasProcedure): boolean;
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;
Expand All @@ -7435,16 +7436,15 @@ function TPas2JSResolver.IsDirectlyWritable(const ExprResolved: TPasResolverResu
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;
Expand Down Expand Up @@ -22869,10 +22869,9 @@ function TPasToJSConverter.ConvertAssignStatement(El: TPasImplAssign;
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;
Expand Down Expand Up @@ -23213,7 +23212,6 @@ function TPasToJSConverter.ConvertDirectAssignArrayConcat(El: TPasImplAssign;
LeftRef, ParamRef: TResolvedReference;
SubParams: TParamsExpr;
ParentContext: TConvertContext;
AssignSt: TJSSimpleAssignStatement;
Call: TJSCallExpression;
i: Integer;
JS: TJSElement;
Expand Down Expand Up @@ -23254,23 +23252,19 @@ function TPasToJSConverter.ConvertDirectAssignArrayConcat(El: TPasImplAssign;
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;
Expand Down
52 changes: 47 additions & 5 deletions packages/pastojs/tests/tcmodules.pas
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ TTestModule = class(TCustomTestModule)
Procedure TestArray_ConstRef;
Procedure TestArray_Concat;
Procedure TestArray_Concat_Append;
Procedure TestArray_Concat_Append_Var;
Procedure TestArray_Copy;
Procedure TestArray_InsertDelete;
Procedure TestArray_DynArrayConstObjFPC;
Expand Down Expand Up @@ -11431,24 +11432,63 @@ ' TRec = record',
'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);
Expand Down Expand Up @@ -27249,6 +27289,7 @@ procedure TTestModule.TestTypeHelper_Array;
' Self[1]:=true;',
' Self[2]:=not Self[3];',
' SetLength(Self,4);',
' Self:=Concat(Self,[true]);',
'end;',
'var',
' b: TArrOfBool;',
Expand All @@ -27265,6 +27306,7 @@ procedure TTestModule.TestTypeHelper_Array;
' 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 = [];',
Expand Down

0 comments on commit 34605e9

Please sign in to comment.