mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Add the ability to store variable types in wasm AST
This commit is contained in:
		
							parent
							
								
									840ff40263
								
							
						
					
					
						commit
						6a82d32ef6
					
				| @ -298,7 +298,8 @@ bytes BinaryTransform::run(Module const& _module) | ||||
| 
 | ||||
| bytes BinaryTransform::operator()(Literal const& _literal) | ||||
| { | ||||
| 	return toBytes(Opcode::I64Const) + lebEncodeSigned(_literal.value); | ||||
| 	yulAssert(holds_alternative<uint64_t>(_literal.value), ""); | ||||
| 	return toBytes(Opcode::I64Const) + lebEncodeSigned(get<uint64_t>(_literal.value)); | ||||
| } | ||||
| 
 | ||||
| bytes BinaryTransform::operator()(StringLiteral const&) | ||||
| @ -457,8 +458,8 @@ bytes BinaryTransform::operator()(FunctionDefinition const& _function) | ||||
| 
 | ||||
| 	m_locals.clear(); | ||||
| 	size_t varIdx = 0; | ||||
| 	for (size_t i = 0; i < _function.parameterNames.size(); ++i) | ||||
| 		m_locals[_function.parameterNames[i]] = varIdx++; | ||||
| 	for (size_t i = 0; i < _function.parameters.size(); ++i) | ||||
| 		m_locals[_function.parameters[i].name] = varIdx++; | ||||
| 	for (size_t i = 0; i < _function.locals.size(); ++i) | ||||
| 		m_locals[_function.locals[i].variableName] = varIdx++; | ||||
| 
 | ||||
| @ -484,8 +485,8 @@ BinaryTransform::Type BinaryTransform::typeOf(FunctionDefinition const& _funDef) | ||||
| { | ||||
| 
 | ||||
| 	return { | ||||
| 		encodeTypes(vector<wasm::Type>(_funDef.parameterNames.size(), wasm::Type::i64)), | ||||
| 		encodeTypes(vector<wasm::Type>(_funDef.returns ? 1 : 0, wasm::Type::i64)) | ||||
| 		encodeTypes(vector<wasm::Type>(_funDef.parameters.size(), wasm::Type::i64)), | ||||
| 		encodeTypes(vector<wasm::Type>(_funDef.returnType.has_value() ? 1 : 0, wasm::Type::i64)) | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -67,7 +67,8 @@ string TextTransform::run(wasm::Module const& _module) | ||||
| 
 | ||||
| string TextTransform::operator()(wasm::Literal const& _literal) | ||||
| { | ||||
| 	return "(i64.const " + to_string(_literal.value) + ")"; | ||||
| 	yulAssert(holds_alternative<uint64_t>(_literal.value), ""); | ||||
| 	return "(i64.const " + to_string(get<uint64_t>(_literal.value)) + ")"; | ||||
| } | ||||
| 
 | ||||
| string TextTransform::operator()(wasm::StringLiteral const& _literal) | ||||
| @ -164,9 +165,9 @@ string TextTransform::indented(string const& _in) | ||||
| string TextTransform::transform(wasm::FunctionDefinition const& _function) | ||||
| { | ||||
| 	string ret = "(func $" + _function.name + "\n"; | ||||
| 	for (auto const& param: _function.parameterNames) | ||||
| 		ret += "    (param $" + param + " i64)\n"; | ||||
| 	if (_function.returns) | ||||
| 	for (auto const& param: _function.parameters) | ||||
| 		ret += "    (param $" + param.name + " i64)\n"; | ||||
| 	if (_function.returnType.has_value()) | ||||
| 		ret += "    (result i64)\n"; | ||||
| 	for (auto const& local: _function.locals) | ||||
| 		ret += "    (local $" + local.variableName + " i64)\n"; | ||||
|  | ||||
| @ -36,6 +36,9 @@ enum class Type | ||||
| 	i64, | ||||
| }; | ||||
| 
 | ||||
| struct TypedName { std::string name; Type type; }; | ||||
| using TypedNameList = std::vector<TypedName>; | ||||
| 
 | ||||
| struct Literal; | ||||
| struct StringLiteral; | ||||
| struct LocalVariable; | ||||
| @ -56,7 +59,7 @@ using Expression = std::variant< | ||||
| 	Block, If, Loop, Branch, BranchIf, Return | ||||
| >; | ||||
| 
 | ||||
| struct Literal { uint64_t value; }; | ||||
| struct Literal { std::variant<uint32_t, uint64_t> value; }; | ||||
| struct StringLiteral { std::string value; }; | ||||
| struct LocalVariable { std::string name; }; | ||||
| struct GlobalVariable { std::string name; }; | ||||
| @ -76,8 +79,8 @@ struct Branch { Label label; }; | ||||
| struct Return {}; | ||||
| struct BranchIf { Label label; std::unique_ptr<Expression> condition; }; | ||||
| 
 | ||||
| struct VariableDeclaration { std::string variableName; }; | ||||
| struct GlobalVariableDeclaration { std::string variableName; }; | ||||
| struct VariableDeclaration { std::string variableName; Type type; }; | ||||
| struct GlobalVariableDeclaration { std::string variableName; Type type; }; | ||||
| struct FunctionImport { | ||||
| 	std::string module; | ||||
| 	std::string externalName; | ||||
| @ -89,8 +92,8 @@ struct FunctionImport { | ||||
| struct FunctionDefinition | ||||
| { | ||||
| 	std::string name; | ||||
| 	std::vector<std::string> parameterNames; | ||||
| 	bool returns; | ||||
| 	std::vector<TypedName> parameters; | ||||
| 	std::optional<Type> returnType; | ||||
| 	std::vector<VariableDeclaration> locals; | ||||
| 	std::vector<Expression> body; | ||||
| }; | ||||
|  | ||||
| @ -88,7 +88,7 @@ wasm::Expression WasmCodeTransform::operator()(VariableDeclaration const& _varDe | ||||
| 	for (auto const& var: _varDecl.variables) | ||||
| 	{ | ||||
| 		variableNames.emplace_back(var.name.str()); | ||||
| 		m_localVariables.emplace_back(wasm::VariableDeclaration{variableNames.back()}); | ||||
| 		m_localVariables.emplace_back(wasm::VariableDeclaration{variableNames.back(), wasm::Type::i64}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (_varDecl.value) | ||||
| @ -184,7 +184,7 @@ wasm::Expression WasmCodeTransform::operator()(Literal const& _literal) | ||||
| { | ||||
| 	u256 value = valueOfLiteral(_literal); | ||||
| 	yulAssert(value <= numeric_limits<uint64_t>::max(), "Literal too large: " + value.str()); | ||||
| 	return wasm::Literal{uint64_t(value)}; | ||||
| 	return wasm::Literal{static_cast<uint64_t>(value)}; | ||||
| } | ||||
| 
 | ||||
| wasm::Expression WasmCodeTransform::operator()(If const& _if) | ||||
| @ -193,7 +193,7 @@ wasm::Expression WasmCodeTransform::operator()(If const& _if) | ||||
| 
 | ||||
| 	vector<wasm::Expression> args; | ||||
| 	args.emplace_back(visitReturnByValue(*_if.condition)); | ||||
| 	args.emplace_back(wasm::Literal{0}); | ||||
| 	args.emplace_back(wasm::Literal{static_cast<uint64_t>(0)}); | ||||
| 	return wasm::If{ | ||||
| 		make_unique<wasm::Expression>(wasm::BuiltinCall{"i64.ne", std::move(args)}), | ||||
| 		visit(_if.body.statements), | ||||
| @ -205,7 +205,7 @@ wasm::Expression WasmCodeTransform::operator()(Switch const& _switch) | ||||
| { | ||||
| 	wasm::Block block; | ||||
| 	string condition = m_nameDispenser.newName("condition"_yulstring).str(); | ||||
| 	m_localVariables.emplace_back(wasm::VariableDeclaration{condition}); | ||||
| 	m_localVariables.emplace_back(wasm::VariableDeclaration{condition, wasm::Type::i64}); | ||||
| 	block.statements.emplace_back(wasm::LocalAssignment{condition, visit(*_switch.expression)}); | ||||
| 
 | ||||
| 	vector<wasm::Expression>* currentBlock = &block.statements; | ||||
| @ -325,10 +325,11 @@ wasm::FunctionDefinition WasmCodeTransform::translateFunction(yul::FunctionDefin | ||||
| 	wasm::FunctionDefinition fun; | ||||
| 	fun.name = _fun.name.str(); | ||||
| 	for (auto const& param: _fun.parameters) | ||||
| 		fun.parameterNames.emplace_back(param.name.str()); | ||||
| 		fun.parameters.push_back({param.name.str(), wasm::Type::i64}); | ||||
| 	for (auto const& retParam: _fun.returnVariables) | ||||
| 		fun.locals.emplace_back(wasm::VariableDeclaration{retParam.name.str()}); | ||||
| 	fun.returns = !_fun.returnVariables.empty(); | ||||
| 		fun.locals.emplace_back(wasm::VariableDeclaration{retParam.name.str(), wasm::Type::i64}); | ||||
| 	if (!_fun.returnVariables.empty()) | ||||
| 		fun.returnType = wasm::Type::i64; | ||||
| 
 | ||||
| 	yulAssert(m_localVariables.empty(), ""); | ||||
| 	yulAssert(m_functionBodyLabel.empty(), ""); | ||||
| @ -400,7 +401,8 @@ void WasmCodeTransform::allocateGlobals(size_t _amount) | ||||
| { | ||||
| 	while (m_globalVariables.size() < _amount) | ||||
| 		m_globalVariables.emplace_back(wasm::GlobalVariableDeclaration{ | ||||
| 			m_nameDispenser.newName("global_"_yulstring).str() | ||||
| 			m_nameDispenser.newName("global_"_yulstring).str(), | ||||
| 			wasm::Type::i64 | ||||
| 		}); | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user