mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Basic logging in Solidity (though no tests yet).
This commit is contained in:
parent
d18fa27b6a
commit
ffce12b7ee
@ -143,6 +143,11 @@ string const& CompilerStack::getInterface(string const& _contractName) const
|
||||
return getJsonDocumentation(_contractName, DocumentationType::ABI_INTERFACE);
|
||||
}
|
||||
|
||||
string const& CompilerStack::getSolidityInterface(string const& _contractName) const
|
||||
{
|
||||
return getJsonDocumentation(_contractName, DocumentationType::ABI_SOLIDITY_INTERFACE);
|
||||
}
|
||||
|
||||
string const& CompilerStack::getJsonDocumentation(string const& _contractName, DocumentationType _type) const
|
||||
{
|
||||
if (!m_parseSuccessful)
|
||||
@ -162,6 +167,9 @@ string const& CompilerStack::getJsonDocumentation(string const& _contractName, D
|
||||
case DocumentationType::ABI_INTERFACE:
|
||||
doc = &contract.interface;
|
||||
break;
|
||||
case DocumentationType::ABI_SOLIDITY_INTERFACE:
|
||||
doc = &contract.solidityInterface;
|
||||
break;
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal documentation type."));
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ enum class DocumentationType: uint8_t
|
||||
{
|
||||
NATSPEC_USER = 1,
|
||||
NATSPEC_DEV,
|
||||
ABI_INTERFACE
|
||||
ABI_INTERFACE,
|
||||
ABI_SOLIDITY_INTERFACE
|
||||
};
|
||||
|
||||
/**
|
||||
@ -81,6 +82,9 @@ public:
|
||||
/// Returns a string representing the contract interface in JSON.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
std::string const& getInterface(std::string const& _contractName = "") const;
|
||||
/// Returns a string representing the contract interface in JSON.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
std::string const& getSolidityInterface(std::string const& _contractName = "") const;
|
||||
/// Returns a string representing the contract's documentation in JSON.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
/// @param type The type of the documentation to get.
|
||||
@ -118,6 +122,7 @@ private:
|
||||
bytes bytecode;
|
||||
std::shared_ptr<InterfaceHandler> interfaceHandler;
|
||||
mutable std::unique_ptr<std::string const> interface;
|
||||
mutable std::unique_ptr<std::string const> solidityInterface;
|
||||
mutable std::unique_ptr<std::string const> userDocumentation;
|
||||
mutable std::unique_ptr<std::string const> devDocumentation;
|
||||
|
||||
|
@ -256,6 +256,61 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
CompilerUtils(m_context).storeInMemory(0);
|
||||
m_context << u256(32) << u256(0) << eth::Instruction::SHA3;
|
||||
break;
|
||||
case Location::LOG0:
|
||||
arguments.front()->accept(*this);
|
||||
appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front(), true);
|
||||
// @todo move this once we actually use memory
|
||||
CompilerUtils(m_context).storeInMemory(0);
|
||||
m_context << u256(32) << u256(0) << eth::Instruction::LOG0;
|
||||
break;
|
||||
case Location::LOG1:
|
||||
arguments[1]->accept(*this);
|
||||
arguments[0]->accept(*this);
|
||||
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
|
||||
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
|
||||
// @todo move this once we actually use memory
|
||||
CompilerUtils(m_context).storeInMemory(0);
|
||||
m_context << u256(32) << u256(0) << eth::Instruction::LOG1;
|
||||
break;
|
||||
case Location::LOG2:
|
||||
arguments[2]->accept(*this);
|
||||
arguments[1]->accept(*this);
|
||||
arguments[0]->accept(*this);
|
||||
appendTypeConversion(*arguments[2]->getType(), *function.getParameterTypes()[2], true);
|
||||
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
|
||||
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
|
||||
// @todo move this once we actually use memory
|
||||
CompilerUtils(m_context).storeInMemory(0);
|
||||
m_context << u256(32) << u256(0) << eth::Instruction::LOG2;
|
||||
break;
|
||||
case Location::LOG3:
|
||||
arguments[3]->accept(*this);
|
||||
arguments[2]->accept(*this);
|
||||
arguments[1]->accept(*this);
|
||||
arguments[0]->accept(*this);
|
||||
appendTypeConversion(*arguments[3]->getType(), *function.getParameterTypes()[3], true);
|
||||
appendTypeConversion(*arguments[2]->getType(), *function.getParameterTypes()[2], true);
|
||||
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
|
||||
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
|
||||
// @todo move this once we actually use memory
|
||||
CompilerUtils(m_context).storeInMemory(0);
|
||||
m_context << u256(32) << u256(0) << eth::Instruction::LOG3;
|
||||
break;
|
||||
case Location::LOG4:
|
||||
arguments[4]->accept(*this);
|
||||
arguments[3]->accept(*this);
|
||||
arguments[2]->accept(*this);
|
||||
arguments[1]->accept(*this);
|
||||
arguments[0]->accept(*this);
|
||||
appendTypeConversion(*arguments[4]->getType(), *function.getParameterTypes()[4], true);
|
||||
appendTypeConversion(*arguments[3]->getType(), *function.getParameterTypes()[3], true);
|
||||
appendTypeConversion(*arguments[2]->getType(), *function.getParameterTypes()[2], true);
|
||||
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
|
||||
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
|
||||
// @todo move this once we actually use memory
|
||||
CompilerUtils(m_context).storeInMemory(0);
|
||||
m_context << u256(32) << u256(0) << eth::Instruction::LOG4;
|
||||
break;
|
||||
case Location::ECRECOVER:
|
||||
case Location::SHA256:
|
||||
case Location::RIPEMD160:
|
||||
|
@ -33,33 +33,54 @@ namespace solidity
|
||||
{
|
||||
|
||||
GlobalContext::GlobalContext():
|
||||
// TODO: make this cleaner.
|
||||
m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::BLOCK)),
|
||||
make_shared<MagicVariableDeclaration>("msg", make_shared<MagicType>(MagicType::Kind::MSG)),
|
||||
make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::TX)),
|
||||
make_shared<MagicVariableDeclaration>("suicide",
|
||||
make_shared<MagicVariableDeclaration>("msg", make_shared<MagicType>(MagicType::Kind::MSG)),
|
||||
make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::TX)),
|
||||
make_shared<MagicVariableDeclaration>("suicide",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(0,
|
||||
IntegerType::Modifier::ADDRESS)}),
|
||||
TypePointers(),
|
||||
FunctionType::Location::SUICIDE)),
|
||||
make_shared<MagicVariableDeclaration>("sha3",
|
||||
TypePointers(),
|
||||
FunctionType::Location::SUICIDE)),
|
||||
make_shared<MagicVariableDeclaration>("sha3",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
FunctionType::Location::SHA3)),
|
||||
make_shared<MagicVariableDeclaration>("sha256",
|
||||
TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
FunctionType::Location::SHA3)),
|
||||
make_shared<MagicVariableDeclaration>("log0",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
FunctionType::Location::SHA256)),
|
||||
make_shared<MagicVariableDeclaration>("ecrecover",
|
||||
TypePointers(),
|
||||
FunctionType::Location::LOG0)),
|
||||
make_shared<MagicVariableDeclaration>("log1",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers(),
|
||||
FunctionType::Location::LOG1)),
|
||||
make_shared<MagicVariableDeclaration>("log2",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers(),
|
||||
FunctionType::Location::LOG2)),
|
||||
make_shared<MagicVariableDeclaration>("log3",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers(),
|
||||
FunctionType::Location::LOG3)),
|
||||
make_shared<MagicVariableDeclaration>("log4",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH), std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers(),
|
||||
FunctionType::Location::LOG4)),
|
||||
make_shared<MagicVariableDeclaration>("sha256",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
FunctionType::Location::SHA256)),
|
||||
make_shared<MagicVariableDeclaration>("ecrecover",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH),
|
||||
std::make_shared<IntegerType>(8, IntegerType::Modifier::HASH),
|
||||
std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH),
|
||||
std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers({std::make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS)}),
|
||||
FunctionType::Location::ECRECOVER)),
|
||||
make_shared<MagicVariableDeclaration>("ripemd160",
|
||||
TypePointers({std::make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS)}),
|
||||
FunctionType::Location::ECRECOVER)),
|
||||
make_shared<MagicVariableDeclaration>("ripemd160",
|
||||
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
|
||||
TypePointers({std::make_shared<IntegerType>(160, IntegerType::Modifier::HASH)}),
|
||||
FunctionType::Location::RIPEMD160))})
|
||||
TypePointers({std::make_shared<IntegerType>(160, IntegerType::Modifier::HASH)}),
|
||||
FunctionType::Location::RIPEMD160))})
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <libsolidity/InterfaceHandler.h>
|
||||
#include <libsolidity/AST.h>
|
||||
#include <libsolidity/CompilerStack.h>
|
||||
using namespace std;
|
||||
|
||||
namespace dev
|
||||
{
|
||||
@ -26,6 +27,8 @@ std::unique_ptr<std::string> InterfaceHandler::getDocumentation(ContractDefiniti
|
||||
return getDevDocumentation(_contractDef);
|
||||
case DocumentationType::ABI_INTERFACE:
|
||||
return getABIInterface(_contractDef);
|
||||
case DocumentationType::ABI_SOLIDITY_INTERFACE:
|
||||
return getABISolidityInterface(_contractDef);
|
||||
}
|
||||
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation type"));
|
||||
@ -64,6 +67,28 @@ std::unique_ptr<std::string> InterfaceHandler::getABIInterface(ContractDefinitio
|
||||
return std::unique_ptr<std::string>(new std::string(m_writer.write(methods)));
|
||||
}
|
||||
|
||||
unique_ptr<string> InterfaceHandler::getABISolidityInterface(ContractDefinition const& _contractDef)
|
||||
{
|
||||
string ret = "contract " + _contractDef.getName() + "{";
|
||||
for (FunctionDefinition const* f: _contractDef.getInterfaceFunctions())
|
||||
{
|
||||
auto populateParameters = [](vector<ASTPointer<VariableDeclaration>> const& _vars)
|
||||
{
|
||||
string r = "";
|
||||
for (ASTPointer<VariableDeclaration> const& var: _vars)
|
||||
r += (r.size() ? "," : "(") + var->getType()->toString() + " " + var->getName();
|
||||
return r.size() ? r + ")" : "()";
|
||||
};
|
||||
ret += "function " + f->getName() + populateParameters(f->getParameters()) + (f->isDeclaredConst() ? "constant " : "");
|
||||
if (f->getReturnParameters().size())
|
||||
ret += "returns" + populateParameters(f->getReturnParameters());
|
||||
else if (ret.back() == ' ')
|
||||
ret.pop_back();
|
||||
ret += "{}";
|
||||
}
|
||||
return unique_ptr<string>(new string(ret + "}"));
|
||||
}
|
||||
|
||||
std::unique_ptr<std::string> InterfaceHandler::getUserDocumentation(ContractDefinition const& _contractDef)
|
||||
{
|
||||
Json::Value doc;
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
/// @return A unique pointer contained string with the json
|
||||
/// representation of the contract's ABI Interface
|
||||
std::unique_ptr<std::string> getABIInterface(ContractDefinition const& _contractDef);
|
||||
std::unique_ptr<std::string> getABISolidityInterface(ContractDefinition const& _contractDef);
|
||||
/// Get the User documentation of the contract
|
||||
/// @param _contractDef The contract definition
|
||||
/// @return A unique pointer contained string with the json
|
||||
|
2
Types.h
2
Types.h
@ -318,7 +318,7 @@ public:
|
||||
/// INTERNAL: jump tag, EXTERNAL: contract address + function index,
|
||||
/// BARE: contract address (non-abi contract call)
|
||||
/// OTHERS: special virtual function, nothing on the stack
|
||||
enum class Location { INTERNAL, EXTERNAL, SEND, SHA3, SUICIDE, ECRECOVER, SHA256, RIPEMD160, BARE };
|
||||
enum class Location { INTERNAL, EXTERNAL, SEND, SHA3, SUICIDE, ECRECOVER, SHA256, RIPEMD160, LOG0, LOG1, LOG2, LOG3, LOG4, BARE };
|
||||
|
||||
virtual Category getCategory() const override { return Category::FUNCTION; }
|
||||
explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true);
|
||||
|
Loading…
Reference in New Issue
Block a user