mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10258 from ethereum/develop
Merge develop into breaking.
This commit is contained in:
commit
0a31a6bc36
@ -14,7 +14,7 @@ indent_size = 4
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
[*.sol]
|
[*.{sol,yul}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
|
@ -19,10 +19,13 @@
|
|||||||
* Component that transforms internal Wasm representation to text.
|
* Component that transforms internal Wasm representation to text.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <libyul/backends/wasm/BinaryTransform.h>
|
||||||
#include <libyul/backends/wasm/TextTransform.h>
|
#include <libyul/backends/wasm/TextTransform.h>
|
||||||
|
|
||||||
#include <libyul/Exceptions.h>
|
#include <libyul/Exceptions.h>
|
||||||
|
|
||||||
|
#include <libsolutil/CommonData.h>
|
||||||
|
#include <libsolutil/Keccak256.h>
|
||||||
#include <libsolutil/StringUtils.h>
|
#include <libsolutil/StringUtils.h>
|
||||||
#include <libsolutil/Visitor.h>
|
#include <libsolutil/Visitor.h>
|
||||||
|
|
||||||
@ -39,16 +42,27 @@ using namespace solidity::util;
|
|||||||
string TextTransform::run(wasm::Module const& _module)
|
string TextTransform::run(wasm::Module const& _module)
|
||||||
{
|
{
|
||||||
string ret = "(module\n";
|
string ret = "(module\n";
|
||||||
for (auto const& sub: _module.subModules)
|
for (auto const& [name, module]: _module.subModules)
|
||||||
ret +=
|
ret +=
|
||||||
" ;; sub-module \"" +
|
" ;; custom section for sub-module\n"
|
||||||
sub.first +
|
" ;; The Keccak-256 hash of the text representation of \"" +
|
||||||
"\" will be encoded as custom section in binary here, but is skipped in text mode.\n";
|
name +
|
||||||
for (auto const& data: _module.customSections)
|
"\": " +
|
||||||
|
toHex(keccak256(run(module))) +
|
||||||
|
"\n"
|
||||||
|
" ;; (@custom \"" +
|
||||||
|
name +
|
||||||
|
"\" \"" +
|
||||||
|
toHex(BinaryTransform::run(module)) +
|
||||||
|
"\")\n";
|
||||||
|
for (auto const& [name, data]: _module.customSections)
|
||||||
ret +=
|
ret +=
|
||||||
" ;; custom-section \"" +
|
" ;; custom section for data\n"
|
||||||
data.first +
|
" ;; (@custom \"" +
|
||||||
"\" will be encoded as custom section in binary here, but is skipped in text mode.\n";
|
name +
|
||||||
|
"\" \"" +
|
||||||
|
toHex(data) +
|
||||||
|
"\")\n";
|
||||||
for (wasm::FunctionImport const& imp: _module.imports)
|
for (wasm::FunctionImport const& imp: _module.imports)
|
||||||
{
|
{
|
||||||
ret += " (import \"" + imp.module + "\" \"" + imp.externalName + "\" (func $" + imp.internalName;
|
ret += " (import \"" + imp.module + "\" \"" + imp.externalName + "\" (func $" + imp.internalName;
|
||||||
|
@ -261,12 +261,6 @@ printTask "Running general commandline tests..."
|
|||||||
|
|
||||||
inputFiles="$(find "${tdir}" -name 'input.*' -type f -exec printf "%s\n" "{}" \;)"
|
inputFiles="$(find "${tdir}" -name 'input.*' -type f -exec printf "%s\n" "{}" \;)"
|
||||||
inputCount="$(echo "${inputFiles}" | wc -l)"
|
inputCount="$(echo "${inputFiles}" | wc -l)"
|
||||||
if (( ${inputCount} == 0 ))
|
|
||||||
then
|
|
||||||
printError "No input files found."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (( ${inputCount} > 1 ))
|
if (( ${inputCount} > 1 ))
|
||||||
then
|
then
|
||||||
printError "Ambiguous input. Found input files in multiple formats:"
|
printError "Ambiguous input. Found input files in multiple formats:"
|
||||||
@ -277,6 +271,11 @@ printTask "Running general commandline tests..."
|
|||||||
# Use printf to get rid of the trailing newline
|
# Use printf to get rid of the trailing newline
|
||||||
inputFile=$(printf "%s" "${inputFiles}")
|
inputFile=$(printf "%s" "${inputFiles}")
|
||||||
|
|
||||||
|
# If no files specified, assume input.sol as the default
|
||||||
|
if [ -z "${inputFile}" ]; then
|
||||||
|
inputFile="${tdir}/input.sol"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${inputFile}" = "${tdir}/input.json" ]
|
if [ "${inputFile}" = "${tdir}/input.json" ]
|
||||||
then
|
then
|
||||||
stdin="${inputFile}"
|
stdin="${inputFile}"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
{"contracts":{"A":{"C":{"ewasm":{"wast":"(module
|
{"contracts":{"A":{"C":{"ewasm":{"wast":"(module
|
||||||
;; sub-module \"C_2_deployed\" will be encoded as custom section in binary here, but is skipped in text mode.
|
;; custom section for sub-module
|
||||||
|
;; The Keccak-256 hash of the text representation of \"C_2_deployed\": f03f5b9154b9eb6803a947177e38e92e2860de95e90ba0e75eb71a58f18ed589
|
||||||
|
;; (@custom \"C_2_deployed\" \"0061736d0100000001160460000060017e017e60047e7e7e7e017f60027f7f0002130108657468657265756d067265766572740003030504000201010503010001060100071102066d656d6f72790200046d61696e00010ab60204ca0104017e027f057e037f02404200210020002000200042c00010022101200141c0006a210220022001490440000b20001003421086210320032000421088100384422086210420042000422088100484210520022005370000200241086a2005370000200241106a20053700004280011003421086210620064280014210881003844220862107200241186a2007428001422088100484370000200020002000200010022108200020002000200010022109200941c0006a210a200a2009490440000b200a200810000b0b2901017f024042002000200184200284520440000b42002003422088520440000b2003a721040b20040b1f01017e024020004208864280fe0383200042088842ff01838421010b20010b1e01027e02402000100342108621022002200042108810038421010b20010b\")
|
||||||
(import \"ethereum\" \"codeCopy\" (func $eth.codeCopy (param i32 i32 i32)))
|
(import \"ethereum\" \"codeCopy\" (func $eth.codeCopy (param i32 i32 i32)))
|
||||||
(import \"ethereum\" \"revert\" (func $eth.revert (param i32 i32)))
|
(import \"ethereum\" \"revert\" (func $eth.revert (param i32 i32)))
|
||||||
(import \"ethereum\" \"getCallValue\" (func $eth.getCallValue (param i32)))
|
(import \"ethereum\" \"getCallValue\" (func $eth.getCallValue (param i32)))
|
||||||
|
@ -44,6 +44,7 @@ ObjectCompilerTest::ObjectCompilerTest(string const& _filename):
|
|||||||
{
|
{
|
||||||
m_source = m_reader.source();
|
m_source = m_reader.source();
|
||||||
m_optimize = m_reader.boolSetting("optimize", false);
|
m_optimize = m_reader.boolSetting("optimize", false);
|
||||||
|
m_wasm = m_reader.boolSetting("wasm", false);
|
||||||
m_expectation = m_reader.simpleExpectations();
|
m_expectation = m_reader.simpleExpectations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ TestCase::TestResult ObjectCompilerTest::run(ostream& _stream, string const& _li
|
|||||||
{
|
{
|
||||||
AssemblyStack stack(
|
AssemblyStack stack(
|
||||||
EVMVersion(),
|
EVMVersion(),
|
||||||
AssemblyStack::Language::StrictAssembly,
|
m_wasm ? AssemblyStack::Language::Ewasm : AssemblyStack::Language::StrictAssembly,
|
||||||
m_optimize ? OptimiserSettings::full() : OptimiserSettings::minimal()
|
m_optimize ? OptimiserSettings::full() : OptimiserSettings::minimal()
|
||||||
);
|
);
|
||||||
if (!stack.parseAndAnalyze("source", m_source))
|
if (!stack.parseAndAnalyze("source", m_source))
|
||||||
@ -62,22 +63,33 @@ TestCase::TestResult ObjectCompilerTest::run(ostream& _stream, string const& _li
|
|||||||
}
|
}
|
||||||
stack.optimize();
|
stack.optimize();
|
||||||
|
|
||||||
MachineAssemblyObject obj = stack.assemble(AssemblyStack::Machine::EVM);
|
if (m_wasm)
|
||||||
solAssert(obj.bytecode, "");
|
{
|
||||||
solAssert(obj.sourceMappings, "");
|
MachineAssemblyObject obj = stack.assemble(AssemblyStack::Machine::Ewasm);
|
||||||
|
solAssert(obj.bytecode, "");
|
||||||
|
|
||||||
m_obtainedResult = "Assembly:\n" + obj.assembly;
|
m_obtainedResult = "Text:\n" + obj.assembly + "\n";
|
||||||
if (obj.bytecode->bytecode.empty())
|
m_obtainedResult += "Binary:\n" + toHex(obj.bytecode->bytecode) + "\n";
|
||||||
m_obtainedResult += "-- empty bytecode --\n";
|
}
|
||||||
else
|
else
|
||||||
m_obtainedResult +=
|
{
|
||||||
"Bytecode: " +
|
MachineAssemblyObject obj = stack.assemble(AssemblyStack::Machine::EVM);
|
||||||
toHex(obj.bytecode->bytecode) +
|
solAssert(obj.bytecode, "");
|
||||||
"\nOpcodes: " +
|
solAssert(obj.sourceMappings, "");
|
||||||
boost::trim_copy(evmasm::disassemble(obj.bytecode->bytecode)) +
|
|
||||||
"\nSourceMappings:" +
|
m_obtainedResult = "Assembly:\n" + obj.assembly;
|
||||||
(obj.sourceMappings->empty() ? "" : " " + *obj.sourceMappings) +
|
if (obj.bytecode->bytecode.empty())
|
||||||
"\n";
|
m_obtainedResult += "-- empty bytecode --\n";
|
||||||
|
else
|
||||||
|
m_obtainedResult +=
|
||||||
|
"Bytecode: " +
|
||||||
|
toHex(obj.bytecode->bytecode) +
|
||||||
|
"\nOpcodes: " +
|
||||||
|
boost::trim_copy(evmasm::disassemble(obj.bytecode->bytecode)) +
|
||||||
|
"\nSourceMappings:" +
|
||||||
|
(obj.sourceMappings->empty() ? "" : " " + *obj.sourceMappings) +
|
||||||
|
"\n";
|
||||||
|
}
|
||||||
|
|
||||||
return checkResult(_stream, _linePrefix, _formatted);
|
return checkResult(_stream, _linePrefix, _formatted);
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ private:
|
|||||||
static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors);
|
static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors);
|
||||||
|
|
||||||
bool m_optimize = false;
|
bool m_optimize = false;
|
||||||
|
bool m_wasm = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
22
test/libyul/objectCompiler/wasm/no_main_function.yul
Normal file
22
test/libyul/objectCompiler/wasm/no_main_function.yul
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
function not_main() {
|
||||||
|
i64.drop(i64.add(0, 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// wasm: true
|
||||||
|
// ----
|
||||||
|
// Text:
|
||||||
|
// (module
|
||||||
|
// (memory $memory (export "memory") 1)
|
||||||
|
//
|
||||||
|
// (func $not_main
|
||||||
|
// (block $label_
|
||||||
|
// (drop (i64.add (i64.const 0) (i64.const 1)))
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// Binary:
|
||||||
|
// 0061736d01000000010401600000020100030201000503010001060100070a01066d656d6f727902000a0801060002401a0b0b
|
23
test/libyul/objectCompiler/wasm/simple.yul
Normal file
23
test/libyul/objectCompiler/wasm/simple.yul
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
function main() {
|
||||||
|
i64.drop(i64.add(0, 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// wasm: true
|
||||||
|
// ----
|
||||||
|
// Text:
|
||||||
|
// (module
|
||||||
|
// (memory $memory (export "memory") 1)
|
||||||
|
// (export "main" (func $main))
|
||||||
|
//
|
||||||
|
// (func $main
|
||||||
|
// (block $label_
|
||||||
|
// (drop (i64.add (i64.const 0) (i64.const 1)))
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// Binary:
|
||||||
|
// 0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0801060002401a0b0b
|
22
test/libyul/objectCompiler/wasm/subObject.yul
Normal file
22
test/libyul/objectCompiler/wasm/subObject.yul
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
object "a" {
|
||||||
|
code {}
|
||||||
|
// Unreferenced data is not added to the assembled bytecode.
|
||||||
|
data "str" "Hello, World!"
|
||||||
|
object "sub" { code { function main() { i64.drop(11) } } }
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// wasm: true
|
||||||
|
// ----
|
||||||
|
// Text:
|
||||||
|
// (module
|
||||||
|
// ;; custom section for sub-module
|
||||||
|
// ;; The Keccak-256 hash of the text representation of "sub": 78ac3419d75c8d6f42f663717b8e964eeb994d77ff175145133084422dbd23d7
|
||||||
|
// ;; (@custom "sub" "0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0801060002401a0b0b")
|
||||||
|
// ;; custom section for data
|
||||||
|
// ;; (@custom "str" "48656c6c6f2c20576f726c6421")
|
||||||
|
// (memory $memory (export "memory") 1)
|
||||||
|
//
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// Binary:
|
||||||
|
// 0061736d010000000101000201000301000503010001060100070a01066d656d6f72790200003e037375620061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0801060002401a0b0b00110373747248656c6c6f2c20576f726c64210a0100
|
79
test/libyul/objectCompiler/wasm/subObjectAccess.yul
Normal file
79
test/libyul/objectCompiler/wasm/subObjectAccess.yul
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
object "A" {
|
||||||
|
code {
|
||||||
|
function main() {
|
||||||
|
// TODO: support this
|
||||||
|
// i64.drop(dataoffset("A"))
|
||||||
|
// i64.drop(datasize("A"))
|
||||||
|
i64.drop(dataoffset("B"))
|
||||||
|
i64.drop(datasize("B"))
|
||||||
|
// TODO: support sub-subobjects
|
||||||
|
// i64.drop(dataoffset("B.C"))
|
||||||
|
// i64.drop(datasize("B.C"))
|
||||||
|
// i64.drop(dataoffset("B.E"))
|
||||||
|
// i64.drop(datasize("B.E"))
|
||||||
|
// i64.drop(dataoffset("B.C.D"))
|
||||||
|
// i64.drop(datasize("B.C.D"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "data1" "Hello, World!"
|
||||||
|
|
||||||
|
object "B" {
|
||||||
|
code {
|
||||||
|
function main() {
|
||||||
|
i64.drop(dataoffset("C"))
|
||||||
|
i64.drop(datasize("C"))
|
||||||
|
i64.drop(dataoffset("E"))
|
||||||
|
i64.drop(datasize("E"))
|
||||||
|
// i64.drop(dataoffset("C.D"))
|
||||||
|
// i64.drop(datasize("C.D"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object "C" {
|
||||||
|
code {
|
||||||
|
function main() {
|
||||||
|
i64.drop(dataoffset("D"))
|
||||||
|
i64.drop(datasize("D"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object "D" {
|
||||||
|
code {
|
||||||
|
function main() {
|
||||||
|
unreachable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object "E" {
|
||||||
|
code {
|
||||||
|
function main() {
|
||||||
|
unreachable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// wasm: true
|
||||||
|
// ----
|
||||||
|
// Text:
|
||||||
|
// (module
|
||||||
|
// ;; custom section for sub-module
|
||||||
|
// ;; The Keccak-256 hash of the text representation of "B": 1eeffe5bc8d8819350ead60cc71ccd92c223cf52a908330db53461eb9ac89b62
|
||||||
|
// ;; (@custom "B" "0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000007b01430061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000003c01440061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0901070002401a1a0b0b003c01450061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0b01090002401a1a1a1a0b0b")
|
||||||
|
// ;; custom section for data
|
||||||
|
// ;; (@custom "data1" "48656c6c6f2c20576f726c6421")
|
||||||
|
// (memory $memory (export "memory") 1)
|
||||||
|
// (export "main" (func $main))
|
||||||
|
//
|
||||||
|
// (func $main
|
||||||
|
// (block $label_
|
||||||
|
// (drop (dataoffset "B"))
|
||||||
|
// (drop (datasize "B"))
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// Binary:
|
||||||
|
// 0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e000000fa0101420061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000007b01430061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000003c01440061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0901070002401a1a0b0b003c01450061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0b01090002401a1a1a1a0b0b001305646174613148656c6c6f2c20576f726c64210a0901070002401a1a0b0b
|
Loading…
Reference in New Issue
Block a user