Search Unity

Bug 1297609 - WASM build - Constrained opcode was followed a Call rather than a Callvirt

Discussion in 'Project Tiny' started by Sarkahn, Dec 6, 2020.

  1. Sarkahn

    Sarkahn

    Joined:
    Jan 9, 2013
    Posts:
    440
    Just hit this exception when trying to do a wasm build:
    Unity_SvShHM3yth.png

    Dotnet build works fine, and I tested the method it's pointing to in a non-tiny Standalone IL2CPP, no errors there. I tried to pare my code down to try and narrow down what exactly might be causing it and ended up getting this, which I'm not sure what I'm supposed to do with:

    Unity_UQ3osfVo0I.png

    Any help?
     
  2. Sarkahn

    Sarkahn

    Joined:
    Jan 9, 2013
    Posts:
    440
    I figured it out. This appears to be the culprit:
    devenv_wseZgXXvXh.png

    As indicated by the comment, there's a bug in Burst 1.4.1 and 1.4.2 that causes MemMove to be converted to MemCopy. The "NoOptimization" attribute was suggested to me as a workaround until they fix the bug. Worked great in other builds, but I guess this attribute isn't supported in a wasm build? For now I'll have to rework the code to not use MemMove I guess.
     
  3. Sarkahn

    Sarkahn

    Joined:
    Jan 9, 2013
    Posts:
    440
    Spoke too soon...it seems the NoOptimization thing was a different bug. Still getting the original Constrained Opcode exception after removing the memmove. Trying to make a repro project but tiny really doesn't make it easy with the long recompile/assembly rebuild times anytime you change anything.
     
  4. Sarkahn

    Sarkahn

    Joined:
    Jan 9, 2013
    Posts:
    440
    Report submitted, id 1297609

    My project is pretty much dead in the water until I can fix this, hopefully someone can take a look
     
  5. kevinmv

    kevinmv

    Unity Technologies

    Joined:
    Nov 15, 2018
    Posts:
    28
    Hey hey!

    Thanks for the report it was very helpful for diagnosing the issue. This looks like a real problem in our compilation pipeline which we will take a look at fixing.

    The problem is coming from some IL mangling which is stripping what would normally be a constrained function call to your functions generic argument interface method, however the call seems to be stripped and is leaving a lingering `constrained` opcode which is breaking the next `call` op.

    You should be able to workaround this issue locally by replacing your generic FindPath call to the following prototype: `public void FindPath(IPathingMap<T> map, T start, T end, NativeList<T> output)` which excludes the generic parameter `Map`

    All the best,
    Kev
     
    Sarkahn likes this.
  6. Sarkahn

    Sarkahn

    Joined:
    Jan 9, 2013
    Posts:
    440
    Awesome, thanks for looking into it! Replacing the generic parameter with an interface would have prevented me from bursting it so I just created a non-generic implementation which uses my pathing map directly for now. Works great!

    FWIW I use a similar setup for my FOV where I have a generic function that takes interface type as a generic parameter passed in. I also use that in Burst but it never caused that issue. Here's the interface

    Code (CSharp):
    1.     public interface IVisibilityMap
    2.     {
    3.         bool IsOpaque(int2 p);
    4.         bool IsInBounds(int2 p);
    5.         void SetVisible(int2 p);
    6.         float Distance(int2 a, int2 b);
    7.     }
    8.  
    9.     public static class FOV
    10.     {
    11.         static public void Compute<T>(int2 origin, int range, T map)
    12.             where T : IVisibilityMap
    13.         {
    14.             map.SetVisible(origin);
    15.             for (int octant = 0; octant < 8; octant++)
    16.                 ComputeOctant(octant, origin, range, 1,
    17.                     new Slope(1, 1),
    18.                     new Slope(0, 1), map);
    19.         }
    20. }
     
unityunity