Browse Source

* refactored call_indirect to use a 'functype' operand type. This type will be reused for block instructions as well.

git-svn-id: branches/wasm@48027 -
nickysn 4 years ago
parent
commit
07c1783e24
4 changed files with 30 additions and 13 deletions
  1. 6 0
      compiler/aasmtai.pas
  2. 18 5
      compiler/wasm32/aasmcpu.pas
  3. 5 7
      compiler/wasm32/agllvmmc.pas
  4. 1 1
      compiler/wasm32/hlcgcpu.pas

+ 6 - 0
compiler/aasmtai.pas

@@ -299,6 +299,7 @@ interface
        ,top_roundingmode
 {$endif defined(riscv32) or defined(riscv64)}
 {$ifdef wasm}
+       ,top_functype
        ,top_single
        ,top_double
 {$endif wasm}
@@ -534,6 +535,7 @@ interface
             top_roundingmode : (roundingmode : TRoundingMode);
         {$endif defined(riscv32) or defined(riscv64)}
         {$ifdef wasm}
+            top_functype : (functype: TWasmFuncType);
             top_single : (sval:single);
             top_double : (dval:double);
         {$endif wasm}
@@ -3016,6 +3018,10 @@ implementation
               top_wstring:
                 donewidestring(pwstrval);
 {$endif jvm}
+{$ifdef wasm}
+              top_functype:
+                FreeAndNil(functype);
+{$endif wasm}
               else
                 ;
             end;

+ 18 - 5
compiler/wasm32/aasmcpu.pas

@@ -44,7 +44,6 @@ uses
       { taicpu }
 
       taicpu = class(tai_cpu_abstract_sym)
-         functype : TWasmFuncType; // used for call_indirect
          constructor op_none(op : tasmop);
 
          constructor op_reg(op : tasmop;_op1 : tregister);
@@ -57,10 +56,11 @@ uses
          constructor op_single(op : tasmop;_op1 : single);
          constructor op_double(op : tasmop;_op1 : double);
 
-         constructor op_callindirect(afunctype: TWasmFuncType);
+         constructor op_functype(op : tasmop; _op1: TWasmFuncType);
          //constructor op_string(op : tasmop;_op1len : aint;_op1 : pchar);
          //constructor op_wstring(op : tasmop;_op1 : pcompilerwidestring);
 
+         procedure loadfunctype(opidx:longint;ft:TWasmFuncType);
          procedure loadsingle(opidx:longint;f:single);
          procedure loaddouble(opidx:longint;d:double);
          //procedure loadstr(opidx:longint;vallen: aint;pc: pchar);
@@ -251,10 +251,23 @@ implementation
         loaddouble(0,_op1);
       end;
 
-    constructor taicpu.op_callindirect(afunctype: TWasmFuncType);
+    constructor taicpu.op_functype(op: tasmop; _op1: TWasmFuncType);
       begin
-        functype := afunctype;
-        op_none(a_call_indirect);
+       inherited create(op);
+       ops:=1;
+       loadfunctype(0,_op1);
+      end;
+
+    procedure taicpu.loadfunctype(opidx: longint; ft: TWasmFuncType);
+      begin
+       allocate_oper(opidx+1);
+       with oper[opidx]^ do
+        begin
+          if typ<>top_functype then
+            clearop(opidx);
+          functype:=ft;
+          typ:=top_functype;
+        end;
       end;
 
     {constructor taicpu.op_string(op: tasmop; _op1len: aint; _op1: pchar);

+ 5 - 7
compiler/wasm32/agllvmmc.pas

@@ -304,19 +304,17 @@ implementation
       writer.AsmWrite(#9#9);
       writer.AsmWrite(gas_op2str[cpu.opcode]);
 
-      if cpu.opcode = a_call_indirect then
-        begin
-          writer.AsmWrite(#9);
-          owner.WriteFuncType(cpu.functype);
-        end
-      else if (cpu.opcode = a_if) then
+      if (cpu.opcode = a_if) then
         writer.AsmWrite(' i32') //todo: this is a hardcode, but shouldn't
       else if cpu.ops<>0 then
         begin
           for i:=0 to cpu.ops-1 do
             begin
               writer.AsmWrite(#9);
-              writer.AsmWrite(getopstr(cpu.oper[i]^));
+              if cpu.oper[i]^.typ=top_functype then
+                owner.WriteFuncType(cpu.oper[i]^.functype)
+              else
+                writer.AsmWrite(getopstr(cpu.oper[i]^));
             end;
         end;
       writer.AsmLn;

+ 1 - 1
compiler/wasm32/hlcgcpu.pas

@@ -379,7 +379,7 @@ implementation
   function thlcgwasm.a_call_reg(list: TAsmList; pd: tabstractprocdef; reg: tregister; const paras: array of pcgpara): tcgpara;
     begin
       a_load_reg_stack(list, ptrsinttype, reg);
-      current_asmdata.CurrAsmList.Concat(taicpu.op_callindirect(tcpuprocdef(pd).create_functype));
+      current_asmdata.CurrAsmList.Concat(taicpu.op_functype(a_call_indirect,tcpuprocdef(pd).create_functype));
       result:=hlcg.get_call_result_cgpara(pd, nil);
     end;