Browse Source

Merge branch 'develop-evmcc' of https://github.com/imapp-pl/ethereum into develop-evmcc

cl-refactor
Artur Zawłocki 10 years ago
parent
commit
630da235af
  1. 7
      alethzero/MainWin.cpp
  2. 12
      eth/main.cpp
  3. 2
      libdevcore/Common.cpp
  4. 18
      libethcore/BlockInfo.cpp
  5. 4
      libethcore/BlockInfo.h
  6. 4
      libethcore/CommonEth.cpp
  7. 21
      libethereum/BlockChain.cpp
  8. 12
      libethereum/BlockChain.h
  9. 22
      libethereum/BlockDetails.h
  10. 14
      libethereum/Executive.cpp
  11. 2
      libethereum/Interface.h
  12. 3
      libethereum/State.cpp
  13. 6
      libevm/FeeStructure.cpp
  14. 6
      libevm/FeeStructure.h
  15. 13
      libevm/VM.h
  16. 30
      libevmjit/interface.c
  17. 4
      libp2p/Host.cpp
  18. 27
      libsolidity/AST.h
  19. 2
      libsolidity/ExpressionCompiler.cpp
  20. 2
      libsolidity/GlobalContext.cpp
  21. 9
      libsolidity/Parser.cpp
  22. 93
      libsolidity/Scanner.cpp
  23. 32
      libsolidity/Scanner.h
  24. 2
      libsolidity/Types.cpp
  25. 1
      libweb3jsonrpc/WebThreeStubServer.cpp
  26. 6
      libwhisper/WhisperHost.cpp
  27. 9
      libwhisper/WhisperHost.h
  28. 14
      libwhisper/WhisperPeer.cpp
  29. 2
      libwhisper/WhisperPeer.h
  30. 18
      neth/main.cpp
  31. 161
      test/solidityParser.cpp
  32. 4
      windows/LibEthereum.vcxproj
  33. 16
      windows/LibEthereum.vcxproj.filters
  34. 1
      windows/LibEvmJit.vcxproj
  35. 3
      windows/LibEvmJit.vcxproj.filters

7
alethzero/MainWin.cpp

@ -1259,7 +1259,6 @@ void Main::on_blocks_currentItemChanged()
s << "<br/>D/TD: <b>2^" << log2((double)info.difficulty) << "</b>/<b>2^" << log2((double)details.totalDifficulty) << "</b>"; s << "<br/>D/TD: <b>2^" << log2((double)info.difficulty) << "</b>/<b>2^" << log2((double)details.totalDifficulty) << "</b>";
s << "&nbsp;&emsp;&nbsp;Children: <b>" << details.children.size() << "</b></h5>"; s << "&nbsp;&emsp;&nbsp;Children: <b>" << details.children.size() << "</b></h5>";
s << "<br/>Gas used/limit: <b>" << info.gasUsed << "</b>/<b>" << info.gasLimit << "</b>"; s << "<br/>Gas used/limit: <b>" << info.gasUsed << "</b>/<b>" << info.gasLimit << "</b>";
s << "&nbsp;&emsp;&nbsp;Minimum gas price: <b>" << formatBalance(info.minGasPrice) << "</b>";
s << "<br/>Coinbase: <b>" << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << "</b> " << info.coinbaseAddress; s << "<br/>Coinbase: <b>" << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << "</b> " << info.coinbaseAddress;
s << "<br/>Nonce: <b>" << info.nonce << "</b>"; s << "<br/>Nonce: <b>" << info.nonce << "</b>";
s << "<br/>Parent: <b>" << info.parentHash << "</b>"; s << "<br/>Parent: <b>" << info.parentHash << "</b>";
@ -1665,7 +1664,7 @@ void Main::on_data_textChanged()
errs.append("<div style=\"border-left: 6px solid #c00; margin-top: 2px\">" + QString::fromStdString(i).toHtmlEscaped() + "</div>"); errs.append("<div style=\"border-left: 6px solid #c00; margin-top: 2px\">" + QString::fromStdString(i).toHtmlEscaped() + "</div>");
} }
ui->code->setHtml(errs + lll + solidity + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped()); ui->code->setHtml(errs + lll + solidity + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped());
ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 0)); ui->gas->setMinimum((qint64)Client::txGas(m_data, 0));
if (!ui->gas->isEnabled()) if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas); ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true); ui->gas->setEnabled(true);
@ -1676,7 +1675,7 @@ void Main::on_data_textChanged()
ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true)));
if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size()) if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size())
{ {
ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 1)); ui->gas->setMinimum((qint64)Client::txGas(m_data, 1));
if (!ui->gas->isEnabled()) if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas); ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true); ui->gas->setEnabled(true);
@ -1685,7 +1684,7 @@ void Main::on_data_textChanged()
{ {
if (ui->gas->isEnabled()) if (ui->gas->isEnabled())
m_backupGas = ui->gas->value(); m_backupGas = ui->gas->value();
ui->gas->setValue((qint64)Client::txGas(m_data.size())); ui->gas->setValue((qint64)Client::txGas(m_data));
ui->gas->setEnabled(false); ui->gas->setEnabled(false);
} }
} }

12
eth/main.cpp

@ -492,14 +492,12 @@ int main(int argc, char** argv)
cnote << ssbd.str(); cnote << ssbd.str();
int ssize = sechex.length(); int ssize = sechex.length();
int size = hexAddr.length(); int size = hexAddr.length();
u256 minGas = (u256)Client::txGas(data.size(), 0); u256 minGas = (u256)Client::txGas(data, 0);
if (size < 40) if (size < 40)
{ {
if (size > 0) if (size > 0)
cwarn << "Invalid address length:" << size; cwarn << "Invalid address length:" << size;
} }
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40) else if (ssize < 40)
@ -559,9 +557,9 @@ int main(int argc, char** argv)
auto h = bc.currentHash(); auto h = bc.currentHash();
auto blockData = bc.block(h); auto blockData = bc.block(h);
BlockInfo info(blockData); BlockInfo info(blockData);
u256 minGas = (u256)Client::txGas(0, 0); u256 minGas = (u256)Client::txGas(bytes(), 0);
Address dest = h160(fromHex(hexAddr)); Address dest = h160(fromHex(hexAddr));
c->transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice); c->transact(us.secret(), amount, dest, bytes(), minGas);
} }
} }
else else
@ -598,11 +596,9 @@ int main(int argc, char** argv)
cnote << "Init:"; cnote << "Init:";
cnote << ssc.str(); cnote << ssc.str();
} }
u256 minGas = (u256)Client::txGas(init.size(), 0); u256 minGas = (u256)Client::txGas(init, 0);
if (endowment < 0) if (endowment < 0)
cwarn << "Invalid endowment"; cwarn << "Invalid endowment";
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else else

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev namespace dev
{ {
char const* Version = "0.7.10"; char const* Version = "0.7.11";
} }

18
libethcore/BlockInfo.cpp

@ -58,9 +58,9 @@ h256 BlockInfo::headerHashWithoutNonce() const
void BlockInfo::streamRLP(RLPStream& _s, bool _nonce) const void BlockInfo::streamRLP(RLPStream& _s, bool _nonce) const
{ {
_s.appendList(_nonce ? 15 : 14) _s.appendList(_nonce ? 14 : 13)
<< parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot << receiptsRoot << logBloom << parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot << receiptsRoot << logBloom
<< difficulty << number << minGasPrice << gasLimit << gasUsed << timestamp << extraData; << difficulty << number << gasLimit << gasUsed << timestamp << extraData;
if (_nonce) if (_nonce)
_s << nonce; _s << nonce;
} }
@ -86,12 +86,11 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce)
logBloom = _header[field = 6].toHash<h512>(); logBloom = _header[field = 6].toHash<h512>();
difficulty = _header[field = 7].toInt<u256>(); difficulty = _header[field = 7].toInt<u256>();
number = _header[field = 8].toInt<u256>(); number = _header[field = 8].toInt<u256>();
minGasPrice = _header[field = 9].toInt<u256>(); gasLimit = _header[field = 9].toInt<u256>();
gasLimit = _header[field = 10].toInt<u256>(); gasUsed = _header[field = 10].toInt<u256>();
gasUsed = _header[field = 11].toInt<u256>(); timestamp = _header[field = 11].toInt<u256>();
timestamp = _header[field = 12].toInt<u256>(); extraData = _header[field = 12].toBytes();
extraData = _header[field = 13].toBytes(); nonce = _header[field = 13].toHash<h256>();
nonce = _header[field = 14].toHash<h256>();
} }
catch (Exception const& _e) catch (Exception const& _e)
@ -147,9 +146,6 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
if (transactionsRoot != t.root()) if (transactionsRoot != t.root())
BOOST_THROW_EXCEPTION(InvalidTransactionsHash(t.root(), transactionsRoot)); BOOST_THROW_EXCEPTION(InvalidTransactionsHash(t.root(), transactionsRoot));
if (minGasPrice > mgp)
BOOST_THROW_EXCEPTION(InvalidMinGasPrice(minGasPrice, mgp));
if (sha3Uncles != sha3(root[2].data())) if (sha3Uncles != sha3(root[2].data()))
BOOST_THROW_EXCEPTION(InvalidUnclesHash()); BOOST_THROW_EXCEPTION(InvalidUnclesHash());
} }

4
libethcore/BlockInfo.h

@ -66,7 +66,6 @@ public:
h512 logBloom; // TODO LogBloom - get include h512 logBloom; // TODO LogBloom - get include
u256 difficulty; u256 difficulty;
u256 number; u256 number;
u256 minGasPrice;
u256 gasLimit; u256 gasLimit;
u256 gasUsed; u256 gasUsed;
u256 timestamp; u256 timestamp;
@ -95,7 +94,6 @@ public:
logBloom == _cmp.logBloom && logBloom == _cmp.logBloom &&
difficulty == _cmp.difficulty && difficulty == _cmp.difficulty &&
number == _cmp.number && number == _cmp.number &&
minGasPrice == _cmp.minGasPrice &&
gasLimit == _cmp.gasLimit && gasLimit == _cmp.gasLimit &&
gasUsed == _cmp.gasUsed && gasUsed == _cmp.gasUsed &&
timestamp == _cmp.timestamp && timestamp == _cmp.timestamp &&
@ -122,7 +120,7 @@ public:
inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi) inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi)
{ {
_out << _bi.hash << " " << _bi.parentHash << " " << _bi.sha3Uncles << " " << _bi.coinbaseAddress << " " << _bi.stateRoot << " " << _bi.transactionsRoot << " " << _out << _bi.hash << " " << _bi.parentHash << " " << _bi.sha3Uncles << " " << _bi.coinbaseAddress << " " << _bi.stateRoot << " " << _bi.transactionsRoot << " " <<
_bi.receiptsRoot << " " << _bi.logBloom << " " << _bi.difficulty << " " << _bi.number << " " << _bi.minGasPrice << " " << _bi.gasLimit << " " << _bi.receiptsRoot << " " << _bi.logBloom << " " << _bi.difficulty << " " << _bi.number << " " << _bi.gasLimit << " " <<
_bi.gasUsed << " " << _bi.timestamp << " " << _bi.nonce; _bi.gasUsed << " " << _bi.timestamp << " " << _bi.nonce;
return _out; return _out;
} }

4
libethcore/CommonEth.cpp

@ -33,8 +33,8 @@ namespace dev
namespace eth namespace eth
{ {
const unsigned c_protocolVersion = 44; const unsigned c_protocolVersion = 45;
const unsigned c_databaseVersion = 4; const unsigned c_databaseVersion = 5;
static const vector<pair<u256, string>> g_units = static const vector<pair<u256, string>> g_units =
{ {

21
libethereum/BlockChain.cpp

@ -101,9 +101,8 @@ bytes BlockChain::createGenesisBlock()
stateRoot = state.root(); stateRoot = state.root();
} }
block.appendList(15) block.appendList(14)
// TODO: maybe make logbloom correct? << h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
<< h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
return block.out(); return block.out();
@ -169,8 +168,6 @@ void BlockChain::close()
delete m_db; delete m_db;
m_lastBlockHash = m_genesisHash; m_lastBlockHash = m_genesisHash;
m_details.clear(); m_details.clear();
m_blooms.clear();
m_traces.clear();
m_cache.clear(); m_cache.clear();
} }
@ -307,14 +304,10 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
State s(bi.coinbaseAddress, _db); State s(bi.coinbaseAddress, _db);
auto tdIncrease = s.enactOn(&_block, bi, *this); auto tdIncrease = s.enactOn(&_block, bi, *this);
auto b = s.oldBloom(); auto b = s.oldBloom();
BlockBlooms bb;
BlockTraces bt;
BlockLogBlooms blb; BlockLogBlooms blb;
BlockReceipts br; BlockReceipts br;
for (unsigned i = 0; i < s.pending().size(); ++i) for (unsigned i = 0; i < s.pending().size(); ++i)
{ {
bb.blooms.push_back(s.changesFromPending(i).bloom());
bt.traces.push_back(s.changesFromPending(i));
blb.blooms.push_back(s.receipt(i).bloom()); blb.blooms.push_back(s.receipt(i).bloom());
br.receipts.push_back(s.receipt(i)); br.receipts.push_back(s.receipt(i));
} }
@ -330,14 +323,6 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_details[newHash] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}, b); m_details[newHash] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}, b);
m_details[bi.parentHash].children.push_back(newHash); m_details[bi.parentHash].children.push_back(newHash);
} }
{
WriteGuard l(x_blooms);
m_blooms[newHash] = bb;
}
{
WriteGuard l(x_traces);
m_traces[newHash] = bt;
}
{ {
WriteGuard l(x_logBlooms); WriteGuard l(x_logBlooms);
m_logBlooms[newHash] = blb; m_logBlooms[newHash] = blb;
@ -349,8 +334,6 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_extrasDB->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)dev::ref(m_details[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)dev::ref(m_details[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 1), (ldb::Slice)dev::ref(m_blooms[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 2), (ldb::Slice)dev::ref(m_traces[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 3), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash, 3), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp()));
m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block)); m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block));

12
libethereum/BlockChain.h

@ -101,14 +101,6 @@ public:
BlockDetails details(h256 _hash) const { return queryExtras<BlockDetails, 0>(_hash, m_details, x_details, NullBlockDetails); } BlockDetails details(h256 _hash) const { return queryExtras<BlockDetails, 0>(_hash, m_details, x_details, NullBlockDetails); }
BlockDetails details() const { return details(currentHash()); } BlockDetails details() const { return details(currentHash()); }
/// Get the transactions' bloom filters of a block (or the most recent mined if none given). Thread-safe.
BlockBlooms blooms(h256 _hash) const { return queryExtras<BlockBlooms, 1>(_hash, m_blooms, x_blooms, NullBlockBlooms); }
BlockBlooms blooms() const { return blooms(currentHash()); }
/// Get the transactions' trace manifests of a block (or the most recent mined if none given). Thread-safe.
BlockTraces traces(h256 _hash) const { return queryExtras<BlockTraces, 2>(_hash, m_traces, x_traces, NullBlockTraces); }
BlockTraces traces() const { return traces(currentHash()); }
/// Get the transactions' log blooms of a block (or the most recent mined if none given). Thread-safe. /// Get the transactions' log blooms of a block (or the most recent mined if none given). Thread-safe.
BlockLogBlooms logBlooms(h256 _hash) const { return queryExtras<BlockLogBlooms, 3>(_hash, m_logBlooms, x_logBlooms, NullBlockLogBlooms); } BlockLogBlooms logBlooms(h256 _hash) const { return queryExtras<BlockLogBlooms, 3>(_hash, m_logBlooms, x_logBlooms, NullBlockLogBlooms); }
BlockLogBlooms logBlooms() const { return logBlooms(currentHash()); } BlockLogBlooms logBlooms() const { return logBlooms(currentHash()); }
@ -193,10 +185,6 @@ private:
/// The caches of the disk DB and their locks. /// The caches of the disk DB and their locks.
mutable boost::shared_mutex x_details; mutable boost::shared_mutex x_details;
mutable BlockDetailsHash m_details; mutable BlockDetailsHash m_details;
mutable boost::shared_mutex x_blooms;
mutable BlockBloomsHash m_blooms;
mutable boost::shared_mutex x_traces;
mutable BlockTracesHash m_traces;
mutable boost::shared_mutex x_logBlooms; mutable boost::shared_mutex x_logBlooms;
mutable BlockLogBloomsHash m_logBlooms; mutable BlockLogBloomsHash m_logBlooms;
mutable boost::shared_mutex x_receipts; mutable boost::shared_mutex x_receipts;

22
libethereum/BlockDetails.h

@ -54,24 +54,6 @@ struct BlockDetails
h256 bloom; h256 bloom;
}; };
struct BlockBlooms
{
BlockBlooms() {}
BlockBlooms(RLP const& _r) { blooms = _r.toVector<h256>(); }
bytes rlp() const { RLPStream s; s << blooms; return s.out(); }
h256s blooms;
};
struct BlockTraces
{
BlockTraces() {}
BlockTraces(RLP const& _r) { for (auto const& i: _r) traces.emplace_back(i.data()); }
bytes rlp() const { RLPStream s(traces.size()); for (auto const& i: traces) i.streamRLP(s); return s.out(); }
Manifests traces;
};
struct BlockLogBlooms struct BlockLogBlooms
{ {
BlockLogBlooms() {} BlockLogBlooms() {}
@ -91,14 +73,10 @@ struct BlockReceipts
}; };
typedef std::map<h256, BlockDetails> BlockDetailsHash; typedef std::map<h256, BlockDetails> BlockDetailsHash;
typedef std::map<h256, BlockBlooms> BlockBloomsHash;
typedef std::map<h256, BlockTraces> BlockTracesHash;
typedef std::map<h256, BlockLogBlooms> BlockLogBloomsHash; typedef std::map<h256, BlockLogBlooms> BlockLogBloomsHash;
typedef std::map<h256, BlockReceipts> BlockReceiptsHash; typedef std::map<h256, BlockReceipts> BlockReceiptsHash;
static const BlockDetails NullBlockDetails; static const BlockDetails NullBlockDetails;
static const BlockBlooms NullBlockBlooms;
static const BlockTraces NullBlockTraces;
static const BlockLogBlooms NullBlockLogBlooms; static const BlockLogBlooms NullBlockLogBlooms;
static const BlockReceipts NullBlockReceipts; static const BlockReceipts NullBlockReceipts;

14
libethereum/Executive.cpp

@ -22,6 +22,7 @@
#include <boost/timer.hpp> #include <boost/timer.hpp>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libevm/VM.h> #include <libevm/VM.h>
#include "Interface.h"
#include "Executive.h" #include "Executive.h"
#include "State.h" #include "State.h"
#include "ExtVM.h" #include "ExtVM.h"
@ -58,15 +59,8 @@ bool Executive::setup(bytesConstRef _rlp)
BOOST_THROW_EXCEPTION(InvalidNonce(nonceReq, m_t.nonce())); BOOST_THROW_EXCEPTION(InvalidNonce(nonceReq, m_t.nonce()));
} }
// Don't like transactions whose gas price is too low. NOTE: this won't stay here forever - it's just until we get a proper gas price discovery protocol going.
if (m_t.gasPrice() < m_s.m_currentBlock.minGasPrice)
{
clog(StateDetail) << "Offered gas-price is too low: Require >" << m_s.m_currentBlock.minGasPrice << " Got" << m_t.gasPrice();
BOOST_THROW_EXCEPTION(GasPriceTooLow());
}
// Check gas cost is enough. // Check gas cost is enough.
u256 gasCost = m_t.data().size() * c_txDataGas + c_txGas; auto gasCost = Interface::txGas(m_t.data());
if (m_t.gas() < gasCost) if (m_t.gas() < gasCost)
{ {
@ -106,9 +100,9 @@ bool Executive::setup(bytesConstRef _rlp)
} }
if (m_t.isCreation()) if (m_t.isCreation())
return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - gasCost, &m_t.data(), m_sender); return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_sender);
else else
return call(m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - gasCost, m_sender); return call(m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_sender);
} }
bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress)

2
libethereum/Interface.h

@ -128,7 +128,7 @@ public:
virtual Addresses addresses(int _block) const = 0; virtual Addresses addresses(int _block) const = 0;
/// Get the fee associated for a transaction with the given data. /// Get the fee associated for a transaction with the given data.
static u256 txGas(unsigned _dataCount, u256 _gas = 0) { return c_txDataGas * _dataCount + c_txGas + _gas; } template <class T> static bigint txGas(T const& _data, u256 _gas = 0) { bigint ret = c_txGas + _gas; for (auto i: _data) ret += i ? c_txDataNonZeroGas : c_txDataZeroGas; return ret; }
/// Get the remaining gas limit in this block. /// Get the remaining gas limit in this block.
virtual u256 gasLimitRemaining() const = 0; virtual u256 gasLimitRemaining() const = 0;

3
libethereum/State.cpp

@ -54,7 +54,7 @@ void ecrecoverCode(bytesConstRef _in, bytesRef _out)
memcpy(&in, _in.data(), min(_in.size(), sizeof(in))); memcpy(&in, _in.data(), min(_in.size(), sizeof(in)));
memset(_out.data(), 0, _out.size()); memset(_out.data(), 0, _out.size());
if (in.v > 28) if ((u256)in.v > 28)
return; return;
SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)}; SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)};
if (!sig.isValid()) if (!sig.isValid())
@ -503,7 +503,6 @@ void State::resetCurrent()
m_currentBlock.timestamp = time(0); m_currentBlock.timestamp = time(0);
m_currentBlock.transactionsRoot = h256(); m_currentBlock.transactionsRoot = h256();
m_currentBlock.sha3Uncles = h256(); m_currentBlock.sha3Uncles = h256();
m_currentBlock.minGasPrice = 10 * szabo;
m_currentBlock.populateFromParent(m_previousBlock); m_currentBlock.populateFromParent(m_previousBlock);
// Update timestamp according to clock. // Update timestamp according to clock.

6
libevm/FeeStructure.cpp

@ -34,9 +34,13 @@ u256 const dev::eth::c_sstoreResetGas = 100;
u256 const dev::eth::c_sstoreRefundGas = 100; u256 const dev::eth::c_sstoreRefundGas = 100;
u256 const dev::eth::c_createGas = 100; u256 const dev::eth::c_createGas = 100;
u256 const dev::eth::c_callGas = 20; u256 const dev::eth::c_callGas = 20;
u256 const dev::eth::c_expGas = 1;
u256 const dev::eth::c_expByteGas = 1;
u256 const dev::eth::c_memoryGas = 1; u256 const dev::eth::c_memoryGas = 1;
u256 const dev::eth::c_txDataGas = 5; u256 const dev::eth::c_txDataZeroGas = 1;
u256 const dev::eth::c_txDataNonZeroGas = 5;
u256 const dev::eth::c_txGas = 500; u256 const dev::eth::c_txGas = 500;
u256 const dev::eth::c_logGas = 32; u256 const dev::eth::c_logGas = 32;
u256 const dev::eth::c_logDataGas = 1; u256 const dev::eth::c_logDataGas = 1;
u256 const dev::eth::c_logTopicGas = 32; u256 const dev::eth::c_logTopicGas = 32;
u256 const dev::eth::c_copyGas = 1;

6
libevm/FeeStructure.h

@ -37,12 +37,16 @@ extern u256 const c_sstoreResetGas; ///< Once per SSTORE operation if the zeron
extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero. extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero.
extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction. extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction.
extern u256 const c_callGas; ///< Once per CALL operation & message call transaction. extern u256 const c_callGas; ///< Once per CALL operation & message call transaction.
extern u256 const c_expGas; ///< Once per EXP instuction.
extern u256 const c_expByteGas; ///< Times ceil(log256(exponent)) for the EXP instruction.
extern u256 const c_memoryGas; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. extern u256 const c_memoryGas; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
extern u256 const c_txDataGas; ///< Per byte of data attached to a transaction. NOTE: Not payable on data of calls between transactions. extern u256 const c_txDataZeroGas; ///< Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txDataNonZeroGas; ///< Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions. extern u256 const c_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions.
extern u256 const c_logGas; ///< Per LOG* operation. extern u256 const c_logGas; ///< Per LOG* operation.
extern u256 const c_logDataGas; ///< Per byte in a LOG* operation's data. extern u256 const c_logDataGas; ///< Per byte in a LOG* operation's data.
extern u256 const c_logTopicGas; ///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas. extern u256 const c_logTopicGas; ///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
extern u256 const c_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
} }
} }

13
libevm/VM.h

@ -110,6 +110,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
// FEES... // FEES...
bigint runGas = c_stepGas; bigint runGas = c_stepGas;
bigint newTempSize = m_temp.size(); bigint newTempSize = m_temp.size();
bigint copySize = 0;
auto onOperation = [&]() auto onOperation = [&]()
{ {
@ -172,14 +173,17 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break; break;
case Instruction::CALLDATACOPY: case Instruction::CALLDATACOPY:
require(3); require(3);
copySize = m_stack[m_stack.size() - 3];
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]);
break; break;
case Instruction::CODECOPY: case Instruction::CODECOPY:
require(3); require(3);
copySize = m_stack[m_stack.size() - 3];
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]);
break; break;
case Instruction::EXTCODECOPY: case Instruction::EXTCODECOPY:
require(4); require(4);
copySize = m_stack[m_stack.size() - 4];
newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]); newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]);
break; break;
@ -217,6 +221,13 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
runGas = c_createGas; runGas = c_createGas;
break; break;
} }
case Instruction::EXP:
{
require(2);
auto expon = m_stack[m_stack.size() - 2];
runGas = c_expGas + c_expByteGas * (32 - (h256(expon).firstBitSet() / 8));
break;
}
case Instruction::PC: case Instruction::PC:
case Instruction::MSIZE: case Instruction::MSIZE:
@ -283,7 +294,6 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
case Instruction::SDIV: case Instruction::SDIV:
case Instruction::MOD: case Instruction::MOD:
case Instruction::SMOD: case Instruction::SMOD:
case Instruction::EXP:
case Instruction::LT: case Instruction::LT:
case Instruction::GT: case Instruction::GT:
case Instruction::SLT: case Instruction::SLT:
@ -344,6 +354,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
newTempSize = (newTempSize + 31) / 32 * 32; newTempSize = (newTempSize + 31) / 32 * 32;
if (newTempSize > m_temp.size()) if (newTempSize > m_temp.size())
runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32; runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32;
runGas += c_copyGas * (copySize + 31) / 32;
onOperation(); onOperation();
// if (_onOp) // if (_onOp)

30
libevmjit/interface.c

@ -0,0 +1,30 @@
#include <stdint.h>
// JIT object opaque type
typedef struct evm_jit evm_jit;
// Contract execution return code
typedef int evm_jit_return_code;
// Host-endian 256-bit integer type
typedef struct i256 i256;
// Big-endian right aligned 256-bit hash
typedef struct h256 h256;
// Runtime data struct - must be provided by external language (Go, C++, Python)
typedef struct evm_jit_rt evm_jit_rt;
// Runtime callback functions - implementations must be provided by external language (Go, C++, Python)
void evm_jit_rt_sload(evm_jit_rt* _rt, i256* _index, i256* _ret);
void evm_jit_rt_sstore(evm_jit_rt* _rt, i256* _index, i256* _value);
void evm_jit_rt_balance(evm_jit_rt* _rt, h256* _address, i256* _ret);
// And so on...
evm_jit* evm_jit_create(evm_jit_rt* _runtime_data);
evm_jit_return_code evm_jit_execute(evm_jit* _jit);
void evm_jit_get_return_data(evm_jit* _jit, char* _return_data_offset, size_t* _return_data_size);
void evm_jit_destroy(evm_jit* _jit);

4
libp2p/Host.cpp

@ -78,7 +78,7 @@ std::vector<bi::address> Host::getInterfaceAddresses()
char *addrStr = inet_ntoa(addr); char *addrStr = inet_ntoa(addr);
bi::address address(bi::address::from_string(addrStr)); bi::address address(bi::address::from_string(addrStr));
if (!isLocalHostAddress(address)) if (!isLocalHostAddress(address))
addresses.push_back(ad.to_v4()); addresses.push_back(address.to_v4());
} }
WSACleanup(); WSACleanup();
@ -153,7 +153,7 @@ int Host::listen4(bi::tcp::acceptor* _acceptor, unsigned short _listenPort)
bi::tcp::endpoint Host::traverseNAT(std::vector<bi::address> const& _ifAddresses, unsigned short _listenPort, bi::address& o_upnpifaddr) bi::tcp::endpoint Host::traverseNAT(std::vector<bi::address> const& _ifAddresses, unsigned short _listenPort, bi::address& o_upnpifaddr)
{ {
asserts(_listenPort); asserts(_listenPort != 0);
UPnP* upnp; UPnP* upnp;
try try

27
libsolidity/AST.h

@ -173,14 +173,21 @@ private:
class FunctionDefinition: public Declaration class FunctionDefinition: public Declaration
{ {
public: public:
FunctionDefinition(Location const& _location, ASTPointer<ASTString> const& _name, bool _isPublic, FunctionDefinition(Location const& _location, ASTPointer<ASTString> const& _name,
ASTPointer<ParameterList> const& _parameters, bool _isPublic,
bool _isDeclaredConst, ASTPointer<ASTString> const& _documentation,
ASTPointer<ParameterList> const& _returnParameters, ASTPointer<ParameterList> const& _parameters,
ASTPointer<Block> const& _body): bool _isDeclaredConst,
Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters), ASTPointer<ParameterList> const& _returnParameters,
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters), ASTPointer<Block> const& _body):
m_body(_body) {} Declaration(_location, _name), m_isPublic(_isPublic),
m_parameters(_parameters),
m_isDeclaredConst(_isDeclaredConst),
m_returnParameters(_returnParameters),
m_body(_body),
m_documentation(_documentation)
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
bool isPublic() const { return m_isPublic; } bool isPublic() const { return m_isPublic; }
@ -190,6 +197,9 @@ public:
std::vector<ASTPointer<VariableDeclaration>> const& getReturnParameters() const { return m_returnParameters->getParameters(); } std::vector<ASTPointer<VariableDeclaration>> const& getReturnParameters() const { return m_returnParameters->getParameters(); }
ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; } ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
Block& getBody() { return *m_body; } Block& getBody() { return *m_body; }
/// @return A shared pointer of an ASTString.
/// Can contain a nullptr in which case indicates absence of documentation
ASTPointer<ASTString> const& getDocumentation() { return m_documentation; }
void addLocalVariable(VariableDeclaration const& _localVariable) { m_localVariables.push_back(&_localVariable); } void addLocalVariable(VariableDeclaration const& _localVariable) { m_localVariables.push_back(&_localVariable); }
std::vector<VariableDeclaration const*> const& getLocalVariables() const { return m_localVariables; } std::vector<VariableDeclaration const*> const& getLocalVariables() const { return m_localVariables; }
@ -203,6 +213,7 @@ private:
bool m_isDeclaredConst; bool m_isDeclaredConst;
ASTPointer<ParameterList> m_returnParameters; ASTPointer<ParameterList> m_returnParameters;
ASTPointer<Block> m_body; ASTPointer<Block> m_body;
ASTPointer<ASTString> m_documentation;
std::vector<VariableDeclaration const*> m_localVariables; std::vector<VariableDeclaration const*> m_localVariables;
}; };

2
libsolidity/ExpressionCompiler.cpp

@ -363,7 +363,7 @@ void ExpressionCompiler::endVisit(Identifier& _identifier)
m_context << m_context.getFunctionEntryLabel(*functionDef).pushTag(); m_context << m_context.getFunctionEntryLabel(*functionDef).pushTag();
return; return;
} }
if (VariableDeclaration* varDef = dynamic_cast<VariableDeclaration*>(declaration)) if (/*VariableDeclaration* varDef = */dynamic_cast<VariableDeclaration*>(declaration))
{ {
m_currentLValue.fromIdentifier(_identifier, *_identifier.getReferencedDeclaration()); m_currentLValue.fromIdentifier(_identifier, *_identifier.getReferencedDeclaration());
m_currentLValue.retrieveValueIfLValueNotRequested(_identifier); m_currentLValue.retrieveValueIfLValueNotRequested(_identifier);

2
libsolidity/GlobalContext.cpp

@ -58,7 +58,7 @@ GlobalContext::GlobalContext():
FunctionType::Location::ECRECOVER)), FunctionType::Location::ECRECOVER)),
make_shared<MagicVariableDeclaration>("ripemd160", make_shared<MagicVariableDeclaration>("ripemd160",
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}), make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}), TypePointers({std::make_shared<IntegerType>(160, IntegerType::Modifier::HASH)}),
FunctionType::Location::RIPEMD160))} FunctionType::Location::RIPEMD160))}
{ {
} }

9
libsolidity/Parser.cpp

@ -117,6 +117,10 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic) ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
{ {
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
ASTPointer<ASTString> docstring;
if (m_scanner->getCurrentCommentLiteral() != "")
docstring = std::make_shared<ASTString>(m_scanner->getCurrentCommentLiteral());
expectToken(Token::FUNCTION); expectToken(Token::FUNCTION);
ASTPointer<ASTString> name(expectIdentifierToken()); ASTPointer<ASTString> name(expectIdentifierToken());
ASTPointer<ParameterList> parameters(parseParameterList()); ASTPointer<ParameterList> parameters(parseParameterList());
@ -142,8 +146,9 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
} }
ASTPointer<Block> block = parseBlock(); ASTPointer<Block> block = parseBlock();
nodeFactory.setEndPositionFromNode(block); nodeFactory.setEndPositionFromNode(block);
return nodeFactory.createNode<FunctionDefinition>(name, _isPublic, parameters, return nodeFactory.createNode<FunctionDefinition>(name, _isPublic, docstring,
isDeclaredConst, returnParameters, block); parameters,
isDeclaredConst, returnParameters, block);
} }
ASTPointer<StructDefinition> Parser::parseStructDefinition() ASTPointer<StructDefinition> Parser::parseStructDefinition()

93
libsolidity/Scanner.cpp

@ -102,18 +102,55 @@ int hexValue(char c)
} }
} // end anonymous namespace } // end anonymous namespace
/// Scoped helper for literal recording. Automatically drops the literal
/// if aborting the scanning before it's complete.
enum LiteralType {
LITERAL_TYPE_STRING,
LITERAL_TYPE_NUMBER, // not really different from string type in behaviour
LITERAL_TYPE_COMMENT
};
class LiteralScope
{
public:
explicit LiteralScope(Scanner* _self, enum LiteralType _type): m_type(_type)
, m_scanner(_self)
, m_complete(false)
{
if (_type == LITERAL_TYPE_COMMENT)
m_scanner->m_nextSkippedComment.literal.clear();
else
m_scanner->m_nextToken.literal.clear();
}
~LiteralScope()
{
if (!m_complete)
{
if (m_type == LITERAL_TYPE_COMMENT)
m_scanner->m_nextSkippedComment.literal.clear();
else
m_scanner->m_nextToken.literal.clear();
}
}
void complete() { m_complete = true; }
private:
enum LiteralType m_type;
Scanner* m_scanner;
bool m_complete;
}; // end of LiteralScope class
void Scanner::reset(CharStream const& _source) void Scanner::reset(CharStream const& _source)
{ {
bool foundDocComment;
m_source = _source; m_source = _source;
m_char = m_source.get(); m_char = m_source.get();
skipWhitespace(); skipWhitespace();
foundDocComment = scanToken(); scanToken();
// special version of Scanner:next() taking the previous scanToken() result into account next();
m_currentToken = m_nextToken;
if (scanToken() || foundDocComment)
m_skippedComment = m_nextSkippedComment;
} }
@ -142,8 +179,9 @@ BOOST_STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
Token::Value Scanner::next() Token::Value Scanner::next()
{ {
m_currentToken = m_nextToken; m_currentToken = m_nextToken;
if (scanToken()) m_skippedComment = m_nextSkippedComment;
m_skippedComment = m_nextSkippedComment; scanToken();
return m_currentToken.token; return m_currentToken.token;
} }
@ -180,10 +218,26 @@ Token::Value Scanner::skipSingleLineComment()
/// For the moment this function simply consumes a single line triple slash doc comment /// For the moment this function simply consumes a single line triple slash doc comment
Token::Value Scanner::scanDocumentationComment() Token::Value Scanner::scanDocumentationComment()
{ {
LiteralScope literal(this); LiteralScope literal(this, LITERAL_TYPE_COMMENT);
advance(); //consume the last '/' advance(); //consume the last '/'
while (!isSourcePastEndOfInput() && !isLineTerminator(m_char)) while (!isSourcePastEndOfInput())
{ {
if (isLineTerminator(m_char))
{
// check if next line is also a documentation comment
skipWhitespace();
if (!m_source.isPastEndOfInput(3) &&
m_source.get(0) == '/' &&
m_source.get(1) == '/' &&
m_source.get(2) == '/')
{
addCommentLiteralChar('\n');
m_char = m_source.advanceAndGet(3);
}
else
break; // next line is not a documentation comment, we are done
}
addCommentLiteralChar(m_char); addCommentLiteralChar(m_char);
advance(); advance();
} }
@ -214,10 +268,10 @@ Token::Value Scanner::skipMultiLineComment()
return Token::ILLEGAL; return Token::ILLEGAL;
} }
bool Scanner::scanToken() void Scanner::scanToken()
{ {
bool foundDocComment = false;
m_nextToken.literal.clear(); m_nextToken.literal.clear();
m_nextSkippedComment.literal.clear();
Token::Value token; Token::Value token;
do do
{ {
@ -329,7 +383,6 @@ bool Scanner::scanToken()
m_nextSkippedComment.location.end = getSourcePos(); m_nextSkippedComment.location.end = getSourcePos();
m_nextSkippedComment.token = comment; m_nextSkippedComment.token = comment;
token = Token::WHITESPACE; token = Token::WHITESPACE;
foundDocComment = true;
} }
else else
token = skipSingleLineComment(); token = skipSingleLineComment();
@ -425,8 +478,6 @@ bool Scanner::scanToken()
while (token == Token::WHITESPACE); while (token == Token::WHITESPACE);
m_nextToken.location.end = getSourcePos(); m_nextToken.location.end = getSourcePos();
m_nextToken.token = token; m_nextToken.token = token;
return foundDocComment;
} }
bool Scanner::scanEscape() bool Scanner::scanEscape()
@ -474,7 +525,7 @@ Token::Value Scanner::scanString()
{ {
char const quote = m_char; char const quote = m_char;
advance(); // consume quote advance(); // consume quote
LiteralScope literal(this); LiteralScope literal(this, LITERAL_TYPE_STRING);
while (m_char != quote && !isSourcePastEndOfInput() && !isLineTerminator(m_char)) while (m_char != quote && !isSourcePastEndOfInput() && !isLineTerminator(m_char))
{ {
char c = m_char; char c = m_char;
@ -505,7 +556,7 @@ void Scanner::scanDecimalDigits()
Token::Value Scanner::scanNumber(char _charSeen) Token::Value Scanner::scanNumber(char _charSeen)
{ {
enum { DECIMAL, HEX, BINARY } kind = DECIMAL; enum { DECIMAL, HEX, BINARY } kind = DECIMAL;
LiteralScope literal(this); LiteralScope literal(this, LITERAL_TYPE_NUMBER);
if (_charSeen == '.') if (_charSeen == '.')
{ {
// we have already seen a decimal point of the float // we have already seen a decimal point of the float
@ -758,7 +809,7 @@ Token::Value Scanner::scanIdentifierOrKeyword()
{ {
if (asserts(isIdentifierStart(m_char))) if (asserts(isIdentifierStart(m_char)))
BOOST_THROW_EXCEPTION(InternalCompilerError()); BOOST_THROW_EXCEPTION(InternalCompilerError());
LiteralScope literal(this); LiteralScope literal(this, LITERAL_TYPE_STRING);
addLiteralCharAndAdvance(); addLiteralCharAndAdvance();
// Scan the rest of the identifier characters. // Scan the rest of the identifier characters.
while (isIdentifierPart(m_char)) while (isIdentifierPart(m_char))
@ -767,14 +818,14 @@ Token::Value Scanner::scanIdentifierOrKeyword()
return KeywordOrIdentifierToken(m_nextToken.literal); return KeywordOrIdentifierToken(m_nextToken.literal);
} }
char CharStream::advanceAndGet() char CharStream::advanceAndGet(size_t _chars)
{ {
if (isPastEndOfInput()) if (isPastEndOfInput())
return 0; return 0;
++m_pos; m_pos += _chars;
if (isPastEndOfInput()) if (isPastEndOfInput())
return 0; return 0;
return get(); return m_source[m_pos];
} }
char CharStream::rollback(size_t _amount) char CharStream::rollback(size_t _amount)

32
libsolidity/Scanner.h

@ -74,9 +74,9 @@ public:
CharStream(): m_pos(0) {} CharStream(): m_pos(0) {}
explicit CharStream(std::string const& _source): m_source(_source), m_pos(0) {} explicit CharStream(std::string const& _source): m_source(_source), m_pos(0) {}
int getPos() const { return m_pos; } int getPos() const { return m_pos; }
bool isPastEndOfInput() const { return m_pos >= m_source.size(); } bool isPastEndOfInput(size_t _charsForward = 0) const { return (m_pos + _charsForward) >= m_source.size(); }
char get() const { return m_source[m_pos]; } char get(size_t _charsForward = 0) const { return m_source[m_pos + _charsForward]; }
char advanceAndGet(); char advanceAndGet(size_t _chars=1);
char rollback(size_t _amount); char rollback(size_t _amount);
///@{ ///@{
@ -93,22 +93,11 @@ private:
}; };
class Scanner class Scanner
{ {
friend class LiteralScope;
public: public:
/// Scoped helper for literal recording. Automatically drops the literal
/// if aborting the scanning before it's complete.
class LiteralScope
{
public:
explicit LiteralScope(Scanner* self): m_scanner(self), m_complete(false) { m_scanner->startNewLiteral(); }
~LiteralScope() { if (!m_complete) m_scanner->dropLiteral(); }
void complete() { m_complete = true; }
private:
Scanner* m_scanner;
bool m_complete;
};
Scanner() { reset(CharStream()); } Scanner() { reset(CharStream()); }
explicit Scanner(CharStream const& _source) { reset(_source); } explicit Scanner(CharStream const& _source) { reset(_source); }
@ -133,8 +122,12 @@ public:
///@{ ///@{
///@name Information about the current comment token ///@name Information about the current comment token
Location getCurrentCommentLocation() const { return m_skippedComment.location; } Location getCurrentCommentLocation() const { return m_skippedComment.location; }
std::string const& getCurrentCommentLiteral() const { return m_skippedComment.literal; } std::string const& getCurrentCommentLiteral() const { return m_skippedComment.literal; }
/// Called by the parser during FunctionDefinition parsing to clear the current comment
void clearCurrentCommentLiteral() { m_skippedComment.literal.clear(); }
///@} ///@}
///@{ ///@{
@ -165,10 +158,8 @@ private:
///@{ ///@{
///@name Literal buffer support ///@name Literal buffer support
inline void startNewLiteral() { m_nextToken.literal.clear(); }
inline void addLiteralChar(char c) { m_nextToken.literal.push_back(c); } inline void addLiteralChar(char c) { m_nextToken.literal.push_back(c); }
inline void addCommentLiteralChar(char c) { m_nextSkippedComment.literal.push_back(c); } inline void addCommentLiteralChar(char c) { m_nextSkippedComment.literal.push_back(c); }
inline void dropLiteral() { m_nextToken.literal.clear(); }
inline void addLiteralCharAndAdvance() { addLiteralChar(m_char); advance(); } inline void addLiteralCharAndAdvance() { addLiteralChar(m_char); advance(); }
///@} ///@}
@ -181,9 +172,8 @@ private:
bool scanHexByte(char& o_scannedByte); bool scanHexByte(char& o_scannedByte);
/// Scans a single Solidity token. Returns true if the scanned token was /// Scans a single Solidity token.
/// a skipped documentation comment. False in all other cases. void scanToken();
bool scanToken();
/// Skips all whitespace and @returns true if something was skipped. /// Skips all whitespace and @returns true if something was skipped.
bool skipWhitespace(); bool skipWhitespace();

2
libsolidity/Types.cpp

@ -397,11 +397,11 @@ MagicType::MagicType(MagicType::Kind _kind):
break; break;
case Kind::MSG: case Kind::MSG:
m_members = MemberList({{"sender", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)}, m_members = MemberList({{"sender", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)},
{"gas", make_shared<IntegerType const>(256)},
{"value", make_shared<IntegerType const>(256)}}); {"value", make_shared<IntegerType const>(256)}});
break; break;
case Kind::TX: case Kind::TX:
m_members = MemberList({{"origin", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)}, m_members = MemberList({{"origin", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)},
{"gas", make_shared<IntegerType const>(256)},
{"gasprice", make_shared<IntegerType const>(256)}}); {"gasprice", make_shared<IntegerType const>(256)}});
break; break;
default: default:

1
libweb3jsonrpc/WebThreeStubServer.cpp

@ -51,7 +51,6 @@ static Json::Value toJson(dev::eth::BlockInfo const& _bi)
res["transactionsRoot"] = toJS(_bi.transactionsRoot); res["transactionsRoot"] = toJS(_bi.transactionsRoot);
res["difficulty"] = toJS(_bi.difficulty); res["difficulty"] = toJS(_bi.difficulty);
res["number"] = (int)_bi.number; res["number"] = (int)_bi.number;
res["minGasPrice"] = toJS(_bi.minGasPrice);
res["gasLimit"] = (int)_bi.gasLimit; res["gasLimit"] = (int)_bi.gasLimit;
res["timestamp"] = (int)_bi.timestamp; res["timestamp"] = (int)_bi.timestamp;
res["extraData"] = jsFromBinary(_bi.extraData); res["extraData"] = jsFromBinary(_bi.extraData);

6
libwhisper/WhisperHost.cpp

@ -156,6 +156,12 @@ void WhisperHost::uninstallWatch(unsigned _i)
m_filters.erase(fit); m_filters.erase(fit);
} }
void WhisperHost::doWork()
{
for (auto& i: peers())
i->cap<WhisperPeer>()->sendMessages();
}
void WhisperHost::cleanup() void WhisperHost::cleanup()
{ {
// remove old messages. // remove old messages.

9
libwhisper/WhisperHost.h

@ -27,6 +27,7 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcore/Worker.h>
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h> #include <libdevcrypto/SHA3.h>
#include "Common.h" #include "Common.h"
@ -38,7 +39,7 @@ namespace dev
namespace shh namespace shh
{ {
class WhisperHost: public HostCapability<WhisperPeer>, public Interface class WhisperHost: public HostCapability<WhisperPeer>, public Interface, public Worker
{ {
friend class WhisperPeer; friend class WhisperPeer;
@ -64,7 +65,13 @@ public:
void cleanup(); void cleanup();
protected:
void doWork();
private: private:
virtual void onStarting() { startWorking(); }
virtual void onStopping() { stopWorking(); }
void streamMessage(h256 _m, RLPStream& _s) const; void streamMessage(h256 _m, RLPStream& _s) const;
void noteChanged(h256 _messageHash, h256 _filter); void noteChanged(h256 _messageHash, h256 _filter);

14
libwhisper/WhisperPeer.cpp

@ -72,7 +72,6 @@ bool WhisperPeer::interpret(unsigned _id, RLP const& _r)
for (auto i: _r) for (auto i: _r)
if (n++) if (n++)
host()->inject(Envelope(i), this); host()->inject(Envelope(i), this);
sendMessages();
break; break;
} }
default: default:
@ -97,10 +96,15 @@ void WhisperPeer::sendMessages()
} }
} }
if (!n) // the message subsystem should really just keep pumping out messages while m_unseen.size() and there's bandwidth for them.
// pause for a bit if no messages to send - this is horrible and broken. auto diff = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - m_timer);
// the message subsystem should really just keep pumping out messages while m_unseen.size() and there's bandwidth for them. if (n || diff.count() > 0)
this_thread::sleep_for(chrono::milliseconds(20)); {
RLPStream s;
prep(s, MessagesPacket, n).appendRaw(amalg.out(), n);
sealAndSend(s);
m_timer = chrono::system_clock::now();
}
{ {
RLPStream s; RLPStream s;

2
libwhisper/WhisperPeer.h

@ -68,6 +68,8 @@ private:
mutable dev::Mutex x_unseen; mutable dev::Mutex x_unseen;
std::map<unsigned, h256> m_unseen; ///< Rated according to what they want. std::map<unsigned, h256> m_unseen; ///< Rated according to what they want.
std::chrono::system_clock::time_point m_timer = std::chrono::system_clock::now();
}; };
} }

18
neth/main.cpp

@ -603,7 +603,7 @@ int main(int argc, char** argv)
vector<string> l; vector<string> l;
l.push_back("Amount"); l.push_back("Amount");
stringstream label; stringstream label;
label << "Gas price (" << info.minGasPrice << ")"; label << "Gas price";
l.push_back(label.str()); l.push_back(label.str());
l.push_back("Gas"); l.push_back("Gas");
vector<string> b; vector<string> b;
@ -646,14 +646,12 @@ int main(int argc, char** argv)
ssbd << bbd; ssbd << bbd;
cnote << ssbd.str(); cnote << ssbd.str();
int ssize = fields[4].length(); int ssize = fields[4].length();
u256 minGas = (u256)Client::txGas(data.size(), 0); u256 minGas = (u256)Client::txGas(data, 0);
if (size < 40) if (size < 40)
{ {
if (size > 0) if (size > 0)
cwarn << "Invalid address length:" << size; cwarn << "Invalid address length:" << size;
} }
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40) else if (ssize < 40)
@ -702,9 +700,9 @@ int main(int argc, char** argv)
auto h = bc.currentHash(); auto h = bc.currentHash();
auto blockData = bc.block(h); auto blockData = bc.block(h);
BlockInfo info(blockData); BlockInfo info(blockData);
u256 minGas = (u256)Client::txGas(0, 0); u256 minGas = (u256)Client::txGas(bytes(), 0);
Address dest = h160(fromHex(fields[0])); Address dest = h160(fromHex(fields[0]));
c.transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice); c.transact(us.secret(), amount, dest, bytes(), minGas);
} }
} }
} }
@ -718,7 +716,7 @@ int main(int argc, char** argv)
vector<string> l; vector<string> l;
l.push_back("Endowment"); l.push_back("Endowment");
stringstream label; stringstream label;
label << "Gas price (" << info.minGasPrice << ")"; label << "Gas price";
l.push_back(label.str()); l.push_back(label.str());
l.push_back("Gas"); l.push_back("Gas");
vector<string> b; vector<string> b;
@ -763,16 +761,14 @@ int main(int argc, char** argv)
cnote << "Init:"; cnote << "Init:";
cnote << ssc.str(); cnote << ssc.str();
} }
u256 minGas = (u256)Client::txGas(init.size(), 0); u256 minGas = (u256)Client::txGas(init, 0);
if (endowment < 0) if (endowment < 0)
cwarn << "Invalid endowment"; cwarn << "Invalid endowment";
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else else
{ {
c.transact(us.secret(), endowment, init, gas, gasPrice); c.transact(us.secret(), endowment, init, gas);
} }
} }
} }

161
test/solidityParser.cpp

@ -37,13 +37,14 @@ namespace test
namespace namespace
{ {
ASTPointer<ASTNode> parseText(std::string const& _source) ASTPointer<ContractDefinition> parseText(std::string const& _source)
{ {
Parser parser; Parser parser;
return parser.parse(std::make_shared<Scanner>(CharStream(_source))); return parser.parse(std::make_shared<Scanner>(CharStream(_source)));
} }
} }
BOOST_AUTO_TEST_SUITE(SolidityParser) BOOST_AUTO_TEST_SUITE(SolidityParser)
BOOST_AUTO_TEST_CASE(smoke_test) BOOST_AUTO_TEST_CASE(smoke_test)
@ -91,6 +92,164 @@ BOOST_AUTO_TEST_CASE(single_function_param)
BOOST_CHECK_NO_THROW(parseText(text)); BOOST_CHECK_NO_THROW(parseText(text));
} }
BOOST_AUTO_TEST_CASE(function_natspec_documentation)
{
ASTPointer<ContractDefinition> contract;
ASTPointer<FunctionDefinition> function;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" /// This is a test function\n"
" function functionName(hash hashin) returns (hash hashout) {}\n"
"}\n";
BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is a test function");
}
BOOST_AUTO_TEST_CASE(function_normal_comments)
{
ASTPointer<ContractDefinition> contract;
ASTPointer<FunctionDefinition> function;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" // We won't see this comment\n"
" function functionName(hash hashin) returns (hash hashout) {}\n"
"}\n";
BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_MESSAGE(function->getDocumentation() == nullptr,
"Should not have gotten a Natspect comment for this function");
}
BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
{
ASTPointer<ContractDefinition> contract;
ASTPointer<FunctionDefinition> function;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" /// This is test function 1\n"
" function functionName1(hash hashin) returns (hash hashout) {}\n"
" /// This is test function 2\n"
" function functionName2(hash hashin) returns (hash hashout) {}\n"
" // nothing to see here\n"
" function functionName3(hash hashin) returns (hash hashout) {}\n"
" /// This is test function 4\n"
" function functionName4(hash hashin) returns (hash hashout) {}\n"
"}\n";
BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 1");
BOOST_REQUIRE_NO_THROW(function = functions.at(1));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 2");
BOOST_REQUIRE_NO_THROW(function = functions.at(2));
BOOST_CHECK_MESSAGE(function->getDocumentation() == nullptr,
"Should not have gotten natspec comment for functionName3()");
BOOST_REQUIRE_NO_THROW(function = functions.at(3));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 4");
}
BOOST_AUTO_TEST_CASE(multiline_function_documentation)
{
ASTPointer<ContractDefinition> contract;
ASTPointer<FunctionDefinition> function;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" /// This is a test function\n"
" /// and it has 2 lines\n"
" function functionName1(hash hashin) returns (hash hashout) {}\n"
"}\n";
BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(),
" This is a test function\n"
" and it has 2 lines");
}
BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
{
ASTPointer<ContractDefinition> contract;
ASTPointer<FunctionDefinition> function;
char const* text = "contract test {\n"
" /// fun1 description\n"
" function fun1(uint256 a) {\n"
" var b;\n"
" /// I should not interfere with actual natspec comments\n"
" uint256 c;\n"
" mapping(address=>hash) d;\n"
" string name = \"Solidity\";"
" }\n"
" uint256 stateVar;\n"
" /// This is a test function\n"
" /// and it has 2 lines\n"
" function fun(hash hashin) returns (hash hashout) {}\n"
"}\n";
BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " fun1 description");
BOOST_REQUIRE_NO_THROW(function = functions.at(1));
BOOST_CHECK_EQUAL(*function->getDocumentation(),
" This is a test function\n"
" and it has 2 lines");
}
BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
{
ASTPointer<ContractDefinition> contract;
ASTPointer<FunctionDefinition> function;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" function ///I am in the wrong place \n"
" fun1(uint256 a) {\n"
" var b;\n"
" /// I should not interfere with actual natspec comments\n"
" uint256 c;\n"
" mapping(address=>hash) d;\n"
" string name = \"Solidity\";"
" }\n"
"}\n";
BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_MESSAGE(!function->getDocumentation(),
"Shouldn't get natspec docstring for this function");
}
BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)
{
ASTPointer<ContractDefinition> contract;
ASTPointer<FunctionDefinition> function;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" function fun1(uint256 a) {\n"
" /// I should have been above the function signature\n"
" var b;\n"
" /// I should not interfere with actual natspec comments\n"
" uint256 c;\n"
" mapping(address=>hash) d;\n"
" string name = \"Solidity\";"
" }\n"
"}\n";
BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_MESSAGE(!function->getDocumentation(),
"Shouldn't get natspec docstring for this function");
}
BOOST_AUTO_TEST_CASE(struct_definition) BOOST_AUTO_TEST_CASE(struct_definition)
{ {
char const* text = "contract test {\n" char const* text = "contract test {\n"

4
windows/LibEthereum.vcxproj

@ -125,6 +125,7 @@
<ClCompile Include="..\libethereum\Transaction.cpp" /> <ClCompile Include="..\libethereum\Transaction.cpp" />
<ClCompile Include="..\libethereum\TransactionQueue.cpp" /> <ClCompile Include="..\libethereum\TransactionQueue.cpp" />
<ClCompile Include="..\libethereum\Utility.cpp" /> <ClCompile Include="..\libethereum\Utility.cpp" />
<ClCompile Include="..\libethereum\VMFactory.cpp" />
<ClCompile Include="..\libevmcore\Assembly.cpp" /> <ClCompile Include="..\libevmcore\Assembly.cpp" />
<ClCompile Include="..\libevmcore\Instruction.cpp" /> <ClCompile Include="..\libevmcore\Instruction.cpp" />
<ClCompile Include="..\libevm\ExtVMFace.cpp"> <ClCompile Include="..\libevm\ExtVMFace.cpp">
@ -342,6 +343,7 @@
<ClInclude Include="..\libethereum\Transaction.h" /> <ClInclude Include="..\libethereum\Transaction.h" />
<ClInclude Include="..\libethereum\TransactionQueue.h" /> <ClInclude Include="..\libethereum\TransactionQueue.h" />
<ClInclude Include="..\libethereum\Utility.h" /> <ClInclude Include="..\libethereum\Utility.h" />
<ClInclude Include="..\libethereum\VMFactory.h" />
<ClInclude Include="..\libevmcore\Assembly.h" /> <ClInclude Include="..\libevmcore\Assembly.h" />
<ClInclude Include="..\libevmcore\Exceptions.h" /> <ClInclude Include="..\libevmcore\Exceptions.h" />
<ClInclude Include="..\libevmcore\Instruction.h" /> <ClInclude Include="..\libevmcore\Instruction.h" />
@ -574,4 +576,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

16
windows/LibEthereum.vcxproj.filters

@ -190,12 +190,6 @@
<ClCompile Include="..\libdevcrypto\CryptoPP.cpp"> <ClCompile Include="..\libdevcrypto\CryptoPP.cpp">
<Filter>libdevcrypto</Filter> <Filter>libdevcrypto</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libdevcrypto\EC.cpp">
<Filter>libdevcrypto</Filter>
</ClCompile>
<ClCompile Include="..\libdevcrypto\SHA3MAC.cpp">
<Filter>libdevcrypto</Filter>
</ClCompile>
<ClCompile Include="..\libethereum\Account.cpp"> <ClCompile Include="..\libethereum\Account.cpp">
<Filter>libethereum</Filter> <Filter>libethereum</Filter>
</ClCompile> </ClCompile>
@ -205,6 +199,11 @@
<ClCompile Include="..\libevm\VMFace.cpp"> <ClCompile Include="..\libevm\VMFace.cpp">
<Filter>libevm</Filter> <Filter>libevm</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libdevcrypto\AES.cpp" />
<ClCompile Include="..\libdevcrypto\ECDHE.cpp" />
<ClCompile Include="..\libethereum\VMFactory.cpp">
<Filter>libethereum</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h"> <ClInclude Include="stdafx.h">
@ -444,6 +443,9 @@
<ClInclude Include="..\libevm\VMFace.h"> <ClInclude Include="..\libevm\VMFace.h">
<Filter>libevm</Filter> <Filter>libevm</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libethereum\VMFactory.h">
<Filter>libethereum</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="Windows"> <Filter Include="Windows">
@ -480,4 +482,4 @@
<UniqueIdentifier>{d838fece-fc20-42f6-bff5-97c236159b80}</UniqueIdentifier> <UniqueIdentifier>{d838fece-fc20-42f6-bff5-97c236159b80}</UniqueIdentifier>
</Filter> </Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

1
windows/LibEvmJit.vcxproj

@ -131,6 +131,7 @@
<ClCompile Include="..\libevmjit\ExecutionEngine.cpp" /> <ClCompile Include="..\libevmjit\ExecutionEngine.cpp" />
<ClCompile Include="..\libevmjit\Ext.cpp" /> <ClCompile Include="..\libevmjit\Ext.cpp" />
<ClCompile Include="..\libevmjit\GasMeter.cpp" /> <ClCompile Include="..\libevmjit\GasMeter.cpp" />
<ClCompile Include="..\libevmjit\interface.c" />
<ClCompile Include="..\libevmjit\Memory.cpp" /> <ClCompile Include="..\libevmjit\Memory.cpp" />
<ClCompile Include="..\libevmjit\Runtime.cpp" /> <ClCompile Include="..\libevmjit\Runtime.cpp" />
<ClCompile Include="..\libevmjit\Stack.cpp" /> <ClCompile Include="..\libevmjit\Stack.cpp" />

3
windows/LibEvmJit.vcxproj.filters

@ -48,6 +48,9 @@
<ClCompile Include="..\libevmjit\Arith256.cpp"> <ClCompile Include="..\libevmjit\Arith256.cpp">
<Filter>libevmjit</Filter> <Filter>libevmjit</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libevmjit\interface.c">
<Filter>libevmjit</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\libevmjit\BasicBlock.h"> <ClInclude Include="..\libevmjit\BasicBlock.h">

Loading…
Cancel
Save