2018-08-08 19:25:04 +00:00
|
|
|
/*
|
|
|
|
This file is part of solidity.
|
|
|
|
|
|
|
|
solidity is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
solidity is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-07-17 14:54:12 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0
|
2018-08-08 19:25:04 +00:00
|
|
|
/**
|
|
|
|
* @author Alex Beregszaszi
|
|
|
|
* @date 2018
|
|
|
|
* Tests for the assembler.
|
|
|
|
*/
|
2022-11-23 10:51:34 +00:00
|
|
|
#include <test/Common.h>
|
2018-08-08 19:25:04 +00:00
|
|
|
|
|
|
|
#include <libevmasm/Assembly.h>
|
2021-09-22 13:14:31 +00:00
|
|
|
#include <libsolutil/JSON.h>
|
2022-03-02 12:47:04 +00:00
|
|
|
#include <libevmasm/Disassemble.h>
|
2021-09-22 13:14:31 +00:00
|
|
|
#include <libyul/Exceptions.h>
|
2018-08-08 19:25:04 +00:00
|
|
|
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
|
2021-09-22 13:14:31 +00:00
|
|
|
#include <algorithm>
|
|
|
|
#include <memory>
|
2018-08-08 19:25:04 +00:00
|
|
|
#include <string>
|
|
|
|
#include <tuple>
|
|
|
|
|
2019-12-23 15:50:30 +00:00
|
|
|
using namespace solidity::langutil;
|
|
|
|
using namespace solidity::evmasm;
|
2023-08-30 00:08:06 +00:00
|
|
|
using namespace std::string_literals;
|
2018-08-08 19:25:04 +00:00
|
|
|
|
2019-12-23 15:50:30 +00:00
|
|
|
namespace solidity::frontend::test
|
2018-08-08 19:25:04 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
2019-12-23 15:50:30 +00:00
|
|
|
void checkCompilation(evmasm::Assembly const& _assembly)
|
2018-08-08 19:25:04 +00:00
|
|
|
{
|
2018-08-09 08:14:47 +00:00
|
|
|
LinkerObject output = _assembly.assemble();
|
2018-08-08 19:25:04 +00:00
|
|
|
BOOST_CHECK(output.bytecode.size() > 0);
|
|
|
|
BOOST_CHECK(output.toHex().length() > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE(Assembler)
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(all_assembly_items)
|
|
|
|
{
|
2023-08-30 00:08:06 +00:00
|
|
|
std::map<std::string, unsigned> indices = {
|
2020-02-18 09:22:34 +00:00
|
|
|
{ "root.asm", 0 },
|
2022-03-15 20:25:51 +00:00
|
|
|
{ "sub.asm", 1 },
|
|
|
|
{ "verbatim.asm", 2 }
|
2020-02-18 09:22:34 +00:00
|
|
|
};
|
2022-11-23 10:51:34 +00:00
|
|
|
EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
|
|
|
Assembly _assembly{evmVersion, false, {}};
|
2023-08-30 00:08:06 +00:00
|
|
|
auto root_asm = std::make_shared<std::string>("root.asm");
|
2018-12-12 13:43:34 +00:00
|
|
|
_assembly.setSourceLocation({1, 3, root_asm});
|
2018-08-08 19:25:04 +00:00
|
|
|
|
2022-11-23 10:51:34 +00:00
|
|
|
Assembly _subAsm{evmVersion, false, {}};
|
2023-08-30 00:08:06 +00:00
|
|
|
auto sub_asm = std::make_shared<std::string>("sub.asm");
|
2018-12-12 13:43:34 +00:00
|
|
|
_subAsm.setSourceLocation({6, 8, sub_asm});
|
2022-03-15 20:25:51 +00:00
|
|
|
|
2022-11-23 10:51:34 +00:00
|
|
|
Assembly _verbatimAsm(evmVersion, true, "");
|
2023-08-30 00:08:06 +00:00
|
|
|
auto verbatim_asm = std::make_shared<std::string>("verbatim.asm");
|
2022-03-15 20:25:51 +00:00
|
|
|
_verbatimAsm.setSourceLocation({8, 18, verbatim_asm});
|
|
|
|
|
2020-03-12 16:32:10 +00:00
|
|
|
// PushImmutable
|
|
|
|
_subAsm.appendImmutable("someImmutable");
|
2022-03-15 20:25:51 +00:00
|
|
|
_subAsm.append(AssemblyItem(PushTag, 0));
|
2018-08-08 19:25:04 +00:00
|
|
|
_subAsm.append(Instruction::INVALID);
|
2023-08-30 00:08:06 +00:00
|
|
|
std::shared_ptr<Assembly> _subAsmPtr = std::make_shared<Assembly>(_subAsm);
|
2018-08-08 19:25:04 +00:00
|
|
|
|
2022-03-15 20:25:51 +00:00
|
|
|
_verbatimAsm.appendVerbatim({0xff,0xff}, 0, 0);
|
|
|
|
_verbatimAsm.appendVerbatim({0x74, 0x65, 0x73, 0x74}, 0, 1);
|
|
|
|
_verbatimAsm.append(Instruction::MSTORE);
|
2023-08-30 00:08:06 +00:00
|
|
|
std::shared_ptr<Assembly> _verbatimAsmPtr = std::make_shared<Assembly>(_verbatimAsm);
|
2022-03-15 20:25:51 +00:00
|
|
|
|
2018-08-08 19:25:04 +00:00
|
|
|
// Tag
|
2018-08-09 08:14:47 +00:00
|
|
|
auto tag = _assembly.newTag();
|
|
|
|
_assembly.append(tag);
|
2018-08-08 19:25:04 +00:00
|
|
|
// Operation
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.append(u256(1));
|
|
|
|
_assembly.append(u256(2));
|
2018-08-08 19:25:04 +00:00
|
|
|
// Push
|
2022-03-15 20:25:51 +00:00
|
|
|
auto keccak256 = AssemblyItem(Instruction::KECCAK256);
|
|
|
|
_assembly.m_currentModifierDepth = 1;
|
|
|
|
_assembly.append(keccak256);
|
|
|
|
_assembly.m_currentModifierDepth = 0;
|
2018-08-08 19:25:04 +00:00
|
|
|
// PushProgramSize
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.appendProgramSize();
|
2018-08-08 19:25:04 +00:00
|
|
|
// PushLibraryAddress
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.appendLibraryAddress("someLibrary");
|
2018-08-08 19:25:04 +00:00
|
|
|
// PushTag + Operation
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.appendJump(tag);
|
2018-08-08 19:25:04 +00:00
|
|
|
// PushData
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.append(bytes{0x1, 0x2, 0x3, 0x4});
|
2018-08-08 19:25:04 +00:00
|
|
|
// PushSubSize
|
2018-08-09 08:14:47 +00:00
|
|
|
auto sub = _assembly.appendSubroutine(_subAsmPtr);
|
2018-08-08 19:25:04 +00:00
|
|
|
// PushSub
|
2020-06-02 13:10:14 +00:00
|
|
|
_assembly.pushSubroutineOffset(static_cast<size_t>(sub.data()));
|
2022-03-15 20:25:51 +00:00
|
|
|
// PushSubSize
|
|
|
|
auto verbatim_sub = _assembly.appendSubroutine(_verbatimAsmPtr);
|
|
|
|
// PushSub
|
|
|
|
_assembly.pushSubroutineOffset(static_cast<size_t>(verbatim_sub.data()));
|
2018-08-08 19:25:04 +00:00
|
|
|
// PushDeployTimeAddress
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.append(PushDeployTimeAddress);
|
2020-03-12 16:32:10 +00:00
|
|
|
// AssignImmutable.
|
2020-10-14 11:20:20 +00:00
|
|
|
// Note that since there is no reference to "someOtherImmutable", this will just compile to two POPs in the hex output.
|
2020-03-12 16:32:10 +00:00
|
|
|
_assembly.appendImmutableAssignment("someOtherImmutable");
|
|
|
|
_assembly.append(u256(2));
|
|
|
|
_assembly.appendImmutableAssignment("someImmutable");
|
2018-08-08 19:25:04 +00:00
|
|
|
// Operation
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.append(Instruction::STOP);
|
2021-06-08 14:35:37 +00:00
|
|
|
_assembly.appendToAuxiliaryData(bytes{0x42, 0x66});
|
|
|
|
_assembly.appendToAuxiliaryData(bytes{0xee, 0xaa});
|
2018-08-09 08:14:47 +00:00
|
|
|
|
2022-03-15 20:25:51 +00:00
|
|
|
_assembly.m_currentModifierDepth = 2;
|
|
|
|
_assembly.appendJump(tag);
|
|
|
|
_assembly.m_currentModifierDepth = 0;
|
|
|
|
|
2018-08-09 08:14:47 +00:00
|
|
|
checkCompilation(_assembly);
|
2018-08-08 19:25:04 +00:00
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.assemble().toHex(),
|
2022-03-15 20:25:51 +00:00
|
|
|
"5b6001600220607f73__$bf005014d9d0f534b8fcb268bd84c491a2$__"
|
|
|
|
"60005660776024604c600760707300000000000000000000000000000000000000005050"
|
2020-10-14 15:31:01 +00:00
|
|
|
"600260010152"
|
2022-03-15 20:25:51 +00:00
|
|
|
"006000"
|
|
|
|
"56fe"
|
2020-03-12 16:32:10 +00:00
|
|
|
"7f0000000000000000000000000000000000000000000000000000000000000000"
|
2022-03-15 20:25:51 +00:00
|
|
|
"6000feffff7465737452010203044266eeaa"
|
2018-08-08 19:25:04 +00:00
|
|
|
);
|
|
|
|
BOOST_CHECK_EQUAL(
|
2018-08-09 08:14:47 +00:00
|
|
|
_assembly.assemblyString(),
|
2018-08-08 19:25:04 +00:00
|
|
|
" /* \"root.asm\":1:3 */\n"
|
|
|
|
"tag_1:\n"
|
2018-12-05 21:11:31 +00:00
|
|
|
" keccak256(0x02, 0x01)\n"
|
2018-08-08 19:25:04 +00:00
|
|
|
" bytecodeSize\n"
|
|
|
|
" linkerSymbol(\"bf005014d9d0f534b8fcb268bd84c491a2380f4acd260d1ccfe9cd8201f7e994\")\n"
|
|
|
|
" jump(tag_1)\n"
|
|
|
|
" data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b\n"
|
|
|
|
" dataSize(sub_0)\n"
|
|
|
|
" dataOffset(sub_0)\n"
|
2022-03-15 20:25:51 +00:00
|
|
|
" dataSize(sub_1)\n"
|
|
|
|
" dataOffset(sub_1)\n"
|
2018-08-08 19:25:04 +00:00
|
|
|
" deployTimeAddress()\n"
|
2020-03-12 16:32:10 +00:00
|
|
|
" assignImmutable(\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\")\n"
|
|
|
|
" 0x02\n"
|
|
|
|
" assignImmutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
|
2018-08-08 19:25:04 +00:00
|
|
|
" stop\n"
|
2022-03-15 20:25:51 +00:00
|
|
|
" jump(tag_1)\n"
|
2018-08-08 19:25:04 +00:00
|
|
|
"stop\n"
|
|
|
|
"data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b 01020304\n"
|
|
|
|
"\n"
|
|
|
|
"sub_0: assembly {\n"
|
|
|
|
" /* \"sub.asm\":6:8 */\n"
|
2020-03-12 16:32:10 +00:00
|
|
|
" immutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
|
2022-03-15 20:25:51 +00:00
|
|
|
" tag_0\n"
|
2018-08-08 19:25:04 +00:00
|
|
|
" invalid\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
2022-03-15 20:25:51 +00:00
|
|
|
"sub_1: assembly {\n"
|
|
|
|
" /* \"verbatim.asm\":8:18 */\n"
|
|
|
|
" verbatimbytecode_ffff\n"
|
|
|
|
" verbatimbytecode_74657374\n"
|
|
|
|
" mstore\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
2018-08-08 19:25:04 +00:00
|
|
|
"auxdata: 0x4266eeaa\n"
|
|
|
|
);
|
2023-08-30 00:08:06 +00:00
|
|
|
std::string json{
|
2020-02-18 09:22:34 +00:00
|
|
|
"{\".auxdata\":\"4266eeaa\",\".code\":["
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"tag\",\"source\":0,\"value\":\"1\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"JUMPDEST\",\"source\":0},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"1\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"2\"},"
|
2022-03-15 20:25:51 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"modifierDepth\":1,\"name\":\"KECCAK256\",\"source\":0},"
|
2020-02-18 09:22:34 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSHSIZE\",\"source\":0},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSHLIB\",\"source\":0,\"value\":\"someLibrary\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [tag]\",\"source\":0,\"value\":\"1\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"JUMP\",\"source\":0},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH data\",\"source\":0,\"value\":\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
2022-03-15 20:25:51 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000001\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000001\"},"
|
2020-02-18 09:22:34 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSHDEPLOYADDRESS\",\"source\":0},"
|
2020-03-12 16:32:10 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someOtherImmutable\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"2\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someImmutable\"},"
|
2022-03-15 20:25:51 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"STOP\",\"source\":0},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"modifierDepth\":2,\"name\":\"PUSH [tag]\",\"source\":0,\"value\":\"1\"},{\"begin\":1,\"end\":3,\"modifierDepth\":2,\"name\":\"JUMP\",\"source\":0}"
|
2020-03-12 16:32:10 +00:00
|
|
|
"],\".data\":{\"0\":{\".code\":["
|
|
|
|
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someImmutable\"},"
|
2022-03-15 20:25:51 +00:00
|
|
|
"{\"begin\":6,\"end\":8,\"name\":\"PUSH [ErrorTag]\",\"source\":1},"
|
2020-03-12 16:32:10 +00:00
|
|
|
"{\"begin\":6,\"end\":8,\"name\":\"INVALID\",\"source\":1}"
|
2022-03-15 20:25:51 +00:00
|
|
|
"]},"
|
|
|
|
"\"1\":{\".code\":["
|
|
|
|
"{\"begin\":8,\"end\":18,\"name\":\"VERBATIM\",\"source\":2,\"value\":\"ffff\"},"
|
|
|
|
"{\"begin\":8,\"end\":18,\"name\":\"VERBATIM\",\"source\":2,\"value\":\"74657374\"},"
|
|
|
|
"{\"begin\":8,\"end\":18,\"name\":\"MSTORE\",\"source\":2}"
|
|
|
|
"]},\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\":\"01020304\"},\"sourceList\":[\"root.asm\",\"sub.asm\",\"verbatim.asm\"]}"
|
|
|
|
};
|
|
|
|
Json::Value jsonValue;
|
|
|
|
BOOST_CHECK(util::jsonParseStrict(json, jsonValue));
|
|
|
|
BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assembly.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue));
|
2020-03-12 16:32:10 +00:00
|
|
|
}
|
|
|
|
|
2021-09-22 13:14:31 +00:00
|
|
|
BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps)
|
|
|
|
{
|
2022-11-23 10:51:34 +00:00
|
|
|
EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
2021-09-22 13:14:31 +00:00
|
|
|
// Tests for 1, 2, 3 number of immutables.
|
|
|
|
for (int numImmutables = 1; numImmutables <= 3; ++numImmutables)
|
|
|
|
{
|
2023-08-30 00:08:06 +00:00
|
|
|
BOOST_TEST_MESSAGE("NumImmutables: "s + std::to_string(numImmutables));
|
2021-09-22 13:14:31 +00:00
|
|
|
// Tests for the cases 1, 2, 3 occurrences of an immutable reference.
|
|
|
|
for (int numActualRefs = 1; numActualRefs <= 3; ++numActualRefs)
|
|
|
|
{
|
2023-08-30 00:08:06 +00:00
|
|
|
BOOST_TEST_MESSAGE("NumActualRefs: "s + std::to_string(numActualRefs));
|
2021-09-22 13:14:31 +00:00
|
|
|
auto const NumExpectedMappings =
|
|
|
|
(
|
|
|
|
2 + // PUSH <a> PUSH <b>
|
2023-08-19 23:15:08 +00:00
|
|
|
(numActualRefs - 1) * 5 + // DUP DUP PUSH <n> ADD MSTORE
|
|
|
|
3 // PUSH <n> ADD MSTORE
|
2021-09-22 13:14:31 +00:00
|
|
|
) * numImmutables;
|
|
|
|
|
|
|
|
auto constexpr NumSubs = 1;
|
|
|
|
auto constexpr NumOpcodesWithoutMappings =
|
|
|
|
NumSubs + // PUSH <addr> for every sub assembly
|
|
|
|
1; // INVALID
|
|
|
|
|
2023-08-30 00:08:06 +00:00
|
|
|
auto assemblyName = std::make_shared<std::string>("root.asm");
|
|
|
|
auto subName = std::make_shared<std::string>("sub.asm");
|
2021-09-22 13:14:31 +00:00
|
|
|
|
2023-08-30 00:08:06 +00:00
|
|
|
std::map<std::string, unsigned> indices = {
|
2021-09-22 13:14:31 +00:00
|
|
|
{ *assemblyName, 0 },
|
|
|
|
{ *subName, 1 }
|
|
|
|
};
|
|
|
|
|
2023-08-30 00:08:06 +00:00
|
|
|
auto subAsm = std::make_shared<Assembly>(evmVersion, false, std::string{});
|
2021-09-22 13:14:31 +00:00
|
|
|
for (char i = 0; i < numImmutables; ++i)
|
|
|
|
{
|
|
|
|
for (int r = 0; r < numActualRefs; ++r)
|
|
|
|
{
|
|
|
|
subAsm->setSourceLocation(SourceLocation{10*i, 10*i + 6 + r, subName});
|
2023-08-30 00:08:06 +00:00
|
|
|
subAsm->appendImmutable(std::string(1, char('a' + i))); // "a", "b", ...
|
2021-09-22 13:14:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-23 10:51:34 +00:00
|
|
|
Assembly assembly{evmVersion, true, {}};
|
2021-09-22 13:14:31 +00:00
|
|
|
for (char i = 1; i <= numImmutables; ++i)
|
|
|
|
{
|
|
|
|
assembly.setSourceLocation({10*i, 10*i + 3+i, assemblyName});
|
|
|
|
assembly.append(u256(0x71)); // immutble value
|
|
|
|
assembly.append(u256(0)); // target... modules?
|
2023-08-30 00:08:06 +00:00
|
|
|
assembly.appendImmutableAssignment(std::string(1, char('a' + i - 1)));
|
2021-09-22 13:14:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
assembly.appendSubroutine(subAsm);
|
|
|
|
|
|
|
|
checkCompilation(assembly);
|
|
|
|
|
2023-08-30 00:08:06 +00:00
|
|
|
std::string const sourceMappings = AssemblyItem::computeSourceMapping(assembly.items(), indices);
|
2021-09-22 13:14:31 +00:00
|
|
|
auto const numberOfMappings = std::count(sourceMappings.begin(), sourceMappings.end(), ';');
|
|
|
|
|
|
|
|
LinkerObject const& obj = assembly.assemble();
|
2023-08-30 00:08:06 +00:00
|
|
|
std::string const disassembly = disassemble(obj.bytecode, evmVersion, "\n");
|
2021-09-22 13:14:31 +00:00
|
|
|
auto const numberOfOpcodes = std::count(disassembly.begin(), disassembly.end(), '\n');
|
|
|
|
|
|
|
|
#if 0 // {{{ debug prints
|
|
|
|
{
|
|
|
|
LinkerObject const& subObj = assembly.sub(0).assemble();
|
2023-08-30 00:08:06 +00:00
|
|
|
std::string const subDisassembly = disassemble(subObj.bytecode, "\n");
|
|
|
|
std::cout << '\n';
|
|
|
|
std::cout << "### immutables: " << numImmutables << ", refs: " << numActualRefs << '\n';
|
|
|
|
std::cout << " - srcmap: \"" << sourceMappings << "\"\n";
|
|
|
|
std::cout << " - src mappings: " << numberOfMappings << '\n';
|
|
|
|
std::cout << " - opcodes: " << numberOfOpcodes << '\n';
|
|
|
|
std::cout << " - subs: " << assembly.numSubs() << '\n';
|
|
|
|
std::cout << " - sub opcodes " << std::count(subDisassembly.begin(), subDisassembly.end(), '\n') << '\n';
|
|
|
|
std::cout << " - sub srcmaps " << AssemblyItem::computeSourceMapping(subAsm->items(), indices) << '\n';
|
|
|
|
std::cout << " - main bytecode:\n\t" << disassemble(obj.bytecode, "\n\t");
|
|
|
|
std::cout << "\r - sub bytecode:\n\t" << disassemble(subObj.bytecode, "\n\t");
|
2021-09-22 13:14:31 +00:00
|
|
|
}
|
|
|
|
#endif // }}}
|
|
|
|
|
|
|
|
BOOST_REQUIRE_EQUAL(NumExpectedMappings, numberOfMappings);
|
|
|
|
BOOST_REQUIRE_EQUAL(NumExpectedMappings, numberOfOpcodes - NumOpcodesWithoutMappings);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-12 16:32:10 +00:00
|
|
|
BOOST_AUTO_TEST_CASE(immutable)
|
|
|
|
{
|
2023-08-30 00:08:06 +00:00
|
|
|
std::map<std::string, unsigned> indices = {
|
2020-03-12 16:32:10 +00:00
|
|
|
{ "root.asm", 0 },
|
|
|
|
{ "sub.asm", 1 }
|
|
|
|
};
|
2022-11-23 10:51:34 +00:00
|
|
|
EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
|
|
|
Assembly _assembly{evmVersion, true, {}};
|
2023-08-30 00:08:06 +00:00
|
|
|
auto root_asm = std::make_shared<std::string>("root.asm");
|
2020-03-12 16:32:10 +00:00
|
|
|
_assembly.setSourceLocation({1, 3, root_asm});
|
|
|
|
|
2022-11-23 10:51:34 +00:00
|
|
|
Assembly _subAsm{evmVersion, false, {}};
|
2023-08-30 00:08:06 +00:00
|
|
|
auto sub_asm = std::make_shared<std::string>("sub.asm");
|
2020-03-12 16:32:10 +00:00
|
|
|
_subAsm.setSourceLocation({6, 8, sub_asm});
|
|
|
|
_subAsm.appendImmutable("someImmutable");
|
|
|
|
_subAsm.appendImmutable("someOtherImmutable");
|
|
|
|
_subAsm.appendImmutable("someImmutable");
|
2023-08-30 00:08:06 +00:00
|
|
|
std::shared_ptr<Assembly> _subAsmPtr = std::make_shared<Assembly>(_subAsm);
|
2020-03-12 16:32:10 +00:00
|
|
|
|
|
|
|
_assembly.append(u256(42));
|
2020-10-14 11:20:20 +00:00
|
|
|
_assembly.append(u256(0));
|
2020-03-12 16:32:10 +00:00
|
|
|
_assembly.appendImmutableAssignment("someImmutable");
|
|
|
|
_assembly.append(u256(23));
|
2020-10-14 11:20:20 +00:00
|
|
|
_assembly.append(u256(0));
|
2020-03-12 16:32:10 +00:00
|
|
|
_assembly.appendImmutableAssignment("someOtherImmutable");
|
|
|
|
|
|
|
|
auto sub = _assembly.appendSubroutine(_subAsmPtr);
|
2020-06-02 13:10:14 +00:00
|
|
|
_assembly.pushSubroutineOffset(static_cast<size_t>(sub.data()));
|
2020-03-12 16:32:10 +00:00
|
|
|
|
|
|
|
checkCompilation(_assembly);
|
|
|
|
|
2023-08-30 00:08:06 +00:00
|
|
|
std::string genericPush0 = evmVersion.hasPush0() ? "5f" : "6000";
|
2023-04-09 14:40:09 +00:00
|
|
|
// PUSH1 0x1b v/s PUSH1 0x19
|
2023-08-30 00:08:06 +00:00
|
|
|
std::string dataOffset = evmVersion.hasPush0() ? "6019" : "601b" ;
|
2023-04-09 14:40:09 +00:00
|
|
|
|
2020-03-12 16:32:10 +00:00
|
|
|
BOOST_CHECK_EQUAL(
|
|
|
|
_assembly.assemble().toHex(),
|
|
|
|
// root.asm
|
|
|
|
// assign "someImmutable"
|
2023-04-09 14:40:09 +00:00
|
|
|
"602a" + // PUSH1 42 - value for someImmutable
|
|
|
|
genericPush0 + // PUSH1 0 - offset of code into which to insert the immutable
|
2020-10-14 11:20:20 +00:00
|
|
|
"8181" // DUP2 DUP2
|
2020-03-12 16:32:10 +00:00
|
|
|
"6001" // PUSH1 1 - offset of first someImmutable in sub_0
|
2020-10-14 11:20:20 +00:00
|
|
|
"01" // ADD - add offset of immutable to offset of code
|
2020-03-12 16:32:10 +00:00
|
|
|
"52" // MSTORE
|
|
|
|
"6043" // PUSH1 67 - offset of second someImmutable in sub_0
|
2020-10-14 11:20:20 +00:00
|
|
|
"01" // ADD - add offset of immutable to offset of code
|
2020-03-12 16:32:10 +00:00
|
|
|
"52" // MSTORE
|
|
|
|
// assign "someOtherImmutable"
|
2023-04-09 14:40:09 +00:00
|
|
|
"6017" + // PUSH1 23 - value for someOtherImmutable
|
|
|
|
genericPush0 + // PUSH1 0 - offset of code into which to insert the immutable
|
2020-03-12 16:32:10 +00:00
|
|
|
"6022" // PUSH1 34 - offset of someOtherImmutable in sub_0
|
2020-10-14 11:20:20 +00:00
|
|
|
"01" // ADD - add offset of immutable to offset of code
|
2020-03-12 16:32:10 +00:00
|
|
|
"52" // MSTORE
|
2023-04-09 14:40:09 +00:00
|
|
|
"6063" + // PUSH1 0x63 - dataSize(sub_0)
|
|
|
|
dataOffset + // PUSH1 0x23 - dataOffset(sub_0)
|
2020-03-12 16:32:10 +00:00
|
|
|
"fe" // INVALID
|
|
|
|
// end of root.asm
|
|
|
|
// sub.asm
|
|
|
|
"7f0000000000000000000000000000000000000000000000000000000000000000" // PUSHIMMUTABLE someImmutable - data at offset 1
|
|
|
|
"7f0000000000000000000000000000000000000000000000000000000000000000" // PUSHIMMUTABLE someOtherImmutable - data at offset 34
|
|
|
|
"7f0000000000000000000000000000000000000000000000000000000000000000" // PUSHIMMUTABLE someImmutable - data at offset 67
|
|
|
|
);
|
|
|
|
BOOST_CHECK_EQUAL(
|
|
|
|
_assembly.assemblyString(),
|
|
|
|
" /* \"root.asm\":1:3 */\n"
|
|
|
|
" 0x2a\n"
|
2020-10-14 11:20:20 +00:00
|
|
|
" 0x00\n"
|
2020-03-12 16:32:10 +00:00
|
|
|
" assignImmutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
|
|
|
|
" 0x17\n"
|
2020-10-14 11:20:20 +00:00
|
|
|
" 0x00\n"
|
2020-03-12 16:32:10 +00:00
|
|
|
" assignImmutable(\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\")\n"
|
|
|
|
" dataSize(sub_0)\n"
|
|
|
|
" dataOffset(sub_0)\n"
|
|
|
|
"stop\n"
|
|
|
|
"\n"
|
|
|
|
"sub_0: assembly {\n"
|
|
|
|
" /* \"sub.asm\":6:8 */\n"
|
|
|
|
" immutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
|
|
|
|
" immutable(\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\")\n"
|
|
|
|
" immutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
BOOST_CHECK_EQUAL(
|
|
|
|
util::jsonCompactPrint(_assembly.assemblyJSON(indices)),
|
|
|
|
"{\".code\":["
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"2A\"},"
|
2020-10-14 11:20:20 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"},"
|
2020-03-12 16:32:10 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someImmutable\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"17\"},"
|
2020-10-14 11:20:20 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"},"
|
2020-03-12 16:32:10 +00:00
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someOtherImmutable\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
|
|
|
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}"
|
|
|
|
"],\".data\":{\"0\":{\".code\":["
|
|
|
|
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someImmutable\"},"
|
|
|
|
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someOtherImmutable\"},"
|
|
|
|
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someImmutable\"}"
|
2022-03-15 20:25:51 +00:00
|
|
|
"]}},\"sourceList\":[\"root.asm\",\"sub.asm\"]}"
|
2018-08-08 19:25:04 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-06-17 09:17:35 +00:00
|
|
|
BOOST_AUTO_TEST_CASE(subobject_encode_decode)
|
|
|
|
{
|
2022-11-23 10:51:34 +00:00
|
|
|
EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
|
|
|
Assembly assembly{evmVersion, true, {}};
|
2020-06-17 09:17:35 +00:00
|
|
|
|
2023-08-30 00:08:06 +00:00
|
|
|
std::shared_ptr<Assembly> subAsmPtr = std::make_shared<Assembly>(evmVersion, false, std::string{});
|
|
|
|
std::shared_ptr<Assembly> subSubAsmPtr = std::make_shared<Assembly>(evmVersion, false, std::string{});
|
2020-06-17 09:17:35 +00:00
|
|
|
|
|
|
|
assembly.appendSubroutine(subAsmPtr);
|
|
|
|
subAsmPtr->appendSubroutine(subSubAsmPtr);
|
|
|
|
|
|
|
|
BOOST_CHECK(assembly.encodeSubPath({0}) == 0);
|
|
|
|
BOOST_REQUIRE_THROW(assembly.encodeSubPath({1}), solidity::evmasm::AssemblyException);
|
|
|
|
BOOST_REQUIRE_THROW(assembly.decodeSubPath(1), solidity::evmasm::AssemblyException);
|
|
|
|
|
2023-08-30 00:08:06 +00:00
|
|
|
std::vector<size_t> subPath{0, 0};
|
2020-06-17 09:17:35 +00:00
|
|
|
BOOST_CHECK(assembly.decodeSubPath(assembly.encodeSubPath(subPath)) == subPath);
|
|
|
|
}
|
|
|
|
|
2018-08-08 19:25:04 +00:00
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|
|
|
|
|
|
|
|
} // end namespaces
|