Browse Source

+ added a second TWasmFuncType parameter to the CALL WebAssembly instruction. It
is not part of the WebAssembly syntax and binary encoding, but it helps
WebAssembly stack tracking and validation.

Nikolay Nikolov 1 year ago
parent
commit
21cc89f1e3
3 changed files with 21 additions and 10 deletions
  1. 12 2
      compiler/wasm32/aasmcpu.pas
  2. 8 7
      compiler/wasm32/agllvmmc.pas
  3. 1 1
      compiler/wasm32/hlcgcpu.pas

+ 12 - 2
compiler/wasm32/aasmcpu.pas

@@ -143,6 +143,7 @@ uses
          constructor op_sym(op : tasmop;_op1 : tasmsymbol);
          constructor op_sym(op : tasmop;_op1 : tasmsymbol);
 
 
          constructor op_sym_const(op : tasmop;_op1 : tasmsymbol;_op2 : aint);
          constructor op_sym_const(op : tasmop;_op1 : tasmsymbol;_op2 : aint);
+         constructor op_sym_functype(op : tasmop;_op1 : tasmsymbol;_op2 : TWasmFuncType);
 
 
          constructor op_single(op : tasmop;_op1 : single);
          constructor op_single(op : tasmop;_op1 : single);
          constructor op_double(op : tasmop;_op1 : double);
          constructor op_double(op : tasmop;_op1 : double);
@@ -1808,6 +1809,15 @@ uses
       end;
       end;
 
 
 
 
+    constructor taicpu.op_sym_functype(op : tasmop;_op1 : tasmsymbol;_op2 : TWasmFuncType);
+      begin
+        inherited create(op);
+        ops:=2;
+        loadsymbol(0,_op1,0);
+        loadfunctype(1,_op2);
+      end;
+
+
     constructor taicpu.op_single(op: tasmop; _op1: single);
     constructor taicpu.op_single(op: tasmop; _op1: single);
       begin
       begin
         inherited create(op);
         inherited create(op);
@@ -2341,7 +2351,7 @@ uses
             end;
             end;
           a_call:
           a_call:
             begin
             begin
-              if ops<>1 then
+              if ops<>2 then
                 internalerror(2021092021);
                 internalerror(2021092021);
               with oper[0]^ do
               with oper[0]^ do
                 case typ of
                 case typ of
@@ -3320,7 +3330,7 @@ uses
             end;
             end;
           a_call:
           a_call:
             begin
             begin
-              if ops<>1 then
+              if ops<>2 then
                 internalerror(2021092021);
                 internalerror(2021092021);
               with oper[0]^ do
               with oper[0]^ do
                 case typ of
                 case typ of

+ 8 - 7
compiler/wasm32/agllvmmc.pas

@@ -348,13 +348,14 @@ implementation
       if cpu.ops<>0 then
       if cpu.ops<>0 then
         begin
         begin
           for i:=0 to cpu.ops-1 do
           for i:=0 to cpu.ops-1 do
-            begin
-              writer.AsmWrite(#9);
-              if cpu.oper[i]^.typ=top_functype then
-                owner.WriteFuncType(cpu.oper[i]^.functype)
-              else
-                writer.AsmWrite(getopstr(cpu.oper[i]^));
-            end;
+            if not ((cpu.opcode=a_call) and (i=1) and (cpu.oper[i]^.typ=top_functype)) then
+              begin
+                writer.AsmWrite(#9);
+                if cpu.oper[i]^.typ=top_functype then
+                  owner.WriteFuncType(cpu.oper[i]^.functype)
+                else
+                  writer.AsmWrite(getopstr(cpu.oper[i]^));
+              end;
         end;
         end;
       writer.AsmLn;
       writer.AsmLn;
     end;
     end;

+ 1 - 1
compiler/wasm32/hlcgcpu.pas

@@ -412,7 +412,7 @@ implementation
 
 
   function thlcgwasm.a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;
   function thlcgwasm.a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;
     begin
     begin
-      list.concat(taicpu.op_sym(a_call,current_asmdata.RefAsmSymbol(s,AT_FUNCTION)));
+      list.concat(taicpu.op_sym_functype(a_call,current_asmdata.RefAsmSymbol(s,AT_FUNCTION),tcpuprocdef(pd).create_functype));
       result:=get_call_result_cgpara(pd,forceresdef);
       result:=get_call_result_cgpara(pd,forceresdef);
     end;
     end;