mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
wasm/BinaryTransform: Make most of section generation stateless and pass global/function/type maps via parameters
This commit is contained in:
parent
adbd4be151
commit
b2a8639c20
@ -255,34 +255,42 @@ bytes BinaryTransform::run(Module const& _module)
|
|||||||
{
|
{
|
||||||
map<Type, vector<string>> const types = typeToFunctionMap(_module.imports, _module.functions);
|
map<Type, vector<string>> const types = typeToFunctionMap(_module.imports, _module.functions);
|
||||||
|
|
||||||
BinaryTransform bt(
|
map<string, size_t> const globals = enumerateGlobals(_module);
|
||||||
enumerateGlobals(_module),
|
map<string, size_t> const functions = enumerateFunctions(_module);
|
||||||
enumerateFunctions(_module),
|
map<string, size_t> const functionTypes = enumerateFunctionTypes(types);
|
||||||
enumerateFunctionTypes(types)
|
|
||||||
);
|
|
||||||
|
|
||||||
yulAssert(bt.m_globals.size() == _module.globals.size(), "");
|
yulAssert(globals.size() == _module.globals.size(), "");
|
||||||
yulAssert(bt.m_functions.size() == _module.imports.size() + _module.functions.size(), "");
|
yulAssert(functions.size() == _module.imports.size() + _module.functions.size(), "");
|
||||||
yulAssert(bt.m_functionTypes.size() == bt.m_functions.size(), "");
|
yulAssert(functionTypes.size() == functions.size(), "");
|
||||||
yulAssert(bt.m_functionTypes.size() >= types.size(), "");
|
yulAssert(functionTypes.size() >= types.size(), "");
|
||||||
|
|
||||||
bytes ret{0, 'a', 's', 'm'};
|
bytes ret{0, 'a', 's', 'm'};
|
||||||
// version
|
// version
|
||||||
ret += bytes{1, 0, 0, 0};
|
ret += bytes{1, 0, 0, 0};
|
||||||
ret += bt.typeSection(types);
|
ret += typeSection(types);
|
||||||
ret += bt.importSection(_module.imports);
|
ret += importSection(_module.imports, functionTypes);
|
||||||
ret += bt.functionSection(_module.functions);
|
ret += functionSection(_module.functions, functionTypes);
|
||||||
ret += bt.memorySection();
|
ret += memorySection();
|
||||||
ret += bt.globalSection();
|
ret += globalSection(_module.globals);
|
||||||
ret += bt.exportSection();
|
ret += exportSection(functions);
|
||||||
|
|
||||||
|
map<string, pair<size_t, size_t>> subModulePosAndSize;
|
||||||
for (auto const& sub: _module.subModules)
|
for (auto const& sub: _module.subModules)
|
||||||
{
|
{
|
||||||
// TODO should we prefix and / or shorten the name?
|
// TODO should we prefix and / or shorten the name?
|
||||||
bytes data = BinaryTransform::run(sub.second);
|
bytes data = BinaryTransform::run(sub.second);
|
||||||
size_t length = data.size();
|
size_t length = data.size();
|
||||||
ret += bt.customSection(sub.first, std::move(data));
|
ret += customSection(sub.first, std::move(data));
|
||||||
bt.m_subModulePosAndSize[sub.first] = {ret.size() - length, length};
|
subModulePosAndSize[sub.first] = {ret.size() - length, length};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BinaryTransform bt(
|
||||||
|
move(globals),
|
||||||
|
move(functions),
|
||||||
|
move(functionTypes),
|
||||||
|
move(subModulePosAndSize)
|
||||||
|
);
|
||||||
|
|
||||||
ret += bt.codeSection(_module.functions);
|
ret += bt.codeSection(_module.functions);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -565,7 +573,8 @@ bytes BinaryTransform::typeSection(map<BinaryTransform::Type, vector<string>> co
|
|||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::importSection(
|
bytes BinaryTransform::importSection(
|
||||||
vector<FunctionImport> const& _imports
|
vector<FunctionImport> const& _imports,
|
||||||
|
map<string, size_t> const& _functionTypes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bytes result = lebEncode(_imports.size());
|
bytes result = lebEncode(_imports.size());
|
||||||
@ -576,16 +585,19 @@ bytes BinaryTransform::importSection(
|
|||||||
encodeName(import.module) +
|
encodeName(import.module) +
|
||||||
encodeName(import.externalName) +
|
encodeName(import.externalName) +
|
||||||
toBytes(importKind) +
|
toBytes(importKind) +
|
||||||
lebEncode(m_functionTypes.at(import.internalName));
|
lebEncode(_functionTypes.at(import.internalName));
|
||||||
}
|
}
|
||||||
return makeSection(Section::IMPORT, std::move(result));
|
return makeSection(Section::IMPORT, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::functionSection(vector<FunctionDefinition> const& _functions)
|
bytes BinaryTransform::functionSection(
|
||||||
|
vector<FunctionDefinition> const& _functions,
|
||||||
|
map<string, size_t> const& _functionTypes
|
||||||
|
)
|
||||||
{
|
{
|
||||||
bytes result = lebEncode(_functions.size());
|
bytes result = lebEncode(_functions.size());
|
||||||
for (auto const& fun: _functions)
|
for (auto const& fun: _functions)
|
||||||
result += lebEncode(m_functionTypes.at(fun.name));
|
result += lebEncode(_functionTypes.at(fun.name));
|
||||||
return makeSection(Section::FUNCTION, std::move(result));
|
return makeSection(Section::FUNCTION, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,10 +609,10 @@ bytes BinaryTransform::memorySection()
|
|||||||
return makeSection(Section::MEMORY, std::move(result));
|
return makeSection(Section::MEMORY, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::globalSection()
|
bytes BinaryTransform::globalSection(vector<wasm::GlobalVariableDeclaration> const& _globals)
|
||||||
{
|
{
|
||||||
bytes result = lebEncode(m_globals.size());
|
bytes result = lebEncode(_globals.size());
|
||||||
for (size_t i = 0; i < m_globals.size(); ++i)
|
for (size_t i = 0; i < _globals.size(); ++i)
|
||||||
result +=
|
result +=
|
||||||
toBytes(ValueType::I64) +
|
toBytes(ValueType::I64) +
|
||||||
lebEncode(static_cast<uint8_t>(Mutability::Var)) +
|
lebEncode(static_cast<uint8_t>(Mutability::Var)) +
|
||||||
@ -611,11 +623,11 @@ bytes BinaryTransform::globalSection()
|
|||||||
return makeSection(Section::GLOBAL, std::move(result));
|
return makeSection(Section::GLOBAL, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::exportSection()
|
bytes BinaryTransform::exportSection(map<string, size_t> const& _functions)
|
||||||
{
|
{
|
||||||
bytes result = lebEncode(2);
|
bytes result = lebEncode(2);
|
||||||
result += encodeName("memory") + toBytes(Export::Memory) + lebEncode(0);
|
result += encodeName("memory") + toBytes(Export::Memory) + lebEncode(0);
|
||||||
result += encodeName("main") + toBytes(Export::Function) + lebEncode(m_functions.at("main"));
|
result += encodeName("main") + toBytes(Export::Function) + lebEncode(_functions.at("main"));
|
||||||
return makeSection(Section::EXPORT, std::move(result));
|
return makeSection(Section::EXPORT, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,11 +58,13 @@ private:
|
|||||||
BinaryTransform(
|
BinaryTransform(
|
||||||
std::map<std::string, size_t> _globals,
|
std::map<std::string, size_t> _globals,
|
||||||
std::map<std::string, size_t> _functions,
|
std::map<std::string, size_t> _functions,
|
||||||
std::map<std::string, size_t> _functionTypes
|
std::map<std::string, size_t> _functionTypes,
|
||||||
|
std::map<std::string, std::pair<size_t, size_t>> _subModulePosAndSize
|
||||||
):
|
):
|
||||||
m_globals(std::move(_globals)),
|
m_globals(std::move(_globals)),
|
||||||
m_functions(std::move(_functions)),
|
m_functions(std::move(_functions)),
|
||||||
m_functionTypes(std::move(_functionTypes))
|
m_functionTypes(std::move(_functionTypes)),
|
||||||
|
m_subModulePosAndSize(std::move(_subModulePosAndSize))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
using Type = std::pair<std::vector<std::uint8_t>, std::vector<std::uint8_t>>;
|
using Type = std::pair<std::vector<std::uint8_t>, std::vector<std::uint8_t>>;
|
||||||
@ -83,13 +85,19 @@ private:
|
|||||||
std::map<Type, std::vector<std::string>> const& _typeToFunctionMap
|
std::map<Type, std::vector<std::string>> const& _typeToFunctionMap
|
||||||
);
|
);
|
||||||
|
|
||||||
bytes typeSection(std::map<Type, std::vector<std::string>> const& _typeToFunctionMap);
|
static bytes typeSection(std::map<Type, std::vector<std::string>> const& _typeToFunctionMap);
|
||||||
bytes importSection(std::vector<wasm::FunctionImport> const& _imports);
|
static bytes importSection(
|
||||||
bytes functionSection(std::vector<wasm::FunctionDefinition> const& _functions);
|
std::vector<wasm::FunctionImport> const& _imports,
|
||||||
bytes memorySection();
|
std::map<std::string, size_t> const& _functionTypes
|
||||||
bytes globalSection();
|
);
|
||||||
bytes exportSection();
|
static bytes functionSection(
|
||||||
bytes customSection(std::string const& _name, bytes _data);
|
std::vector<wasm::FunctionDefinition> const& _functions,
|
||||||
|
std::map<std::string, size_t> const& _functionTypes
|
||||||
|
);
|
||||||
|
static bytes memorySection();
|
||||||
|
static bytes globalSection(std::vector<wasm::GlobalVariableDeclaration> const& _globals);
|
||||||
|
static bytes exportSection(std::map<std::string, size_t> const& _functions);
|
||||||
|
static bytes customSection(std::string const& _name, bytes _data);
|
||||||
bytes codeSection(std::vector<wasm::FunctionDefinition> const& _functions);
|
bytes codeSection(std::vector<wasm::FunctionDefinition> const& _functions);
|
||||||
|
|
||||||
bytes visit(std::vector<wasm::Expression> const& _expressions);
|
bytes visit(std::vector<wasm::Expression> const& _expressions);
|
||||||
@ -102,10 +110,10 @@ private:
|
|||||||
std::map<std::string, size_t> const m_globals;
|
std::map<std::string, size_t> const m_globals;
|
||||||
std::map<std::string, size_t> const m_functions;
|
std::map<std::string, size_t> const m_functions;
|
||||||
std::map<std::string, size_t> const m_functionTypes;
|
std::map<std::string, size_t> const m_functionTypes;
|
||||||
|
std::map<std::string, std::pair<size_t, size_t>> const m_subModulePosAndSize;
|
||||||
|
|
||||||
std::map<std::string, size_t> m_locals;
|
std::map<std::string, size_t> m_locals;
|
||||||
std::vector<std::string> m_labels;
|
std::vector<std::string> m_labels;
|
||||||
std::map<std::string, std::pair<size_t, size_t>> m_subModulePosAndSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user