wasm/BinaryTransform: Make most of section generation stateless and pass global/function/type maps via parameters

This commit is contained in:
Kamil Śliwak 2020-06-08 20:17:59 +02:00
parent adbd4be151
commit b2a8639c20
2 changed files with 56 additions and 36 deletions

View File

@ -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));
} }

View File

@ -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;
}; };
} }