mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[ewasm] Add support for hera debugging module.
This commit is contained in:
parent
957e9995a0
commit
321e971eb3
@ -118,28 +118,35 @@ wasm::Expression WasmCodeTransform::operator()(yul::ExpressionStatement const& _
|
|||||||
return visitReturnByValue(_statement.expression);
|
return visitReturnByValue(_statement.expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WasmCodeTransform::importBuiltinFunction(BuiltinFunction const* _builtin, string const& _module, string const& _externalName, string const& _internalName)
|
||||||
|
{
|
||||||
|
yulAssert(_builtin, "");
|
||||||
|
yulAssert(_builtin->returns.size() <= 1, "");
|
||||||
|
// Imported function, use regular call, but mark for import.
|
||||||
|
YulString internalName(_internalName);
|
||||||
|
if (!m_functionsToImport.count(internalName))
|
||||||
|
{
|
||||||
|
wasm::FunctionImport imp{
|
||||||
|
_module,
|
||||||
|
_externalName,
|
||||||
|
_internalName,
|
||||||
|
{},
|
||||||
|
_builtin->returns.empty() ? nullopt : make_optional<wasm::Type>(translatedType(_builtin->returns.front()))
|
||||||
|
};
|
||||||
|
for (auto const& param: _builtin->parameters)
|
||||||
|
imp.paramTypes.emplace_back(translatedType(param));
|
||||||
|
m_functionsToImport[internalName] = move(imp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wasm::Expression WasmCodeTransform::operator()(yul::FunctionCall const& _call)
|
wasm::Expression WasmCodeTransform::operator()(yul::FunctionCall const& _call)
|
||||||
{
|
{
|
||||||
if (BuiltinFunction const* builtin = m_dialect.builtin(_call.functionName.name))
|
if (BuiltinFunction const* builtin = m_dialect.builtin(_call.functionName.name))
|
||||||
{
|
{
|
||||||
if (_call.functionName.name.str().substr(0, 4) == "eth.")
|
if (_call.functionName.name.str().substr(0, 6) == "debug.")
|
||||||
{
|
importBuiltinFunction(builtin, "debug", builtin->name.str().substr(6), builtin->name.str());
|
||||||
yulAssert(builtin->returns.size() <= 1, "");
|
else if (_call.functionName.name.str().substr(0, 4) == "eth.")
|
||||||
// Imported function, use regular call, but mark for import.
|
importBuiltinFunction(builtin, "ethereum", builtin->name.str().substr(4), builtin->name.str());
|
||||||
if (!m_functionsToImport.count(builtin->name))
|
|
||||||
{
|
|
||||||
wasm::FunctionImport imp{
|
|
||||||
"ethereum",
|
|
||||||
builtin->name.str().substr(4),
|
|
||||||
builtin->name.str(),
|
|
||||||
{},
|
|
||||||
builtin->returns.empty() ? nullopt : make_optional<wasm::Type>(translatedType(builtin->returns.front()))
|
|
||||||
};
|
|
||||||
for (auto const& param: builtin->parameters)
|
|
||||||
imp.paramTypes.emplace_back(translatedType(param));
|
|
||||||
m_functionsToImport[builtin->name] = std::move(imp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vector<wasm::Expression> arguments;
|
vector<wasm::Expression> arguments;
|
||||||
|
@ -85,6 +85,13 @@ private:
|
|||||||
|
|
||||||
wasm::FunctionDefinition translateFunction(yul::FunctionDefinition const& _funDef);
|
wasm::FunctionDefinition translateFunction(yul::FunctionDefinition const& _funDef);
|
||||||
|
|
||||||
|
/// Imports an external function into the current module.
|
||||||
|
/// @param _builtin _builtin the builtin that will be imported into the current module.
|
||||||
|
/// @param _module _module the module name under which the external function can be found.
|
||||||
|
/// @param _externalName the name of the external function within the module _module.
|
||||||
|
/// @param _internalName the name of the internal function under that the external function is accessible.
|
||||||
|
void importBuiltinFunction(BuiltinFunction const* _builtin, std::string const& _module, std::string const& _externalName, std::string const& _internalName);
|
||||||
|
|
||||||
std::string newLabel();
|
std::string newLabel();
|
||||||
/// Selects a subset of global variables matching specified sequence of variable types.
|
/// Selects a subset of global variables matching specified sequence of variable types.
|
||||||
/// Defines more global variables of a given type if there's not enough.
|
/// Defines more global variables of a given type if there's not enough.
|
||||||
|
@ -135,7 +135,7 @@ WasmDialect::WasmDialect()
|
|||||||
addFunction("datasize", {i64}, {i64}, true, {LiteralKind::String});
|
addFunction("datasize", {i64}, {i64}, true, {LiteralKind::String});
|
||||||
addFunction("dataoffset", {i64}, {i64}, true, {LiteralKind::String});
|
addFunction("dataoffset", {i64}, {i64}, true, {LiteralKind::String});
|
||||||
|
|
||||||
addEthereumExternals();
|
addExternals();
|
||||||
}
|
}
|
||||||
|
|
||||||
BuiltinFunction const* WasmDialect::builtin(YulString _name) const
|
BuiltinFunction const* WasmDialect::builtin(YulString _name) const
|
||||||
@ -172,7 +172,7 @@ WasmDialect const& WasmDialect::instance()
|
|||||||
return *dialect;
|
return *dialect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WasmDialect::addEthereumExternals()
|
void WasmDialect::addExternals()
|
||||||
{
|
{
|
||||||
// These are not YulStrings because that would be too complicated with regards
|
// These are not YulStrings because that would be too complicated with regards
|
||||||
// to the YulStringRepository reset.
|
// to the YulStringRepository reset.
|
||||||
@ -181,48 +181,55 @@ void WasmDialect::addEthereumExternals()
|
|||||||
static string const i32ptr{"i32"}; // Uses "i32" on purpose.
|
static string const i32ptr{"i32"}; // Uses "i32" on purpose.
|
||||||
struct External
|
struct External
|
||||||
{
|
{
|
||||||
|
string module;
|
||||||
string name;
|
string name;
|
||||||
vector<string> parameters;
|
vector<string> parameters;
|
||||||
vector<string> returns;
|
vector<string> returns;
|
||||||
ControlFlowSideEffects controlFlowSideEffects = ControlFlowSideEffects{};
|
ControlFlowSideEffects controlFlowSideEffects = ControlFlowSideEffects{};
|
||||||
};
|
};
|
||||||
static vector<External> externals{
|
static vector<External> externals{
|
||||||
{"getAddress", {i32ptr}, {}},
|
{"eth", "getAddress", {i32ptr}, {}},
|
||||||
{"getExternalBalance", {i32ptr, i32ptr}, {}},
|
{"eth", "getExternalBalance", {i32ptr, i32ptr}, {}},
|
||||||
{"getBlockHash", {i64, i32ptr}, {i32}},
|
{"eth", "getBlockHash", {i64, i32ptr}, {i32}},
|
||||||
{"call", {i64, i32ptr, i32ptr, i32ptr, i32}, {i32}},
|
{"eth", "call", {i64, i32ptr, i32ptr, i32ptr, i32}, {i32}},
|
||||||
{"callDataCopy", {i32ptr, i32, i32}, {}},
|
{"eth", "callDataCopy", {i32ptr, i32, i32}, {}},
|
||||||
{"getCallDataSize", {}, {i32}},
|
{"eth", "getCallDataSize", {}, {i32}},
|
||||||
{"callCode", {i64, i32ptr, i32ptr, i32ptr, i32}, {i32}},
|
{"eth", "callCode", {i64, i32ptr, i32ptr, i32ptr, i32}, {i32}},
|
||||||
{"callDelegate", {i64, i32ptr, i32ptr, i32}, {i32}},
|
{"eth", "callDelegate", {i64, i32ptr, i32ptr, i32}, {i32}},
|
||||||
{"callStatic", {i64, i32ptr, i32ptr, i32}, {i32}},
|
{"eth", "callStatic", {i64, i32ptr, i32ptr, i32}, {i32}},
|
||||||
{"storageStore", {i32ptr, i32ptr}, {}},
|
{"eth", "storageStore", {i32ptr, i32ptr}, {}},
|
||||||
{"storageLoad", {i32ptr, i32ptr}, {}},
|
{"eth", "storageLoad", {i32ptr, i32ptr}, {}},
|
||||||
{"getCaller", {i32ptr}, {}},
|
{"eth", "getCaller", {i32ptr}, {}},
|
||||||
{"getCallValue", {i32ptr}, {}},
|
{"eth", "getCallValue", {i32ptr}, {}},
|
||||||
{"codeCopy", {i32ptr, i32, i32}, {}},
|
{"eth", "codeCopy", {i32ptr, i32, i32}, {}},
|
||||||
{"getCodeSize", {}, {i32}},
|
{"eth", "getCodeSize", {}, {i32}},
|
||||||
{"getBlockCoinbase", {i32ptr}, {}},
|
{"eth", "getBlockCoinbase", {i32ptr}, {}},
|
||||||
{"create", {i32ptr, i32ptr, i32, i32ptr}, {i32}},
|
{"eth", "create", {i32ptr, i32ptr, i32, i32ptr}, {i32}},
|
||||||
{"getBlockDifficulty", {i32ptr}, {}},
|
{"eth", "getBlockDifficulty", {i32ptr}, {}},
|
||||||
{"externalCodeCopy", {i32ptr, i32ptr, i32, i32}, {}},
|
{"eth", "externalCodeCopy", {i32ptr, i32ptr, i32, i32}, {}},
|
||||||
{"getExternalCodeSize", {i32ptr}, {i32}},
|
{"eth", "getExternalCodeSize", {i32ptr}, {i32}},
|
||||||
{"getGasLeft", {}, {i64}},
|
{"eth", "getGasLeft", {}, {i64}},
|
||||||
{"getBlockGasLimit", {}, {i64}},
|
{"eth", "getBlockGasLimit", {}, {i64}},
|
||||||
{"getTxGasPrice", {i32ptr}, {}},
|
{"eth", "getTxGasPrice", {i32ptr}, {}},
|
||||||
{"log", {i32ptr, i32, i32, i32ptr, i32ptr, i32ptr, i32ptr}, {}},
|
{"eth", "log", {i32ptr, i32, i32, i32ptr, i32ptr, i32ptr, i32ptr}, {}},
|
||||||
{"getBlockNumber", {}, {i64}},
|
{"eth", "getBlockNumber", {}, {i64}},
|
||||||
{"getTxOrigin", {i32ptr}, {}},
|
{"eth", "getTxOrigin", {i32ptr}, {}},
|
||||||
{"finish", {i32ptr, i32}, {}, ControlFlowSideEffects{true, false}},
|
{"eth", "finish", {i32ptr, i32}, {}, ControlFlowSideEffects{true, false}},
|
||||||
{"revert", {i32ptr, i32}, {}, ControlFlowSideEffects{true, true}},
|
{"eth", "revert", {i32ptr, i32}, {}, ControlFlowSideEffects{true, true}},
|
||||||
{"getReturnDataSize", {}, {i32}},
|
{"eth", "getReturnDataSize", {}, {i32}},
|
||||||
{"returnDataCopy", {i32ptr, i32, i32}, {}},
|
{"eth", "returnDataCopy", {i32ptr, i32, i32}, {}},
|
||||||
{"selfDestruct", {i32ptr}, {}, ControlFlowSideEffects{true, false}},
|
{"eth", "selfDestruct", {i32ptr}, {}, ControlFlowSideEffects{true, false}},
|
||||||
{"getBlockTimestamp", {}, {i64}}
|
{"eth", "getBlockTimestamp", {}, {i64}},
|
||||||
|
{"debug", "print32", {i32}, {}},
|
||||||
|
{"debug", "print64", {i64}, {}},
|
||||||
|
{"debug", "printMem", {i32, i32}, {}},
|
||||||
|
{"debug", "printMemHex", {i32, i32}, {}},
|
||||||
|
{"debug", "printStorage", {i32}, {}},
|
||||||
|
{"debug", "printStorageHex", {i32}, {}},
|
||||||
};
|
};
|
||||||
for (External const& ext: externals)
|
for (External const& ext: externals)
|
||||||
{
|
{
|
||||||
YulString name{"eth." + ext.name};
|
YulString name{ext.module + "." + ext.name};
|
||||||
BuiltinFunction& f = m_functions[name];
|
BuiltinFunction& f = m_functions[name];
|
||||||
f.name = name;
|
f.name = name;
|
||||||
for (string const& p: ext.parameters)
|
for (string const& p: ext.parameters)
|
||||||
|
@ -55,7 +55,7 @@ struct WasmDialect: public Dialect
|
|||||||
static WasmDialect const& instance();
|
static WasmDialect const& instance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addEthereumExternals();
|
void addExternals();
|
||||||
|
|
||||||
void addFunction(
|
void addFunction(
|
||||||
std::string _name,
|
std::string _name,
|
||||||
|
Loading…
Reference in New Issue
Block a user