yann300
10 years ago
302 changed files with 15279 additions and 974 deletions
@ -0,0 +1,27 @@ |
|||||
|
cmake_minimum_required(VERSION 2.8.12) |
||||
|
|
||||
|
project(evmjit) |
||||
|
|
||||
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON) |
||||
|
|
||||
|
# LLVM |
||||
|
if(LLVM_DIR) # local LLVM build |
||||
|
find_package(LLVM REQUIRED CONFIG) |
||||
|
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") |
||||
|
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") |
||||
|
# TODO: bitwriter is needed only for evmcc |
||||
|
llvm_map_components_to_libnames(LLVM_LIBS core support mcjit x86asmparser x86codegen bitwriter) |
||||
|
else() |
||||
|
# Workaround for Ubuntu broken LLVM package |
||||
|
message(STATUS "Using llvm-3.5-dev package from Ubuntu. If does not work, build LLVM and set -DLLVM_DIR=llvm-build/share/llvm/cmake") |
||||
|
execute_process(COMMAND llvm-config-3.5 --includedir OUTPUT_VARIABLE LLVM_INCLUDE_DIRS) |
||||
|
message(STATUS "LLVM include dirs: ${LLVM_INCLUDE_DIRS}") |
||||
|
set(LLVM_LIBS "-lLLVMBitWriter -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMX86AsmParser -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMExecutionEngine -lLLVMMC -lLLVMCore -lLLVMSupport -lz -lpthread -lffi -ltinfo -ldl -lm") |
||||
|
endif() |
||||
|
|
||||
|
# Boost |
||||
|
find_package(Boost REQUIRED) |
||||
|
|
||||
|
add_subdirectory(libevmjit) |
||||
|
add_subdirectory(libevmjit-cpp) |
||||
|
add_subdirectory(evmcc) |
@ -0,0 +1,18 @@ |
|||||
|
set(TARGET_NAME evmcc) |
||||
|
|
||||
|
set(SOURCES |
||||
|
evmcc.cpp |
||||
|
) |
||||
|
source_group("" FILES ${SOURCES}) |
||||
|
|
||||
|
add_executable(${TARGET_NAME} ${SOURCES}) |
||||
|
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "tools") |
||||
|
|
||||
|
include_directories(../..) |
||||
|
include_directories(${LLVM_INCLUDE_DIRS}) |
||||
|
include_directories(${Boost_INCLUDE_DIRS}) |
||||
|
|
||||
|
target_link_libraries(${TARGET_NAME} ethereum) |
||||
|
target_link_libraries(${TARGET_NAME} ${Boost_PROGRAM_OPTIONS_LIBRARIES}) |
||||
|
|
||||
|
install(TARGETS ${TARGET_NAME} DESTINATION bin ) |
@ -0,0 +1,211 @@ |
|||||
|
|
||||
|
#include <chrono> |
||||
|
#include <iostream> |
||||
|
#include <fstream> |
||||
|
#include <ostream> |
||||
|
#include <string> |
||||
|
#include <vector> |
||||
|
|
||||
|
#include <boost/algorithm/string.hpp> |
||||
|
#include <boost/program_options.hpp> |
||||
|
|
||||
|
#include <llvm/Bitcode/ReaderWriter.h> |
||||
|
#include <llvm/Support/raw_os_ostream.h> |
||||
|
#include <llvm/Support/Signals.h> |
||||
|
#include <llvm/Support/PrettyStackTrace.h> |
||||
|
|
||||
|
#include <libdevcore/Common.h> |
||||
|
#include <libdevcore/CommonIO.h> |
||||
|
#include <libevmcore/Instruction.h> |
||||
|
#include <libevm/ExtVMFace.h> |
||||
|
#include <evmjit/libevmjit/Compiler.h> |
||||
|
#include <evmjit/libevmjit/ExecutionEngine.h> |
||||
|
|
||||
|
|
||||
|
void parseProgramOptions(int _argc, char** _argv, boost::program_options::variables_map& _varMap) |
||||
|
{ |
||||
|
namespace opt = boost::program_options; |
||||
|
|
||||
|
opt::options_description explicitOpts("Allowed options"); |
||||
|
explicitOpts.add_options() |
||||
|
("help,h", "show usage information") |
||||
|
("compile,c", "compile the code to LLVM IR") |
||||
|
("interpret,i", "compile the code to LLVM IR and execute") |
||||
|
("gas,g", opt::value<size_t>(), "set initial gas for execution") |
||||
|
("disassemble,d", "dissassemble the code") |
||||
|
("dump-cfg", "dump control flow graph to graphviz file") |
||||
|
("dont-optimize", "turn off optimizations") |
||||
|
("optimize-stack", "optimize stack use between basic blocks (default: on)") |
||||
|
("rewrite-switch", "rewrite LLVM switch to branches (default: on)") |
||||
|
("output-ll", opt::value<std::string>(), "dump generated LLVM IR to file") |
||||
|
("output-bc", opt::value<std::string>(), "dump generated LLVM bitcode to file") |
||||
|
("show-logs", "output LOG statements to stderr") |
||||
|
("verbose,V", "enable verbose output"); |
||||
|
|
||||
|
opt::options_description implicitOpts("Input files"); |
||||
|
implicitOpts.add_options() |
||||
|
("input-file", opt::value<std::string>(), "input file"); |
||||
|
|
||||
|
opt::options_description allOpts(""); |
||||
|
allOpts.add(explicitOpts).add(implicitOpts); |
||||
|
|
||||
|
opt::positional_options_description inputOpts; |
||||
|
inputOpts.add("input-file", 1); |
||||
|
|
||||
|
const char* errorMsg = nullptr; |
||||
|
try |
||||
|
{ |
||||
|
auto parser = opt::command_line_parser(_argc, _argv).options(allOpts).positional(inputOpts); |
||||
|
opt::store(parser.run(), _varMap); |
||||
|
opt::notify(_varMap); |
||||
|
} |
||||
|
catch (boost::program_options::error& err) |
||||
|
{ |
||||
|
errorMsg = err.what(); |
||||
|
} |
||||
|
|
||||
|
if (!errorMsg && _varMap.count("input-file") == 0) |
||||
|
errorMsg = "missing input file name"; |
||||
|
|
||||
|
if (_varMap.count("disassemble") == 0 |
||||
|
&& _varMap.count("compile") == 0 |
||||
|
&& _varMap.count("interpret") == 0) |
||||
|
{ |
||||
|
errorMsg = "at least one of -c, -i, -d is required"; |
||||
|
} |
||||
|
|
||||
|
if (errorMsg || _varMap.count("help")) |
||||
|
{ |
||||
|
if (errorMsg) |
||||
|
std::cerr << "Error: " << errorMsg << std::endl; |
||||
|
|
||||
|
std::cout << "Usage: " << _argv[0] << " <options> input-file " << std::endl |
||||
|
<< explicitOpts << std::endl; |
||||
|
std::exit(errorMsg ? 1 : 0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int main(int argc, char** argv) |
||||
|
{ |
||||
|
llvm::sys::PrintStackTraceOnErrorSignal(); |
||||
|
llvm::PrettyStackTraceProgram X(argc, argv); |
||||
|
|
||||
|
boost::program_options::variables_map options; |
||||
|
parseProgramOptions(argc, argv, options); |
||||
|
|
||||
|
auto inputFile = options["input-file"].as<std::string>(); |
||||
|
std::ifstream ifs(inputFile); |
||||
|
if (!ifs.is_open()) |
||||
|
{ |
||||
|
std::cerr << "cannot open input file " << inputFile << std::endl; |
||||
|
exit(1); |
||||
|
} |
||||
|
|
||||
|
std::string src((std::istreambuf_iterator<char>(ifs)), |
||||
|
(std::istreambuf_iterator<char>())); |
||||
|
|
||||
|
boost::algorithm::trim(src); |
||||
|
|
||||
|
using namespace dev; |
||||
|
|
||||
|
bytes bytecode = fromHex(src); |
||||
|
|
||||
|
if (options.count("disassemble")) |
||||
|
{ |
||||
|
std::string assembly = eth::disassemble(bytecode); |
||||
|
std::cout << assembly << std::endl; |
||||
|
} |
||||
|
|
||||
|
if (options.count("compile") || options.count("interpret")) |
||||
|
{ |
||||
|
size_t initialGas = 10000; |
||||
|
|
||||
|
if (options.count("gas")) |
||||
|
initialGas = options["gas"].as<size_t>(); |
||||
|
|
||||
|
auto compilationStartTime = std::chrono::high_resolution_clock::now(); |
||||
|
|
||||
|
eth::jit::Compiler::Options compilerOptions; |
||||
|
compilerOptions.dumpCFG = options.count("dump-cfg") > 0; |
||||
|
bool optimize = options.count("dont-optimize") == 0; |
||||
|
compilerOptions.optimizeStack = optimize || options.count("optimize-stack") > 0; |
||||
|
compilerOptions.rewriteSwitchToBranches = optimize || options.count("rewrite-switch") > 0; |
||||
|
|
||||
|
auto compiler = eth::jit::Compiler(compilerOptions); |
||||
|
auto module = compiler.compile(bytecode, "main"); |
||||
|
|
||||
|
auto compilationEndTime = std::chrono::high_resolution_clock::now(); |
||||
|
|
||||
|
module->dump(); |
||||
|
|
||||
|
if (options.count("output-ll")) |
||||
|
{ |
||||
|
auto outputFile = options["output-ll"].as<std::string>(); |
||||
|
std::ofstream ofs(outputFile); |
||||
|
if (!ofs.is_open()) |
||||
|
{ |
||||
|
std::cerr << "cannot open output file " << outputFile << std::endl; |
||||
|
exit(1); |
||||
|
} |
||||
|
llvm::raw_os_ostream ros(ofs); |
||||
|
module->print(ros, nullptr); |
||||
|
ofs.close(); |
||||
|
} |
||||
|
|
||||
|
if (options.count("output-bc")) |
||||
|
{ |
||||
|
auto outputFile = options["output-bc"].as<std::string>(); |
||||
|
std::ofstream ofs(outputFile); |
||||
|
if (!ofs.is_open()) |
||||
|
{ |
||||
|
std::cerr << "cannot open output file " << outputFile << std::endl; |
||||
|
exit(1); |
||||
|
} |
||||
|
llvm::raw_os_ostream ros(ofs); |
||||
|
llvm::WriteBitcodeToFile(module.get(), ros); |
||||
|
ros.flush(); |
||||
|
ofs.close(); |
||||
|
} |
||||
|
|
||||
|
if (options.count("verbose")) |
||||
|
{ |
||||
|
std::cerr << "*** Compilation time: " |
||||
|
<< std::chrono::duration_cast<std::chrono::microseconds>(compilationEndTime - compilationStartTime).count() |
||||
|
<< std::endl; |
||||
|
} |
||||
|
|
||||
|
if (options.count("interpret")) |
||||
|
{ |
||||
|
using namespace eth::jit; |
||||
|
|
||||
|
ExecutionEngine engine; |
||||
|
eth::jit::u256 gas = initialGas; |
||||
|
|
||||
|
// Create random runtime data
|
||||
|
RuntimeData data; |
||||
|
data.set(RuntimeData::Gas, gas); |
||||
|
data.set(RuntimeData::Address, (u160)Address(1122334455667788)); |
||||
|
data.set(RuntimeData::Caller, (u160)Address(0xfacefacefaceface)); |
||||
|
data.set(RuntimeData::Origin, (u160)Address(101010101010101010)); |
||||
|
data.set(RuntimeData::CallValue, 0xabcd); |
||||
|
data.set(RuntimeData::CallDataSize, 3); |
||||
|
data.set(RuntimeData::GasPrice, 1003); |
||||
|
data.set(RuntimeData::PrevHash, 1003); |
||||
|
data.set(RuntimeData::CoinBase, (u160)Address(101010101010101015)); |
||||
|
data.set(RuntimeData::TimeStamp, 1005); |
||||
|
data.set(RuntimeData::Number, 1006); |
||||
|
data.set(RuntimeData::Difficulty, 16); |
||||
|
data.set(RuntimeData::GasLimit, 1008); |
||||
|
data.set(RuntimeData::CodeSize, bytecode.size()); |
||||
|
data.callData = (uint8_t*)"abc"; |
||||
|
data.code = bytecode.data(); |
||||
|
|
||||
|
// BROKEN: env_* functions must be implemented & RuntimeData struct created
|
||||
|
// TODO: Do not compile module again
|
||||
|
auto result = engine.run(bytecode, &data, nullptr); |
||||
|
return static_cast<int>(result); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
60646107b760271460005560006001f2 |
@ -0,0 +1,12 @@ |
|||||
|
;; Should return (1975 + 39) `mod` 100 = 14 = 0x0e |
||||
|
(asm |
||||
|
100 |
||||
|
1975 |
||||
|
39 |
||||
|
ADDMOD |
||||
|
0 |
||||
|
MSTORE8 |
||||
|
0 |
||||
|
1 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
60016001900160070260050160029004600490066021900560150160030260059007600303600960110860005460086000f2 |
@ -0,0 +1,37 @@ |
|||||
|
|
||||
|
(asm |
||||
|
1 |
||||
|
1 |
||||
|
SWAP1 |
||||
|
ADD ;; 2 |
||||
|
7 |
||||
|
MUL ;; 14 |
||||
|
5 |
||||
|
ADD ;; 19 |
||||
|
2 |
||||
|
SWAP1 |
||||
|
DIV ;; 9 |
||||
|
4 |
||||
|
SWAP1 |
||||
|
MOD ;; 1 |
||||
|
33 |
||||
|
SWAP1 |
||||
|
SDIV;; 0 |
||||
|
21 |
||||
|
ADD ;; 21 |
||||
|
3 |
||||
|
MUL ;; 63 |
||||
|
5 |
||||
|
SWAP1 |
||||
|
SMOD;; 3 |
||||
|
3 |
||||
|
SUB ;; 0 |
||||
|
9 |
||||
|
17 |
||||
|
EXP ;; 17^9 |
||||
|
0 |
||||
|
MSTORE |
||||
|
8 |
||||
|
0 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6201e2406000546000530960005460206000f2 |
@ -0,0 +1,14 @@ |
|||||
|
|
||||
|
(asm |
||||
|
123456 |
||||
|
0 |
||||
|
MSTORE |
||||
|
0 |
||||
|
MLOAD |
||||
|
BNOT |
||||
|
0 |
||||
|
MSTORE |
||||
|
32 |
||||
|
0 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
60027ffedcba9876543210fedcba9876543210fedcba9876543210fedcba98765432100460005460206000f2 |
@ -0,0 +1,10 @@ |
|||||
|
(asm |
||||
|
0x2 |
||||
|
0xfedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210 |
||||
|
DIV |
||||
|
0 |
||||
|
MSTORE |
||||
|
32 |
||||
|
0 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
60016001818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101 |
@ -0,0 +1,57 @@ |
|||||
|
;; Fibbonacci unrolled |
||||
|
|
||||
|
(asm |
||||
|
1 |
||||
|
1 |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
DUP2 |
||||
|
DUP2 |
||||
|
ADD |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
7001234567890abcdef0fedcba09876543217001234567890abcdef0fedcba09876543217001234567890abcdef0fedcba0987654321020260005460206000f2 |
@ -0,0 +1,13 @@ |
|||||
|
(asm |
||||
|
0x1234567890abcdef0fedcba0987654321 |
||||
|
0x1234567890abcdef0fedcba0987654321 |
||||
|
0x1234567890abcdef0fedcba0987654321 |
||||
|
MUL |
||||
|
MUL |
||||
|
0 |
||||
|
MSTORE |
||||
|
32 |
||||
|
0 |
||||
|
RETURN |
||||
|
;; 47d0817e4167b1eb4f9fc722b133ef9d7d9a6fb4c2c1c442d000107a5e419561 |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6064601b60251560005560006001f2 |
@ -0,0 +1,12 @@ |
|||||
|
;; Should return (27 * 37) `mod` 100 = 99 = 0x63 |
||||
|
(asm |
||||
|
100 |
||||
|
27 |
||||
|
37 |
||||
|
MULMOD |
||||
|
0 |
||||
|
MSTORE8 |
||||
|
0 |
||||
|
1 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
4a |
@ -0,0 +1 @@ |
|||||
|
60326000600a37600053600a6014f2 |
@ -0,0 +1,13 @@ |
|||||
|
(asm |
||||
|
50 ;; byte count |
||||
|
0 ;; source index in calldata array |
||||
|
10 ;; dest index in memory |
||||
|
CALLDATACOPY |
||||
|
|
||||
|
0 |
||||
|
MLOAD ;; to dump memory |
||||
|
|
||||
|
10 |
||||
|
20 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
606464e8d4a510006000376000536000600af2 |
@ -0,0 +1,13 @@ |
|||||
|
(asm |
||||
|
100 ;; byte count |
||||
|
1000000000000 ;; source index in calldata array |
||||
|
0 ;; dest index in memory |
||||
|
CALLDATACOPY |
||||
|
|
||||
|
0 |
||||
|
MLOAD ;; to dump memory |
||||
|
|
||||
|
0 |
||||
|
10 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
60146000600a39600053600a6014f2 |
@ -0,0 +1,13 @@ |
|||||
|
(asm |
||||
|
20 ;; byte count |
||||
|
0 ;; source index in code array |
||||
|
10 ;; dest index in memory |
||||
|
CODECOPY |
||||
|
|
||||
|
0 |
||||
|
MLOAD ;; to dump memory |
||||
|
|
||||
|
10 |
||||
|
20 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
606464e8d4a510006000396000536000600af2 |
@ -0,0 +1,13 @@ |
|||||
|
(asm |
||||
|
100 ;; byte count |
||||
|
1000000000000 ;; source index in code array |
||||
|
0 ;; dest index in memory |
||||
|
CODECOPY |
||||
|
|
||||
|
0 |
||||
|
MLOAD ;; to dump memory |
||||
|
|
||||
|
0 |
||||
|
10 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
3860006000396000536000600af2 |
@ -0,0 +1,13 @@ |
|||||
|
(asm |
||||
|
CODESIZE ;; byte count |
||||
|
0 ;; source index in code array |
||||
|
0 ;; dest index in memory |
||||
|
CODECOPY |
||||
|
|
||||
|
0 |
||||
|
MLOAD ;; to dump memory |
||||
|
|
||||
|
0 |
||||
|
10 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
5a3031333234363a4041424344455a36600035602635601335387f1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff600054602060006000f06020600060206000600030610bb8f1600053611000545b60200260002030ff60016002f2 |
@ -0,0 +1,55 @@ |
|||||
|
|
||||
|
(asm |
||||
|
PC |
||||
|
ADDRESS |
||||
|
BALANCE |
||||
|
CALLER |
||||
|
ORIGIN |
||||
|
CALLVALUE |
||||
|
CALLDATASIZE |
||||
|
GASPRICE |
||||
|
PREVHASH |
||||
|
COINBASE |
||||
|
TIMESTAMP |
||||
|
NUMBER |
||||
|
DIFFICULTY |
||||
|
GASLIMIT |
||||
|
PC |
||||
|
CALLDATASIZE |
||||
|
0 |
||||
|
CALLDATALOAD |
||||
|
38 |
||||
|
CALLDATALOAD |
||||
|
19 |
||||
|
CALLDATALOAD |
||||
|
CODESIZE |
||||
|
0x1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff |
||||
|
0 |
||||
|
MSTORE |
||||
|
32 |
||||
|
0 |
||||
|
0 |
||||
|
CREATE |
||||
|
32 |
||||
|
0 |
||||
|
32 |
||||
|
0 |
||||
|
0 |
||||
|
ADDRESS |
||||
|
3000 |
||||
|
CALL |
||||
|
0 |
||||
|
MLOAD |
||||
|
4096 |
||||
|
MSTORE |
||||
|
MSIZE |
||||
|
32 |
||||
|
MUL |
||||
|
0 |
||||
|
SHA3 |
||||
|
ADDRESS |
||||
|
SUICIDE |
||||
|
1 |
||||
|
2 |
||||
|
RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
60c86000600a303c60005360006020f2 |
@ -0,0 +1,11 @@ |
|||||
|
(asm |
||||
|
200 ;; byte count |
||||
|
0 ;; source index in code array |
||||
|
10 ;; dest index in memory |
||||
|
ADDRESS |
||||
|
EXTCODECOPY |
||||
|
|
||||
|
0 MLOAD ;; to dump memory |
||||
|
|
||||
|
0 32 RETURN |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6104d26063576000606357 |
@ -0,0 +1,9 @@ |
|||||
|
|
||||
|
(asm |
||||
|
1234 |
||||
|
99 |
||||
|
SSTORE |
||||
|
0 |
||||
|
99 |
||||
|
SSTORE |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
607b607c60015760005760015660005603 |
@ -0,0 +1,14 @@ |
|||||
|
|
||||
|
(asm |
||||
|
123 |
||||
|
124 |
||||
|
1 |
||||
|
SSTORE |
||||
|
0 |
||||
|
SSTORE |
||||
|
1 |
||||
|
SLOAD |
||||
|
0 |
||||
|
SLOAD |
||||
|
SUB |
||||
|
) |
@ -0,0 +1,7 @@ |
|||||
|
let A m n = |
||||
|
if m == 0 then n+1 |
||||
|
else if n == 0 then A (m-1) 1 |
||||
|
else A (m-1) (A (m) (n-1)) |
||||
|
|
||||
|
return A 3 8 |
||||
|
|
@ -0,0 +1 @@ |
|||||
|
6009600360086012585d60005460206000f26000820e6047596000810e603859603460018303603084600185036012585d6012585d60445860436001830360016012585d604b5860018101905090509058 |
@ -0,0 +1 @@ |
|||||
|
601b602502585d |
@ -0,0 +1,9 @@ |
|||||
|
;; Indirect jump out of code |
||||
|
|
||||
|
(asm |
||||
|
27 |
||||
|
37 |
||||
|
MUL |
||||
|
JUMP |
||||
|
JUMPDEST |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
60016003600302596000600058 |
@ -0,0 +1,12 @@ |
|||||
|
;; Indirect jump into data |
||||
|
|
||||
|
(asm |
||||
|
1 ;; 0 |
||||
|
3 |
||||
|
3 |
||||
|
MUL ;; 6 |
||||
|
JUMPI ;; 7 |
||||
|
0 ;; 8 |
||||
|
0 |
||||
|
JUMP |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6103e758 |
@ -0,0 +1,6 @@ |
|||||
|
;; Direct jump out of code. |
||||
|
|
||||
|
(asm |
||||
|
999 |
||||
|
JUMP |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6004586000600058 |
@ -0,0 +1,9 @@ |
|||||
|
;; Direct jump into data |
||||
|
|
||||
|
(asm |
||||
|
4 ;; 0 0-3 |
||||
|
JUMP ;; 2 |
||||
|
0 ;; 3 3-4 |
||||
|
0 ;; 5 4-7 |
||||
|
JUMP ;; 6 |
||||
|
) |
@ -0,0 +1,5 @@ |
|||||
|
let f n = n + 1 |
||||
|
|
||||
|
return f 2 |
||||
|
|
||||
|
|
@ -0,0 +1 @@ |
|||||
|
600760026010585d60005460206000f28060010190509058 |
@ -0,0 +1,5 @@ |
|||||
|
let f a b = a + b |
||||
|
|
||||
|
return f 2 3 |
||||
|
|
||||
|
|
@ -0,0 +1 @@ |
|||||
|
6009600260036012585d60005460206000f2818101905090509058 |
@ -0,0 +1,5 @@ |
|||||
|
let fac n = |
||||
|
if n == 0 then 1 |
||||
|
else n * fac (n-1) |
||||
|
|
||||
|
return fac 60 |
@ -0,0 +1 @@ |
|||||
|
6007603c6010585d60005460206000f26000810e6026596020600182036010585d8102602858600190509058 |
@ -0,0 +1,5 @@ |
|||||
|
let fac a n = |
||||
|
if n == 0 then a |
||||
|
else fac (a*n) (n-1) |
||||
|
|
||||
|
return fac 1 60 |
@ -0,0 +1 @@ |
|||||
|
60096001603c6012585d60005460206000f26000810e6029596025818302600183036012585d602a5881905090509058 |
@ -0,0 +1,6 @@ |
|||||
|
let fib n = |
||||
|
if n < 3 then 1 |
||||
|
else fib (n-1) + fib (n-2) |
||||
|
|
||||
|
return fib 10 |
||||
|
|
@ -0,0 +1 @@ |
|||||
|
6007600a6010585d60005460206000f26003810a602f596020600282036010585d602a600183036010585d01603158600190509058 |
@ -0,0 +1 @@ |
|||||
|
600a60805460006080530b0f60255960a0536080530160a054600160805303608054600558 |
@ -0,0 +1,3 @@ |
|||||
|
(for [i]:10 (> @i 0) [i](- @i 1) |
||||
|
[j](+ @i @j) |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6000608054600a6080530a0f60255960a0536080530160a054600160805301608054600558 |
@ -0,0 +1,3 @@ |
|||||
|
(for [i]:0 (< @i 10) [i](+ @i 1) |
||||
|
[j](+ @i @j) |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
return if 0 then 1 else 2 |
@ -0,0 +1 @@ |
|||||
|
60006300000010596002630000001258600160005460206000f2 |
@ -0,0 +1 @@ |
|||||
|
return if 1 then 1 else 2 |
@ -0,0 +1 @@ |
|||||
|
60016300000010596002630000001258600160005460206000f2 |
@ -0,0 +1 @@ |
|||||
|
600460030158005d6001600054 |
@ -0,0 +1,13 @@ |
|||||
|
;; Indirect JUMP |
||||
|
|
||||
|
(asm |
||||
|
4 ;; 0 |
||||
|
3 ;; 2 |
||||
|
ADD ;; 4 |
||||
|
JUMP ;; 5 |
||||
|
STOP ;; 6 |
||||
|
JUMPDEST ;; 7 |
||||
|
1 |
||||
|
0 |
||||
|
MSTORE |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
600860060158005d6001600054005d600260005400 |
@ -0,0 +1,19 @@ |
|||||
|
;; Indirect JUMP |
||||
|
|
||||
|
(asm |
||||
|
8 ;; 0 |
||||
|
6 ;; 2 |
||||
|
ADD ;; 4 |
||||
|
JUMP ;; 5 --> 14 |
||||
|
STOP ;; 6 |
||||
|
JUMPDEST ;; 7 |
||||
|
1 ;; 8 |
||||
|
0 ;; 10 |
||||
|
MSTORE ;; 12 |
||||
|
STOP ;; 13 |
||||
|
JUMPDEST ;; 14 |
||||
|
2 |
||||
|
0 |
||||
|
MSTORE |
||||
|
STOP |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6001600460050159005d6001600054 |
@ -0,0 +1,14 @@ |
|||||
|
;; Indirect JUMP |
||||
|
|
||||
|
(asm |
||||
|
1 ;; 0 |
||||
|
4 ;; 2 |
||||
|
5 ;; 4 |
||||
|
ADD ;; 6 |
||||
|
JUMPI ;; 7 |
||||
|
STOP ;; 8 |
||||
|
JUMPDEST ;; 9 |
||||
|
1 |
||||
|
0 |
||||
|
MSTORE |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
60006007600501596001600054005d00 |
@ -0,0 +1,15 @@ |
|||||
|
;; Indirect JUMP |
||||
|
|
||||
|
(asm |
||||
|
0 ;; 0 |
||||
|
7 ;; 2 |
||||
|
5 ;; 4 |
||||
|
ADD ;; 6 |
||||
|
JUMPI ;; 7 |
||||
|
1 ;; 8 |
||||
|
0 ;; 9 |
||||
|
MSTORE ;; 10 |
||||
|
STOP ;; 11 |
||||
|
JUMPDEST ;; 12 |
||||
|
STOP |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
600458006001600154 |
@ -0,0 +1,11 @@ |
|||||
|
;; Direct JUMP. |
||||
|
;; output: memory[1] == 1 |
||||
|
|
||||
|
(asm |
||||
|
4 ;; 0 |
||||
|
JUMP ;; 2 |
||||
|
STOP ;; 3 |
||||
|
1 ;; 4 |
||||
|
1 ;; 6 |
||||
|
MSTORE ;; 8 |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6008586001600154 |
@ -0,0 +1,10 @@ |
|||||
|
;; Direct JUMP to the end of code. |
||||
|
;; output: memory should have size 0. |
||||
|
|
||||
|
(asm |
||||
|
8 ;; 0 |
||||
|
JUMP ;; 2 |
||||
|
1 ;; 3 |
||||
|
1 ;; 5 |
||||
|
MSTORE ;; 7 |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
602a586001600154 |
@ -0,0 +1,10 @@ |
|||||
|
;; Direct JUMP past the end of code. |
||||
|
;; output: memory should have size 0. |
||||
|
|
||||
|
(asm |
||||
|
42 |
||||
|
JUMP |
||||
|
1 |
||||
|
1 |
||||
|
MSTORE |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
600b6009580000600558005d6001600154 |
@ -0,0 +1,17 @@ |
|||||
|
;; Direct JUMP. |
||||
|
;; output: memory[1] = 1 |
||||
|
|
||||
|
(asm |
||||
|
11 ;; 0 |
||||
|
9 ;; 2 |
||||
|
JUMP ;; 4 --> 9 |
||||
|
STOP ;; 5 |
||||
|
STOP ;; 6 |
||||
|
5 ;; 7 |
||||
|
JUMP ;; 9 --> 11 |
||||
|
STOP ;; 10 |
||||
|
JUMPDEST |
||||
|
1 ;; 11 |
||||
|
1 |
||||
|
MSTORE |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
6005600e585d600160015400600f5800 |
@ -0,0 +1,16 @@ |
|||||
|
;; Direct JUMP. |
||||
|
;; output: memory[1] = 1 |
||||
|
|
||||
|
(asm |
||||
|
5 ;; 0 |
||||
|
14 ;; 2 |
||||
|
JUMP ;; 4 --> 14 |
||||
|
JUMPDEST ;; 5 |
||||
|
1 ;; 6 |
||||
|
1 ;; 8 |
||||
|
MSTORE ;; 10 |
||||
|
STOP ;; 11 |
||||
|
15 ;; 12 |
||||
|
JUMP ;; 14 --> 5 |
||||
|
STOP ;; 15 |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
600358600f600d58006014600758005d6001600154005d600260025400 |
@ -0,0 +1,32 @@ |
|||||
|
;; Direct JUMP. |
||||
|
;; output: memory[1] = 1 |
||||
|
|
||||
|
;; 0, 2 --> 3 .. 7 --> 13 -*-> 15 .. 19 |
||||
|
|
||||
|
(asm |
||||
|
3 ;; 0 |
||||
|
JUMP ;; 2 |
||||
|
|
||||
|
15 ;; 3 <- start |
||||
|
13 ;; 5 |
||||
|
JUMP ;; 7 <- b |
||||
|
STOP ;; 8 |
||||
|
|
||||
|
20 ;; 9 |
||||
|
7 ;; 11 |
||||
|
|
||||
|
JUMP ;; 13 <- a |
||||
|
STOP ;; 14 |
||||
|
|
||||
|
JUMPDEST ;; 15 <- c |
||||
|
1 ;; 16 |
||||
|
1 ;; 18 |
||||
|
MSTORE ;; 19 |
||||
|
STOP ;; 20 |
||||
|
|
||||
|
JUMPDEST ;; 21 <- d |
||||
|
2 ;; 22 |
||||
|
2 ;; 24 |
||||
|
MSTORE ;; 26 |
||||
|
STOP ;; 27 |
||||
|
) |
@ -0,0 +1 @@ |
|||||
|
600a6000545d6000536001900380600054600659 |
@ -0,0 +1 @@ |
|||||
|
(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI) |
@ -0,0 +1 @@ |
|||||
|
600a600181038060025960005460015460025400 |
@ -0,0 +1,27 @@ |
|||||
|
;; Produces 1 2 3 4 5 6 7 8 9 10 on the stack and exits |
||||
|
|
||||
|
(asm |
||||
|
10 |
||||
|
|
||||
|
;; 2 |
||||
|
1 |
||||
|
DUP2 |
||||
|
SUB |
||||
|
DUP1 |
||||
|
2 |
||||
|
JUMPI |
||||
|
|
||||
|
;; stack = 1 2 3 4 5 6 7 8 9 10 |
||||
|
0 |
||||
|
MSTORE |
||||
|
1 |
||||
|
MSTORE |
||||
|
2 |
||||
|
MSTORE |
||||
|
;;3 |
||||
|
;;MSTORE |
||||
|
|
||||
|
STOP |
||||
|
) |
||||
|
|
||||
|
|
@ -0,0 +1 @@ |
|||||
|
600a80600190038060025960005460015460025400 |
@ -0,0 +1,28 @@ |
|||||
|
;; Produces 1 2 3 4 5 6 7 8 9 10 on the stack and exits |
||||
|
|
||||
|
(asm |
||||
|
10 |
||||
|
|
||||
|
;; 2 |
||||
|
DUP1 |
||||
|
1 |
||||
|
SWAP1 |
||||
|
SUB |
||||
|
DUP1 |
||||
|
2 |
||||
|
JUMPI |
||||
|
|
||||
|
;; stack = 1 2 3 4 5 6 7 8 9 10 |
||||
|
0 |
||||
|
MSTORE |
||||
|
1 |
||||
|
MSTORE |
||||
|
2 |
||||
|
MSTORE |
||||
|
;;3 |
||||
|
;;MSTORE |
||||
|
|
||||
|
STOP |
||||
|
) |
||||
|
|
||||
|
|
@ -0,0 +1,4 @@ |
|||||
|
let f n = |
||||
|
if n == 0 then 2 else f (n-1) |
||||
|
|
||||
|
return f 10 |
@ -0,0 +1 @@ |
|||||
|
6007600a6010585d60005460206000f26000810e6024596020600182036010585d602658600290509058 |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue