Browse Source

* disallow passing WebAssembly reference types as untyped var/constref/const parameters

Nikolay Nikolov 2 years ago
parent
commit
6ff566350c

+ 26 - 1
compiler/wasm32/nwasmcal.pas

@@ -40,6 +40,7 @@ interface
 
        twasmcallnode = class(tcgcallnode)
        protected
+         function  pass_typecheck:tnode;override;
          procedure extra_post_call_code; override;
          procedure do_release_unused_return_value; override;
          procedure set_result_location(realresdef: tstoreddef); override;
@@ -49,10 +50,34 @@ interface
 implementation
 
     uses
-      globals, globtype, aasmdata, defutil, tgobj, hlcgcpu, symconst, symcpu;
+      globals, globtype, verbose, aasmdata, defutil, tgobj, hlcgcpu, symconst, symsym, symcpu;
 
       { twasmcallnode }
 
+    function twasmcallnode.pass_typecheck:tnode;
+      var
+        p: tcallparanode;
+        paranr: Integer;
+        pvs: tparavarsym;
+      begin
+        result:=inherited;
+        if codegenerror then
+          exit;
+
+        p:=tcallparanode(left);
+        paranr:=0;
+        while assigned(p) do
+          begin
+            pvs:=tparavarsym(procdefinition.paras[paranr]);
+            if is_wasm_reference_type(p.left.resultdef) and
+              (pvs.varspez in [vs_var,vs_constref]) or
+               ((pvs.varspez=vs_const) and (pvs.vardef.typ=formaldef)) then
+              CGMessage(parser_e_wasm_ref_types_can_only_be_passed_by_value);
+            Inc(paranr);
+            p:=tcallparanode(tcallparanode(p).right);
+          end;
+      end;
+
     procedure twasmcallnode.extra_post_call_code;
       begin
         thlcgwasm(hlcg).g_adjust_stack_after_call(current_asmdata.CurrAsmList,procdefinition);

+ 1 - 0
tests/test/wasm/twasmexternref1.pp

@@ -49,4 +49,5 @@ end;
 
 begin
   testproc5(nil);
+  testproc7(nil);
 end.

+ 19 - 0
tests/test/wasm/twasmexternref4c.pp

@@ -0,0 +1,19 @@
+{ %cpu=wasm32 }
+{ %fail }
+
+program twasmexternref4c;
+
+procedure testproc(var p);
+begin
+end;
+
+procedure testproc2;
+var
+  q: WasmExternRef;
+begin
+  { WasmExternRef cannot be passed as an untyped var parameter }
+  testproc(q);
+end;
+
+begin
+end.

+ 19 - 0
tests/test/wasm/twasmexternref4d.pp

@@ -0,0 +1,19 @@
+{ %cpu=wasm32 }
+{ %fail }
+
+program twasmexternref4d;
+
+procedure testproc(const p);
+begin
+end;
+
+procedure testproc2;
+var
+  q: WasmExternRef;
+begin
+  { WasmExternRef cannot be passed as an untyped const parameter }
+  testproc(q);
+end;
+
+begin
+end.

+ 19 - 0
tests/test/wasm/twasmexternref4e.pp

@@ -0,0 +1,19 @@
+{ %cpu=wasm32 }
+{ %fail }
+
+program twasmexternref4e;
+
+procedure testproc(constref p);
+begin
+end;
+
+procedure testproc2;
+var
+  q: WasmExternRef;
+begin
+  { WasmExternRef cannot be passed as an untyped constref parameter }
+  testproc(q);
+end;
+
+begin
+end.