mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into HEAD
This commit is contained in:
@@ -1,16 +1,43 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract c {
|
||||
uint256[][] a;
|
||||
uint256[][] a1;
|
||||
uint256[][2] a2;
|
||||
uint256[2][] a3;
|
||||
uint256[2][2] a4;
|
||||
|
||||
function test(uint256[][] calldata d) external returns (uint256, uint256) {
|
||||
a = d;
|
||||
assert(a[0][0] == d[0][0]);
|
||||
assert(a[0][1] == d[0][1]);
|
||||
return (a.length, a[1][0] + a[1][1]);
|
||||
function test1(uint256[][] calldata c) external returns (uint256, uint256) {
|
||||
a1 = c;
|
||||
assert(a1[0][0] == c[0][0]);
|
||||
assert(a1[0][1] == c[0][1]);
|
||||
return (a1.length, a1[1][0] + a1[1][1]);
|
||||
}
|
||||
|
||||
function test2(uint256[][2] calldata c) external returns (uint256, uint256) {
|
||||
a2 = c;
|
||||
assert(a2[0][0] == c[0][0]);
|
||||
assert(a2[0][1] == c[0][1]);
|
||||
return (a2[0].length, a2[1][0] + a2[1][1]);
|
||||
}
|
||||
|
||||
function test3(uint256[2][] calldata c) external returns (uint256, uint256) {
|
||||
a3 = c;
|
||||
assert(a3[0][0] == c[0][0]);
|
||||
assert(a3[0][1] == c[0][1]);
|
||||
return (a3.length, a3[1][0] + a3[1][1]);
|
||||
}
|
||||
|
||||
function test4(uint256[2][2] calldata c) external returns (uint256) {
|
||||
a4 = c;
|
||||
assert(a4[0][0] == c[0][0]);
|
||||
assert(a4[0][1] == c[0][1]);
|
||||
return (a4[1][0] + a4[1][1]);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// test(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65
|
||||
// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65
|
||||
// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65
|
||||
// test3(uint256[2][]): 0x20, 2, 0x40, 0x40, 23, 42 -> 2, 65
|
||||
// test4(uint256[2][2]): 23, 42, 23, 42 -> 65
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct S {
|
||||
uint128 p1;
|
||||
uint256[][2] a;
|
||||
uint32 p2;
|
||||
}
|
||||
S s;
|
||||
function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {
|
||||
s = c;
|
||||
assert(s.a[0][0] == c.a[0][0]);
|
||||
assert(s.a[1][1] == c.a[1][1]);
|
||||
return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// f(uint32, (uint128, uint256[][2], uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88
|
||||
@@ -0,0 +1,30 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract A {
|
||||
int x;
|
||||
int y;
|
||||
function a() public {
|
||||
require(A.x < 100);
|
||||
A.y = A.x++;
|
||||
assert(A.y == A.x - 1);
|
||||
// Fails
|
||||
assert(A.y == 0);
|
||||
A.y = ++A.x;
|
||||
assert(A.y == A.x);
|
||||
delete A.x;
|
||||
assert(A.x == 0);
|
||||
A.y = A.x--;
|
||||
assert(A.y == A.x + 1);
|
||||
assert(A.y == 0);
|
||||
A.y = --A.x;
|
||||
assert(A.y == A.x);
|
||||
A.x += 10;
|
||||
// Fails
|
||||
assert(A.y == 0);
|
||||
assert(A.y + 10 == A.x);
|
||||
A.x -= 10;
|
||||
assert(A.y == A.x);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (160-176): CHC: Assertion violation happens here.
|
||||
// Warning 6328: (373-389): CHC: Assertion violation happens here.
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract A {
|
||||
uint[] a;
|
||||
function f() public {
|
||||
A.a.push(2);
|
||||
assert(A.a[A.a.length - 1] == 2);
|
||||
A.a.pop();
|
||||
// Fails
|
||||
assert(A.a.length > 0);
|
||||
assert(A.a.length == 0);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (156-178): CHC: Assertion violation happens here.
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
==== Source: AASource ====
|
||||
pragma experimental SMTChecker;
|
||||
import "AASource" as AA;
|
||||
contract A {
|
||||
int x;
|
||||
int y;
|
||||
function a() public {
|
||||
require(A.x < 100);
|
||||
AA.A.y = A.x++;
|
||||
assert(A.y == AA.A.x - 1);
|
||||
// Fails
|
||||
assert(AA.A.y == 0);
|
||||
A.y = ++AA.A.x;
|
||||
assert(A.y == A.x);
|
||||
delete AA.A.x;
|
||||
assert(A.x == 0);
|
||||
A.y = A.x--;
|
||||
assert(AA.A.y == AA.A.x + 1);
|
||||
A.y = --A.x;
|
||||
assert(A.y == A.x);
|
||||
AA.A.x += 10;
|
||||
// Fails
|
||||
assert(A.y == 0);
|
||||
assert(A.y + 10 == A.x);
|
||||
A.x -= 10;
|
||||
assert(AA.A.y == A.x);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (AASource:191-210): CHC: Assertion violation happens here.
|
||||
// Warning 6328: (AASource:402-418): CHC: Assertion violation happens here.
|
||||
@@ -7,9 +7,7 @@ contract C {
|
||||
function f(bool b) public {
|
||||
if (b)
|
||||
s.x[2] |= 1;
|
||||
assert(s.x[2] != 1);
|
||||
// Removed because of Spacer nondeterminism.
|
||||
//assert(s.x[2] != 1);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (173-192): CHC: Assertion violation might happen here.
|
||||
// Warning 7812: (173-192): BMC: Assertion violation might happen here.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f() public pure {
|
||||
fixed x;
|
||||
assert(x >>> 6 == 0);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// UnimplementedFeatureError: Not yet implemented - FixedPointType.
|
||||
@@ -0,0 +1,11 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(bool x) public pure {
|
||||
(uint a, uint b) = x ? (10000000001, 2) : (3, 4);
|
||||
assert(a != 0);
|
||||
assert(b != 0);
|
||||
assert(a % 2 == 1);
|
||||
assert(b % 2 == 0);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,8 @@ contract C
|
||||
// Should not fail since knowledge is erased only for mapping (uint => uint).
|
||||
assert(severalMaps8[0][0] == 42);
|
||||
// Should not fail since singleMap == severalMaps3d[0][0] is not possible.
|
||||
assert(severalMaps3d[0][0][0] == 42);
|
||||
// Removed because of Spacer nondeterminism.
|
||||
//assert(severalMaps3d[0][0][0] == 42);
|
||||
// Should fail since singleMap == map is possible.
|
||||
assert(map[0] == 42);
|
||||
}
|
||||
@@ -26,4 +27,4 @@ contract C
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (781-801): CHC: Assertion violation happens here.
|
||||
// Warning 6328: (830-850): CHC: Assertion violation happens here.
|
||||
|
||||
@@ -14,7 +14,7 @@ contract C {
|
||||
// ====
|
||||
// EVMVersion: =homestead
|
||||
// ----
|
||||
// TypeError 7756: (86-100): The "returndatasize" instruction is only available for Byzantium-compatible VMs (you are currently compiling for "homestead").
|
||||
// TypeError 4778: (86-100): The "returndatasize" instruction is only available for Byzantium-compatible VMs (you are currently compiling for "homestead").
|
||||
// DeclarationError 3812: (77-102): Variable count mismatch: 1 variables and 0 values.
|
||||
// TypeError 7756: (115-129): The "returndatacopy" instruction is only available for Byzantium-compatible VMs (you are currently compiling for "homestead").
|
||||
// TypeError 1503: (245-255): The "staticcall" instruction is only available for Byzantium-compatible VMs (you are currently compiling for "homestead").
|
||||
|
||||
@@ -17,9 +17,9 @@ contract C {
|
||||
// ----
|
||||
// TypeError 6612: (103-106): The "shl" instruction is only available for Constantinople-compatible VMs (you are currently compiling for "byzantium").
|
||||
// DeclarationError 8678: (96-116): Variable count does not match number of values (1 vs. 0)
|
||||
// TypeError 6612: (136-139): The "shr" instruction is only available for Constantinople-compatible VMs (you are currently compiling for "byzantium").
|
||||
// TypeError 7458: (136-139): The "shr" instruction is only available for Constantinople-compatible VMs (you are currently compiling for "byzantium").
|
||||
// DeclarationError 8678: (129-147): Variable count does not match number of values (1 vs. 0)
|
||||
// TypeError 6612: (167-170): The "sar" instruction is only available for Constantinople-compatible VMs (you are currently compiling for "byzantium").
|
||||
// TypeError 2054: (167-170): The "sar" instruction is only available for Constantinople-compatible VMs (you are currently compiling for "byzantium").
|
||||
// DeclarationError 8678: (160-178): Variable count does not match number of values (1 vs. 0)
|
||||
// TypeError 6166: (283-290): The "create2" instruction is only available for Constantinople-compatible VMs (you are currently compiling for "byzantium").
|
||||
// DeclarationError 8678: (276-302): Variable count does not match number of values (1 vs. 0)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Trace:
|
||||
// Memory dump:
|
||||
// 0: 0000000000000000000000000000000000000000000000000000000000000001
|
||||
// 20: 0000000000000000000000000000000000000000000000000000000022222222
|
||||
// 20: 0000000000000000000000000000000022222222000000000000000000000000
|
||||
// Storage dump:
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000022222222
|
||||
// 0000000000000000000000000000000000000000000000000000000000000001: 0000000000000000000000000000000000000000000000000000000022222222
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000022222222000000000000000000000000
|
||||
// 0000000000000000000000000000000000000000000000000000000000000001: 0000000000000000000000000000000022222222000000000000000000000000
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
// ----
|
||||
// Trace:
|
||||
// Memory dump:
|
||||
// 20: 0000000000000000000000005555555500000000000000000000000000000000
|
||||
// 20: 5555555500000000000000000000000000000000000000000000000000000000
|
||||
// Storage dump:
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000005555555500000000000000000000000000000000
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 5555555500000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
// ----
|
||||
// Trace:
|
||||
// Memory dump:
|
||||
// 20: 0000000000000000000000000000000000000000000000000000000009999999
|
||||
// 20: 9999990900000000000000000000000000000000000000000000000000000000
|
||||
// Storage dump:
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000009999999
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 9999990900000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
// ----
|
||||
// Trace:
|
||||
// Memory dump:
|
||||
// 20: 000000000000000000000000000000000000000000000000000000000000077b
|
||||
// 20: 0000000000000000000000000000000000000000000000000000000000000dd6
|
||||
// Storage dump:
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 000000000000000000000000000000000000000000000000000000000000077b
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000dd6
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
// ----
|
||||
// Trace:
|
||||
// Memory dump:
|
||||
// 20: 0000000000000000000000006666666600000000000000000000000000000000
|
||||
// 20: 6666666600000000000000000000000000000000000000000000000000000000
|
||||
// Storage dump:
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000006666666600000000000000000000000000000000
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000: 6666666600000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -35,6 +35,7 @@ using namespace solidity;
|
||||
using namespace solidity::yul;
|
||||
using namespace solidity::yul::test;
|
||||
|
||||
using solidity::util::h160;
|
||||
using solidity::util::h256;
|
||||
|
||||
namespace
|
||||
@@ -297,9 +298,7 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
}
|
||||
else if (_fun == "getExternalBalance")
|
||||
{
|
||||
// TODO this does not read the address, but is consistent with
|
||||
// EVM interpreter implementation.
|
||||
// If we take the address into account, this needs to use readAddress.
|
||||
readAddress(arg[0]);
|
||||
writeU128(arg[1], m_state.balance);
|
||||
return 0;
|
||||
}
|
||||
@@ -309,14 +308,15 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
writeU256(arg[1], 0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256));
|
||||
writeBytes32(arg[1], h256(0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (_fun == "call")
|
||||
{
|
||||
// TODO read args from memory
|
||||
// TODO use readAddress to read address.
|
||||
readAddress(arg[1]);
|
||||
readU128(arg[2]);
|
||||
accessMemory(arg[3], arg[4]);
|
||||
logTrace(evmasm::Instruction::CALL, {});
|
||||
return arg[0] & 1;
|
||||
}
|
||||
@@ -335,38 +335,38 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
return m_state.calldata.size();
|
||||
else if (_fun == "callCode")
|
||||
{
|
||||
// TODO read args from memory
|
||||
// TODO use readAddress to read address.
|
||||
readAddress(arg[1]);
|
||||
readU128(arg[2]);
|
||||
accessMemory(arg[3], arg[4]);
|
||||
logTrace(evmasm::Instruction::CALLCODE, {});
|
||||
return arg[0] & 1;
|
||||
}
|
||||
else if (_fun == "callDelegate")
|
||||
{
|
||||
// TODO read args from memory
|
||||
// TODO use readAddress to read address.
|
||||
readAddress(arg[1]);
|
||||
accessMemory(arg[2], arg[3]);
|
||||
logTrace(evmasm::Instruction::DELEGATECALL, {});
|
||||
return arg[0] & 1;
|
||||
}
|
||||
else if (_fun == "callStatic")
|
||||
{
|
||||
// TODO read args from memory
|
||||
// TODO use readAddress to read address.
|
||||
readAddress(arg[1]);
|
||||
accessMemory(arg[2], arg[3]);
|
||||
logTrace(evmasm::Instruction::STATICCALL, {});
|
||||
return arg[0] & 1;
|
||||
}
|
||||
else if (_fun == "storageStore")
|
||||
{
|
||||
m_state.storage[h256(readU256(arg[0]))] = readU256((arg[1]));
|
||||
m_state.storage[readBytes32(arg[0])] = readBytes32(arg[1]);
|
||||
return 0;
|
||||
}
|
||||
else if (_fun == "storageLoad")
|
||||
{
|
||||
writeU256(arg[1], m_state.storage[h256(readU256(arg[0]))]);
|
||||
writeBytes32(arg[1], m_state.storage[readBytes32(arg[0])]);
|
||||
return 0;
|
||||
}
|
||||
else if (_fun == "getCaller")
|
||||
{
|
||||
// TODO should this only write 20 bytes?
|
||||
writeAddress(arg[0], m_state.caller);
|
||||
return 0;
|
||||
}
|
||||
@@ -393,10 +393,11 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
}
|
||||
else if (_fun == "create")
|
||||
{
|
||||
// TODO access memory
|
||||
// TODO use writeAddress to store resulting address
|
||||
readU128(arg[0]);
|
||||
accessMemory(arg[1], arg[2]);
|
||||
logTrace(evmasm::Instruction::CREATE, {});
|
||||
return 0xcccccc + arg[1];
|
||||
writeAddress(arg[3], h160(h256(0xcccccc + arg[1])));
|
||||
return 1;
|
||||
}
|
||||
else if (_fun == "getBlockDifficulty")
|
||||
{
|
||||
@@ -405,7 +406,7 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
}
|
||||
else if (_fun == "externalCodeCopy")
|
||||
{
|
||||
// TODO use readAddress to read address.
|
||||
readAddress(arg[0]);
|
||||
if (accessMemory(arg[1], arg[3]))
|
||||
// TODO this way extcodecopy and codecopy do the same thing.
|
||||
copyZeroExtended(
|
||||
@@ -415,8 +416,8 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
return 0;
|
||||
}
|
||||
else if (_fun == "getExternalCodeSize")
|
||||
// Generate "random" code length. Make sure it fits the page size.
|
||||
return u256(keccak256(h256(readAddress(arg[0])))) & 0xfff;
|
||||
// Generate "random" code length.
|
||||
return uint32_t(u256(keccak256(h256(readAddress(arg[0])))) & 0xfff);
|
||||
else if (_fun == "getGasLeft")
|
||||
return 0x99;
|
||||
else if (_fun == "getBlockGasLimit")
|
||||
@@ -428,9 +429,18 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
}
|
||||
else if (_fun == "log")
|
||||
{
|
||||
accessMemory(arg[0], arg[1]);
|
||||
uint64_t numberOfTopics = arg[2];
|
||||
if (numberOfTopics > 4)
|
||||
throw ExplicitlyTerminated();
|
||||
if (numberOfTopics > 0)
|
||||
readBytes32(arg[3]);
|
||||
if (numberOfTopics > 1)
|
||||
readBytes32(arg[4]);
|
||||
if (numberOfTopics > 2)
|
||||
readBytes32(arg[5]);
|
||||
if (numberOfTopics > 3)
|
||||
readBytes32(arg[6]);
|
||||
logTrace(evmasm::logInstruction(numberOfTopics), {});
|
||||
return 0;
|
||||
}
|
||||
@@ -472,7 +482,7 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
}
|
||||
else if (_fun == "selfDestruct")
|
||||
{
|
||||
// TODO use readAddress to read address.
|
||||
readAddress(arg[0]);
|
||||
logTrace(evmasm::Instruction::SELFDESTRUCT, {});
|
||||
throw ExplicitlyTerminated();
|
||||
}
|
||||
@@ -523,6 +533,12 @@ uint32_t EwasmBuiltinInterpreter::readMemoryHalfWord(uint64_t _offset)
|
||||
return r;
|
||||
}
|
||||
|
||||
void EwasmBuiltinInterpreter::writeMemory(uint64_t _offset, bytes const& _value)
|
||||
{
|
||||
for (size_t i = 0; i < _value.size(); i++)
|
||||
m_state.memory[_offset + i] = _value[i];
|
||||
}
|
||||
|
||||
void EwasmBuiltinInterpreter::writeMemoryWord(uint64_t _offset, uint64_t _value)
|
||||
{
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
@@ -545,7 +561,7 @@ void EwasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _c
|
||||
accessMemory(_offset, _croppedTo);
|
||||
for (size_t i = 0; i < _croppedTo; i++)
|
||||
{
|
||||
m_state.memory[_offset + _croppedTo - 1 - i] = uint8_t(_value & 0xff);
|
||||
m_state.memory[_offset + i] = uint8_t(_value & 0xff);
|
||||
_value >>= 8;
|
||||
}
|
||||
}
|
||||
@@ -553,9 +569,9 @@ void EwasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _c
|
||||
u256 EwasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo)
|
||||
{
|
||||
accessMemory(_offset, _croppedTo);
|
||||
u256 value;
|
||||
u256 value{0};
|
||||
for (size_t i = 0; i < _croppedTo; i++)
|
||||
value = (value << 8) | m_state.memory[_offset + i];
|
||||
value = (value << 8) | m_state.memory[_offset + _croppedTo - 1 - i];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <libyul/AsmDataForward.h>
|
||||
|
||||
#include <libsolutil/CommonData.h>
|
||||
#include <libsolutil/FixedHash.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -61,6 +62,8 @@ struct InterpreterState;
|
||||
*
|
||||
* The main focus is that the generated execution trace is the same for equivalent executions
|
||||
* and likely to be different for non-equivalent executions.
|
||||
*
|
||||
* The type names are following the Ewasm specification (https://github.com/ewasm/design/blob/master/eth_interface.md).
|
||||
*/
|
||||
class EwasmBuiltinInterpreter
|
||||
{
|
||||
@@ -99,6 +102,9 @@ private:
|
||||
/// @returns the memory contents (4 bytes) at the provided address (little-endian).
|
||||
/// Does not adjust msize, use @a accessMemory for that
|
||||
uint32_t readMemoryHalfWord(uint64_t _offset);
|
||||
/// Writes bytes to memory.
|
||||
/// Does not adjust msize, use @a accessMemory for that
|
||||
void writeMemory(uint64_t _offset, bytes const& _value);
|
||||
/// Writes a word to memory (little-endian)
|
||||
/// Does not adjust msize, use @a accessMemory for that
|
||||
void writeMemoryWord(uint64_t _offset, uint64_t _value);
|
||||
@@ -109,14 +115,18 @@ private:
|
||||
/// Does not adjust msize, use @a accessMemory for that
|
||||
void writeMemoryByte(uint64_t _offset, uint8_t _value);
|
||||
|
||||
/// Helper for eth.* builtins. Writes to memory (big-endian) and always returns zero.
|
||||
/// Helper for eth.* builtins. Writes to memory (little-endian) and always returns zero.
|
||||
void writeU256(uint64_t _offset, u256 _value, size_t _croppedTo = 32);
|
||||
void writeU128(uint64_t _offset, u256 _value) { writeU256(_offset, std::move(_value), 16); }
|
||||
void writeAddress(uint64_t _offset, u256 _value) { writeU256(_offset, std::move(_value), 20); }
|
||||
/// Helper for eth.* builtins. Reads from memory (big-endian) and returns the value;
|
||||
/// Helper for eth.* builtins. Writes to memory (as a byte string).
|
||||
void writeBytes32(uint64_t _offset, util::h256 _value) { accessMemory(_offset, 32); writeMemory(_offset, _value.asBytes()); }
|
||||
void writeAddress(uint64_t _offset, util::h160 _value) { accessMemory(_offset, 20); writeMemory(_offset, _value.asBytes()); }
|
||||
/// Helper for eth.* builtins. Reads from memory (little-endian) and returns the value.
|
||||
u256 readU256(uint64_t _offset, size_t _croppedTo = 32);
|
||||
u256 readU128(uint64_t _offset) { return readU256(_offset, 16); }
|
||||
u256 readAddress(uint64_t _offset) { return readU256(_offset, 20); }
|
||||
/// Helper for eth.* builtins. Reads from memory (as a byte string).
|
||||
util::h256 readBytes32(uint64_t _offset) { accessMemory(_offset, 32); return util::h256(readMemory(_offset, 32)); }
|
||||
util::h160 readAddress(uint64_t _offset) { accessMemory(_offset, 20); return util::h160(readMemory(_offset, 20)); }
|
||||
|
||||
void logTrace(evmasm::Instruction _instruction, std::vector<u256> const& _arguments = {}, bytes const& _data = {});
|
||||
/// Appends a log to the trace representing an instruction or similar operation by string,
|
||||
|
||||
Reference in New Issue
Block a user