瀏覽代碼

* 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.

Nikolay Nikolov 10 月之前
父節點
當前提交
4b757dd360
共有 1 個文件被更改,包括 45 次插入0 次删除
  1. 45 0
      compiler/wasm32/nwasmcal.pas

+ 45 - 0
compiler/wasm32/nwasmcal.pas

@@ -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;