// constructor also goes here private EvmByteCode WrapByteCode(EvmByteCode toWrap) { var preAssembly = new EthSharpAssembly(); preAssembly.Append(toWrap.ByteCode.Count); // push length of bytecode preAssembly.Append(0x0c); // push offset of bytecode - TODO: THIS COULD CHANGE IF THIS BLOCK CHANGES! preAssembly.Append(UInt256.Zero); // push memory location to store in (0) preAssembly.Append(EvmInstruction.CODECOPY); // codecopy preAssembly.Append(toWrap.ByteCode.Count); // push length of code to pick preAssembly.Append(UInt256.Zero); // push location of code (0) preAssembly.Append(EvmInstruction.RETURN); var preByteCode = preAssembly.Assemble(); toWrap.ByteCode.InsertRange(0, preByteCode.ByteCode); return(toWrap); }
public EvmByteCode Assemble() { EvmByteCode ret = new EvmByteCode(); Dictionary <int, List <int> > jumpFromLocations = new Dictionary <int, List <int> >(); Dictionary <int, int> tagLocations = new Dictionary <int, int>(); foreach (var item in Items) { switch (item.Type) { case AssemblyItemType.Operation: ret.ByteCode.Add((byte)item.Instruction); break; case AssemblyItemType.Push: { int length = item.Data.ByteLength; var sizedPushInstruction = EvmInstruction.PUSH1 - 1 + length; ret.ByteCode.Add((byte)sizedPushInstruction); ret.ByteCode.AddRange(item.Data.ToByteArrayBE().Skip(32 - length).Take(length)); break; } case AssemblyItemType.PushTag: { ret.ByteCode.Add((byte)EvmInstruction.PUSH1); if (jumpFromLocations.ContainsKey(item.Data.ToInt())) { jumpFromLocations[item.Data.ToInt()].Add(ret.ByteCode.Count); } else { jumpFromLocations[item.Data.ToInt()] = new List <int> { ret.ByteCode.Count }; } ret.ByteCode.Add((byte)0); //This will get replaced with the location to jump to! break; } case AssemblyItemType.Tag: tagLocations.Add(item.Data.ToInt(), ret.ByteCode.Count); ret.ByteCode.Add((byte)EvmInstruction.JUMPDEST); break; } } //Update all jumps to correct location foreach (var tag in tagLocations) { int tagId = tag.Key; int tagLocation = tag.Value; foreach (var jumpFrom in jumpFromLocations[tagId]) { ret.ByteCode[jumpFrom] = (byte)tagLocation; } } return(ret); }