Skip to content
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 abi offset #219

Merged
merged 48 commits into from
Apr 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d353ee9
add abi offset
Mar 24, 2020
c90cb3e
fix
Mar 24, 2020
fcb7dc2
clean optimizer
lightszero Mar 24, 2020
4af85aa
Clean code
shargon Mar 24, 2020
132a190
Update NefOptimizeTool.cs
shargon Mar 24, 2020
5e7e947
fix GetAddrConvertTable bug,return all offsets now
lightszero Mar 25, 2020
432605c
format
Mar 25, 2020
1fd03cd
format
Mar 25, 2020
1de60d1
Merge branch 'master' into add-abi-offset
erikzhang Mar 25, 2020
e8aee62
Clean code
shargon Mar 25, 2020
0fd7964
add abi-offset-unitTest
Mar 25, 2020
e27f299
Merge branch 'add-abi-offset' of https://github.com/ShawnYun/neo-devp…
Mar 25, 2020
739f653
Rename Contract_AbiOffset.cs to Contract_ABIOffset.cs
ShawnYun Mar 25, 2020
1c74e62
fix
Mar 26, 2020
d469495
Clean code
shargon Mar 26, 2020
a524038
Optimize
shargon Mar 26, 2020
4262ba4
Fix
shargon Mar 26, 2020
b162242
fix NDEBUG
shargon Mar 26, 2020
1b0ce50
Fix NDEBUG
shargon Mar 26, 2020
1331c73
Merge branch 'master' into add-abi-offset
lightszero Mar 29, 2020
f770a97
Merge branch 'master' into add-abi-offset
shargon Mar 30, 2020
57b94ac
modify abi offset uintTest
Mar 31, 2020
71869a9
Merge branch 'master' into add-abi-offset
shargon Apr 7, 2020
24fec80
Merge branch 'master' into add-abi-offset
lightszero Apr 13, 2020
d933683
Merge branch 'master' of https://github.com/neo-project/neo-devpack-d…
Apr 16, 2020
c9453a6
Merge branch 'master' into add-abi-offset
lightszero Apr 16, 2020
93f292a
add initializing static variables
Apr 20, 2020
4b46326
Merge branch 'add-abi-offset' of https://github.com/ShawnYun/neo-devp…
Apr 20, 2020
9af0429
format
Apr 20, 2020
1faaebd
format
Apr 20, 2020
8d767bb
modify UTs
Apr 21, 2020
bcaa2e4
fix and rename
Apr 21, 2020
a7dcd5f
modify ContractTest
Apr 23, 2020
2d23cbc
fix conflicts
Apr 23, 2020
e7b114f
format
Apr 23, 2020
9c6243e
fix
Apr 24, 2020
bfde89a
fix TestEngine and modify _initialize
Apr 24, 2020
ab99dc3
fix
Apr 24, 2020
3165a34
fix conflicts
Apr 24, 2020
3b5b466
format
Apr 24, 2020
b3cd688
fix void return
Apr 24, 2020
a424b24
Update Opcodes
shargon Apr 24, 2020
806f988
resolve review issues
Apr 24, 2020
f70aa8d
Merge branch 'add-abi-offset' of https://github.com/ShawnYun/neo-devp…
Apr 24, 2020
9140bbb
fix
Apr 24, 2020
54ad1b0
fix
Apr 24, 2020
5c01853
fix
Apr 24, 2020
575c3d7
resolve conflicts
Apr 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 4 additions & 18 deletions src/Neo.Compiler.MSIL/FuncExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static string ConvType(string _type)
return "Unknown:" + _type;
}

public static MyJson.JsonNode_Object Export(NeoModule module, byte[] script)
public static MyJson.JsonNode_Object Export(NeoModule module, byte[] script, Dictionary<int, int> addrConvTable)
{
var sha256 = System.Security.Cryptography.SHA256.Create();
byte[] hash256 = sha256.ComputeHash(script);
Expand All @@ -81,14 +81,6 @@ public static MyJson.JsonNode_Object Export(NeoModule module, byte[] script)
}
outjson.SetDictValue("hash", sb.ToString());

//entrypoint
var entryPoint = "main";
var mainmethod = module.mapMethods[module.mainMethod];
if (mainmethod != null)
{
entryPoint = mainmethod.displayName;
}

//functions
var methods = new MyJson.JsonNode_Array();
outjson["methods"] = methods;
Expand All @@ -103,21 +95,15 @@ public static MyJson.JsonNode_Object Export(NeoModule module, byte[] script)
continue;

var funcsign = new MyJson.JsonNode_Object();
if (function.Value.displayName == entryPoint)
{
// This is the entryPoint
outjson.SetDictValue("entryPoint", funcsign);
}
else
{
methods.Add(funcsign);
}
methods.Add(funcsign);
funcsign.SetDictValue("name", function.Value.displayName);
if (names.Contains(function.Value.displayName))
{
throw new Exception("abi not allow same name functions");
}
names.Add(function.Value.displayName);
var offset = addrConvTable?[function.Value.funcaddr] ?? function.Value.funcaddr;
funcsign.SetDictValue("offset", offset.ToString());
MyJson.JsonNode_Array funcparams = new MyJson.JsonNode_Array();
funcsign["parameters"] = funcparams;
if (mm.paramtypes != null)
Expand Down
18 changes: 4 additions & 14 deletions src/Neo.Compiler.MSIL/MSIL/Conv_Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,6 @@ private int ConvertPushI4WithConv(ILMethod from, int i, OpCode src, NeoMethod to

private void InsertSharedStaticVarCode(NeoMethod to)
{
if (this.outModule.mapFields.Count > 255)
throw new Exception("too mush static fields");

//insert init constvalue part
byte count = (byte)this.outModule.mapFields.Count;
if (count > 0)
Expand Down Expand Up @@ -328,10 +325,10 @@ private void InsertSharedStaticVarCode(NeoMethod to)

private void InsertBeginCode(ILMethod from, NeoMethod to)
{
if (from.paramtypes.Count > 255)
throw new Exception("too mush params in:" + from);
if (from.body_Variables.Count > 255)
throw new Exception("too mush local varibles in:" + from);
if (from.paramtypes.Count > MAX_PARAMS_COUNT)
throw new Exception("too much params in:" + from);
if (from.body_Variables.Count > MAX_LOCAL_VARIABLES_COUNT)
throw new Exception("too much local variables in:" + from);

byte paramcount = (byte)from.paramtypes.Count;
byte varcount = (byte)from.body_Variables.Count;
Expand All @@ -340,12 +337,5 @@ private void InsertBeginCode(ILMethod from, NeoMethod to)
Insert1(VM.OpCode.INITSLOT, "begincode", to, new byte[] { varcount, paramcount });
}
}

private void InsertBeginCodeEntry(NeoMethod to)
{
byte paramcount = (byte)2;
byte varcount = (byte)0;
Insert1(VM.OpCode.INITSLOT, "begincode", to, new byte[] { varcount, paramcount });
}
}
}
4 changes: 2 additions & 2 deletions src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private void ConvertCastclass(OpCode src, NeoMethod to)
try
{
var dtype = type.Resolve();
if (dtype.BaseType.FullName == "System.MulticastDelegate" || dtype.BaseType.FullName == "System.Delegate")
if (dtype.BaseType != null && (dtype.BaseType.FullName == "System.MulticastDelegate" || dtype.BaseType.FullName == "System.Delegate"))
{
foreach (var m in dtype.Methods)
{
Expand All @@ -85,7 +85,7 @@ private void ConvertLdArg(ILMethod method, OpCode src, NeoMethod to, int pos)
try
{
var ptype = method.method.Parameters[pos].ParameterType.Resolve();
if (ptype.BaseType.FullName == "System.MulticastDelegate" || ptype.BaseType.FullName == "System.Delegate")
if (ptype.BaseType != null && (ptype.BaseType.FullName == "System.MulticastDelegate" || ptype.BaseType.FullName == "System.Delegate"))
{
foreach (var m in ptype.Methods)
{
Expand Down
174 changes: 25 additions & 149 deletions src/Neo.Compiler.MSIL/MSIL/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public ModuleConverter(ILogger logger)
this.logger = logger;
}

private const int MAX_STATIC_FIELDS_COUNT = 255;
private const int MAX_PARAMS_COUNT = 255;
private const int MAX_LOCAL_VARIABLES_COUNT = 255;

private readonly ILogger logger;
public NeoModule outModule;
private ILModule inModule;
Expand Down Expand Up @@ -129,68 +133,27 @@ public NeoModule Convert(ILModule _in, ConvOption option = null)
if (m.Key.Contains("::Main("))
{
NeoMethod _m = outModule.mapMethods[m.Key];
if (_m.inSmartContract)
{
nm.isEntry = true;
}
}
this.ConvertMethod(m.Value, nm);
}
}
}

// Check entry Points

var entryPoints = outModule.mapMethods.Values.Where(u => u.inSmartContract).Select(u => u.type).Distinct().Count();

if (entryPoints > 1)
throw new EntryPointException(entryPoints, "The smart contract contains multiple entryPoints, please check it.");

// Done converting, make a link to connect all together
string mainmethod = "";
foreach (var key in outModule.mapMethods.Keys)
{
if (key.Contains("::Main("))
{
NeoMethod m = outModule.mapMethods[key];
if (m.inSmartContract)
{
foreach (var l in this.methodLink)
{
if (l.Value == m)
{
if (mainmethod != "")
throw new Exception("Have too mush EntryPoint,Check it.");
mainmethod = key;
}
}
}
}
}

if (string.IsNullOrEmpty(mainmethod))
{
mainmethod = InsertAutoEntry();

if (string.IsNullOrEmpty(mainmethod))
{
throw new EntryPointException(0, "The smart contract doesn't contain any entryPoints, please check it.");
}

logger.Log("Auto Insert entrypoint.");
}
else
if (this.outModule.mapFields.Count > MAX_STATIC_FIELDS_COUNT)
throw new Exception("too much static fields");
if (this.outModule.mapFields.Count > 0)
{
logger.Log("Find entrypoint:" + mainmethod); // Single default entry
InsertInitializeMethod();
logger.Log("Insert _initialize().");
}

var attr = outModule.mapMethods.Values.Where(u => u.inSmartContract).Select(u => u.type.attributes.ToArray()).FirstOrDefault();
if (attr?.Length > 0)
{
outModule.attributes.AddRange(attr);
}
outModule.mainMethod = mainmethod;
this.LinkCode(mainmethod);

this.LinkCode();

// this.findFirstFunc();// Need to find the first method
// Assign func addr for each method
Expand All @@ -199,28 +162,27 @@ public NeoModule Convert(ILModule _in, ConvOption option = null)
return outModule;
}

private string InsertAutoEntry()
private string InsertInitializeMethod()
{
string name = "::autoentrypoint";
NeoMethod autoEntry = new NeoMethod
string name = "::initializemethod";
NeoMethod initialize = new NeoMethod
{
_namespace = "",
name = "Main",
displayName = "main"
name = "Initialize",
displayName = "_initialize",
inSmartContract = true
};
autoEntry.paramtypes.Add(new NeoParam(name, "string"));
autoEntry.paramtypes.Add(new NeoParam(name, "array"));
autoEntry.returntype = "object";
autoEntry.funcaddr = 0;
if (!FillEntryMethod(autoEntry))
initialize.returntype = "System.Void";
initialize.funcaddr = 0;
if (!FillInitializeMethod(initialize))
{
return "";
}
outModule.mapMethods[name] = autoEntry;
outModule.mapMethods[name] = initialize;
return name;
}

private bool FillEntryMethod(NeoMethod to)
private bool FillInitializeMethod(NeoMethod to)
{
this.addr = 0;
this.addrconv.Clear();
Expand All @@ -229,104 +191,21 @@ private bool FillEntryMethod(NeoMethod to)
Insert1(VM.OpCode.NOP, "this is a debug code.", to);
#endif
InsertSharedStaticVarCode(to);
InsertBeginCodeEntry(to);

bool inserted = false;
List<int> calladdr = new List<int>();
List<int> calladdrbegin = new List<int>();

//add callfunc
foreach (var m in this.outModule.mapMethods)
{
if (m.Value.inSmartContract && m.Value.isPublic)
{
//add a call;
//get name
calladdrbegin.Add(this.addr);
//_Insert1(VM.OpCode.DUPFROMALTSTACK, "get name", to);
//_InsertPush(0, "", to);
//_Insert1(VM.OpCode.PICKITEM, "", to);
Insert1(VM.OpCode.LDARG0, "get name", to);

InsertPush(System.Text.Encoding.UTF8.GetBytes(m.Value.displayName), "", to);
Insert1(VM.OpCode.NUMEQUAL, "", to);
calladdr.Add(this.addr);//record add fix jumppos later
Insert1(VM.OpCode.JMPIFNOT_L, "tonextcallpos", to, new byte[] { 0, 0, 0, 0 });
if (m.Value.paramtypes.Count > 0)
{
for (var i = m.Value.paramtypes.Count - 1; i >= 0; i--)
{
Insert1(VM.OpCode.LDARG1, "get params array", to);
InsertPush(i, "get one param:" + i, to);
Insert1(VM.OpCode.PICKITEM, "", to);
}
//add params;
}
//call and return it
var c = Insert1(VM.OpCode.CALL_L, "", to, new byte[] { 0, 0, 0, 0 });
c.needfixfunc = true;
c.srcfunc = m.Key;
if (m.Value.returntype == "System.Void")
{
Insert1(VM.OpCode.PUSH0, "", to);
}
Insert1(VM.OpCode.RET, "", to);
inserted = true;
}
}

if (!inserted) return false;

//add returen
calladdrbegin.Add(this.addr);//record add fix jumppos later

//if go here,mean methodname is wrong
//use throw to instead ret,make vm fault.
Insert1(VM.OpCode.THROW, "", to);

//convert all Jmp
for (var i = 0; i < calladdr.Count; i++)
{
var addr = calladdr[i];
var nextaddr = calladdrbegin[i + 1];
var op = to.body_Codes[addr];
Int32 addroff = (Int32)(nextaddr - addr);
op.bytes = BitConverter.GetBytes(addroff);
}
#if DEBUG
Insert1(VM.OpCode.NOP, "this is a end debug code.", to);
#endif
Insert1(VM.OpCode.RET, "", to);
ConvertAddrInMethod(to);
return true;
}

private void LinkCode(string main)
private void LinkCode()
{
if (this.outModule.mapMethods.ContainsKey(main) == false)
{
throw new Exception("Can't find entrypoint:" + main);
}

var first = this.outModule.mapMethods[main];
first.funcaddr = 0;
this.outModule.totalCodes.Clear();
int addr = 0;
foreach (var c in first.body_Codes)
{
if (addr != c.Key)
{
throw new Exception("sth error");
}
this.outModule.totalCodes[addr] = c.Value;
addr += 1;
if (c.Value.bytes != null)
addr += c.Value.bytes.Length;
}

foreach (var m in this.outModule.mapMethods)
{
if (m.Key == main) continue;

m.Value.funcaddr = addr;

foreach (var c in m.Value.body_Codes)
Expand Down Expand Up @@ -405,6 +284,7 @@ private void FillMethod(ILMethod from, NeoMethod to, bool withReturn)
}
}
}

ConvertAddrInMethod(to);
}

Expand All @@ -413,10 +293,6 @@ private void ConvertMethod(ILMethod from, NeoMethod to)
this.addr = 0;
this.addrconv.Clear();

if (to.isEntry)
{
InsertSharedStaticVarCode(to);
}
// Insert a code that record the depth
InsertBeginCode(from, to);

Expand Down
2 changes: 1 addition & 1 deletion src/Neo.Compiler.MSIL/Neo.Compiler.MSIL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="3.4.0" />
<PackageReference Include="Mono.Cecil" Version="0.11.1" />
<PackageReference Include="Neo" Version="3.0.0-preview2-00" />
<PackageReference Include="Neo" Version="3.0.0-CI00897" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading