mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-04-13 15:39:22 +02:00
fcl-passrc: process TBinaryExpr left lists without stack
This commit is contained in:
parent
6999e0d475
commit
d2eb00eaab
@ -1488,6 +1488,8 @@ function TResExprEvaluator.EvalBinaryExpr(Expr: TBinaryExpr;
|
||||
Flags: TResEvalFlags): TResEvalValue;
|
||||
var
|
||||
LeftValue, RightValue: TResEvalValue;
|
||||
Left: TPasExpr;
|
||||
SubBin: TBinaryExpr;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (Expr.Kind=pekBinary) and (Expr.OpCode=eopSubIdent) then
|
||||
@ -1498,6 +1500,52 @@ begin
|
||||
LeftValue:=nil;
|
||||
RightValue:=nil;
|
||||
try
|
||||
if Expr.OpCode=eopAdd then
|
||||
begin
|
||||
// handle multi adds without stack
|
||||
Left:=Expr.left;
|
||||
while Left.ClassType=TBinaryExpr do
|
||||
begin
|
||||
SubBin:=TBinaryExpr(Left);
|
||||
if SubBin.OpCode<>eopAdd then break;
|
||||
Left:=SubBin.left;
|
||||
end;
|
||||
LeftValue:=Eval(Left,Flags);
|
||||
while LeftValue<>nil do
|
||||
begin
|
||||
SubBin:=TBinaryExpr(Left.Parent);
|
||||
RightValue:=Eval(SubBin.right,Flags);
|
||||
if RightValue=nil then exit;
|
||||
|
||||
if LeftValue.Kind=revkExternal then
|
||||
begin
|
||||
if [refConst,refConstExt]*Flags=[refConst] then
|
||||
RaiseConstantExprExp(20210321205928,Expr.left);
|
||||
Result:=LeftValue;
|
||||
LeftValue:=nil;
|
||||
exit;
|
||||
end;
|
||||
if RightValue.Kind=revkExternal then
|
||||
begin
|
||||
if [refConst,refConstExt]*Flags=[refConst] then
|
||||
RaiseConstantExprExp(20210321205948,Expr.right);
|
||||
Result:=RightValue;
|
||||
RightValue:=nil;
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result:=EvalBinaryAddExpr(SubBin,LeftValue,RightValue);
|
||||
ReleaseEvalValue(LeftValue);
|
||||
if SubBin=Expr then exit;
|
||||
|
||||
LeftValue:=Result;
|
||||
Result:=nil;
|
||||
Left:=SubBin;
|
||||
end;
|
||||
|
||||
exit;
|
||||
end;
|
||||
|
||||
LeftValue:=Eval(Expr.left,Flags);
|
||||
if LeftValue=nil then exit;
|
||||
RightValue:=Eval(Expr.right,Flags);
|
||||
|
@ -5869,7 +5869,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
constructor TBinaryExpr.Create(AParent : TPasElement; xleft,xright:TPasExpr; AOpCode:TExprOpCode);
|
||||
begin
|
||||
inherited Create(AParent,pekBinary, AOpCode);
|
||||
@ -5889,9 +5888,33 @@ begin
|
||||
end;
|
||||
|
||||
destructor TBinaryExpr.Destroy;
|
||||
var
|
||||
El: TPasExpr;
|
||||
SubBin: TBinaryExpr;
|
||||
begin
|
||||
ReleaseAndNil(TPasElement(left){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.left'{$ENDIF});
|
||||
ReleaseAndNil(TPasElement(right){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.right'{$ENDIF});
|
||||
// handle left of binary chains without stack
|
||||
El:=Left;
|
||||
while El is TBinaryExpr do
|
||||
begin
|
||||
SubBin:=TBinaryExpr(El);
|
||||
El:=SubBin.left;
|
||||
if (El=nil) or (El.Parent<>SubBin) then
|
||||
begin
|
||||
El:=SubBin;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
repeat
|
||||
if El=left then
|
||||
SubBin:=Self
|
||||
else
|
||||
SubBin:=TBinaryExpr(El.Parent);
|
||||
ReleaseAndNil(TPasElement(SubBin.left){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.left'{$ENDIF});
|
||||
ReleaseAndNil(TPasElement(SubBin.right){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.left'{$ENDIF});
|
||||
El:=SubBin;
|
||||
until El=Self;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
@ -1711,6 +1711,8 @@ var
|
||||
Decl: TPasElement;
|
||||
ModScope: TPasModuleScope;
|
||||
Access: TResolvedRefAccess;
|
||||
Bin: TBinaryExpr;
|
||||
Left: TPasExpr;
|
||||
begin
|
||||
if El=nil then exit;
|
||||
// Note: expression itself is not marked, but it can reference identifiers
|
||||
@ -1792,8 +1794,29 @@ begin
|
||||
// ok
|
||||
else if C=TBinaryExpr then
|
||||
begin
|
||||
UseExpr(TBinaryExpr(El).left);
|
||||
UseExpr(TBinaryExpr(El).right);
|
||||
Bin:=TBinaryExpr(El);
|
||||
if Bin.OpCode=eopAdd then
|
||||
begin
|
||||
// handle multi add expressions without stack
|
||||
Left:=Bin;
|
||||
while Left.ClassType=TBinaryExpr do
|
||||
begin
|
||||
Bin:=TBinaryExpr(Left);
|
||||
if Bin.OpCode<>eopAdd then break;
|
||||
Left:=Bin.left;
|
||||
end;
|
||||
UseExpr(Left);
|
||||
repeat
|
||||
Bin:=TBinaryExpr(Left.Parent);
|
||||
UseExpr(Bin.right);
|
||||
Left:=Bin;
|
||||
until Left=El;
|
||||
end
|
||||
else
|
||||
begin
|
||||
UseExpr(Bin.left);
|
||||
UseExpr(Bin.right);
|
||||
end;
|
||||
end
|
||||
else if C=TUnaryExpr then
|
||||
UseExpr(TUnaryExpr(El).Operand)
|
||||
|
Loading…
Reference in New Issue
Block a user