mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 10:19:17 +02:00
pastojs: convert TBinaryExpr left lists without stack
git-svn-id: trunk@49031 -
(cherry picked from commit d62da7bc5d
)
This commit is contained in:
parent
708de2786f
commit
16c118c881
@ -2261,6 +2261,7 @@ type
|
|||||||
Function ConvertBinaryExpression(El: TBinaryExpr; AContext: TConvertContext): TJSElement; virtual;
|
Function ConvertBinaryExpression(El: TBinaryExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function ConvertBinaryExpressionRes(El: TBinaryExpr; AContext: TConvertContext;
|
Function ConvertBinaryExpressionRes(El: TBinaryExpr; AContext: TConvertContext;
|
||||||
const LeftResolved, RightResolved: TPasResolverResult; var A,B: TJSElement): TJSElement; virtual;
|
const LeftResolved, RightResolved: TPasResolverResult; var A,B: TJSElement): TJSElement; virtual;
|
||||||
|
function ConvertBinaryExpressionMultiAdd(El: TBinaryExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function ConvertSubIdentExpression(El: TBinaryExpr; AContext: TConvertContext): TJSElement; virtual;
|
Function ConvertSubIdentExpression(El: TBinaryExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function ConvertSubIdentExprCustom(El: TBinaryExpr; AContext: TConvertContext;
|
Function ConvertSubIdentExprCustom(El: TBinaryExpr; AContext: TConvertContext;
|
||||||
const OnConvertRight: TConvertJSEvent = nil; Data: Pointer = nil): TJSElement; virtual;
|
const OnConvertRight: TConvertJSEvent = nil; Data: Pointer = nil): TJSElement; virtual;
|
||||||
@ -8787,6 +8788,11 @@ begin
|
|||||||
aResolver:=AContext.Resolver;
|
aResolver:=AContext.Resolver;
|
||||||
|
|
||||||
case El.OpCode of
|
case El.OpCode of
|
||||||
|
eopAdd:
|
||||||
|
begin
|
||||||
|
Result:=ConvertBinaryExpressionMultiAdd(El,aContext);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
eopSubIdent:
|
eopSubIdent:
|
||||||
begin
|
begin
|
||||||
Result:=ConvertSubIdentExpression(El,AContext);
|
Result:=ConvertSubIdentExpression(El,AContext);
|
||||||
@ -8803,9 +8809,10 @@ begin
|
|||||||
OldAccess:=AContext.Access;
|
OldAccess:=AContext.Access;
|
||||||
AContext.Access:=caRead;
|
AContext.Access:=caRead;
|
||||||
Call:=nil;
|
Call:=nil;
|
||||||
A:=ConvertExpression(El.left,AContext);
|
A:=nil;
|
||||||
B:=nil;
|
B:=nil;
|
||||||
try
|
try
|
||||||
|
A:=ConvertExpression(El.left,AContext);
|
||||||
B:=ConvertExpression(El.right,AContext);
|
B:=ConvertExpression(El.right,AContext);
|
||||||
|
|
||||||
if aResolver<>nil then
|
if aResolver<>nil then
|
||||||
@ -9677,6 +9684,103 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPasToJSConverter.ConvertBinaryExpressionMultiAdd(El: TBinaryExpr;
|
||||||
|
AContext: TConvertContext): TJSElement;
|
||||||
|
// handle multi add without stack
|
||||||
|
// Note: The parser generates a list of TBinaryExpr.Lefts
|
||||||
|
var
|
||||||
|
aResolver: TPas2JSResolver;
|
||||||
|
Left: TPasExpr;
|
||||||
|
SubBin: TBinaryExpr;
|
||||||
|
A, B: TJSElement;
|
||||||
|
LeftResolved, RightResolved, ResultResolved: TPasResolverResult;
|
||||||
|
Flags: TPasResolverComputeFlags;
|
||||||
|
R: TJSBinary;
|
||||||
|
OldAccess: TCtxAccess;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
aResolver:=AContext.Resolver;
|
||||||
|
Left:=El;
|
||||||
|
while Left.ClassType=TBinaryExpr do
|
||||||
|
begin
|
||||||
|
SubBin:=TBinaryExpr(Left);
|
||||||
|
if SubBin.OpCode<>eopAdd then break;
|
||||||
|
Left:=SubBin.left;
|
||||||
|
if Left.Parent<>SubBin then
|
||||||
|
begin
|
||||||
|
if aResolver<>nil then
|
||||||
|
RaiseNotSupported(SubBin,AContext,20210321220458)
|
||||||
|
else if Left.Parent=nil then
|
||||||
|
Left.Parent:=SubBin
|
||||||
|
else
|
||||||
|
RaiseNotSupported(SubBin,AContext,20210321221135);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Left=El then
|
||||||
|
RaiseNotSupported(El,AContext,20210321221047);
|
||||||
|
OldAccess:=AContext.Access;
|
||||||
|
AContext.Access:=caRead;
|
||||||
|
A:=nil;
|
||||||
|
B:=nil;
|
||||||
|
try
|
||||||
|
A:=ConvertExpression(Left,AContext);
|
||||||
|
Flags:=[];
|
||||||
|
if aResolver<>nil then
|
||||||
|
aResolver.ComputeElement(Left,LeftResolved,Flags);
|
||||||
|
repeat
|
||||||
|
SubBin:=TBinaryExpr(Left.Parent);
|
||||||
|
B:=ConvertExpression(SubBin.right,AContext);
|
||||||
|
if aResolver<>nil then
|
||||||
|
begin
|
||||||
|
aResolver.ComputeElement(El.right,RightResolved,Flags);
|
||||||
|
Result:=ConvertBinaryExpressionRes(SubBin,AContext,LeftResolved,RightResolved,A,B);
|
||||||
|
if (Result<>nil) then
|
||||||
|
begin
|
||||||
|
A:=nil;
|
||||||
|
B:=nil;
|
||||||
|
if SubBin=El then exit;
|
||||||
|
end;
|
||||||
|
aResolver.ComputeBinaryExprRes(SubBin,ResultResolved,Flags,LeftResolved,RightResolved);
|
||||||
|
end;
|
||||||
|
if Result=nil then
|
||||||
|
begin
|
||||||
|
// +
|
||||||
|
R:=TJSBinary(CreateElement(TJSAdditiveExpressionPlus,El));
|
||||||
|
R.A:=A; A:=nil;
|
||||||
|
R.B:=B; B:=nil;
|
||||||
|
Result:=R;
|
||||||
|
|
||||||
|
if (bsOverflowChecks in AContext.ScannerBoolSwitches) and (aResolver<>nil) then
|
||||||
|
case El.OpCode of
|
||||||
|
eopAdd,eopSubtract:
|
||||||
|
if (LeftResolved.BaseType in btAllJSOverflowAddSubType)
|
||||||
|
or (RightResolved.BaseType in btAllJSOverflowAddSubType) then
|
||||||
|
Result:=CreateOverflowCheckCall(Result,SubBin);
|
||||||
|
eopMultiply:
|
||||||
|
if (LeftResolved.BaseType in btAllJSOverflowMultType)
|
||||||
|
or (RightResolved.BaseType in btAllJSOverflowMultType) then
|
||||||
|
Result:=CreateOverflowCheckCall(Result,SubBin);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if SubBin=El then exit;
|
||||||
|
end;
|
||||||
|
// next
|
||||||
|
A:=Result;
|
||||||
|
Result:=nil;
|
||||||
|
if aResolver<>nil then
|
||||||
|
LeftResolved:=ResultResolved;
|
||||||
|
Left:=SubBin;
|
||||||
|
until false;
|
||||||
|
finally
|
||||||
|
AContext.Access:=OldAccess;
|
||||||
|
if Result=nil then
|
||||||
|
begin
|
||||||
|
A.Free;
|
||||||
|
B.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.ConvertSubIdentExpression(El: TBinaryExpr;
|
function TPasToJSConverter.ConvertSubIdentExpression(El: TBinaryExpr;
|
||||||
AContext: TConvertContext): TJSElement;
|
AContext: TConvertContext): TJSElement;
|
||||||
// connect El.left and El.right with a dot.
|
// connect El.left and El.right with a dot.
|
||||||
|
Loading…
Reference in New Issue
Block a user