Skip to content

Commit

Permalink
fix call stack problem (neo-project#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
lightszero authored and Erik Zhang committed May 10, 2017
1 parent 1803f96 commit faa5037
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 18 deletions.
86 changes: 71 additions & 15 deletions src/AntShares.Compiler.MSIL/Conv_Multi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ private void _ConvertLdArg(OpCode src, AntsMethod to, int pos)
c.debugline = 0;
}
//push n
_Convert1by1(AntShares.VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(to.paramtypes.Count - 1 - pos));
_Convert1by1(AntShares.VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(pos));//翻转取参数顺序
//_Convert1by1(AntShares.VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(to.paramtypes.Count - 1 - pos));
//d+n
_Convert1by1(AntShares.VM.OpCode.ADD, null, to);

Expand Down Expand Up @@ -165,12 +166,12 @@ private int _ConvertCall(OpCode src, AntsMethod to)
{
Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference;

int calltype = 0;
string callname = "";
VM.OpCode callcode = VM.OpCode.NOP;
if (this.outModule.mapMethods.ContainsKey(src.tokenMethod))
{//this is a call
var c = _Convert1by1(AntShares.VM.OpCode.CALL, src, to, new byte[] { 5, 0 });
c.needfix = true;
c.srcfunc = src.tokenMethod;
return 0;
calltype = 1;
}
else if (refs.ReturnType.Name == "ExecutionEngine")
{
Expand Down Expand Up @@ -230,25 +231,80 @@ private int _ConvertCall(OpCode src, AntsMethod to)
}
else
{

string name;
if (IsOpCall(refs, out name))
if (IsOpCall(refs, out callname))
{
if (name == "CHECKSIG")
if (callname == "CHECKSIG")
{
_Convert1by1(AntShares.VM.OpCode.CHECKSIG, src, to);
return 0;
callcode = VM.OpCode.CHECKSIG;
calltype = 2;
}
}
if (IsSysCall(refs, out name))
if (IsSysCall(refs, out callname))
{
_Convert1by1(AntShares.VM.OpCode.SYSCALL, src, to,str2Pushdata1bytes(name));
return 0;
calltype = 3;
}
throw new Exception("unknown call:" + src.tokenMethod);

}
}

if (calltype == 0)
throw new Exception("unknown call:" + src.tokenMethod);
var md = src.tokenUnknown as Mono.Cecil.MethodReference;
var pcount = md.Parameters.Count;
_Convert1by1(VM.OpCode.NOP, src, to);
if (pcount <= 1)
{
}
else if (pcount == 2)
{
_Insert1(VM.OpCode.SWAP, "swap 2 param", to);
}
else if(pcount==3)
{
_Insert1(VM.OpCode.PUSHDATA1, "swap 0 and 2 param", to, int2Pushdata1bytes(2));
_Insert1(VM.OpCode.XSWAP, "", to);
}
else
{
for (var i = 0; i < pcount / 2; i++)
{
int saveto = (pcount - 1 - i);
_Insert1(VM.OpCode.PUSHDATA1, "load" + saveto, to, int2Pushdata1bytes(saveto));
_Insert1(VM.OpCode.PICK, "", to);

_Insert1(VM.OpCode.PUSHDATA1, "load" + i + 1, to, int2Pushdata1bytes(i + 1));
_Insert1(VM.OpCode.PICK, "", to);


_Insert1(VM.OpCode.PUSHDATA1, "save to" + saveto + 2, to, int2Pushdata1bytes(saveto + 2));
_Insert1(VM.OpCode.XSWAP, "", to);
_Insert1(VM.OpCode.DROP, "", to);

_Insert1(VM.OpCode.PUSHDATA1, "save to" + i + 1, to, int2Pushdata1bytes(i + 1));
_Insert1(VM.OpCode.XSWAP, "", to);
_Insert1(VM.OpCode.DROP, "", to);

}
}

if (calltype == 1)
{
var c = _Convert1by1(AntShares.VM.OpCode.CALL, null, to, new byte[] { 5, 0 });
c.needfix = true;
c.srcfunc = src.tokenMethod;
return 0;
}
else if (calltype == 2)
{
_Convert1by1(callcode, null, to);
return 0;
}
else if (calltype == 3)
{
_Convert1by1(AntShares.VM.OpCode.SYSCALL, null, to, str2Pushdata1bytes(callname));
return 0;
}
return 0;
}

private int _ConvertNewArr(ILMethod method, OpCode src, AntsMethod to)
Expand Down
8 changes: 5 additions & 3 deletions src/AntShares.Compiler.MSIL/ILModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ public ILModule()
public void LoadModule(System.IO.Stream dllStream, System.IO.Stream pdbStream)
{
this.module = Mono.Cecil.ModuleDefinition.ReadModule(dllStream);
#if WITHPDB
if (pdbStream != null)
{
//Mono.Cecil.Pdb is not available.
//var debugInfoLoader = new Mono.Cecil.Pdb.PdbReaderProvider();
//module.ReadSymbols(debugInfoLoader.GetSymbolReader(module, pdbStream));
var debugInfoLoader = new Mono.Cecil.Pdb.PdbReaderProvider();

module.ReadSymbols(debugInfoLoader.GetSymbolReader(module, pdbStream));
}
#endif
if (module.HasAssemblyReferences)
{
foreach (var ar in module.AssemblyReferences)
Expand Down

0 comments on commit faa5037

Please sign in to comment.