@@ -1129,13 +1129,22 @@ private void ExecBNot()
11291129 }
11301130 }
11311131
1132+ // The .NET optimizer seems to break on this instruction on ARM
1133+ // The bytecode format should be reduced to 32-bit to help with this
1134+ [ MethodImpl ( MethodImplOptions . NoInlining | MethodImplOptions . NoOptimization ) ]
1135+ void UnpackSwitch ( Instruction i , out uint strCount , out uint numCount )
1136+ {
1137+ strCount = ( uint ) i . NumVal ;
1138+ numCount = i . NumValB ;
1139+ }
1140+
11321141 private int ExecSwitch ( int currentPtr , Instruction i , ref CallStackItem cframe )
11331142 {
11341143 //Decode
11351144 //First 3 table entries are present with bit flags
11361145 int nil = - 1 , ctrue = - 1 , cfalse = - 1 ;
11371146 int strOff = 1 ;
1138- uint strCount = ( uint ) i . NumVal ;
1147+ UnpackSwitch ( i , out var strCount , out var numCount ) ;
11391148 if ( ( strCount & 0x80000000 ) != 0 )
11401149 nil = strOff ++ ;
11411150 if ( ( strCount & 0x40000000 ) != 0 )
@@ -1146,10 +1155,14 @@ private int ExecSwitch(int currentPtr, Instruction i, ref CallStackItem cframe)
11461155 strCount &= 0x1FFFFFFF ;
11471156 //get number entries
11481157 int numOff = ( int ) ( strOff + strCount ) ;
1149- uint numCount = i . NumValB ;
11501158 //default comes immediately after switch case
11511159 int defaultPtr = ( int ) ( currentPtr + numOff + numCount ) ;
1152- int GetJump ( FunctionProto p , int offset ) => ( int ) ( currentPtr + ( p . code [ currentPtr + offset ] . NumValB ) ) ;
1160+ int GetJump ( FunctionProto p , int offset )
1161+ {
1162+ UnpackSwitch ( p . code [ currentPtr + offset ] , out _ , out var b ) ;
1163+ return ( int ) ( currentPtr + b ) ;
1164+ }
1165+
11531166 var value = m_ValueStack . Pop ( ) . ToScalar ( ) ;
11541167 switch ( value . Type )
11551168 {
@@ -1167,11 +1180,12 @@ private int ExecSwitch(int currentPtr, Instruction i, ref CallStackItem cframe)
11671180 for ( int j = 0 ; j < numCount ; j ++ )
11681181 {
11691182 var ins = cframe . Function . code [ currentPtr + numOff + j ] ;
1170- if ( ins . OpCode == OpCode . SInteger && ins . NumVal == d ) {
1171- return ( int ) ( currentPtr + ins . NumValB ) ;
1183+ UnpackSwitch ( ins , out var a , out var b ) ;
1184+ if ( ins . OpCode == OpCode . SInteger && a == d ) {
1185+ return ( int ) ( currentPtr + b ) ;
11721186 }
1173- if ( ins . OpCode == OpCode . SNumber && d == cframe . Function . numbers [ ins . NumVal ] ) {
1174- return ( int ) ( currentPtr + ins . NumValB ) ;
1187+ if ( ins . OpCode == OpCode . SNumber && d == cframe . Function . numbers [ a ] ) {
1188+ return ( int ) ( currentPtr + b ) ;
11751189 }
11761190 }
11771191 return defaultPtr ;
@@ -1180,8 +1194,9 @@ private int ExecSwitch(int currentPtr, Instruction i, ref CallStackItem cframe)
11801194 for ( int j = 0 ; j < strCount ; j ++ )
11811195 {
11821196 var ins = cframe . Function . code [ currentPtr + strOff + j ] ;
1183- if ( s == cframe . Function . strings [ ins . NumVal ] ) {
1184- return ( int ) ( currentPtr + ins . NumValB ) ;
1197+ UnpackSwitch ( ins , out var a , out var b ) ;
1198+ if ( s == cframe . Function . strings [ a ] ) {
1199+ return ( int ) ( currentPtr + b ) ;
11851200 }
11861201 }
11871202 return defaultPtr ;
@@ -1277,7 +1292,7 @@ private void ExecBrShiftL()
12771292 {
12781293 m_ValueStack . Pop ( ) ;
12791294 m_ValueStack . Set ( 0 , DynValue . NewNumber ( ( int ) (
1280- ( uint ) ln >> ( int ) rn
1295+ ( uint ) ( int ) ln >> ( int ) rn
12811296 ) ) ) ;
12821297 }
12831298 else
0 commit comments