* On WebAssembly, when calling a function, first generate code for evaluating

all the parameters, and only after that, push them on the stack. This avoids
  problems with our 'goto' support.
This commit is contained in:
Nikolay Nikolov 2025-02-25 07:29:36 +02:00
parent e237da95d2
commit 4b757dd360

View File

@ -34,6 +34,11 @@ interface
{ twasmcallparanode }
twasmcallparanode = class(tcgcallparanode)
private
procedure secondpass_all;
procedure push_all;
public
procedure secondcallparan;override;
end;
{ twasmcallnode }
@ -52,6 +57,46 @@ implementation
uses
globals, globtype, verbose, aasmdata, defutil, tgobj, hlcgcpu, symconst, symsym, symcpu;
{ twasmcallparanode }
procedure twasmcallparanode.secondpass_all;
begin
{ Skip nothingn nodes which are used after disabling
a parameter }
if (left.nodetype<>nothingn) then
secondcallparan_do_secondpass;
{ next parameter }
if assigned(right) then
twasmcallparanode(right).secondpass_all;
end;
procedure twasmcallparanode.push_all;
begin
{ Skip nothingn nodes which are used after disabling
a parameter }
if (left.nodetype<>nothingn) then
secondcallparan_after_secondpass;
{ next parameter }
if assigned(right) then
twasmcallparanode(right).push_all;
end;
procedure twasmcallparanode.secondcallparan;
begin
if not(assigned(parasym)) then
internalerror(200304242);
{ On WebAssembly we generate code for evaluating all the parameters
first, and then we push them only after we've evaluated them all.
This is because the evaluation phase can generate labels, which
wreaks havoc in our 'goto' label resolution algorithm, when there
are labels at different stack heights. }
secondpass_all;
push_all;
end;
{ twasmcallnode }
function twasmcallnode.pass_typecheck:tnode;