-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support to 'long' switch statements #86
Comments
It is because the CLR uses hash table to optimize the |
There is not possible to convert this hash table into a jump table? Pseudocode: // With hash table
hash= [ 0x0a, 0x0b, 0x0c ]
JMP(hash[2]);
// Without hash table
0x00 NOP
0x01 JMP 0x0a
0x02 JMP 0x0b
0x03 JMP 0x0c
JMP 0x02
|
dnSpy decompile the source as: using System;
using Neo.SmartContract.Framework;
namespace Neo.Compiler.MSIL.TestClasses
{
// Token: 0x02000017 RID: 23
internal class Contract_Switch : SmartContract
{
// Token: 0x0600005E RID: 94 RVA: 0x00003C78 File Offset: 0x00001E78
public static object Main(string method, object[] args)
{
if (method != null)
{
uint num = <PrivateImplementationDetails>.ComputeStringHash(method);
if (num <= 518729469u)
{
if (num <= 434841374u)
{
if (num <= 350953279u)
{
if (num != 334175660u)
{
if (num == 350953279u)
{
if (method == "19")
{
return 20;
}
}
}
else if (method == "18")
{
return 19;
}
}
else if (num != 401286136u)
{
if (num != 418063755u)
{
if (num == 434841374u)
{
if (method == "16")
{
return 17;
}
}
}
else if (method == "15")
{
return 16;
}
}
else if (method == "14")
{
return 15;
}
}
else if (num <= 468396612u)
{
if (num != 451618993u)
{
if (num == 468396612u)
{
if (method == "10")
{
return 11;
}
}
}
else if (method == "17")
{
return 18;
}
}
else if (num != 485174231u)
{
if (num != 501951850u)
{
if (num == 518729469u)
{
if (method == "13")
{
return 14;
}
}
}
else if (method == "12")
{
return 13;
}
}
else if (method == "11")
{
return 12;
}
}
else if (num <= 873244444u)
{
if (num <= 822911587u)
{
if (num != 806133968u)
{
if (num == 822911587u)
{
if (method == "4")
{
return 5;
}
}
}
else if (method == "5")
{
return 6;
}
}
else if (num != 839689206u)
{
if (num != 856466825u)
{
if (num == 873244444u)
{
if (method == "1")
{
return 2;
}
}
}
else if (method == "6")
{
return 7;
}
}
else if (method == "7")
{
return 8;
}
}
else if (num <= 923577301u)
{
if (num != 890022063u)
{
if (num != 906799682u)
{
if (num == 923577301u)
{
if (method == "2")
{
return 3;
}
}
}
else if (method == "3")
{
return 4;
}
}
else if (method == "0")
{
return 1;
}
}
else if (num != 1007465396u)
{
if (num != 1024243015u)
{
if (num == 2381486463u)
{
if (method == "20")
{
return 21;
}
}
}
else if (method == "8")
{
return 9;
}
}
else if (method == "9")
{
return 10;
}
}
return 99;
}
}
} |
You need to implement |
@lightszero do you think that this is feasible? |
as eric said. ComputeStringHash is a sad story.
I can't got "aa" form IL in current convert solution(current solution is use Mono.cecil to conv IL -> AVM). One way is add a ComputeStringHash on NEOVM. I will working on rosyln way,but Use rosyln to got more info need input csproj file instead input dll file.It is a big change. I had try add a stringhash way |
@lightszero We can add |
C# 's stringhash is different with java,so we need many stringhash interop. |
I understand the problem ... if we receive a compilation error (user friendly), is enough to me |
@lightszero could you check why here https://github.com/neo-project/neo-devpack-dotnet/pull/87/files#diff-38aefe612b09c5f19d1ec205b952b39cR19 is not throwed any exception? |
And is possible to generate this method on runtime, without a syscall, and just call it? internal static uint ComputeStringHash(string s)
{
uint num;
if (s != null)
{
num = 2166136261u;
for (int i = 0; i < s.Length; i++)
{
num = ((uint)s.get_Chars(i) ^ num) * 16777619u;
}
}
return num;
} |
@lightszero this is something crazy? Try to detect the call, and redirect to another one loaded in the framework |
Calling the generated |
I agree with you @erikzhang |
we can add some simple method for switch. then we got a Hash in IL,we can knwon the string. |
no need to touch contract c# sourcecode |
Thanks @lightszero ! amazing work! |
Can we port this to master-2.x? |
Yes, I think so |
Also, this issue should be closed and create a new one #157 |
There is a problem with the
switch
instruction, it seems that works if we have less entries than 6, with more, it doesn't works.I made a pull request for test this issue at, #87
if you comment some entries, the test will work
The text was updated successfully, but these errors were encountered: