vrchat-community / UdonSharp

A compiler for compiling C# to Udon assembly
https://udonsharp.docs.vrchat.com
MIT License
470 stars 50 forks source link

[1.1.1] Using range comparison on enum compiles into wrong extern #68

Open techanon opened 2 years ago

techanon commented 2 years ago

Describe the bug in detail: Doing a range comparison (such as less-than-or-equal) for an enum value without explicit int casting incorrectly compiles to the SystemInt32.__op_Inequality__SystemInt32_SystemInt32__SystemBoolean extern.

Provide steps/code to reproduce the bug: Create a C# script with the following code and the examine the compiled UASM:

namespace BugTesting
{
    public enum TestLevel { ZERO, ONE, TWO}
    public class EnumComparators : UdonSharp.UdonSharpBehaviour
    {
        public TestLevel level;

        private void Start()
        {
            bool _ = TestLevel.ONE <= level;
            _ = (int)TestLevel.ONE <= (int)level;
        }
    }
}

Outputs:

.data_start
    .export level
    __refl_typeid: %SystemInt64, null
    __refl_typename: %SystemString, null
    __intnl_returnJump_SystemUInt32_0: %SystemUInt32, null
    level: %SystemInt32, null
    __const_SystemUInt32_0: %SystemUInt32, null
    __const_SystemInt32_0: %SystemInt32, null
    __lcl___SystemBoolean_0: %SystemBoolean, null
.data_end
.code_start
    .export _start
    _start:
        PUSH, __const_SystemUInt32_0
# 
# BugTesting.EnumComparators.Start()
# 
        PUSH, __const_SystemInt32_0
        PUSH, level
        PUSH, __lcl___SystemBoolean_0
        EXTERN, "SystemInt32.__op_Inequality__SystemInt32_SystemInt32__SystemBoolean"
        PUSH, __const_SystemInt32_0
        PUSH, level
        PUSH, __lcl___SystemBoolean_0
        EXTERN, "SystemInt32.__op_LessThanOrEqual__SystemInt32_SystemInt32__SystemBoolean"
        PUSH, __intnl_returnJump_SystemUInt32_0
        COPY
        JUMP_INDIRECT, __intnl_returnJump_SystemUInt32_0
.code_end

Expected behavior: Enums are always treated as ints within udon, so the comparison should match the respective comparison extern, such as SystemInt32.__op_LessThanOrEqual__SystemInt32_SystemInt32__SystemBoolean