mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +00:00
Moving Compiler to separated files
This commit is contained in:
commit
f5eda1f1b3
6 changed files with 267 additions and 0 deletions
49
evmcc/CMakeLists.txt
Normal file
49
evmcc/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
cmake_policy(SET CMP0015 NEW)
|
||||||
|
|
||||||
|
aux_source_directory(. SRC_LIST)
|
||||||
|
|
||||||
|
include_directories(..)
|
||||||
|
|
||||||
|
set(EXECUTABLE evmcc)
|
||||||
|
|
||||||
|
add_executable(${EXECUTABLE} ${SRC_LIST})
|
||||||
|
|
||||||
|
target_link_libraries(${EXECUTABLE} evmface)
|
||||||
|
target_link_libraries(${EXECUTABLE} devcore)
|
||||||
|
|
||||||
|
if ("${TARGET_PLATFORM}" STREQUAL "w64")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
|
||||||
|
target_link_libraries(${EXECUTABLE} gcc)
|
||||||
|
target_link_libraries(${EXECUTABLE} gdi32)
|
||||||
|
target_link_libraries(${EXECUTABLE} ws2_32)
|
||||||
|
target_link_libraries(${EXECUTABLE} mswsock)
|
||||||
|
target_link_libraries(${EXECUTABLE} shlwapi)
|
||||||
|
target_link_libraries(${EXECUTABLE} iphlpapi)
|
||||||
|
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
|
||||||
|
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
|
||||||
|
elseif (UNIX)
|
||||||
|
else ()
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# LLVM specific commands
|
||||||
|
|
||||||
|
find_package(LLVM REQUIRED CONFIG)
|
||||||
|
|
||||||
|
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||||
|
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||||
|
|
||||||
|
include_directories(${LLVM_INCLUDE_DIRS})
|
||||||
|
add_definitions(${LLVM_DEFINITIONS})
|
||||||
|
|
||||||
|
llvm_map_components_to_libnames(llvm_libs support core irreader)
|
||||||
|
target_link_libraries(evmcc ${llvm_libs})
|
||||||
|
|
||||||
|
# end of LLVM specific commands
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
install( TARGETS ${EXECUTABLE} DESTINATION bin )
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0015 NEW)
|
||||||
75
evmcc/Compiler.cpp
Normal file
75
evmcc/Compiler.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
|
||||||
|
#include "Compiler.h"
|
||||||
|
|
||||||
|
#include <llvm/IR/IRBuilder.h>
|
||||||
|
#include <llvm/IR/Module.h>
|
||||||
|
|
||||||
|
namespace evmcc
|
||||||
|
{
|
||||||
|
|
||||||
|
Compiler::Compiler()
|
||||||
|
{
|
||||||
|
auto& context = llvm::getGlobalContext();
|
||||||
|
Types.word8 = llvm::Type::getInt8Ty(context);
|
||||||
|
Types.word8ptr = llvm::Type::getInt8PtrTy(context);
|
||||||
|
Types.word256 = llvm::Type::getIntNTy(context, 256);
|
||||||
|
Types.word256ptr = Types.word256->getPointerTo();
|
||||||
|
Types.word256arr = llvm::ArrayType::get(Types.word256, 100);
|
||||||
|
Types.size = llvm::Type::getInt64Ty(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Compiler::compile(const dev::bytes& bytecode)
|
||||||
|
{
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
auto& context = getGlobalContext();
|
||||||
|
|
||||||
|
Module* module = new Module("main", context);
|
||||||
|
IRBuilder<> builder(context);
|
||||||
|
|
||||||
|
// Create globals for memory, memory size, stack and stack top
|
||||||
|
auto memory = new GlobalVariable(*module, Types.word8ptr, false,
|
||||||
|
GlobalValue::LinkageTypes::PrivateLinkage,
|
||||||
|
Constant::getNullValue(Types.word8ptr), "memory");
|
||||||
|
auto memSize = new GlobalVariable(*module, Types.size, false,
|
||||||
|
GlobalValue::LinkageTypes::PrivateLinkage,
|
||||||
|
ConstantInt::get(Types.size, 0), "memsize");
|
||||||
|
auto stack = new GlobalVariable(*module, Types.word256arr, false,
|
||||||
|
GlobalValue::LinkageTypes::PrivateLinkage,
|
||||||
|
ConstantAggregateZero::get(Types.word256arr), "stack");
|
||||||
|
auto stackTop = new GlobalVariable(*module, Types.size, false,
|
||||||
|
GlobalValue::LinkageTypes::PrivateLinkage,
|
||||||
|
ConstantInt::get(Types.size, 0), "stackTop");
|
||||||
|
|
||||||
|
// Create value for void* malloc(size_t)
|
||||||
|
std::vector<Type*> mallocArgTypes = { Types.size };
|
||||||
|
Value* mallocVal = Function::Create(FunctionType::get(Types.word8ptr, mallocArgTypes, false),
|
||||||
|
GlobalValue::LinkageTypes::ExternalLinkage, "malloc", module);
|
||||||
|
|
||||||
|
// Create main function
|
||||||
|
FunctionType* funcType = FunctionType::get(llvm::Type::getInt32Ty(context), false);
|
||||||
|
Function* mainFunc = Function::Create(funcType, Function::ExternalLinkage, "main", module);
|
||||||
|
|
||||||
|
BasicBlock* entryBlock = BasicBlock::Create(context, "entry", mainFunc);
|
||||||
|
builder.SetInsertPoint(entryBlock);
|
||||||
|
|
||||||
|
// Initialize memory with call to malloc, update memsize
|
||||||
|
std::vector<Value*> mallocMemArgs = { ConstantInt::get(Types.size, 100) };
|
||||||
|
auto mallocMemCall = builder.CreateCall(mallocVal, mallocMemArgs, "malloc_mem");
|
||||||
|
builder.CreateStore(mallocMemCall, memory);
|
||||||
|
builder.CreateStore(ConstantInt::get(Types.size, 100), memSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::vector<Value*> mallocStackArgs = { ConstantInt::get(sizeTy, 200) };
|
||||||
|
auto mallocStackCall = builder.CreateCall(mallocVal, mallocStackArgs, "malloc_stack");
|
||||||
|
auto mallocCast = builder.CreatePointerBitCastOrAddrSpaceCast(mallocStackCall, int256ptr);
|
||||||
|
builder.CreateStore(mallocCast, stackVal);
|
||||||
|
*/
|
||||||
|
|
||||||
|
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0));
|
||||||
|
|
||||||
|
module->dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
evmcc/Compiler.h
Normal file
34
evmcc/Compiler.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <llvm/IR/Type.h>
|
||||||
|
|
||||||
|
#include <libdevcore/Common.h>
|
||||||
|
|
||||||
|
namespace evmcc
|
||||||
|
{
|
||||||
|
|
||||||
|
class Compiler
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
llvm::Type* word8;
|
||||||
|
llvm::Type* word8ptr;
|
||||||
|
llvm::Type* word256;
|
||||||
|
llvm::Type* word256ptr;
|
||||||
|
llvm::Type* word256arr;
|
||||||
|
llvm::Type* size;
|
||||||
|
} Types;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Compiler();
|
||||||
|
|
||||||
|
void compile(const dev::bytes& bytecode);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
1
evmcc/bytecode/kv.evm
Normal file
1
evmcc/bytecode/kv.evm
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
33604557602a8060106000396000f200604556330e0f602a59366080530a0f602a59602060805301356080533557604060805301608054600958
|
||||||
98
evmcc/evmcc.cpp
Normal file
98
evmcc/evmcc.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include <libdevcore/Common.h>
|
||||||
|
#include <libdevcore/CommonIO.h>
|
||||||
|
#include <libevmface/Instruction.h>
|
||||||
|
|
||||||
|
#include "Compiler.h"
|
||||||
|
|
||||||
|
using namespace dev;
|
||||||
|
|
||||||
|
|
||||||
|
void show_usage()
|
||||||
|
{
|
||||||
|
// FIXME: Use arg[0] as program name?
|
||||||
|
std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string input_file;
|
||||||
|
bool opt_dissassemble = false;
|
||||||
|
bool opt_show_bytes = false;
|
||||||
|
bool opt_compile = false;
|
||||||
|
bool opt_unknown = false;
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
std::string option = argv[i];
|
||||||
|
if (option == "-b")
|
||||||
|
{
|
||||||
|
opt_show_bytes = true;
|
||||||
|
}
|
||||||
|
else if (option == "-c")
|
||||||
|
{
|
||||||
|
opt_compile = true;
|
||||||
|
}
|
||||||
|
else if (option == "-d")
|
||||||
|
{
|
||||||
|
opt_dissassemble = true;
|
||||||
|
}
|
||||||
|
else if (option[0] != '-' && input_file.empty())
|
||||||
|
{
|
||||||
|
input_file = option;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opt_unknown = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_unknown ||
|
||||||
|
input_file.empty() ||
|
||||||
|
(!opt_show_bytes && !opt_compile && !opt_dissassemble))
|
||||||
|
{
|
||||||
|
show_usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream ifs(input_file);
|
||||||
|
if (!ifs.is_open())
|
||||||
|
{
|
||||||
|
std::cerr << "cannot open file " << input_file << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string src((std::istreambuf_iterator<char>(ifs)),
|
||||||
|
(std::istreambuf_iterator<char>()));
|
||||||
|
|
||||||
|
boost::algorithm::trim(src);
|
||||||
|
|
||||||
|
bytes bytecode = fromHex(src);
|
||||||
|
|
||||||
|
if (opt_show_bytes)
|
||||||
|
{
|
||||||
|
std::cout << dev::memDump(bytecode) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_dissassemble)
|
||||||
|
{
|
||||||
|
std::string assembly = eth::disassemble(bytecode);
|
||||||
|
std::cout << assembly << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_compile)
|
||||||
|
{
|
||||||
|
evmcc::Compiler().compile(bytecode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
10
evmcc/lll/kv.lll
Normal file
10
evmcc/lll/kv.lll
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
[[69]] (caller)
|
||||||
|
(return 0 (lll
|
||||||
|
(when (= (caller) @@69)
|
||||||
|
(for {} (< @i (calldatasize)) [i](+ @i 64)
|
||||||
|
[[ (calldataload @i) ]] (calldataload (+ @i 32))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
0))
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue