mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Prototype for Wasm code transform into in-memory representation.
This commit is contained in:
		
							parent
							
								
									e9f41d1148
								
							
						
					
					
						commit
						ec27f484a1
					
				| @ -31,6 +31,8 @@ | ||||
| #include <libyul/backends/evm/EVMCodeTransform.h> | ||||
| #include <libyul/backends/evm/EVMDialect.h> | ||||
| #include <libyul/backends/evm/EVMObjectCompiler.h> | ||||
| #include <libyul/backends/wasm/WasmDialect.h> | ||||
| #include <libyul/backends/wasm/EWasmObjectCompiler.h> | ||||
| #include <libyul/ObjectParser.h> | ||||
| #include <libyul/optimiser/Suite.h> | ||||
| 
 | ||||
| @ -55,6 +57,8 @@ shared_ptr<Dialect> languageToDialect(AssemblyStack::Language _language, EVMVers | ||||
| 		return EVMDialect::strictAssemblyForEVMObjects(_version); | ||||
| 	case AssemblyStack::Language::Yul: | ||||
| 		return Dialect::yul(); | ||||
| 	case AssemblyStack::Language::EWasm: | ||||
| 		return make_shared<WasmDialect>(); | ||||
| 	} | ||||
| 	solAssert(false, ""); | ||||
| 	return Dialect::yul(); | ||||
| @ -178,7 +182,14 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const | ||||
| 		return object; | ||||
| 	} | ||||
| 	case Machine::eWasm: | ||||
| 		solUnimplemented("eWasm backend is not yet implemented."); | ||||
| 	{ | ||||
| 		solAssert(m_language == Language::EWasm, ""); | ||||
| 		shared_ptr<Dialect> dialect = languageToDialect(m_language, EVMVersion{}); | ||||
| 
 | ||||
| 		MachineAssemblyObject object; | ||||
| 		object.assembly = EWasmObjectCompiler::compile(*m_parserResult, *dialect); | ||||
| 		return object; | ||||
| 	} | ||||
| 	} | ||||
| 	// unreachable
 | ||||
| 	return MachineAssemblyObject(); | ||||
|  | ||||
| @ -57,7 +57,7 @@ struct MachineAssemblyObject | ||||
| class AssemblyStack | ||||
| { | ||||
| public: | ||||
| 	enum class Language { Yul, Assembly, StrictAssembly }; | ||||
| 	enum class Language { Yul, Assembly, StrictAssembly, EWasm }; | ||||
| 	enum class Machine { EVM, EVM15, eWasm }; | ||||
| 
 | ||||
| 	AssemblyStack(): | ||||
|  | ||||
| @ -36,6 +36,10 @@ add_library(yul | ||||
| 	backends/evm/EVMDialect.h | ||||
| 	backends/evm/EVMObjectCompiler.cpp | ||||
| 	backends/evm/EVMObjectCompiler.h | ||||
| 	backends/wasm/EWasmCodeTransform.cpp | ||||
| 	backends/wasm/EWasmCodeTransform.h | ||||
| 	backends/wasm/EWasmObjectCompiler.cpp | ||||
| 	backends/wasm/EWasmObjectCompiler.h | ||||
| 	backends/evm/NoOutputAssembly.h | ||||
| 	backends/evm/NoOutputAssembly.cpp | ||||
| 	backends/wasm/WasmDialect.cpp | ||||
|  | ||||
							
								
								
									
										69
									
								
								libyul/backends/wasm/EWasmAST.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								libyul/backends/wasm/EWasmAST.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| /*
 | ||||
| 	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/>.
 | ||||
| */ | ||||
| /**
 | ||||
|  * Simplified in-memory representation of a Wasm AST. | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <boost/variant.hpp> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace yul | ||||
| { | ||||
| namespace wasm | ||||
| { | ||||
| 
 | ||||
| struct Literal; | ||||
| struct Identifier; | ||||
| struct Label; | ||||
| struct FunctionCall; | ||||
| struct BuiltinCall; | ||||
| struct LocalAssignment; | ||||
| struct Block; | ||||
| struct If; | ||||
| struct Loop; | ||||
| struct Break; | ||||
| struct Continue; | ||||
| using Expression = boost::variant<Literal, Identifier, Label, FunctionCall, BuiltinCall, LocalAssignment, Block, If, Loop, Break, Continue>; | ||||
| 
 | ||||
| struct Literal { uint64_t value; }; | ||||
| struct Identifier { std::string name; }; | ||||
| struct Label { std::string name; }; | ||||
| struct FunctionCall { std::string functionName; std::vector<Expression> arguments; }; | ||||
| struct BuiltinCall { std::string functionName; std::vector<Expression> arguments; }; | ||||
| struct LocalAssignment { std::string variableName; std::unique_ptr<Expression> value; }; | ||||
| struct Block { std::string labelName; std::vector<Expression> statements; }; | ||||
| struct If { std::unique_ptr<Expression> condition; std::vector<Expression> statements; }; | ||||
| struct Loop { std::string labelName; std::vector<Expression> statements; }; | ||||
| struct Break { Label label; }; | ||||
| struct Continue { Label label; }; | ||||
| 
 | ||||
| struct VariableDeclaration { std::string variableName; }; | ||||
| struct FunctionDefinition | ||||
| { | ||||
| 	std::string name; | ||||
| 	std::vector<std::string> parameterNames; | ||||
| 	bool returns; | ||||
| 	std::vector<VariableDeclaration> locals; | ||||
| 	std::vector<Expression> body; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| } | ||||
							
								
								
									
										242
									
								
								libyul/backends/wasm/EWasmCodeTransform.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								libyul/backends/wasm/EWasmCodeTransform.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,242 @@ | ||||
| /*
 | ||||
| 	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/>.
 | ||||
| */ | ||||
| /**
 | ||||
| * Common code generator for translating Yul / inline assembly to EWasm. | ||||
| */ | ||||
| 
 | ||||
| #include <libyul/backends/wasm/EWasmCodeTransform.h> | ||||
| 
 | ||||
| #include <libyul/AsmData.h> | ||||
| #include <libyul/Dialect.h> | ||||
| #include <libyul/Utilities.h> | ||||
| #include <libyul/Exceptions.h> | ||||
| 
 | ||||
| #include <liblangutil/Exceptions.h> | ||||
| 
 | ||||
| #include <boost/range/adaptor/reversed.hpp> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace dev; | ||||
| using namespace yul; | ||||
| 
 | ||||
| string EWasmCodeTransform::run(yul::Block const& _ast) | ||||
| { | ||||
| 	vector<wasm::FunctionDefinition> functions; | ||||
| 
 | ||||
| 	for (auto const& statement: _ast.statements) | ||||
| 	{ | ||||
| 		yulAssert(statement.type() == typeid(yul::FunctionDefinition), ""); | ||||
| 		functions.emplace_back(translateFunction(boost::get<yul::FunctionDefinition>(statement))); | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO translate to text representation
 | ||||
| 
 | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(VariableDeclaration const& _varDecl) | ||||
| { | ||||
| 	for (auto const& var: _varDecl.variables) | ||||
| 		m_localVariables.emplace_back(wasm::VariableDeclaration{var.name.str()}); | ||||
| 
 | ||||
| 	if (_varDecl.value) | ||||
| 	{ | ||||
| 		// TODO otherwise, we have to work with globals.
 | ||||
| 		solUnimplementedAssert(_varDecl.variables.size() == 1, "Only single-variable assignments supported."); | ||||
| 		return wasm::LocalAssignment{ | ||||
| 			_varDecl.variables.front().name.str(), | ||||
| 			visit(*_varDecl.value) | ||||
| 		}; | ||||
| 	} | ||||
| 	else | ||||
| 		// TODO this could be handled better.
 | ||||
| 		return wasm::BuiltinCall{"nop", {}}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Assignment const& _assignment) | ||||
| { | ||||
| 	solUnimplementedAssert(_assignment.variableNames.size() == 1, "Only single-variable assignments supported."); | ||||
| 	return wasm::LocalAssignment{ | ||||
| 		_assignment.variableNames.front().name.str(), | ||||
| 		visit(*_assignment.value) | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(StackAssignment const&) | ||||
| { | ||||
| 	yulAssert(false, ""); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(ExpressionStatement const& _statement) | ||||
| { | ||||
| 	return visitReturnByValue(_statement.expression); | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Label const&) | ||||
| { | ||||
| 	yulAssert(false, ""); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(FunctionalInstruction const&) | ||||
| { | ||||
| 	yulAssert(false, ""); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(FunctionCall const& _call) | ||||
| { | ||||
| 	if (m_dialect.builtin(_call.functionName.name)) | ||||
| 		return wasm::BuiltinCall{_call.functionName.name.str(), visit(_call.arguments)}; | ||||
| 	else | ||||
| 		return wasm::FunctionCall{_call.functionName.name.str(), visit(_call.arguments)}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Identifier const& _identifier) | ||||
| { | ||||
| 	return wasm::Identifier{_identifier.name.str()}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Literal const& _literal) | ||||
| { | ||||
| 	u256 value = valueOfLiteral(_literal); | ||||
| 	yulAssert(value <= numeric_limits<uint64_t>::max(), ""); | ||||
| 	return wasm::Literal{uint64_t(value)}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(yul::Instruction const&) | ||||
| { | ||||
| 	yulAssert(false, ""); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(If const& _if) | ||||
| { | ||||
| 	return wasm::If{visit(*_if.condition), visit(_if.body.statements)}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Switch const&) | ||||
| { | ||||
| 	solUnimplementedAssert(false, ""); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(FunctionDefinition const&) | ||||
| { | ||||
| 	yulAssert(false, "Should not have visited here."); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(ForLoop const& _for) | ||||
| { | ||||
| 	string breakLabel = newLabel(); | ||||
| 	string continueLabel = newLabel(); | ||||
| 	m_breakContinueLabelNames.push({breakLabel, continueLabel}); | ||||
| 
 | ||||
| 	// The AST is constructed in this weird way because of some strange
 | ||||
| 	// problem with move semantics.
 | ||||
| 	wasm::BuiltinCall loopCondition{"i64.eqz", {}}; | ||||
| 	loopCondition.arguments.emplace_back(visitReturnByValue(*_for.condition)); | ||||
| 
 | ||||
| 	wasm::BuiltinCall conditionCheck{"br_if", {}}; | ||||
| 	conditionCheck.arguments.emplace_back(wasm::Label{breakLabel}); | ||||
| 	conditionCheck.arguments.emplace_back(move(loopCondition)); | ||||
| 
 | ||||
| 	wasm::Loop loop; | ||||
| 	loop.statements = visit(_for.pre.statements); | ||||
| 	loop.statements.emplace_back(move(conditionCheck)); | ||||
| 	loop.statements.emplace_back(wasm::Block{continueLabel, visit(_for.body.statements)}); | ||||
| 	loop.statements += visit(_for.post.statements); | ||||
| 
 | ||||
| 	wasm::Block breakBlock{breakLabel, {}}; | ||||
| 	breakBlock.statements.emplace_back(move(loop)); | ||||
| 	return move(breakBlock); | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Break const&) | ||||
| { | ||||
| 	return wasm::Break{wasm::Label{m_breakContinueLabelNames.top().first}}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Continue const&) | ||||
| { | ||||
| 	return wasm::Continue{wasm::Label{m_breakContinueLabelNames.top().second}}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::operator()(Block const& _block) | ||||
| { | ||||
| 	return wasm::Block{{}, visit(_block.statements)}; | ||||
| } | ||||
| 
 | ||||
| unique_ptr<wasm::Expression> EWasmCodeTransform::visit(yul::Expression const& _expression) | ||||
| { | ||||
| 	return make_unique<wasm::Expression>(boost::apply_visitor(*this, _expression)); | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::visitReturnByValue(yul::Expression const& _expression) | ||||
| { | ||||
| 	return boost::apply_visitor(*this, _expression); | ||||
| } | ||||
| 
 | ||||
| vector<wasm::Expression> EWasmCodeTransform::visit(vector<yul::Expression> const& _expressions) | ||||
| { | ||||
| 	vector<wasm::Expression> ret; | ||||
| 	for (auto const& e: _expressions) | ||||
| 		ret.emplace_back(visitReturnByValue(e)); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression EWasmCodeTransform::visit(yul::Statement const& _statement) | ||||
| { | ||||
| 	return boost::apply_visitor(*this, _statement); | ||||
| } | ||||
| 
 | ||||
| vector<wasm::Expression> EWasmCodeTransform::visit(vector<yul::Statement> const& _statements) | ||||
| { | ||||
| 	vector<wasm::Expression> ret; | ||||
| 	for (auto const& s: _statements) | ||||
| 		ret.emplace_back(visit(s)); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| wasm::FunctionDefinition EWasmCodeTransform::translateFunction(yul::FunctionDefinition const& _fun) | ||||
| { | ||||
| 	wasm::FunctionDefinition fun; | ||||
| 	fun.name = _fun.name.str(); | ||||
| 	for (auto const& param: _fun.parameters) | ||||
| 		fun.parameterNames.emplace_back(param.name.str()); | ||||
| 	for (auto const& retParam: _fun.returnVariables) | ||||
| 		fun.locals.emplace_back(wasm::VariableDeclaration{retParam.name.str()}); | ||||
| 	fun.returns = !_fun.returnVariables.empty(); | ||||
| 
 | ||||
| 	yulAssert(m_localVariables.empty(), ""); | ||||
| 	fun.body = visit(_fun.body.statements); | ||||
| 	fun.locals += m_localVariables; | ||||
| 
 | ||||
| 	m_localVariables.clear(); | ||||
| 	yulAssert(_fun.returnVariables.size() <= 1, ""); | ||||
| 	if (_fun.returnVariables.size() == 1) | ||||
| 		fun.body.emplace_back(wasm::Identifier{_fun.returnVariables.front().name.str()}); | ||||
| 	return fun; | ||||
| } | ||||
| 
 | ||||
| string EWasmCodeTransform::newLabel() | ||||
| { | ||||
| 	// TODO this should not clash with other identifiers!
 | ||||
| 	return "label_" + to_string(++m_labelCounter); | ||||
| } | ||||
							
								
								
									
										82
									
								
								libyul/backends/wasm/EWasmCodeTransform.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								libyul/backends/wasm/EWasmCodeTransform.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| /*
 | ||||
| 	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/>.
 | ||||
| */ | ||||
| /**
 | ||||
|  * Common code generator for translating Yul / inline assembly to EWasm. | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <libyul/backends/wasm/EWasmAST.h> | ||||
| #include <libyul/AsmDataForward.h> | ||||
| #include <libyul/Dialect.h> | ||||
| 
 | ||||
| #include <stack> | ||||
| 
 | ||||
| namespace yul | ||||
| { | ||||
| struct AsmAnalysisInfo; | ||||
| 
 | ||||
| class EWasmCodeTransform: public boost::static_visitor<wasm::Expression> | ||||
| { | ||||
| public: | ||||
| 	EWasmCodeTransform( | ||||
| 		AsmAnalysisInfo&, | ||||
| 		Dialect const& _dialect | ||||
| 	): | ||||
| 		m_dialect(_dialect) | ||||
| 	{} | ||||
| 
 | ||||
| 	std::string run(yul::Block const& _ast); | ||||
| 
 | ||||
| public: | ||||
| 	wasm::Expression operator()(yul::Instruction const& _instruction); | ||||
| 	wasm::Expression operator()(yul::Literal const& _literal); | ||||
| 	wasm::Expression operator()(yul::Identifier const& _identifier); | ||||
| 	wasm::Expression operator()(yul::FunctionalInstruction const& _instr); | ||||
| 	wasm::Expression operator()(yul::FunctionCall const&); | ||||
| 	wasm::Expression operator()(yul::ExpressionStatement const& _statement); | ||||
| 	wasm::Expression operator()(yul::Label const& _label); | ||||
| 	wasm::Expression operator()(yul::StackAssignment const& _assignment); | ||||
| 	wasm::Expression operator()(yul::Assignment const& _assignment); | ||||
| 	wasm::Expression operator()(yul::VariableDeclaration const& _varDecl); | ||||
| 	wasm::Expression operator()(yul::If const& _if); | ||||
| 	wasm::Expression operator()(yul::Switch const& _switch); | ||||
| 	wasm::Expression operator()(yul::FunctionDefinition const&); | ||||
| 	wasm::Expression operator()(yul::ForLoop const&); | ||||
| 	wasm::Expression operator()(yul::Break const&); | ||||
| 	wasm::Expression operator()(yul::Continue const&); | ||||
| 	wasm::Expression operator()(yul::Block const& _block); | ||||
| 
 | ||||
| private: | ||||
| 	std::unique_ptr<wasm::Expression> visit(yul::Expression const& _expression); | ||||
| 	wasm::Expression visitReturnByValue(yul::Expression const& _expression); | ||||
| 	std::vector<wasm::Expression> visit(std::vector<yul::Expression> const& _expressions); | ||||
| 	wasm::Expression visit(yul::Statement const& _statement); | ||||
| 	std::vector<wasm::Expression> visit(std::vector<yul::Statement> const& _statements); | ||||
| 
 | ||||
| 	wasm::FunctionDefinition translateFunction(yul::FunctionDefinition const& _funDef); | ||||
| 
 | ||||
| 	std::string newLabel(); | ||||
| 
 | ||||
| 	std::vector<wasm::VariableDeclaration> m_localVariables; | ||||
| 	size_t m_labelCounter = 0; | ||||
| 	std::stack<std::pair<std::string, std::string>> m_breakContinueLabelNames; | ||||
| 
 | ||||
| 	Dialect const& m_dialect; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										52
									
								
								libyul/backends/wasm/EWasmObjectCompiler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								libyul/backends/wasm/EWasmObjectCompiler.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| /*
 | ||||
| 	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/>.
 | ||||
| */ | ||||
| /**
 | ||||
|  * Compiler that transforms Yul Objects to EWasm text representation. | ||||
|  */ | ||||
| 
 | ||||
| #include <libyul/backends/wasm/EWasmObjectCompiler.h> | ||||
| 
 | ||||
| #include <libyul/backends/wasm/EWasmCodeTransform.h> | ||||
| 
 | ||||
| #include <libyul/Object.h> | ||||
| #include <libyul/Exceptions.h> | ||||
| 
 | ||||
| using namespace yul; | ||||
| using namespace std; | ||||
| 
 | ||||
| string EWasmObjectCompiler::compile(Object& _object, Dialect& _dialect) | ||||
| { | ||||
| 	EWasmObjectCompiler compiler(_dialect); | ||||
| 	return compiler.run(_object); | ||||
| } | ||||
| 
 | ||||
| string EWasmObjectCompiler::run(Object& _object) | ||||
| { | ||||
| 	string ret; | ||||
| 
 | ||||
| 	for (auto& subNode: _object.subObjects) | ||||
| 		if (Object* subObject = dynamic_cast<Object*>(subNode.get())) | ||||
| 			ret += compile(*subObject, m_dialect); | ||||
| 		else | ||||
| 			yulAssert(false, "Data is not yet supported for EWasm."); | ||||
| 
 | ||||
| 	yulAssert(_object.analysisInfo, "No analysis info."); | ||||
| 	yulAssert(_object.code, "No code."); | ||||
| 	ret += EWasmCodeTransform{*_object.analysisInfo, m_dialect}.run(*_object.code); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
							
								
								
									
										44
									
								
								libyul/backends/wasm/EWasmObjectCompiler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								libyul/backends/wasm/EWasmObjectCompiler.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /*
 | ||||
| 	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/>.
 | ||||
| */ | ||||
| /**
 | ||||
|  * Compiler that transforms Yul Objects to EWasm text representation. | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| namespace yul | ||||
| { | ||||
| struct Object; | ||||
| struct Dialect; | ||||
| 
 | ||||
| class EWasmObjectCompiler | ||||
| { | ||||
| public: | ||||
| 	static std::string compile(Object& _object, Dialect& _dialect); | ||||
| private: | ||||
| 	EWasmObjectCompiler(Dialect& _dialect): | ||||
| 		m_dialect(_dialect) | ||||
| 	{} | ||||
| 
 | ||||
| 	std::string run(Object& _object); | ||||
| 
 | ||||
| 	Dialect& m_dialect; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
| @ -23,8 +23,8 @@ | ||||
| using namespace std; | ||||
| using namespace yul; | ||||
| 
 | ||||
| WasmDialect::WasmDialect(AsmFlavour _flavour): | ||||
| 	Dialect{_flavour} | ||||
| WasmDialect::WasmDialect(): | ||||
| 	Dialect{AsmFlavour::Strict} | ||||
| { | ||||
| 	for (auto const& name: { | ||||
| 		"i64.add", | ||||
| @ -65,7 +65,7 @@ BuiltinFunction const* WasmDialect::builtin(YulString _name) const | ||||
| 
 | ||||
| void WasmDialect::addFunction(string _name, size_t _params, size_t _returns) | ||||
| { | ||||
| 	YulString name{std::move(_name)}; | ||||
| 	YulString name{move(_name)}; | ||||
| 	BuiltinFunction& f = m_functions[name]; | ||||
| 	f.name = name; | ||||
| 	f.parameters.resize(_params); | ||||
|  | ||||
| @ -42,7 +42,7 @@ struct Object; | ||||
|  */ | ||||
| struct WasmDialect: public Dialect | ||||
| { | ||||
| 	WasmDialect(AsmFlavour _flavour); | ||||
| 	WasmDialect(); | ||||
| 
 | ||||
| 	BuiltinFunction const* builtin(YulString _name) const override; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user