Browse Source

Merge pull request #1709 from chriseth/sol_compileToJSON

JSON compiler.
cl-refactor
chriseth 10 years ago
parent
commit
6aed5ec90b
  1. 15
      libsolidity/ASTJsonConverter.cpp
  2. 5
      libsolidity/ASTJsonConverter.h
  3. 4
      libsolidity/Compiler.h
  4. 4
      libsolidity/CompilerContext.h
  5. 7
      libsolidity/CompilerStack.cpp
  6. 3
      libsolidity/CompilerStack.h
  7. 7
      solc/CMakeLists.txt
  8. 124
      solc/jsonCompiler.cpp

15
libsolidity/ASTJsonConverter.cpp

@ -78,10 +78,16 @@ ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast)
void ASTJsonConverter::print(ostream& _stream)
{
m_ast->accept(*this);
process();
_stream << m_astJson;
}
Json::Value const& ASTJsonConverter::json()
{
process();
return m_astJson;
}
bool ASTJsonConverter::visit(ImportDirective const& _node)
{
addJsonNode("Import", { make_pair("file", _node.getIdentifier())});
@ -460,6 +466,13 @@ void ASTJsonConverter::endVisit(Literal const&)
{
}
void ASTJsonConverter::process()
{
if (!processed)
m_ast->accept(*this);
processed = true;
}
string ASTJsonConverter::getType(Expression const& _expression)
{
return (_expression.getType()) ? _expression.getType()->toString() : "Unknown";

5
libsolidity/ASTJsonConverter.h

@ -44,6 +44,7 @@ public:
ASTJsonConverter(ASTNode const& _ast);
/// Output the json representation of the AST to _stream.
void print(std::ostream& _stream);
Json::Value const& json();
bool visit(ImportDirective const& _node) override;
bool visit(ContractDefinition const& _node) override;
@ -114,6 +115,7 @@ public:
void endVisit(Literal const&) override;
private:
void process();
void addKeyValue(Json::Value& _obj, std::string const& _key, std::string const& _val);
void addJsonNode(std::string const& _nodeName,
std::initializer_list<std::pair<std::string const, std::string const>> _list,
@ -123,8 +125,9 @@ private:
{
solAssert(!m_jsonNodePtrs.empty(), "Uneven json nodes stack. Internal error.");
m_jsonNodePtrs.pop();
};
}
bool processed = false;
Json::Value m_astJson;
std::stack<Json::Value*> m_jsonNodePtrs;
std::string m_source;

4
libsolidity/Compiler.h

@ -43,9 +43,9 @@ public:
bytes getRuntimeBytecode() { return m_runtimeContext.getAssembledBytecode(m_optimize);}
/// @arg _sourceCodes is the map of input files to source code strings
/// @arg _inJsonFromat shows whether the out should be in Json format
void streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const
Json::Value streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const
{
m_context.streamAssembly(_stream, _sourceCodes, _inJsonFormat);
return m_context.streamAssembly(_stream, _sourceCodes, _inJsonFormat);
}
/// @returns Assembly items of the normal compiler context
eth::AssemblyItems const& getAssemblyItems() const { return m_context.getAssembly().getItems(); }

4
libsolidity/CompilerContext.h

@ -123,9 +123,9 @@ public:
eth::Assembly const& getAssembly() const { return m_asm; }
/// @arg _sourceCodes is the map of input files to source code strings
/// @arg _inJsonFormat shows whether the out should be in Json format
void streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const
Json::Value streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const
{
m_asm.stream(_stream, "", _sourceCodes, _inJsonFormat);
return m_asm.stream(_stream, "", _sourceCodes, _inJsonFormat);
}
bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); }

7
libsolidity/CompilerStack.cpp

@ -184,13 +184,16 @@ dev::h256 CompilerStack::getContractCodeHash(string const& _contractName) const
return dev::sha3(getRuntimeBytecode(_contractName));
}
void CompilerStack::streamAssembly(ostream& _outStream, string const& _contractName, StringMap _sourceCodes, bool _inJsonFormat) const
Json::Value CompilerStack::streamAssembly(ostream& _outStream, string const& _contractName, StringMap _sourceCodes, bool _inJsonFormat) const
{
Contract const& contract = getContract(_contractName);
if (contract.compiler)
contract.compiler->streamAssembly(_outStream, _sourceCodes, _inJsonFormat);
return contract.compiler->streamAssembly(_outStream, _sourceCodes, _inJsonFormat);
else
{
_outStream << "Contract not fully implemented" << endl;
return Json::Value();
}
}
string const& CompilerStack::getInterface(string const& _contractName) const

3
libsolidity/CompilerStack.h

@ -28,6 +28,7 @@
#include <memory>
#include <vector>
#include <boost/noncopyable.hpp>
#include <json/json.h>
#include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h>
@ -104,7 +105,7 @@ public:
/// @arg _sourceCodes is the map of input files to source code strings
/// @arg _inJsonFromat shows whether the out should be in Json format
/// Prerequisite: Successful compilation.
void streamAssembly(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap(), bool _inJsonFormat = false) const;
Json::Value streamAssembly(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap(), bool _inJsonFormat = false) const;
/// Returns a string representing the contract interface in JSON.
/// Prerequisite: Successful call to parse or compile.

7
solc/CMakeLists.txt

@ -2,6 +2,7 @@ cmake_policy(SET CMP0015 NEW)
set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST)
list(REMOVE_ITEM SRC_LIST "./jsonCompiler.cpp")
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
include_directories(BEFORE ..)
@ -18,3 +19,9 @@ target_link_libraries(${EXECUTABLE} solidity)
install( TARGETS ${EXECUTABLE} DESTINATION bin )
if (ETH_STATIC)
add_library(soljson STATIC jsonCompiler.cpp ${HEADERS})
else()
add_library(soljson SHARED jsonCompiler.cpp ${HEADERS})
endif()
target_link_libraries(soljson solidity)

124
solc/jsonCompiler.cpp

@ -0,0 +1,124 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum 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.
cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
* @date 2014
* JSON interface for the solidity compiler to be used from Javascript.
*/
#include <string>
#include <iostream>
#include <json/json.h>
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include <libevmcore/Instruction.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
#include <libsolidity/ASTPrinter.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Exceptions.h>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/SourceReferenceFormatter.h>
#include <libsolidity/ASTJsonConverter.h>
using namespace std;
using namespace dev;
using namespace solidity;
string formatError(Exception const& _exception, string const& _name, CompilerStack const& _compiler)
{
ostringstream errorOutput;
SourceReferenceFormatter::printExceptionInformation(errorOutput, _exception, _name, _compiler);
Json::Value output(Json::objectValue);
output["error"] = errorOutput.str();
return Json::FastWriter().write(output);
}
string compile(string _input, bool _optimize)
{
StringMap sources;
sources[""] = _input;
Json::Value output(Json::objectValue);
CompilerStack compiler;
try
{
compiler.compile(_input, _optimize);
}
catch (ParserError const& exception)
{
return formatError(exception, "Parser error", compiler);
}
catch (DeclarationError const& exception)
{
return formatError(exception, "Declaration error", compiler);
}
catch (TypeError const& exception)
{
return formatError(exception, "Type error", compiler);
}
catch (CompilerError const& exception)
{
return formatError(exception, "Compiler error", compiler);
}
catch (InternalCompilerError const& exception)
{
return formatError(exception, "Internal compiler error", compiler);
}
catch (Exception const& exception)
{
output["error"] = "Exception during compilation: " + boost::diagnostic_information(exception);
return Json::FastWriter().write(output);
}
catch (...)
{
output["error"] = "Unknown exception during compilation.";
return Json::FastWriter().write(output);
}
output["contracts"] = Json::Value(Json::objectValue);
for (string const& contractName: compiler.getContractNames())
{
Json::Value contractData(Json::objectValue);
contractData["solidity_interface"] = compiler.getSolidityInterface(contractName);
contractData["interface"] = compiler.getInterface(contractName);
contractData["bytecode"] = toHex(compiler.getBytecode(contractName));
contractData["opcodes"] = eth::disassemble(compiler.getBytecode(contractName));
ostringstream unused;
contractData["assembly"] = compiler.streamAssembly(unused, contractName, sources);
output["contracts"][contractName] = contractData;
}
output["sources"] = Json::Value(Json::objectValue);
output["sources"][""] = Json::Value(Json::objectValue);
output["sources"][""]["AST"] = ASTJsonConverter(compiler.getAST("")).json();
return Json::FastWriter().write(output);
}
static string outputBuffer;
extern "C"
{
extern char const* compileJSON(char const* _input, bool _optimize)
{
outputBuffer = compile(_input, _optimize);
return outputBuffer.c_str();
}
}
Loading…
Cancel
Save