├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── bin └── evm2wasm.js ├── circle.yml ├── cmake ├── HunterGate.cmake ├── ProjectBinaryen.cmake └── toolchains │ └── cxx11-pic.cmake ├── docs └── index.md ├── include ├── evm2wasm.h ├── wast-async.h └── wast.h ├── index.js ├── libs ├── CMakeLists.txt └── evm2wasm │ ├── CMakeLists.txt │ └── evm2wasm.cpp ├── node-cpp-build-env.dockerfile ├── opcodes.js ├── package.json ├── samples ├── sample.evm ├── sample.evmhex ├── sample.wasm └── sample.wast ├── tests ├── README.md ├── code │ ├── add.json │ ├── calldataload.json │ ├── coinbase.json │ ├── div.json │ ├── drain.json │ ├── jumpdest.json │ ├── jumpi.json │ ├── jumpsWithDeadCode.json │ ├── memstoreRevist.json │ ├── msize.json │ ├── msize0.json │ ├── msizebig.json │ ├── mstore.json │ ├── mstore8.json │ ├── origin.json │ ├── pc.json │ ├── pop.json │ ├── push.json │ ├── return.json │ ├── rewriter.js │ ├── soldeploy.json │ ├── soldidityRedux.json │ ├── soldispatcher.json │ ├── solidity_add_uint256.json │ ├── solidity_add_uint256.sol │ ├── sstore.json │ ├── stop.json │ ├── text2bytecode.js │ └── underflow.json ├── codeRunnerJSVM.js ├── opcode │ ├── add.json │ ├── addmod.json │ ├── address.json │ ├── and.json │ ├── byte.json │ ├── calldataload.json │ ├── calldatasize.json │ ├── caller.json │ ├── coinbase.json │ ├── div.json │ ├── dup.json │ ├── eq.json │ ├── exp.json │ ├── gt.json │ ├── iszero.json │ ├── lt.json │ ├── mload.json │ ├── mod.json │ ├── msize.json │ ├── mstore.json │ ├── mstore8.json │ ├── mul.json │ ├── mulmod.json │ ├── not.json │ ├── or.json │ ├── return.json │ ├── rewriter.js │ ├── sdiv.json │ ├── sgt.json │ ├── sha3.json │ ├── signextend.json │ ├── slt.json │ ├── smod.json │ ├── sub.json │ ├── swap.json │ └── xor.json ├── opcodeRunnerJSVM.js └── runVmTests.js ├── tmp └── .gitkeep ├── tools ├── CMakeLists.txt ├── evm2wasm │ ├── CMakeLists.txt │ └── main.cpp └── wast2wasm │ ├── CMakeLists.txt │ └── main.cpp └── wasm ├── ADD.wast ├── ADDMOD.wast ├── AND.wast ├── BYTE.wast ├── CALLDATALOAD.wast ├── DIV.wast ├── DUP.wast ├── EQ.wast ├── EXP.wast ├── GT.wast ├── ISZERO.wast ├── LOG.wast ├── LT.wast ├── MLOAD.wast ├── MOD.wast ├── MSIZE.wast ├── MSTORE.wast ├── MSTORE8.wast ├── MUL.wast ├── MULMOD.wast ├── NOT.wast ├── OR.wast ├── PC.wast ├── PUSH.wast ├── SDIV.wast ├── SGT.wast ├── SHA3.wast ├── SIGNEXTEND.wast ├── SLT.wast ├── SMOD.wast ├── SUB.wast ├── SWAP.wast ├── XOR.wast ├── bswap_i32.wast ├── bswap_i64.wast ├── bswap_m128.wast ├── bswap_m160.wast ├── bswap_m256.wast ├── callback.wast ├── callback_128.wast ├── callback_160.wast ├── callback_256.wast ├── callback_32.wast ├── check_overflow.wast ├── check_overflow_i64.wast ├── generateInterface.js ├── gte_256.wast ├── gte_320.wast ├── gte_512.wast ├── iszero_256.wast ├── iszero_320.wast ├── iszero_512.wast ├── keccak.wast ├── memcpy.wast ├── memset.wast ├── memusegas.wast ├── mod_320.wast ├── mod_512.wast ├── mul_256.wast ├── wast-async.json └── wast.json /.gitignore: -------------------------------------------------------------------------------- 1 | .swp 2 | .gch 3 | 4 | /build 5 | /.idea 6 | /deps 7 | 8 | tmp/* 9 | !tmp/.gitkeep 10 | node_modules/ 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tools/wabt"] 2 | path = tools/wabt 3 | url = https://github.com/WebAssembly/wabt 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | include(GNUInstallDirs) 4 | 5 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 6 | 7 | # Require C++11. 8 | set(CMAKE_CXX_STANDARD 11) 9 | set(CMAKE_CXX_STANDARD_REQUIRED True) 10 | set(CMAKE_CXX_EXTENSIONS Off) 11 | 12 | add_compile_options(-Wall -Wextra -Wconversion -Wsign-conversion -Wno-unknown-pragmas) 13 | 14 | include(HunterGate) 15 | HunterGate( 16 | URL "https://github.com/ruslo/hunter/archive/v0.20.24.tar.gz" 17 | SHA1 "3e2037a462bcf2ec3440f60298d933e74ffd4df3" 18 | ) 19 | 20 | project(evm2wasm) 21 | 22 | include(ProjectBinaryen) 23 | 24 | add_subdirectory(libs) 25 | 26 | option(EVM2WASM_TOOLS ON) 27 | if(EVM2WASM_TOOLS) 28 | add_subdirectory(tools) 29 | endif() 30 | 31 | install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 32 | 33 | install( 34 | EXPORT evm2wasmTargets 35 | NAMESPACE evm2wasm:: 36 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/evm2wasm 37 | ) 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Note: this project is not actively maintained. See [RuneVM](https://github.com/axic/runevm) and [yevm](https://github.com/axic/yevm) for replacement candidates. 2 | 3 | # SYNOPSIS 4 | [![CircleCI](https://circleci.com/gh/ewasm/evm2wasm.svg?style=svg)](https://circleci.com/gh/ewasm/evm2wasm) 5 | [![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) 6 | 7 | EVM (Ethereum VM 1.0) to [eWASM](https://github.com/ewasm/design) transcompiler. Here is a online [frontend](https://ewasm.github.io/evm2wasm-frontend/dist/). 8 | 9 | # INSTALL 10 | Clone the repository and run `npm install` 11 | 12 | # USE 13 | There is a commandline tool to transcompile EVM input: 14 | 15 | #### Transcompile EVM to WASM 16 | ``` 17 | $ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file` 18 | ``` 19 | 20 | #### Transcompile EVM to WAST 21 | ``` 22 | $ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file` --wast 23 | ``` 24 | 25 | #### Transcompile EVM to WAST with embedded EVM trace statements for each transpiled EVM opcode 26 | ``` 27 | $ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file` --wast --trace 28 | ``` 29 | 30 | #### Transcompile EVM to WAST with gas metering per transpiled EVM opcode (not per branch segment) 31 | ``` 32 | $ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file` --wast --charge-per-op 33 | ``` 34 | 35 | # DEVELOP 36 | * After any changes to `.wast` file, `npm run build` needs to be run to compile the files into a .json file 37 | * To rebuild the documentation run `npm run build:docs` 38 | * To lint run `npm run lint` 39 | * And make sure you test with `npm test` and `npm run vmTests` which runs the offical Ethereum test suite 40 | 41 | The above build command will invoke `wasm/generateInterface.js` which generates `wasm/wast.json` and `include/wast.h` containing a 42 | Webassembly function corresponding to each EVM opcode. 43 | 44 | The core logic of the evm2wasm compiler is in `index.js` (Javascript frontend) or `libs/evm2wasm/evm2wasm.cpp` (C++ fronetend), which iterates the input EMV bytecode and generates 45 | a Webassembly output by invoking each of the above generated Webassembly functions and concatenating them into the output. 46 | 47 | To build the C++ frontend: 48 | ``` 49 | $ mkdir build 50 | $ cd build 51 | $ cmake .. 52 | $ make 53 | ``` 54 | 55 | # API 56 | [./docs/](./docs/index.md) 57 | 58 | # TECHNICAL NOTES 59 | EVM is stack based and offers access to memory, storage and state via special instructions. 60 | Here we replicate the stack layout in WebAssembly (WASM) and implement each operation working on this stack. 61 | 62 | ### OPCODES 63 | Every opcode (bar some special instructions) receives the current stack pointer (`$sp`) as `i32` and must return the adjusted stack pointer. 64 | 65 | ### STACK LAYOUT 66 | The stack grows from memory location 0, where 256 bit values are stored linearly in LSB byteorder. 67 | The `$sp` points to the starting position of the top stack entry (and not the next free stack position). If the stack is empty, it is set to `-32`. 68 | 69 | ### MEMORY LAYOUT 70 | The resulting (after transpilation) contract memory layout is currently as follows: 71 | ``` 72 | .--------------------------------------------------- 73 | | Reserved space for the stack (32768 bytes) 74 | | - each stack entry is 256 bits 75 | | - the stack is limited to 1024 entries 76 | +--------------------------------------------------- 77 | | Word count (4 bytes) 78 | | (Number of 256 bit words stored in memory) 79 | +--------------------------------------------------- 80 | | Previous memory cost in word count (4 bytes) 81 | | (The cost charged for the last memory allocation) 82 | +--------------------------------------------------- 83 | | Scratch space (32 bytes) 84 | +--------------------------------------------------- 85 | | Reserved space for the Keccak-256 context (1024 bytes) 86 | +--------------------------------------------------- 87 | | "EVM 1.0" contract memory starts here ("unlimited" in size) 88 | `--------------------------------------------------- 89 | ``` 90 | 91 | ### METERING 92 | The generated *eWASM contract* contains gas metering. It is assumed *evm2wasm* will become a deployed trusted contract, which returns eWASM code that does not need to be run through the gas injector contract. 93 | 94 | # LICENSE 95 | [MPL-2.0](https://tldrlegal.com/license/mozilla-public-license-2.0-(mpl-2)) 96 | 97 | -------------------------------------------------------------------------------- /bin/evm2wasm.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const evm2wasm = require('../index.js') 4 | const argv = require('minimist')(process.argv.slice(2)) 5 | const fs = require('fs') 6 | var tou8 = require('buffer-to-uint8array') 7 | 8 | // convert evm bytecode to WASM or WAST 9 | function convert (bytecode, opts) { 10 | return new Promise((resolve, reject) => { 11 | if (!bytecode) { 12 | return resolve(Buffer.from('')) 13 | } 14 | 15 | if (opts.wast) { 16 | let output = evm2wasm.evm2wast(bytecode, { 17 | stackTrace: opts.trace, 18 | tempName: 'temp', 19 | inlineOps: true, 20 | chargePerOp: opts.chargePerOp 21 | }) 22 | resolve(output) 23 | } else { 24 | evm2wasm.evm2wasm(bytecode, { 25 | stackTrace: opts.trace, 26 | tempName: 'temp', 27 | inlineOps: true, 28 | chargePerOp: opts.chargePerOp 29 | }).then(function (output) { 30 | // output is a node buffer. convert to Uint8Array 31 | let outputUint8 = {} 32 | outputUint8.buffer = tou8(output) 33 | resolve(outputUint8) 34 | }).catch(function (err) { 35 | reject(err) 36 | }) 37 | } 38 | }) 39 | } 40 | 41 | function storeOrPrintResult (output, outputFile) { 42 | if (typeof output !== 'string') { 43 | output = output.buffer 44 | } 45 | 46 | if (outputFile) { 47 | fs.writeFileSync(outputFile, output) 48 | } else { 49 | console.log(Buffer.from(output).toString('binary')) 50 | } 51 | } 52 | 53 | const outputFile = argv.o ? argv.o : undefined 54 | const wast = argv.wast !== undefined 55 | const trace = argv.trace !== undefined 56 | const inputFile = argv.e ? argv.e : undefined 57 | const chargePerOp = argv['charge-per-op'] ? argv['charge-per-op'] : undefined 58 | 59 | let bytecode 60 | 61 | try { 62 | if (!inputFile) { 63 | if (argv._.length > 0) { 64 | // ensure it is a string even it was passed as a number 65 | bytecode = argv._[0].toString() 66 | } else { 67 | throw new Error('must provide evm bytecode file or supply bytecode as a non-named argument') 68 | } 69 | } else { 70 | bytecode = fs.readFileSync(inputFile).toString() 71 | } 72 | 73 | // always consider input EVM as a hex string and translate that into binary for the next stage 74 | bytecode = Buffer.from(bytecode, 'hex') 75 | 76 | convert(bytecode, { wast: wast, trace: trace, chargePerOp: chargePerOp }).then((result) => { 77 | storeOrPrintResult(result, outputFile) 78 | }).catch((err) => { 79 | // Separately handle async promise errors here so they're not swallowed silently 80 | console.error('Error:' + err) 81 | process.exit(1) 82 | }) 83 | } catch (err) { 84 | console.error('Error: ' + err) 85 | process.exit(1) 86 | } 87 | -------------------------------------------------------------------------------- /cmake/ProjectBinaryen.cmake: -------------------------------------------------------------------------------- 1 | if(ProjectBinaryenIncluded) 2 | return() 3 | endif() 4 | set(ProjectBinaryenIncluded TRUE) 5 | 6 | include(ExternalProject) 7 | include(GNUInstallDirs) 8 | 9 | if(MSVC) 10 | # Overwrite build and install commands to force Release build on MSVC. 11 | set(build_command BUILD_COMMAND cmake --build --config Release) 12 | set(install_command INSTALL_COMMAND cmake --build --config Release --target install) 13 | elseif(CMAKE_GENERATOR STREQUAL Ninja) 14 | # For Ninja we have to pass the number of jobs from CI environment. 15 | # Otherwise it will go crazy and run out of memory. 16 | if($ENV{BUILD_PARALLEL_JOBS}) 17 | set(build_command BUILD_COMMAND cmake --build -- -j $ENV{BUILD_PARALLEL_JOBS}) 18 | message(STATUS "Ninja $ENV{BUILD_PARALLEL_JOBS}") 19 | endif() 20 | endif() 21 | 22 | set(prefix ${CMAKE_BINARY_DIR}/deps) 23 | set(source_dir ${prefix}/src/binaryen) 24 | set(binary_dir ${prefix}/src/binaryen-build) 25 | # Use source dir because binaryen only installs single header with C API. 26 | set(binaryen_include_dir ${source_dir}/src) 27 | set(binaryen_library ${prefix}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}binaryen${CMAKE_STATIC_LIBRARY_SUFFIX}) 28 | # Include also other static libs needed: 29 | set(binaryen_other_libraries 30 | ${binary_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}wasm${CMAKE_STATIC_LIBRARY_SUFFIX} 31 | ${binary_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}asmjs${CMAKE_STATIC_LIBRARY_SUFFIX} 32 | ${binary_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}passes${CMAKE_STATIC_LIBRARY_SUFFIX} 33 | ${binary_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}cfg${CMAKE_STATIC_LIBRARY_SUFFIX} 34 | ${binary_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ir${CMAKE_STATIC_LIBRARY_SUFFIX} 35 | ${binary_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}emscripten-optimizer${CMAKE_STATIC_LIBRARY_SUFFIX} 36 | ${binary_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}support${CMAKE_STATIC_LIBRARY_SUFFIX} 37 | ) 38 | 39 | ExternalProject_Add(binaryen 40 | PREFIX ${prefix} 41 | DOWNLOAD_NAME binaryen-1.38.9.tar.gz 42 | DOWNLOAD_DIR ${prefix}/downloads 43 | SOURCE_DIR ${source_dir} 44 | BINARY_DIR ${binary_dir} 45 | URL https://github.com/WebAssembly/binaryen/archive/1.38.9.tar.gz 46 | URL_HASH SHA256=f8c6d4deb83dba8709c4df9f7983080ec0f9412e88899767ed2815b911ce1ebd 47 | CMAKE_ARGS 48 | -DCMAKE_INSTALL_PREFIX= 49 | -DCMAKE_BUILD_TYPE=Release 50 | -DBUILD_STATIC_LIB=ON 51 | ${build_command} 52 | ${install_command} 53 | BUILD_BYPRODUCTS ${binaryen_library} ${binaryen_other_libraries} 54 | ) 55 | 56 | add_library(binaryen::binaryen STATIC IMPORTED) 57 | 58 | file(MAKE_DIRECTORY ${binaryen_include_dir}) # Must exist. 59 | set_target_properties( 60 | binaryen::binaryen 61 | PROPERTIES 62 | IMPORTED_CONFIGURATIONS Release 63 | IMPORTED_LOCATION_RELEASE ${binaryen_library} 64 | INTERFACE_INCLUDE_DIRECTORIES ${binaryen_include_dir} 65 | INTERFACE_LINK_LIBRARIES "${binaryen_other_libraries}" 66 | 67 | ) 68 | 69 | add_dependencies(binaryen::binaryen binaryen) 70 | -------------------------------------------------------------------------------- /cmake/toolchains/cxx11-pic.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 11) 2 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 3 | set(CMAKE_CXX_EXTENSIONS OFF) 4 | 5 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 6 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Table of Contents 4 | 5 | - [evm2wasm][1] 6 | - [evm2wast][2] 7 | - [resolveFunctions][3] 8 | - [buildModule][4] 9 | 10 | ## evm2wasm 11 | 12 | compiles evmCode to wasm in the binary format 13 | 14 | **Parameters** 15 | 16 | - `evmCode` **[Array][5]** 17 | - `opts` **[Object][6]** (optional, default `{'stackTrace':false,'useAsyncAPI':false,'inlineOps':true,'testName':'temp','chargePerOp':false}`) 18 | - `opts.stackTrace` **[boolean][7]** if `true` generates an runtime EVM stack trace (default: false) 19 | - `opts.inlineOps` **[boolean][7]** if `true` inlines the EVM1 operations (default: true) 20 | - `opts.testName` **[String][8]** is the name used for the wast file (default: 'temp') 21 | - `opts.chargePerOp` **[boolean][7]** if `true` adds metering statements for the wasm code section corresponding to each EVM opcode as opposed to metering once per branch segment (default: false). 22 | 23 | Returns **[string][8]** 24 | 25 | ## evm2wast 26 | 27 | Transcompiles EVM code to ewasm in the sexpression text format. The EVM code 28 | is broken into segments and each instruction in those segments is replaced 29 | with a `call` to wasm function that does the equivalent operation. Each 30 | opcode function takes in and returns the stack pointer. 31 | 32 | Segments are sections of EVM code in between flow control 33 | opcodes (JUMPI. JUMP). 34 | All segments start at 35 | 36 | - the beginning for EVM code 37 | - a GAS opcode 38 | - a JUMPDEST opcode 39 | - After a JUMPI opcode 40 | 41 | **Parameters** 42 | 43 | - `evmCode` **Integer** the evm byte code 44 | - `opts` **[Object][6]** (optional, default `{'stackTrace':false,'useAsyncAPI':false,'inlineOps':true,'chargePerOp':false}`) 45 | - `opts.stackTrace` **[boolean][7]** if `true` generates a stack trace (default: false) 46 | - `opts.inlineOps` **[boolean][7]** if `true` inlines the EVM1 operations (default: true) 47 | - `opts.chargePerOp` **[boolean][7]** if `true` adds metering statements for the wasm code section corresponding to each EVM opcode as opposed to metering once per branch segment (default: false). 48 | 49 | Returns **[string][8]** 50 | 51 | ## resolveFunctions 52 | 53 | given a Set of wasm function this return an array for wasm equivalents 54 | 55 | **Parameters** 56 | 57 | - `funcSet` **[Set][9]** 58 | - `wastFiles` 59 | 60 | Returns **[Array][5]** 61 | 62 | ## buildModule 63 | 64 | builds a wasm module 65 | 66 | **Parameters** 67 | 68 | - `funcs` **[Array][5]** the function to include in the module 69 | - `imports` **[Array][5]** the imports for the module's import table (optional, default `[]`) 70 | - `callbacks` (optional, default `[]`) 71 | 72 | Returns **[string][8]** 73 | 74 | [1]: #evm2wasm 75 | 76 | [2]: #evm2wast 77 | 78 | [3]: #resolvefunctions 79 | 80 | [4]: #buildmodule 81 | 82 | [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array 83 | 84 | [6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object 85 | 86 | [7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean 87 | 88 | [8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String 89 | 90 | [9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Set 91 | -------------------------------------------------------------------------------- /libs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(evm2wasm) -------------------------------------------------------------------------------- /libs/evm2wasm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(include_dir ${PROJECT_SOURCE_DIR}/include) 2 | 3 | find_package(Threads REQUIRED) 4 | 5 | hunter_add_package(fmt) 6 | 7 | find_package(fmt CONFIG REQUIRED) 8 | 9 | add_library(libevm2wasm STATIC 10 | evm2wasm.cpp ${include_dir}/evm2wasm.h 11 | ) 12 | set_target_properties(libevm2wasm PROPERTIES OUTPUT_NAME evm2wasm) 13 | 14 | if(BUILD_SHARED_LIBS) 15 | set_target_properties(libevm2wasm PROPERTIES POSITION_INDEPENDENT_CODE TRUE) 16 | endif() 17 | 18 | target_include_directories(libevm2wasm PUBLIC $$) 19 | target_link_libraries(libevm2wasm PRIVATE binaryen::binaryen Threads::Threads fmt::fmt) 20 | 21 | install(TARGETS libevm2wasm EXPORT evm2wasmTargets 22 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 23 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 24 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 25 | ) 26 | -------------------------------------------------------------------------------- /node-cpp-build-env.dockerfile: -------------------------------------------------------------------------------- 1 | # to build this, place in new directory as Dockerfile 2 | # run `docker build -t cdetrio/nodejs-cpp-build-env .` 3 | # then push to dockerhub `docker push cdetrio/nodejs-cpp-build-env` 4 | 5 | # stage for nodejs 6 | FROM node:8 AS nodebuild 7 | 8 | RUN apt-get update 9 | RUN apt-get install sudo 10 | 11 | RUN node --version 12 | RUN npm --version 13 | 14 | # stage for cpp-ethereum 15 | FROM ethereum/cpp-build-env 16 | 17 | # WORKDIR is /home/builder 18 | 19 | # python is needed for node-gyp 20 | RUN sudo apt-get update && sudo apt-get install -y python 21 | 22 | # copy node binary 23 | COPY --from=nodebuild /usr/local/bin/node /usr/local/bin/node 24 | COPY --from=nodebuild /usr/local/lib/node_modules /usr/local/lib/node_modules 25 | 26 | # create npm symlink 27 | RUN sudo ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm 28 | # not sure what npx is for 29 | # RUN ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx 30 | 31 | RUN npm --version 32 | -------------------------------------------------------------------------------- /opcodes.js: -------------------------------------------------------------------------------- 1 | const codes = { 2 | // 0x0 range - arithmetic ops 3 | // name, baseCost, off stack, on stack 4 | 0x00: ['STOP', 0, 0, 0], 5 | 0x01: ['ADD', 3, 2, 1], 6 | 0x02: ['MUL', 5, 2, 1], 7 | 0x03: ['SUB', 3, 2, 1], 8 | 0x04: ['DIV', 5, 2, 1], 9 | 0x05: ['SDIV', 5, 2, 1], 10 | 0x06: ['MOD', 5, 2, 1], 11 | 0x07: ['SMOD', 5, 2, 1], 12 | 0x08: ['ADDMOD', 8, 3, 1], 13 | 0x09: ['MULMOD', 8, 3, 1], 14 | 0x0a: ['EXP', 10, 2, 1], 15 | 0x0b: ['SIGNEXTEND', 5, 2, 1], 16 | 17 | // 0x10 range - bit ops 18 | 0x10: ['LT', 3, 2, 1], 19 | 0x11: ['GT', 3, 2, 1], 20 | 0x12: ['SLT', 3, 2, 1], 21 | 0x13: ['SGT', 3, 2, 1], 22 | 0x14: ['EQ', 3, 2, 1], 23 | 0x15: ['ISZERO', 3, 1, 1], 24 | 0x16: ['AND', 3, 2, 1], 25 | 0x17: ['OR', 3, 2, 1], 26 | 0x18: ['XOR', 3, 2, 1], 27 | 0x19: ['NOT', 3, 1, 1], 28 | 0x1a: ['BYTE', 3, 2, 1], 29 | 30 | // 0x20 range - crypto 31 | 0x20: ['SHA3', 30, 2, 1], 32 | 33 | // 0x30 range - closure state 34 | 0x30: ['ADDRESS', 0, 0, 1], 35 | 0x31: ['BALANCE', 0, 1, 1], 36 | 0x32: ['ORIGIN', 0, 0, 1], 37 | 0x33: ['CALLER', 0, 0, 1], 38 | 0x34: ['CALLVALUE', 0, 0, 1], 39 | 0x35: ['CALLDATALOAD', 0, 1, 1], 40 | 0x36: ['CALLDATASIZE', 0, 0, 1], 41 | 0x37: ['CALLDATACOPY', 0, 3, 0], 42 | 0x38: ['CODESIZE', 0, 0, 1], 43 | 0x39: ['CODECOPY', 0, 3, 0], 44 | 0x3a: ['GASPRICE', 0, 0, 1], 45 | 0x3b: ['EXTCODESIZE', 0, 1, 1], 46 | 0x3c: ['EXTCODECOPY', 0, 4, 0], 47 | 0x3d: ['RETURNDATASIZE', 0, 0, 1], 48 | 0x3e: ['RETURNDATACOPY', 0, 3, 0], 49 | 50 | // '0x40' range - block operations 51 | 0x40: ['BLOCKHASH', 0, 1, 1], 52 | 0x41: ['COINBASE', 0, 0, 1], 53 | 0x42: ['TIMESTAMP', 0, 0, 1], 54 | 0x43: ['NUMBER', 0, 0, 1], 55 | 0x44: ['DIFFICULTY', 0, 0, 1], 56 | 0x45: ['GASLIMIT', 0, 0, 1], 57 | 58 | // 0x50 range - 'storage' and execution 59 | 0x50: ['POP', 2, 1, 0], 60 | 0x51: ['MLOAD', 3, 1, 1], 61 | 0x52: ['MSTORE', 3, 2, 0], 62 | 0x53: ['MSTORE8', 3, 2, 0], 63 | 0x54: ['SLOAD', 0, 1, 1], 64 | 0x55: ['SSTORE', 0, 2, 0], 65 | 0x56: ['JUMP', 8, 0, 0], 66 | 0x57: ['JUMPI', 10, 0, 0], 67 | 0x58: ['PC', 2, 0, 1], 68 | 0x59: ['MSIZE', 2, 0, 1], 69 | 0x5a: ['GAS', 0, 0, 1], 70 | 0x5b: ['JUMPDEST', 0, 0, 0], 71 | 72 | // 0x60, range 73 | 0x60: ['PUSH', 3, 0, 1], 74 | 0x61: ['PUSH', 3, 0, 1], 75 | 0x62: ['PUSH', 3, 0, 1], 76 | 0x63: ['PUSH', 3, 0, 1], 77 | 0x64: ['PUSH', 3, 0, 1], 78 | 0x65: ['PUSH', 3, 0, 1], 79 | 0x66: ['PUSH', 3, 0, 1], 80 | 0x67: ['PUSH', 3, 0, 1], 81 | 0x68: ['PUSH', 3, 0, 1], 82 | 0x69: ['PUSH', 3, 0, 1], 83 | 0x6a: ['PUSH', 3, 0, 1], 84 | 0x6b: ['PUSH', 3, 0, 1], 85 | 0x6c: ['PUSH', 3, 0, 1], 86 | 0x6d: ['PUSH', 3, 0, 1], 87 | 0x6e: ['PUSH', 3, 0, 1], 88 | 0x6f: ['PUSH', 3, 0, 1], 89 | 0x70: ['PUSH', 3, 0, 1], 90 | 0x71: ['PUSH', 3, 0, 1], 91 | 0x72: ['PUSH', 3, 0, 1], 92 | 0x73: ['PUSH', 3, 0, 1], 93 | 0x74: ['PUSH', 3, 0, 1], 94 | 0x75: ['PUSH', 3, 0, 1], 95 | 0x76: ['PUSH', 3, 0, 1], 96 | 0x77: ['PUSH', 3, 0, 1], 97 | 0x78: ['PUSH', 3, 0, 1], 98 | 0x79: ['PUSH', 3, 0, 1], 99 | 0x7a: ['PUSH', 3, 0, 1], 100 | 0x7b: ['PUSH', 3, 0, 1], 101 | 0x7c: ['PUSH', 3, 0, 1], 102 | 0x7d: ['PUSH', 3, 0, 1], 103 | 0x7e: ['PUSH', 3, 0, 1], 104 | 0x7f: ['PUSH', 3, 0, 1], 105 | 106 | 0x80: ['DUP', 3, 0, 1], 107 | 0x81: ['DUP', 3, 0, 1], 108 | 0x82: ['DUP', 3, 0, 1], 109 | 0x83: ['DUP', 3, 0, 1], 110 | 0x84: ['DUP', 3, 0, 1], 111 | 0x85: ['DUP', 3, 0, 1], 112 | 0x86: ['DUP', 3, 0, 1], 113 | 0x87: ['DUP', 3, 0, 1], 114 | 0x88: ['DUP', 3, 0, 1], 115 | 0x89: ['DUP', 3, 0, 1], 116 | 0x8a: ['DUP', 3, 0, 1], 117 | 0x8b: ['DUP', 3, 0, 1], 118 | 0x8c: ['DUP', 3, 0, 1], 119 | 0x8d: ['DUP', 3, 0, 1], 120 | 0x8e: ['DUP', 3, 0, 1], 121 | 0x8f: ['DUP', 3, 0, 1], 122 | 123 | 0x90: ['SWAP', 3, 0, 0], 124 | 0x91: ['SWAP', 3, 0, 0], 125 | 0x92: ['SWAP', 3, 0, 0], 126 | 0x93: ['SWAP', 3, 0, 0], 127 | 0x94: ['SWAP', 3, 0, 0], 128 | 0x95: ['SWAP', 3, 0, 0], 129 | 0x96: ['SWAP', 3, 0, 0], 130 | 0x97: ['SWAP', 3, 0, 0], 131 | 0x98: ['SWAP', 3, 0, 0], 132 | 0x99: ['SWAP', 3, 0, 0], 133 | 0x9a: ['SWAP', 3, 0, 0], 134 | 0x9b: ['SWAP', 3, 0, 0], 135 | 0x9c: ['SWAP', 3, 0, 0], 136 | 0x9d: ['SWAP', 3, 0, 0], 137 | 0x9e: ['SWAP', 3, 0, 0], 138 | 0x9f: ['SWAP', 3, 0, 0], 139 | 140 | 0xa0: ['LOG', 0, 2, 0], 141 | 0xa1: ['LOG', 0, 3, 0], 142 | 0xa2: ['LOG', 0, 4, 0], 143 | 0xa3: ['LOG', 0, 5, 0], 144 | 0xa4: ['LOG', 0, 6, 0], 145 | 146 | // '0xf0' range - closures 147 | 0xf0: ['CREATE', 0, 3, 1], 148 | 0xf1: ['CALL', 0, 7, 1], 149 | 0xf2: ['CALLCODE', 0, 7, 1], 150 | 0xf3: ['RETURN', 0, 2, 0], 151 | 0xf4: ['DELEGATECALL', 0, 6, 1], 152 | 0xfa: ['STATICCALL', 0, 6, 1], 153 | 154 | // '0x70', range - other 155 | 0xfd: ['REVERT', 0, 2, 0], 156 | 0xfe: ['INVALID', 0, 0, 0], 157 | 0xff: ['SELFDESTRUCT', 0, 1, 0] 158 | } 159 | 160 | module.exports = function (op) { 161 | // Map invalid opcodes to the INVALID opcode 162 | const code = codes[op] ? codes[op] : codes[0xfe] 163 | let opcode = code[0] 164 | let number 165 | 166 | switch (opcode) { 167 | case 'LOG': 168 | number = op - 0xa0 169 | break 170 | 171 | case 'PUSH': 172 | number = op - 0x5f 173 | break 174 | 175 | case 'DUP': 176 | number = op - 0x7f 177 | break 178 | 179 | case 'SWAP': 180 | number = op - 0x8f 181 | break 182 | } 183 | 184 | return { 185 | name: opcode, 186 | fee: code[1], 187 | off: code[2], 188 | on: code[3], 189 | number: number 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "evm2wasm", 3 | "version": "0.0.0", 4 | "description": "This is a JS protope of a EVM to eWASM transcompiler", 5 | "main": "index.js", 6 | "scripts": { 7 | "vmTests": "node --expose-wasm --harmony ./tests/runVmTests.js", 8 | "lint": "standard", 9 | "build:validate": "npm run build && npm run build:docs && git diff --exit-code docs/ wasm/", 10 | "build": "node ./wasm/generateInterface.js", 11 | "build:docs": "documentation build -f md ./index.js > ./docs/index.md" 12 | }, 13 | "bin": { 14 | "evm2wasm": "bin/evm2wasm.js" 15 | }, 16 | "author": "mjbecze ", 17 | "license": "MPL-2.0", 18 | "devDependencies": { 19 | "async": "^2.6.0", 20 | "bn.js": "^4.11.8", 21 | "documentation": "^7.0.0", 22 | "ethereumjs-testing": "https://github.com/ethereumjs/ethereumjs-testing", 23 | "ethereumjs-vm": "^2.3.3", 24 | "minimist": "^1.2.0", 25 | "standard": "^11.0.1", 26 | "tape": "^4.9.0" 27 | }, 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/ewasm/evm2wasm.git" 31 | }, 32 | "bugs": { 33 | "url": "https://github.com/ewasm/evm2wasm/issues" 34 | }, 35 | "homepage": "https://github.com/ewasm/evm2wasm", 36 | "keywords": [ 37 | "ethereum", 38 | "webassembly", 39 | "wasm", 40 | "ewasm", 41 | "transcompiler" 42 | ], 43 | "dependencies": { 44 | "buffer-to-uint8array": "^1.1.0", 45 | "eslint": "^4.19.1", 46 | "ethereumjs-block": "^1.2.2", 47 | "ethereumjs-util": "^5.1.5", 48 | "ewasm-kernel": "git+https://github.com/ewasm/ewasm-kernel.git", 49 | "loglevel": "^1.6.0", 50 | "merkle-trie": "0.0.0", 51 | "readable-stream": "^2.3.5", 52 | "wabt": "^1.0.0" 53 | }, 54 | "standard": { 55 | "ignore": [ 56 | "/tools/", 57 | "/wasm/" 58 | ] 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /samples/sample.evm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ewasm/evm2wasm/0491f28cc0f1b516e0b5e85b93761d91d44d87c6/samples/sample.evm -------------------------------------------------------------------------------- /samples/sample.evmhex: -------------------------------------------------------------------------------- 1 | 0x60606040526000357c010000000000000000000000000000000000000000000000000000000090048063771602F7146037576035565b005b60546004808035906020019091908035906020019091905050606A565b6040518082815260200191505060405180910390f35b6000818301905080505b9291505056 2 | -------------------------------------------------------------------------------- /samples/sample.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ewasm/evm2wasm/0491f28cc0f1b516e0b5e85b93761d91d44d87c6/samples/sample.wasm -------------------------------------------------------------------------------- /samples/sample.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (import "ethereum" "useGas" (func $useGas (param i64))) 4 | (global $cb_dest (mut i32) (i32.const 0)) 5 | (global $sp (mut i32) (i32.const -32)) 6 | (global $init (mut i32) (i32.const 0)) 7 | 8 | ;; memory related global 9 | (global $memstart i32 (i32.const 33832)) 10 | ;; the number of 256 words stored in memory 11 | (global $wordCount (mut i64) (i64.const 0)) 12 | ;; what was charged for the last memory allocation 13 | (global $prevMemCost (mut i64) (i64.const 0)) 14 | 15 | ;; TODO: memory should only be 1, but can't resize right now 16 | (memory 500) 17 | (export "memory" (memory 0)) 18 | 19 | 20 | 21 | 22 | (func $main 23 | (export "main") 24 | (local $jump_dest i32) 25 | (set_local $jump_dest (i32.const -1)) 26 | 27 | (block $done 28 | (loop $loop 29 | 30 | (block $0 31 | (if 32 | (i32.eqz (get_global $init)) 33 | (then 34 | (set_global $init (i32.const 1)) 35 | (br $0)) 36 | (else 37 | ;; the callback dest can never be in the first block 38 | (if (i32.eq (get_global $cb_dest) (i32.const 0)) 39 | (then 40 | (unreachable) 41 | ) 42 | (else 43 | ;; return callback destination and zero out $cb_dest 44 | get_global $cb_dest 45 | (set_global $cb_dest (i32.const 0)) 46 | (br_table $0 ) 47 | )))))(call $useGas (i64.const 0)) ))) 48 | ) -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Code Tests 2 | The code tests run a small segments of code switch are designed to test the 3 | effects of opcodes in combination with each other 4 | 5 | # Opcode Tests 6 | The opcode tests are design to test individual opcodes 7 | 8 | ## Schema 9 | ``` 10 | [{ 11 | "op": The Opcode being tested 12 | "value": The opcodes hex value 13 | "description": A short description of the test 14 | "environment": { 15 | "caller": the callers address 16 | }, 17 | "in": { 18 | "memory": { 19 | "index": 32 byte memory segment in hex 20 | }, 21 | "stack": [ the initial stack items in hex ] 22 | }, 23 | "out": { 24 | "stack": [the resulting stack items in hex], 25 | "memory": { 26 | "index": 32 byte memory segment in hex 27 | }, 28 | "return": the resulting return value if any 29 | "cacluatedGasUsed": the gas used by the operation not including it base gas cost 30 | } 31 | }] 32 | ``` 33 | ## Example 34 | 35 | ``` 36 | [{ 37 | "op": "RETURN", 38 | "value": "0xf3", 39 | "description": "return 0x42", 40 | "in": { 41 | "memory": { 42 | "512": "0x000000000000000000000000000000000000000000000000000000000000002a" 43 | }, 44 | "stack": [ 45 | "0x0000000000000000000000000000000000000000000000000000000000000020", 46 | "0x0000000000000000000000000000000000000000000000000000000000000200" 47 | ] 48 | }, 49 | "out": { 50 | "stack": [], 51 | "memory": { 52 | "512": "0x000000000000000000000000000000000000000000000000000000000000002a" 53 | }, 54 | "return": "0x000000000000000000000000000000000000000000000000000000000000002a" 55 | } 56 | }] 57 | ``` 58 | -------------------------------------------------------------------------------- /tests/code/add.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "2 + 2", 4 | "source": [ 5 | "PUSH1", 6 | "0x02", 7 | "PUSH1", 8 | "0x02", 9 | "ADD" 10 | ], 11 | "code": "0x6002600201", 12 | "result": { 13 | "stack": [ 14 | "0x04" 15 | ], 16 | "memory": [] 17 | }, 18 | "gasUsed": 9, 19 | "environment": { 20 | "coinbase": "0x0000000000000000000000000000000000000000", 21 | "address": "0x0000000000000000000000000000000000000000" 22 | }, 23 | "message": { 24 | "data": "0x", 25 | "from": "0x0000000000000000000000000000000000000000" 26 | } 27 | } 28 | ] -------------------------------------------------------------------------------- /tests/code/calldataload.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests that calldata load clears the stack even if it doesn't have any data to load", 4 | "source": [ 5 | "PUSH1", 6 | "0x02", 7 | "CALLDATALOAD" 8 | ], 9 | "code": "0x600235", 10 | "result": { 11 | "stack": [ 12 | "0x00" 13 | ], 14 | "memory": [] 15 | }, 16 | "gasUsed": 6, 17 | "environment": { 18 | "coinbase": "0x0000000000000000000000000000000000000000", 19 | "address": "0x0000000000000000000000000000000000000000" 20 | }, 21 | "message": { 22 | "data": "0x", 23 | "from": "0x0000000000000000000000000000000000000000" 24 | } 25 | } 26 | ] -------------------------------------------------------------------------------- /tests/code/coinbase.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests that COINBASE clears the stack", 4 | "environment": { 5 | "coinbase": "0x4bb96091ee9d802ed039c4d1a5f6216f90f81b01", 6 | "address": "0x0000000000000000000000000000000000000000" 7 | }, 8 | "source": [ 9 | "PUSH32", 10 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 11 | "POP", 12 | "COINBASE" 13 | ], 14 | "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5041", 15 | "result": { 16 | "stack": [ 17 | "0x0000000000000000000000004bb96091ee9d802ed039c4d1a5f6216f90f81b01" 18 | ], 19 | "memory": [] 20 | }, 21 | "gasUsed": 7, 22 | "message": { 23 | "data": "0x", 24 | "from": "0x0000000000000000000000000000000000000000" 25 | } 26 | } 27 | ] -------------------------------------------------------------------------------- /tests/code/div.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "6/2", 4 | "source": [ 5 | "PUSH1", 6 | "0x02", 7 | "PUSH1", 8 | "0x06", 9 | "DIV" 10 | ], 11 | "code": "0x6002600604", 12 | "result": { 13 | "stack": [ 14 | "0x03" 15 | ], 16 | "memory": [] 17 | }, 18 | "gasUsed": 11, 19 | "environment": { 20 | "coinbase": "0x0000000000000000000000000000000000000000", 21 | "address": "0x0000000000000000000000000000000000000000" 22 | }, 23 | "message": { 24 | "data": "0x", 25 | "from": "0x0000000000000000000000000000000000000000" 26 | } 27 | } 28 | ] -------------------------------------------------------------------------------- /tests/code/drain.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "drain gas", 4 | "source": [ 5 | "JUMPDEST", 6 | "GAS", 7 | "PUSH1", 8 | "0x2C", 9 | "LT", 10 | "PUSH1", 11 | "0x00", 12 | "JUMPI", 13 | "STOP" 14 | ], 15 | "code": "0x5b5a602C1060005700", 16 | "result": { 17 | "stack": [], 18 | "memory": [] 19 | }, 20 | "gasUsed": 89980, 21 | "environment": { 22 | "coinbase": "0x0000000000000000000000000000000000000000", 23 | "address": "0x0000000000000000000000000000000000000000" 24 | }, 25 | "message": { 26 | "data": "0x", 27 | "from": "0x0000000000000000000000000000000000000000" 28 | } 29 | } 30 | ] -------------------------------------------------------------------------------- /tests/code/jumpdest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test jumpdest", 4 | "source": [ 5 | "PUSH1", 6 | "0x04", 7 | "JUMP", 8 | "STOP", 9 | "JUMPDEST", 10 | "PUSH1", 11 | "0x03", 12 | "PUSH1", 13 | "0x03", 14 | "ADD" 15 | ], 16 | "code": "0x600456005b6003600301", 17 | "result": { 18 | "stack": [ 19 | "0x06" 20 | ], 21 | "memory": [] 22 | }, 23 | "gasUsed": 21, 24 | "environment": { 25 | "coinbase": "0x0000000000000000000000000000000000000000", 26 | "address": "0x0000000000000000000000000000000000000000" 27 | }, 28 | "message": { 29 | "data": "0x", 30 | "from": "0x0000000000000000000000000000000000000000" 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /tests/code/jumpi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test JUMPI", 4 | "source": [ 5 | "PUSH1", 6 | "0x01", 7 | "PUSH1", 8 | "0x06", 9 | "JUMPI", 10 | "STOP", 11 | "JUMPDEST", 12 | "PUSH1", 13 | "0x03", 14 | "PUSH1", 15 | "0x03", 16 | "MUL" 17 | ], 18 | "code": "0x6001600657005b6003600302", 19 | "result": { 20 | "stack": [ 21 | "0x09" 22 | ], 23 | "memory": [] 24 | }, 25 | "gasUsed": 28, 26 | "environment": { 27 | "coinbase": "0x0000000000000000000000000000000000000000", 28 | "address": "0x0000000000000000000000000000000000000000" 29 | }, 30 | "message": { 31 | "data": "0x", 32 | "from": "0x0000000000000000000000000000000000000000" 33 | } 34 | } 35 | ] -------------------------------------------------------------------------------- /tests/code/jumpsWithDeadCode.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test solidity dispatcher preamble", 4 | "source": [ 5 | "PUSH1", 6 | "0x06", 7 | "JUMP", 8 | "PUSH1", 9 | "0x0d", 10 | "JUMP", 11 | "JUMPDEST", 12 | "PUSH1", 13 | "0x01", 14 | "STOP" 15 | ], 16 | "code": "0x600656600d565b600100", 17 | "result": { 18 | "stack": [ 19 | "0x01" 20 | ], 21 | "memory": [] 22 | }, 23 | "gasUsed": 15, 24 | "environment": { 25 | "coinbase": "0x0000000000000000000000000000000000000000", 26 | "address": "0x0000000000000000000000000000000000000000" 27 | }, 28 | "message": { 29 | "data": "0x", 30 | "from": "0x0000000000000000000000000000000000000000" 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /tests/code/memstoreRevist.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test to see if gas is being calucated correctly in cases where the same memory locaction is written to multiple times", 4 | "source": [ 5 | "PUSH1", 6 | "0x04", 7 | "PUSH1", 8 | "0x00", 9 | "MSTORE", 10 | "PUSH1", 11 | "0x04", 12 | "PUSH1", 13 | "0x00", 14 | "MSTORE" 15 | ], 16 | "code": "0x60046000526004600052", 17 | "result": { 18 | "stack": [], 19 | "memory": [] 20 | }, 21 | "gasUsed": 21, 22 | "environment": { 23 | "coinbase": "0x0000000000000000000000000000000000000000", 24 | "address": "0x0000000000000000000000000000000000000000" 25 | }, 26 | "message": { 27 | "data": "0x", 28 | "from": "0x0000000000000000000000000000000000000000" 29 | } 30 | } 31 | ] -------------------------------------------------------------------------------- /tests/code/msize.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests mstore and msize roundtrip", 4 | "source": [ 5 | "PUSH1", 6 | "0x04", 7 | "PUSH1", 8 | "0x03", 9 | "MSTORE", 10 | "MSIZE" 11 | ], 12 | "code": "0x600460035259", 13 | "result": { 14 | "stack": [ 15 | "0x40" 16 | ], 17 | "memory": [] 18 | }, 19 | "gasUsed": 17, 20 | "environment": { 21 | "address": "0x0000000000000000000000000000000000000000", 22 | "coinbase": "0x0000000000000000000000000000000000000000" 23 | }, 24 | "message": { 25 | "data": "0x", 26 | "from": "0x0000000000000000000000000000000000000000" 27 | } 28 | } 29 | ] -------------------------------------------------------------------------------- /tests/code/msize0.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests empty msize", 4 | "source": [ 5 | "MSIZE" 6 | ], 7 | "code": "0x59", 8 | "result": { 9 | "stack": [ 10 | "0x00" 11 | ], 12 | "memory": [] 13 | }, 14 | "gasUsed": 2, 15 | "environment": { 16 | "coinbase": "0x0000000000000000000000000000000000000000", 17 | "address": "0x0000000000000000000000000000000000000000" 18 | }, 19 | "message": { 20 | "data": "0x", 21 | "from": "0x0000000000000000000000000000000000000000" 22 | } 23 | } 24 | ] -------------------------------------------------------------------------------- /tests/code/msizebig.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests mstore and msize roundtrip (with big memory)", 4 | "source": [ 5 | "PUSH1", 6 | "0x04", 7 | "PUSH2", 8 | "0x8000", 9 | "MSTORE", 10 | "MSIZE" 11 | ], 12 | "code": "0x60046180005259", 13 | "result": { 14 | "stack": [ 15 | "0x8020" 16 | ], 17 | "memory": [] 18 | }, 19 | "gasUsed": 5138, 20 | "environment": { 21 | "address": "0x0000000000000000000000000000000000000000", 22 | "coinbase": "0x0000000000000000000000000000000000000000" 23 | }, 24 | "message": { 25 | "data": "0x", 26 | "from": "0x0000000000000000000000000000000000000000" 27 | } 28 | } 29 | ] -------------------------------------------------------------------------------- /tests/code/mstore.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests mstore and mload round trip", 4 | "source": [ 5 | "PUSH1", 6 | "0x04", 7 | "PUSH1", 8 | "0x03", 9 | "MSTORE", 10 | "PUSH1", 11 | "0x03", 12 | "MLOAD" 13 | ], 14 | "code": "0x6004600352600351", 15 | "result": { 16 | "stack": [ 17 | "0x04" 18 | ], 19 | "memory": [] 20 | }, 21 | "gasUsed": 21, 22 | "environment": { 23 | "address": "0x0000000000000000000000000000000000000000", 24 | "coinbase": "0x0000000000000000000000000000000000000000" 25 | }, 26 | "message": { 27 | "data": "0x", 28 | "from": "0x0000000000000000000000000000000000000000" 29 | } 30 | } 31 | ] -------------------------------------------------------------------------------- /tests/code/mstore8.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests mstore8 and mload round trip", 4 | "source": [ 5 | "PUSH2", 6 | "0x04ff", 7 | "PUSH1", 8 | "0x03", 9 | "MSTORE8", 10 | "PUSH1", 11 | "0x03", 12 | "MLOAD" 13 | ], 14 | "code": "0x6104ff600353600351", 15 | "result": { 16 | "stack": [ 17 | "0xff00000000000000000000000000000000000000000000000000000000000000" 18 | ], 19 | "memory": [] 20 | }, 21 | "gasUsed": 21, 22 | "environment": { 23 | "address": "0x0000000000000000000000000000000000000000", 24 | "coinbase": "0x0000000000000000000000000000000000000000" 25 | }, 26 | "message": { 27 | "data": "0x", 28 | "from": "0x0000000000000000000000000000000000000000" 29 | } 30 | } 31 | ] -------------------------------------------------------------------------------- /tests/code/origin.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests that Origin clears the stack", 4 | "environment": { 5 | "coinbase": "0x0000000000000000000000000000000000000000", 6 | "address": "0x0000000000000000000000000000000000000000" 7 | }, 8 | "source": [ 9 | "PUSH32", 10 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 11 | "POP", 12 | "ORIGIN" 13 | ], 14 | "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5032", 15 | "result": { 16 | "stack": [ 17 | "0x0000000000000000000000004bb96091ee9d802ed039c4d1a5f6216f90f81b01" 18 | ], 19 | "memory": [] 20 | }, 21 | "gasUsed": 7, 22 | "message": { 23 | "data": "0x", 24 | "from": "0x4bb96091ee9d802ed039c4d1a5f6216f90f81b01" 25 | } 26 | } 27 | ] -------------------------------------------------------------------------------- /tests/code/pc.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests the program counter", 4 | "source": [ 5 | "PUSH1", 6 | "0x01", 7 | "POP", 8 | "PC" 9 | ], 10 | "code": "0x60015058", 11 | "result": { 12 | "stack": [ 13 | "0x03" 14 | ], 15 | "memory": [] 16 | }, 17 | "gasUsed": 7, 18 | "environment": { 19 | "coinbase": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000" 21 | }, 22 | "message": { 23 | "data": "0x", 24 | "from": "0x0000000000000000000000000000000000000000" 25 | } 26 | } 27 | ] -------------------------------------------------------------------------------- /tests/code/pop.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests msize and pop", 4 | "source": [ 5 | "MSIZE", 6 | "POP" 7 | ], 8 | "code": "0x5950", 9 | "result": { 10 | "stack": [], 11 | "memory": [] 12 | }, 13 | "gasUsed": 4, 14 | "environment": { 15 | "coinbase": "0x0000000000000000000000000000000000000000", 16 | "address": "0x0000000000000000000000000000000000000000" 17 | }, 18 | "message": { 19 | "data": "0x", 20 | "from": "0x0000000000000000000000000000000000000000" 21 | } 22 | } 23 | ] -------------------------------------------------------------------------------- /tests/code/push.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "pushes", 4 | "source": [ 5 | "PUSH1", 6 | "0x01", 7 | "PUSH2", 8 | "0x0001", 9 | "PUSH3", 10 | "0x000001", 11 | "PUSH4", 12 | "0x00000001", 13 | "PUSH5", 14 | "0x0000000001", 15 | "PUSH6", 16 | "0x000000000001", 17 | "PUSH7", 18 | "0x00000000000001", 19 | "PUSH8", 20 | "0x0000000000000001", 21 | "PUSH9", 22 | "0x000000000000000001", 23 | "PUSH10", 24 | "0x00000000000000000001", 25 | "PUSH11", 26 | "0x0000000000000000000001", 27 | "PUSH12", 28 | "0x000000000000000000000001", 29 | "PUSH13", 30 | "0x00000000000000000000000001", 31 | "PUSH14", 32 | "0x0000000000000000000000000001", 33 | "PUSH15", 34 | "0x000000000000000000000000000001", 35 | "PUSH16", 36 | "0x00000000000000000000000000000001", 37 | "PUSH17", 38 | "0x0000000000000000000000000000000001", 39 | "PUSH18", 40 | "0x000000000000000000000000000000000001", 41 | "PUSH19", 42 | "0x00000000000000000000000000000000000001", 43 | "PUSH20", 44 | "0x0000000000000000000000000000000000000001", 45 | "PUSH21", 46 | "0x000000000000000000000000000000000000000001", 47 | "PUSH22", 48 | "0x00000000000000000000000000000000000000000001", 49 | "PUSH23", 50 | "0x0000000000000000000000000000000000000000000001", 51 | "PUSH24", 52 | "0x000000000000000000000000000000000000000000000001", 53 | "PUSH25", 54 | "0x00000000000000000000000000000000000000000000000001", 55 | "PUSH26", 56 | "0x0000000000000000000000000000000000000000000000000001", 57 | "PUSH27", 58 | "0x000000000000000000000000000000000000000000000000000001", 59 | "PUSH28", 60 | "0x00000000000000000000000000000000000000000000000000000001", 61 | "PUSH29", 62 | "0x0000000000000000000000000000000000000000000000000000000001", 63 | "PUSH30", 64 | "0x000000000000000000000000000000000000000000000000000000000001", 65 | "PUSH31", 66 | "0x00000000000000000000000000000000000000000000000000000000000001", 67 | "PUSH32", 68 | "0x0000000000000000000000000000000000000000000000000000000000000001" 69 | ], 70 | "code": "0x60016100016200000163000000016400000000016500000000000166000000000000016700000000000000016800000000000000000169000000000000000000016a00000000000000000000016b0000000000000000000000016c000000000000000000000000016d00000000000000000000000000016e0000000000000000000000000000016f000000000000000000000000000000017000000000000000000000000000000000017100000000000000000000000000000000000172000000000000000000000000000000000000017300000000000000000000000000000000000000017400000000000000000000000000000000000000000175000000000000000000000000000000000000000000017600000000000000000000000000000000000000000000017700000000000000000000000000000000000000000000000178000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000017a0000000000000000000000000000000000000000000000000000017b000000000000000000000000000000000000000000000000000000017c00000000000000000000000000000000000000000000000000000000017d0000000000000000000000000000000000000000000000000000000000017e000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001", 71 | "result": { 72 | "stack": [ 73 | "0x01", 74 | "0x01", 75 | "0x01", 76 | "0x01", 77 | "0x01", 78 | "0x01", 79 | "0x01", 80 | "0x01", 81 | "0x01", 82 | "0x01", 83 | "0x01", 84 | "0x01", 85 | "0x01", 86 | "0x01", 87 | "0x01", 88 | "0x01", 89 | "0x01", 90 | "0x01", 91 | "0x01", 92 | "0x01", 93 | "0x01", 94 | "0x01", 95 | "0x01", 96 | "0x01", 97 | "0x01", 98 | "0x01", 99 | "0x01", 100 | "0x01", 101 | "0x01" 102 | ], 103 | "memory": [] 104 | }, 105 | "gasUsed": 96, 106 | "environment": { 107 | "coinbase": "0x0000000000000000000000000000000000000000", 108 | "address": "0x0000000000000000000000000000000000000000" 109 | }, 110 | "message": { 111 | "data": "0x", 112 | "from": "0x0000000000000000000000000000000000000000" 113 | } 114 | } 115 | ] -------------------------------------------------------------------------------- /tests/code/return.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test that no code runs after we return", 4 | "source": [ 5 | "PUSH1", 6 | "0x03", 7 | "PUSH1", 8 | "0x03", 9 | "PUSH1", 10 | "0x00", 11 | "PUSH1", 12 | "0x01", 13 | "RETURN", 14 | "MUL" 15 | ], 16 | "code": "0x6003600360006001f302", 17 | "result": { 18 | "stack": [ 19 | "0x03" 20 | ], 21 | "memory": [] 22 | }, 23 | "gasUsed": 12, 24 | "environment": { 25 | "coinbase": "0x0000000000000000000000000000000000000000", 26 | "address": "0x0000000000000000000000000000000000000000" 27 | }, 28 | "message": { 29 | "data": "0x", 30 | "from": "0x0000000000000000000000000000000000000000" 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /tests/code/rewriter.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const files = fs.readdirSync(__dirname).filter((file) => file.endsWith('.json')) 5 | 6 | files.forEach((file) => { 7 | const json = require(path.join(__dirname, '/') + file) 8 | for (let testKey in json) { 9 | const test = json[testKey] 10 | if (!test.environment) { 11 | test.environment = {} 12 | } 13 | 14 | test.message.from = test.environment.origin 15 | delete test.environment.origin 16 | } 17 | console.log(file) 18 | fs.writeFileSync(path.join(__dirname, '/') + file, JSON.stringify(json, null, 2)) 19 | }) 20 | -------------------------------------------------------------------------------- /tests/code/soldeploy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test solidity deploy preamble", 4 | "source": [ 5 | "PUSH1", 6 | "0x60", 7 | "PUSH1", 8 | "0x40", 9 | "MSTORE", 10 | "PUSH1", 11 | "0x15", 12 | "DUP1", 13 | "PUSH1", 14 | "0x10", 15 | "PUSH1", 16 | "0x00", 17 | "CODECOPY", 18 | "PUSH1", 19 | "0x00", 20 | "RETURN", 21 | "PUSH1", 22 | "0x60", 23 | "PUSH1", 24 | "0x40", 25 | "MSTORE", 26 | "CALLDATASIZE", 27 | "ISZERO", 28 | "PUSH1", 29 | "0x0d", 30 | "JUMPI", 31 | "PUSH1", 32 | "0x0d", 33 | "JUMP", 34 | "JUMPDEST", 35 | "PUSH1", 36 | "0x13", 37 | "JUMPDEST", 38 | "JUMPDEST", 39 | "JUMP", 40 | "JUMPDEST", 41 | "STOP" 42 | ], 43 | "code": "0x606060405260158060106000396000f360606040523615600d57600d565b60135b5b565b00", 44 | "gasUsed": 39, 45 | "result": { 46 | "stack": [], 47 | "memory": [] 48 | }, 49 | "environment": { 50 | "coinbase": "0x0000000000000000000000000000000000000000", 51 | "address": "0x0000000000000000000000000000000000000000" 52 | }, 53 | "message": { 54 | "data": "0x", 55 | "from": "0x0000000000000000000000000000000000000000" 56 | } 57 | } 58 | ] -------------------------------------------------------------------------------- /tests/code/soldidityRedux.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test solidity dispatcher preamble", 4 | "source": [ 5 | "PUSH1", 6 | "0x60", 7 | "PUSH1", 8 | "0x40", 9 | "MSTORE", 10 | "CALLDATASIZE", 11 | "ISZERO", 12 | "PUSH1", 13 | "0x0d", 14 | "JUMPI", 15 | "PUSH1", 16 | "0x0d", 17 | "JUMP", 18 | "JUMPDEST", 19 | "PUSH1", 20 | "0x13", 21 | "JUMPDEST", 22 | "JUMPDEST", 23 | "JUMP", 24 | "JUMPDEST", 25 | "STOP" 26 | ], 27 | "code": "0x60606040523615600d57600d565b60135b5b565b00", 28 | "result": { 29 | "stack": [], 30 | "memory": [] 31 | }, 32 | "gasUsed": 51, 33 | "environment": { 34 | "coinbase": "0x0000000000000000000000000000000000000000", 35 | "address": "0x0000000000000000000000000000000000000000" 36 | }, 37 | "message": { 38 | "data": "0x", 39 | "from": "0x0000000000000000000000000000000000000000" 40 | } 41 | } 42 | ] -------------------------------------------------------------------------------- /tests/code/soldispatcher.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test solidity dispatcher preamble", 4 | "source": [ 5 | "PUSH1", 6 | "0x60", 7 | "PUSH1", 8 | "0x40", 9 | "MSTORE", 10 | "CALLDATASIZE", 11 | "ISZERO", 12 | "PUSH1", 13 | "0x0d", 14 | "JUMPI", 15 | "PUSH1", 16 | "0x0d", 17 | "JUMP", 18 | "JUMPDEST", 19 | "PUSH1", 20 | "0x13", 21 | "JUMPDEST", 22 | "JUMPDEST", 23 | "JUMP", 24 | "JUMPDEST", 25 | "STOP" 26 | ], 27 | "code": "0x60606040523615600d57600d565b60135b5b565b00", 28 | "result": { 29 | "stack": [], 30 | "memory": [] 31 | }, 32 | "gasUsed": 51, 33 | "environment": { 34 | "coinbase": "0x0000000000000000000000000000000000000000", 35 | "address": "0x0000000000000000000000000000000000000000" 36 | }, 37 | "message": { 38 | "data": "0x", 39 | "from": "0x0000000000000000000000000000000000000000" 40 | } 41 | } 42 | ] -------------------------------------------------------------------------------- /tests/code/solidity_add_uint256.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "solidity: uint a+b -> c", 4 | "source": [ 5 | "PUSH1", 6 | "0x60", 7 | "PUSH1", 8 | "0x40", 9 | "MSTORE", 10 | "PUSH1", 11 | "0x00", 12 | "CALLDATALOAD", 13 | "PUSH29", 14 | "0x0100000000000000000000000000000000000000000000000000000000", 15 | "SWAP1", 16 | "DIV", 17 | "DUP1", 18 | "PUSH4", 19 | "0x771602F7", 20 | "EQ", 21 | "PUSH1", 22 | "0x37", 23 | "JUMPI", 24 | "PUSH1", 25 | "0x35", 26 | "JUMP", 27 | "JUMPDEST", 28 | "STOP", 29 | "JUMPDEST", 30 | "PUSH1", 31 | "0x54", 32 | "PUSH1", 33 | "0x04", 34 | "DUP1", 35 | "DUP1", 36 | "CALLDATALOAD", 37 | "SWAP1", 38 | "PUSH1", 39 | "0x20", 40 | "ADD", 41 | "SWAP1", 42 | "SWAP2", 43 | "SWAP1", 44 | "DUP1", 45 | "CALLDATALOAD", 46 | "SWAP1", 47 | "PUSH1", 48 | "0x20", 49 | "ADD", 50 | "SWAP1", 51 | "SWAP2", 52 | "SWAP1", 53 | "POP", 54 | "POP", 55 | "PUSH1", 56 | "0x6A", 57 | "JUMP", 58 | "JUMPDEST", 59 | "PUSH1", 60 | "0x40", 61 | "MLOAD", 62 | "DUP1", 63 | "DUP3", 64 | "DUP2", 65 | "MSTORE", 66 | "PUSH1", 67 | "0x20", 68 | "ADD", 69 | "SWAP2", 70 | "POP", 71 | "POP", 72 | "PUSH1", 73 | "0x40", 74 | "MLOAD", 75 | "DUP1", 76 | "SWAP2", 77 | "SUB", 78 | "SWAP1", 79 | "RETURN", 80 | "JUMPDEST", 81 | "PUSH1", 82 | "0x00", 83 | "DUP2", 84 | "DUP4", 85 | "ADD", 86 | "SWAP1", 87 | "POP", 88 | "DUP1", 89 | "POP", 90 | "JUMPDEST", 91 | "SWAP3", 92 | "SWAP2", 93 | "POP", 94 | "POP", 95 | "JUMP" 96 | ], 97 | "code": "0x60606040526000357c010000000000000000000000000000000000000000000000000000000090048063771602F7146037576035565b005b60546004808035906020019091908035906020019091905050606A565b6040518082815260200191505060405180910390f35b6000818301905080505b9291505056", 98 | "result": { 99 | "stack": [], 100 | "memory": [], 101 | "return": "0x0000000000000000000000000000000000000000000000000000000000000066" 102 | }, 103 | "environment": { 104 | "coinbase": "0x0000000000000000000000000000000000000000", 105 | "address": "0x0000000000000000000000000000000000000000" 106 | }, 107 | "gasUsed": 225, 108 | "message": { 109 | "data": "0x771602f7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000024", 110 | "from": "0x0000000000000000000000000000000000000000" 111 | } 112 | } 113 | ] 114 | -------------------------------------------------------------------------------- /tests/code/solidity_add_uint256.sol: -------------------------------------------------------------------------------- 1 | contract Addition { 2 | function add(uint a, uint b) returns (uint c) { 3 | c = a + b; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/code/sstore.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "tests sstore", 4 | "source": [ 5 | "PUSH1", 6 | "0x03", 7 | "PUSH1", 8 | "0x04", 9 | "SSTORE", 10 | "PUSH1", 11 | "0x04", 12 | "SLOAD" 13 | ], 14 | "code": "0x6003600455600454", 15 | "result": { 16 | "stack": [ 17 | "0x03" 18 | ], 19 | "memory": [] 20 | }, 21 | "gasUsed": 20059, 22 | "environment": { 23 | "coinbase": "0x0000000000000000000000000000000000000000", 24 | "address": "0x0000000000000000000000000000000000000000" 25 | }, 26 | "message": { 27 | "data": "0x", 28 | "from": "0x0000000000000000000000000000000000000000" 29 | } 30 | } 31 | ] -------------------------------------------------------------------------------- /tests/code/stop.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test that no code runs STOP", 4 | "source": [ 5 | "PUSH1", 6 | "0x03", 7 | "STOP", 8 | "MUL" 9 | ], 10 | "code": "0x60030002", 11 | "result": { 12 | "stack": [ 13 | "0x03" 14 | ], 15 | "memory": [] 16 | }, 17 | "gasUsed": 3, 18 | "environment": { 19 | "address": "0x0000000000000000000000000000000000000000", 20 | "coinbase": "0x0000000000000000000000000000000000000000" 21 | }, 22 | "message": { 23 | "data": "0x", 24 | "from": "0x0000000000000000000000000000000000000000" 25 | } 26 | } 27 | ] -------------------------------------------------------------------------------- /tests/code/text2bytecode.js: -------------------------------------------------------------------------------- 1 | // converts the `source` in the text to bytecode 2 | const fs = require('fs') 3 | const opcodeMap = { 4 | 'STOP': '00', 5 | 'ADD': '01', 6 | 'MUL': '02', 7 | 'SUB': '03', 8 | 'DIV': '04', 9 | 'SDIV': '05', 10 | 'MOD': '06', 11 | 'SMOD': '07', 12 | 'ADDMOD': '08', 13 | 'MULMOD': '09', 14 | 'EXP': '0a', 15 | 'SIGNEXTEND': '0b', 16 | 'LT': '10', 17 | 'GT': '11', 18 | 'SLT': '12', 19 | 'SGT': '13', 20 | 'EQ': '14', 21 | 'ISZERO': '15', 22 | 'AND': '16', 23 | 'OR': '17', 24 | 'XOR': '18', 25 | 'NOT': '19', 26 | 'BYTE': '1a', 27 | 'SHA3': '20', 28 | 'ADDRESS': '30', 29 | 'BALANCE': '31', 30 | 'ORIGIN': '32', 31 | 'CALLER': '33', 32 | 'CALLVALUE': '34', 33 | 'CALLDATALOAD': '35', 34 | 'CALLDATASIZE': '36', 35 | 'CALLDATACOPY': '37', 36 | 'CODESIZE': '38', 37 | 'CODECOPY': '39', 38 | 'GASPRICE': '3a', 39 | 'EXTCODESIZE': '3b', 40 | 'EXTCODECOPY': '3c', 41 | 'BLOCKHASH': '40', 42 | 'COINBASE': '41', 43 | 'TIMESTAMP': '42', 44 | 'NUMBER': '43', 45 | 'DIFFICULTY': '44', 46 | 'GASLIMIT': '45', 47 | 'POP': '50', 48 | 'MLOAD': '51', 49 | 'MSTORE': '52', 50 | 'MSTORE8': '53', 51 | 'SLOAD': '54', 52 | 'SSTORE': '55', 53 | 'JUMP': '56', 54 | 'JUMPI': '57', 55 | 'PC': '58', 56 | 'MSIZE': '59', 57 | 'GAS': '5a', 58 | 'JUMPDEST': '5b', 59 | 'PUSH1': '60', 60 | 'PUSH2': '61', 61 | 'PUSH3': '62', 62 | 'PUSH4': '63', 63 | 'PUSH5': '64', 64 | 'PUSH6': '65', 65 | 'PUSH7': '66', 66 | 'PUSH8': '67', 67 | 'PUSH9': '68', 68 | 'PUSH10': '69', 69 | 'PUSH11': '6a', 70 | 'PUSH12': '6b', 71 | 'PUSH13': '6c', 72 | 'PUSH14': '6d', 73 | 'PUSH15': '6e', 74 | 'PUSH16': '6f', 75 | 'PUSH17': '70', 76 | 'PUSH18': '71', 77 | 'PUSH19': '72', 78 | 'PUSH20': '73', 79 | 'PUSH21': '74', 80 | 'PUSH22': '75', 81 | 'PUSH23': '76', 82 | 'PUSH24': '77', 83 | 'PUSH25': '78', 84 | 'PUSH26': '79', 85 | 'PUSH27': '7a', 86 | 'PUSH28': '7b', 87 | 'PUSH29': '7c', 88 | 'PUSH30': '7d', 89 | 'PUSH31': '7e', 90 | 'PUSH32': '7f', 91 | 'DUP1': '80', 92 | 'DUP2': '81', 93 | 'DUP3': '82', 94 | 'DUP4': '83', 95 | 'DUP5': '84', 96 | 'DUP6': '85', 97 | 'DUP7': '86', 98 | 'DUP8': '87', 99 | 'DUP9': '88', 100 | 'DUP10': '89', 101 | 'DUP11': '8a', 102 | 'DUP12': '8b', 103 | 'DUP13': '8c', 104 | 'DUP14': '8d', 105 | 'DUP15': '8e', 106 | 'DUP16': '8f', 107 | 'SWAP1': '90', 108 | 'SWAP2': '91', 109 | 'SWAP3': '92', 110 | 'SWAP4': '93', 111 | 'SWAP5': '94', 112 | 'SWAP6': '95', 113 | 'SWAP7': '96', 114 | 'SWAP8': '97', 115 | 'SWAP9': '98', 116 | 'SWAP10': '99', 117 | 'SWAP11': '9a', 118 | 'SWAP12': '9b', 119 | 'SWAP13': '9c', 120 | 'SWAP14': '9d', 121 | 'SWAP15': '9e', 122 | 'SWAP16': '9f', 123 | 'LOG0': 'a1', 124 | 'LOG1': 'a2', 125 | 'LOG2': 'a3', 126 | 'LOG3': 'a4', 127 | 'CREATE': 'f0', 128 | 'CALL': 'f1', 129 | 'CALLCODE': 'f2', 130 | 'RETURN': 'f3', 131 | 'DELEGATECALL': 'f4', 132 | 'SUICIDE': 'ff' 133 | } 134 | 135 | fs.readdir('.', (err, filenames) => { 136 | if (err) { 137 | console.log(err) 138 | } 139 | 140 | filenames = filenames.filter((name) => name.slice(-5) === '.json') 141 | filenames.forEach((filename) => { 142 | let byteCode = '0x' 143 | const tests = require(`./${filename}`) 144 | for (const index in tests) { 145 | tests[index].source.forEach((op) => { 146 | const opcode = opcodeMap[op] 147 | if (opcode) { 148 | byteCode += opcode 149 | } else { 150 | let val = op.slice(2) 151 | if (val.length % 2) { 152 | val = '0' + val 153 | } 154 | byteCode += val 155 | } 156 | }) 157 | 158 | tests[index].code = byteCode 159 | fs.writeFileSync(filename, JSON.stringify(tests, null, ' ')) 160 | } 161 | }) 162 | }) 163 | -------------------------------------------------------------------------------- /tests/code/underflow.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "test that underflows are deteched correctly", 4 | "source": [ 5 | "PUSH1", 6 | "0x02", 7 | "PUSH1", 8 | "0x02", 9 | "POP", 10 | "POP", 11 | "POP" 12 | ], 13 | "code": "0x60026002505050", 14 | "result": { 15 | "stack": [], 16 | "memory": [] 17 | }, 18 | "gasUsed": "Nan", 19 | "trapped": true, 20 | "environment": { 21 | "address": "0x0000000000000000000000000000000000000000", 22 | "coinbase": "0x0000000000000000000000000000000000000000" 23 | }, 24 | "message": { 25 | "data": "0x", 26 | "from": "0x0000000000000000000000000000000000000000" 27 | } 28 | } 29 | ] -------------------------------------------------------------------------------- /tests/codeRunnerJSVM.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const tape = require('tape') 3 | const VM = require('ethereumjs-vm') 4 | const async = require('async') 5 | const BN = require('bn.js') 6 | const argv = require('minimist')(process.argv.slice(2)) 7 | const dir = './code/' 8 | let testFiles = fs.readdirSync(dir).filter((name) => name.endsWith('.json')) 9 | 10 | // run a single file 11 | if (argv.file) { 12 | testFiles = [argv.file] 13 | } 14 | 15 | tape('testing js VM', (t) => { 16 | async.eachSeries(testFiles, (path, cb0) => { 17 | let codeTests = require(dir + path) 18 | async.eachSeries(codeTests, (test, cb1) => { 19 | t.comment(test.description) 20 | const vm = new VM() 21 | // vm.on('step', (info) => { 22 | // console.log(info.opcode.name, info.opcode.fee); 23 | // }) 24 | vm.runCode({ 25 | data: test.environment.callData, 26 | code: Buffer.from(test.code.slice(2), 'hex'), 27 | gasLimit: new BN(90000) 28 | }, (err, results) => { 29 | t.equals(results.gasUsed.toNumber(), test.gasUsed, 'should use correct amount of gas') 30 | // check the results 31 | // console.log(test.gasUsed); 32 | console.log(err) 33 | 34 | t.equals(results.exception, 1, 'should not run into exception') 35 | 36 | // check the gas used 37 | const gasUsed = results.gasUsed.toNumber() 38 | t.equals(gasUsed, test.gasUsed, 'should have correct gas') 39 | 40 | const stack = results.runState.stack 41 | t.equal(stack.length, test.result.stack.length, 'should have correct number of items on the stack') 42 | 43 | test.result.stack.forEach((item, index) => { 44 | t.equals('0x' + stack[index].toString('hex'), item) 45 | }) 46 | cb1() 47 | }) 48 | }, () => { 49 | // fs.writeFileSync(dir + path, JSON.stringify(codeTests, null, 2)) 50 | cb0() 51 | }) 52 | }, t.end) 53 | }) 54 | -------------------------------------------------------------------------------- /tests/opcode/add.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "ADD", 4 | "value": "0x01", 5 | "description": "2^255 + 2^255", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "ADD", 26 | "value": "0x01", 27 | "description": "2^255 + 0", 28 | "in": { 29 | "stack": [ 30 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31 | "0x0000000000000000000000000000000000000000000000000000000000000000" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "ADD", 48 | "value": "0x01", 49 | "description": "2 + 2", 50 | "in": { 51 | "stack": [ 52 | "0x0000000000000000000000000000000000000000000000000000000000000002", 53 | "0x0000000000000000000000000000000000000000000000000000000000000002" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x0000000000000000000000000000000000000000000000000000000000000004" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | } 68 | ] -------------------------------------------------------------------------------- /tests/opcode/addmod.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "ADDMOD", 4 | "value": "0x08", 5 | "description": "2^255 + 2^255 % 0", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000000000", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 10 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 11 | ] 12 | }, 13 | "out": { 14 | "stack": [ 15 | "0x0000000000000000000000000000000000000000000000000000000000000000" 16 | ] 17 | }, 18 | "environment": { 19 | "callData": "0x00", 20 | "caller": "0x0000000000000000000000000000000000000000", 21 | "address": "0x0000000000000000000000000000000000000000", 22 | "coinbase": "0x0000000000000000000000000000000000000000" 23 | } 24 | }, 25 | { 26 | "op": "ADDMOD", 27 | "value": "0x08", 28 | "description": "2^255 + 2^255 % 0", 29 | "in": { 30 | "stack": [ 31 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 33 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 34 | ] 35 | }, 36 | "out": { 37 | "stack": [ 38 | "0x0000000000000000000000000000000000000000000000000000000000000000" 39 | ] 40 | }, 41 | "environment": { 42 | "callData": "0x00", 43 | "caller": "0x0000000000000000000000000000000000000000", 44 | "address": "0x0000000000000000000000000000000000000000", 45 | "coinbase": "0x0000000000000000000000000000000000000000" 46 | } 47 | }, 48 | { 49 | "op": "ADDMOD", 50 | "value": "0x08", 51 | "description": "2 + 5 % 2", 52 | "in": { 53 | "stack": [ 54 | "0x0000000000000000000000000000000000000000000000000000000000000002", 55 | "0x0000000000000000000000000000000000000000000000000000000000000005", 56 | "0x0000000000000000000000000000000000000000000000000000000000000002" 57 | ] 58 | }, 59 | "out": { 60 | "stack": [ 61 | "0x0000000000000000000000000000000000000000000000000000000000000001" 62 | ] 63 | }, 64 | "environment": { 65 | "callData": "0x00", 66 | "caller": "0x0000000000000000000000000000000000000000", 67 | "address": "0x0000000000000000000000000000000000000000", 68 | "coinbase": "0x0000000000000000000000000000000000000000" 69 | } 70 | } 71 | ] -------------------------------------------------------------------------------- /tests/opcode/address.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "ADDRESS", 4 | "value": "0x30", 5 | "description": "return 0x5d48c1018904a172886829bbbd9c6f4a2d06c47b", 6 | "environment": { 7 | "address": "0x5d48c1018904a172886829bbbd9c6f4a2d06c47b", 8 | "callData": "0x00", 9 | "caller": "0x0000000000000000000000000000000000000000", 10 | "coinbase": "0x0000000000000000000000000000000000000000" 11 | }, 12 | "in": { 13 | "stack": [] 14 | }, 15 | "out": { 16 | "stack": [ 17 | "0x0000000000000000000000005d48c1018904a172886829bbbd9c6f4a2d06c47b" 18 | ] 19 | } 20 | } 21 | ] -------------------------------------------------------------------------------- /tests/opcode/and.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "AND", 4 | "value": "0x16", 5 | "description": "0xcc & 0x33", 6 | "in": { 7 | "stack": [ 8 | "0x3333333333333333333333333333333333333333333333333333333333333333", 9 | "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000000" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "AND", 26 | "value": "0x16", 27 | "description": "0x33 & 0x33", 28 | "in": { 29 | "stack": [ 30 | "0x3333333333333333333333333333333333333333333333333333333333333333", 31 | "0x3333333333333333333333333333333333333333333333333333333333333333" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x3333333333333333333333333333333333333333333333333333333333333333" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "AND", 48 | "value": "0x16", 49 | "description": "0xff & 0xf0", 50 | "in": { 51 | "stack": [ 52 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 53 | "0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "AND", 70 | "value": "0x16", 71 | "description": "0xff & 0x00", 72 | "in": { 73 | "stack": [ 74 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 75 | "0xffffffffffffffffffffffffffffffff00000000000000000000000000000000" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0xffffffffffffffffffffffffffffffff00000000000000000000000000000000" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | } 90 | ] -------------------------------------------------------------------------------- /tests/opcode/byte.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "BYTE", 4 | "value": "0x01", 5 | "description": "0x42ffffff[3]", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff42ffffff", 9 | "0x0000000000000000000000000000000000000000000000000000000000000003" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x00000000000000000000000000000000000000000000000000000000000000ff" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "BYTE", 26 | "value": "0x01", 27 | "description": "0x42ffffff[31]", 28 | "in": { 29 | "stack": [ 30 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff42ffffff", 31 | "0x000000000000000000000000000000000000000000000000000000000000001f" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x00000000000000000000000000000000000000000000000000000000000000ff" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "BYTE", 48 | "value": "0x01", 49 | "description": "0x42ffffff[32]", 50 | "in": { 51 | "stack": [ 52 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff42ffffff", 53 | "0x0000000000000000000000000000000000000000000000000000000000000020" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x0000000000000000000000000000000000000000000000000000000000000000" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | } 68 | ] -------------------------------------------------------------------------------- /tests/opcode/calldataload.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "CALLDATALOAD", 4 | "value": "0x35", 5 | "description": "basic callDataLoad test", 6 | "environment": { 7 | "callData": "0x876543210000000000000000000000000000000000000000000000000000000000000001", 8 | "caller": "0x0000000000000000000000000000000000000000", 9 | "address": "0x0000000000000000000000000000000000000000", 10 | "coinbase": "0x0000000000000000000000000000000000000000" 11 | }, 12 | "in": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000000" 15 | ] 16 | }, 17 | "out": { 18 | "stack": [ 19 | "0x8765432100000000000000000000000000000000000000000000000000000000" 20 | ] 21 | } 22 | } 23 | ] -------------------------------------------------------------------------------- /tests/opcode/calldatasize.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "CALLDATASIZE", 4 | "value": "0x36", 5 | "description": "return 24", 6 | "environment": { 7 | "callData": "0x876543210000000000000000000000000000000000000000000000000000000000000001", 8 | "caller": "0x0000000000000000000000000000000000000000", 9 | "address": "0x0000000000000000000000000000000000000000", 10 | "coinbase": "0x0000000000000000000000000000000000000000" 11 | }, 12 | "in": { 13 | "stack": [] 14 | }, 15 | "out": { 16 | "stack": [ 17 | "0x0000000000000000000000000000000000000000000000000000000000000024" 18 | ] 19 | } 20 | } 21 | ] -------------------------------------------------------------------------------- /tests/opcode/caller.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "CALLER", 4 | "value": "0x33", 5 | "description": "return 0x5d48c1018904a172886829bbbd9c6f4a2d06c47b", 6 | "environment": { 7 | "caller": "0x5d48c1018904a172886829bbbd9c6f4a2d06c47b", 8 | "callData": "0x00", 9 | "address": "0x0000000000000000000000000000000000000000", 10 | "coinbase": "0x0000000000000000000000000000000000000000" 11 | }, 12 | "in": { 13 | "stack": [] 14 | }, 15 | "out": { 16 | "stack": [ 17 | "0x0000000000000000000000005d48c1018904a172886829bbbd9c6f4a2d06c47b" 18 | ] 19 | } 20 | } 21 | ] -------------------------------------------------------------------------------- /tests/opcode/coinbase.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "COINBASE", 4 | "value": "0x41", 5 | "description": "basic coinbase test", 6 | "environment": { 7 | "coinbase": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", 8 | "callData": "0x0000000000000000000000000000000000000000000000000000000000000000", 9 | "address": "0x0000000000000000000000000000000000000000000000000000000000000000", 10 | "caller": "0x0000000000000000000000000000000000000000" 11 | }, 12 | "in": { 13 | "stack": [] 14 | }, 15 | "out": { 16 | "stack": [ 17 | "0x000000000000000000000000ea674fdde714fd979de3edf0f56aa9716b898ec8" 18 | ] 19 | } 20 | } 21 | ] -------------------------------------------------------------------------------- /tests/opcode/div.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "DIV", 4 | "value": "0x04", 5 | "description": "2^255 / 2^255", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000001" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "DIV", 26 | "value": "0x04", 27 | "description": "2^255 / 0", 28 | "in": { 29 | "stack": [ 30 | "0x0000000000000000000000000000000000000000000000000000000000000000", 31 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000000" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "DIV", 48 | "value": "0x04", 49 | "description": "2^255 / 2", 50 | "in": { 51 | "stack": [ 52 | "0x0000000000000000000000000000000000000000000000000000000000000002", 53 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "DIV", 70 | "value": "0x04", 71 | "description": "2 / 2^255", 72 | "in": { 73 | "stack": [ 74 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 75 | "0x0000000000000000000000000000000000000000000000000000000000000002" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0x0000000000000000000000000000000000000000000000000000000000000000" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | }, 90 | { 91 | "op": "DIV", 92 | "value": "0x04", 93 | "description": "1/2", 94 | "in": { 95 | "stack": [ 96 | "0x0000000000000000000000000000000000000000000000000000000000000002", 97 | "0x0000000000000000000000000000000000000000000000000000000000000001" 98 | ] 99 | }, 100 | "out": { 101 | "stack": [ 102 | "0x0000000000000000000000000000000000000000000000000000000000000000" 103 | ] 104 | }, 105 | "environment": { 106 | "callData": "0x00", 107 | "caller": "0x0000000000000000000000000000000000000000", 108 | "address": "0x0000000000000000000000000000000000000000", 109 | "coinbase": "0x0000000000000000000000000000000000000000" 110 | } 111 | }, 112 | { 113 | "op": "DIV", 114 | "value": "0x04", 115 | "description": "19/2", 116 | "in": { 117 | "stack": [ 118 | "0x0000000000000000000000000000000000000000000000000000000000000002", 119 | "0x0000000000000000000000000000000000000000000000000000000000000013" 120 | ] 121 | }, 122 | "out": { 123 | "stack": [ 124 | "0x0000000000000000000000000000000000000000000000000000000000000009" 125 | ] 126 | }, 127 | "environment": { 128 | "callData": "0x00", 129 | "caller": "0x0000000000000000000000000000000000000000", 130 | "address": "0x0000000000000000000000000000000000000000", 131 | "coinbase": "0x0000000000000000000000000000000000000000" 132 | } 133 | } 134 | ] -------------------------------------------------------------------------------- /tests/opcode/dup.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "DUP", 4 | "value": "0x80", 5 | "description": "DUP0", 6 | "params": [ 7 | 0 8 | ], 9 | "in": { 10 | "stack": [ 11 | "0x4242000000000000000000000000000000000000000000000000000000004242" 12 | ] 13 | }, 14 | "out": { 15 | "stack": [ 16 | "0x4242000000000000000000000000000000000000000000000000000000004242", 17 | "0x4242000000000000000000000000000000000000000000000000000000004242" 18 | ] 19 | }, 20 | "environment": { 21 | "callData": "0x00", 22 | "caller": "0x0000000000000000000000000000000000000000", 23 | "address": "0x0000000000000000000000000000000000000000", 24 | "coinbase": "0x0000000000000000000000000000000000000000" 25 | } 26 | }, 27 | { 28 | "op": "DUP", 29 | "value": "0x81", 30 | "description": "DUP1", 31 | "params": [ 32 | 1 33 | ], 34 | "in": { 35 | "stack": [ 36 | "0x2424000000000000000000000000000000000000000000000000000000002424", 37 | "0x4242000000000000000000000000000000000000000000000000000000004242" 38 | ] 39 | }, 40 | "out": { 41 | "stack": [ 42 | "0x2424000000000000000000000000000000000000000000000000000000002424", 43 | "0x4242000000000000000000000000000000000000000000000000000000004242", 44 | "0x2424000000000000000000000000000000000000000000000000000000002424" 45 | ] 46 | }, 47 | "environment": { 48 | "callData": "0x00", 49 | "caller": "0x0000000000000000000000000000000000000000", 50 | "address": "0x0000000000000000000000000000000000000000", 51 | "coinbase": "0x0000000000000000000000000000000000000000" 52 | } 53 | } 54 | ] -------------------------------------------------------------------------------- /tests/opcode/eq.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "EQ", 4 | "value": "0x15", 5 | "description": "0 === 0", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000000000", 9 | "0x0000000000000000000000000000000000000000000000000000000000000000" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000001" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "EQ", 26 | "value": "0x15", 27 | "description": "0 === 0", 28 | "in": { 29 | "stack": [ 30 | "0x0000000000000000000000000000000000000000000000000000000000000000", 31 | "0x0000000000000000000000000000000000000000000000000000000000000000" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000001" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "EQ", 48 | "value": "0x15", 49 | "description": "1 === 0", 50 | "in": { 51 | "stack": [ 52 | "0x0000000000000000000000000000000000000000000000000000000000000000", 53 | "0x0000000000000000000000000000000000000000000000000000000000000001" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x0000000000000000000000000000000000000000000000000000000000000000" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "EQ", 70 | "value": "0x15", 71 | "description": "MAX_NUMBER == MAX_NUMBER", 72 | "in": { 73 | "stack": [ 74 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 75 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0x0000000000000000000000000000000000000000000000000000000000000001" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | } 90 | ] -------------------------------------------------------------------------------- /tests/opcode/exp.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "EXP", 4 | "value": "0x0a", 5 | "description": "(2^256 - 1) ^ (2^256 - 1)", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 15 | ], 16 | "gasUsed": 320 17 | }, 18 | "environment": { 19 | "callData": "0x00", 20 | "caller": "0x0000000000000000000000000000000000000000", 21 | "address": "0x0000000000000000000000000000000000000000", 22 | "coinbase": "0x0000000000000000000000000000000000000000" 23 | } 24 | }, 25 | { 26 | "op": "EXP", 27 | "value": "0x0a", 28 | "description": "(2^256 -1) ^ 0", 29 | "in": { 30 | "stack": [ 31 | "0x0000000000000000000000000000000000000000000000000000000000000000", 32 | "0xfhttp://www.comp.nus.edu.sg/~loiluu/#fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 33 | ] 34 | }, 35 | "out": { 36 | "stack": [ 37 | "0x0000000000000000000000000000000000000000000000000000000000000001" 38 | ], 39 | "gasUsed": 0 40 | }, 41 | "environment": { 42 | "callData": "0x00", 43 | "caller": "0x0000000000000000000000000000000000000000", 44 | "address": "0x0000000000000000000000000000000000000000", 45 | "coinbase": "0x0000000000000000000000000000000000000000" 46 | } 47 | }, 48 | { 49 | "op": "EXP", 50 | "value": "0x0a", 51 | "description": "(2^256 - 1) ^ 2", 52 | "in": { 53 | "stack": [ 54 | "0x0000000000000000000000000000000000000000000000000000000000000002", 55 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 56 | ] 57 | }, 58 | "out": { 59 | "stack": [ 60 | "0x0000000000000000000000000000000000000000000000000000000000000001" 61 | ], 62 | "gasUsed": 10 63 | }, 64 | "environment": { 65 | "callData": "0x00", 66 | "caller": "0x0000000000000000000000000000000000000000", 67 | "address": "0x0000000000000000000000000000000000000000", 68 | "coinbase": "0x0000000000000000000000000000000000000000" 69 | } 70 | }, 71 | { 72 | "op": "EXP", 73 | "value": "0x0a", 74 | "description": "2 ^ (2^256 - 1)", 75 | "in": { 76 | "stack": [ 77 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 78 | "0x0000000000000000000000000000000000000000000000000000000000000002" 79 | ] 80 | }, 81 | "out": { 82 | "stack": [ 83 | "0x0000000000000000000000000000000000000000000000000000000000000000" 84 | ], 85 | "gasUsed": 320 86 | }, 87 | "environment": { 88 | "callData": "0x00", 89 | "caller": "0x0000000000000000000000000000000000000000", 90 | "address": "0x0000000000000000000000000000000000000000", 91 | "coinbase": "0x0000000000000000000000000000000000000000" 92 | } 93 | }, 94 | { 95 | "op": "EXP", 96 | "value": "0x0a", 97 | "description": "1 ^ 2", 98 | "in": { 99 | "stack": [ 100 | "0x0000000000000000000000000000000000000000000000000000000000000002", 101 | "0x0000000000000000000000000000000000000000000000000000000000000001" 102 | ] 103 | }, 104 | "out": { 105 | "stack": [ 106 | "0x0000000000000000000000000000000000000000000000000000000000000001" 107 | ], 108 | "gasUsed": 10 109 | }, 110 | "environment": { 111 | "callData": "0x00", 112 | "caller": "0x0000000000000000000000000000000000000000", 113 | "address": "0x0000000000000000000000000000000000000000", 114 | "coinbase": "0x0000000000000000000000000000000000000000" 115 | } 116 | }, 117 | { 118 | "op": "EXP", 119 | "value": "0x0a", 120 | "description": "2 ^ 2", 121 | "in": { 122 | "stack": [ 123 | "0x0000000000000000000000000000000000000000000000000000000000000002", 124 | "0x0000000000000000000000000000000000000000000000000000000000000002" 125 | ] 126 | }, 127 | "out": { 128 | "stack": [ 129 | "0x0000000000000000000000000000000000000000000000000000000000000004" 130 | ], 131 | "gasUsed": 10 132 | }, 133 | "environment": { 134 | "callData": "0x00", 135 | "caller": "0x0000000000000000000000000000000000000000", 136 | "address": "0x0000000000000000000000000000000000000000", 137 | "coinbase": "0x0000000000000000000000000000000000000000" 138 | } 139 | }, 140 | { 141 | "op": "EXP", 142 | "value": "0x0a", 143 | "description": "ff ^ 0x100000000000000000000", 144 | "in": { 145 | "stack": [ 146 | "0x0000000000000000000000000000000000000000000100000000000000000000", 147 | "0x00000000000000000000000000000000000000000000000000000000000000ff" 148 | ] 149 | }, 150 | "out": { 151 | "stack": [ 152 | "0xfe0f60957dc223578a0298879ec55c33085514ff7f0000000000000000000001" 153 | ], 154 | "gasUsed": 110 155 | }, 156 | "environment": { 157 | "callData": "0x00", 158 | "caller": "0x0000000000000000000000000000000000000000", 159 | "address": "0x0000000000000000000000000000000000000000", 160 | "coinbase": "0x0000000000000000000000000000000000000000" 161 | } 162 | } 163 | ] -------------------------------------------------------------------------------- /tests/opcode/gt.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "GT", 4 | "value": "0x11", 5 | "description": "basic", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000000050", 9 | "0x0000000000000000000000000000000000000000000000000000000000126af4" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000001" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | } 24 | ] -------------------------------------------------------------------------------- /tests/opcode/iszero.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "ISZERO", 4 | "value": "0x15", 5 | "description": "0 == 0", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000000000" 9 | ] 10 | }, 11 | "out": { 12 | "stack": [ 13 | "0x0000000000000000000000000000000000000000000000000000000000000001" 14 | ] 15 | }, 16 | "environment": { 17 | "callData": "0x00", 18 | "caller": "0x0000000000000000000000000000000000000000", 19 | "address": "0x0000000000000000000000000000000000000000", 20 | "coinbase": "0x0000000000000000000000000000000000000000" 21 | } 22 | }, 23 | { 24 | "op": "ISZERO", 25 | "value": "0x15", 26 | "description": "1 == 0", 27 | "in": { 28 | "stack": [ 29 | "0x0000000000000000000000000000000000000000000000000000000000000001" 30 | ] 31 | }, 32 | "out": { 33 | "stack": [ 34 | "0x0000000000000000000000000000000000000000000000000000000000000000" 35 | ] 36 | }, 37 | "environment": { 38 | "callData": "0x00", 39 | "caller": "0x0000000000000000000000000000000000000000", 40 | "address": "0x0000000000000000000000000000000000000000", 41 | "coinbase": "0x0000000000000000000000000000000000000000" 42 | } 43 | } 44 | ] -------------------------------------------------------------------------------- /tests/opcode/lt.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /tests/opcode/mload.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "MLOAD", 4 | "value": "0x51", 5 | "description": "mload", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000000000" 9 | ], 10 | "memory": { 11 | "0": "0x4242000000000000000000000000000000000000000000000000000000004242" 12 | } 13 | }, 14 | "out": { 15 | "stack": [ 16 | "0x4242000000000000000000000000000000000000000000000000000000004242" 17 | ], 18 | "memory": {} 19 | }, 20 | "environment": { 21 | "callData": "0x00", 22 | "caller": "0x0000000000000000000000000000000000000000", 23 | "address": "0x0000000000000000000000000000000000000000", 24 | "coinbase": "0x0000000000000000000000000000000000000000" 25 | } 26 | } 27 | ] -------------------------------------------------------------------------------- /tests/opcode/mod.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "MOD", 4 | "value": "0x06", 5 | "description": "(2^255 - 1) mod (2^255 - 1)", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000000" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "MOD", 26 | "value": "0x06", 27 | "description": "(2^255 -1) mod 0", 28 | "in": { 29 | "stack": [ 30 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31 | "0x0000000000000000000000000000000000000000000000000000000000000000" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000000" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "MOD", 48 | "value": "0x06", 49 | "description": "(2^256 - 1) mod 2", 50 | "in": { 51 | "stack": [ 52 | "0x0000000000000000000000000000000000000000000000000000000000000002", 53 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x0000000000000000000000000000000000000000000000000000000000000001" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "MOD", 70 | "value": "0x06", 71 | "description": "2 mod (2^256 - 1)", 72 | "in": { 73 | "stack": [ 74 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 75 | "0x0000000000000000000000000000000000000000000000000000000000000002" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0x0000000000000000000000000000000000000000000000000000000000000002" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | }, 90 | { 91 | "op": "MOD", 92 | "value": "0x06", 93 | "description": "1 mod 2", 94 | "in": { 95 | "stack": [ 96 | "0x0000000000000000000000000000000000000000000000000000000000000002", 97 | "0x0000000000000000000000000000000000000000000000000000000000000001" 98 | ] 99 | }, 100 | "out": { 101 | "stack": [ 102 | "0x0000000000000000000000000000000000000000000000000000000000000001" 103 | ] 104 | }, 105 | "environment": { 106 | "callData": "0x00", 107 | "caller": "0x0000000000000000000000000000000000000000", 108 | "address": "0x0000000000000000000000000000000000000000", 109 | "coinbase": "0x0000000000000000000000000000000000000000" 110 | } 111 | }, 112 | { 113 | "op": "MOD", 114 | "value": "0x06", 115 | "description": "(2^256 -1) mod (2^256 - 2)", 116 | "in": { 117 | "stack": [ 118 | "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", 119 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 120 | ] 121 | }, 122 | "out": { 123 | "stack": [ 124 | "0x0000000000000000000000000000000000000000000000000000000000000001" 125 | ] 126 | }, 127 | "environment": { 128 | "callData": "0x00", 129 | "caller": "0x0000000000000000000000000000000000000000", 130 | "address": "0x0000000000000000000000000000000000000000", 131 | "coinbase": "0x0000000000000000000000000000000000000000" 132 | } 133 | } 134 | ] -------------------------------------------------------------------------------- /tests/opcode/msize.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "MSIZE", 4 | "value": "0x59", 5 | "description": "return 0", 6 | "in": { 7 | "stack": [] 8 | }, 9 | "out": { 10 | "stack": [ 11 | "0x0000000000000000000000000000000000000000000000000000000000000000" 12 | ] 13 | }, 14 | "environment": { 15 | "callData": "0x00", 16 | "caller": "0x0000000000000000000000000000000000000000", 17 | "address": "0x0000000000000000000000000000000000000000", 18 | "coinbase": "0x0000000000000000000000000000000000000000" 19 | } 20 | } 21 | ] -------------------------------------------------------------------------------- /tests/opcode/mstore.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "MSTORE", 4 | "value": "0x52", 5 | "description": "mstore", 6 | "in": { 7 | "stack": [ 8 | "0x4242000000000000000000000000000000000000000000000000000000004242", 9 | "0x0000000000000000000000000000000000000000000000000000000000000000" 10 | ], 11 | "memory": {} 12 | }, 13 | "out": { 14 | "stack": [], 15 | "memory": { 16 | "0": "0x4242000000000000000000000000000000000000000000000000000000004242" 17 | }, 18 | "gasUsed": 3 19 | }, 20 | "environment": { 21 | "callData": "0x00", 22 | "caller": "0x0000000000000000000000000000000000000000", 23 | "address": "0x0000000000000000000000000000000000000000", 24 | "coinbase": "0x0000000000000000000000000000000000000000" 25 | } 26 | }, 27 | { 28 | "op": "MSTORE", 29 | "value": "0x52", 30 | "description": "mstore (extend memory)", 31 | "in": { 32 | "stack": [ 33 | "0x4242000000000000000000000000000000000000000000000000000000004242", 34 | "0x0000000000000000000000000000000000000000000000000000000000008000" 35 | ], 36 | "memory": {} 37 | }, 38 | "out": { 39 | "stack": [], 40 | "memory": { 41 | "32768": "0x4242000000000000000000000000000000000000000000000000000000004242" 42 | }, 43 | "gasUsed": 5127 44 | }, 45 | "environment": { 46 | "callData": "0x00", 47 | "caller": "0x0000000000000000000000000000000000000000", 48 | "address": "0x0000000000000000000000000000000000000000", 49 | "coinbase": "0x0000000000000000000000000000000000000000" 50 | } 51 | } 52 | ] -------------------------------------------------------------------------------- /tests/opcode/mstore8.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "MSTORE8", 4 | "value": "0x53", 5 | "description": "mstore8", 6 | "in": { 7 | "stack": [ 8 | "0x00000000000000000000000000000000000000000000000000000000000000ff", 9 | "0x0000000000000000000000000000000000000000000000000000000000000000" 10 | ], 11 | "memory": { 12 | "0": "0x4242000000000000000000000000000000000000000000000000000000004242" 13 | } 14 | }, 15 | "out": { 16 | "stack": [], 17 | "memory": { 18 | "0": "0x42420000000000000000000000000000000000000000000000000000000042ff" 19 | } 20 | }, 21 | "environment": { 22 | "callData": "0x00", 23 | "caller": "0x0000000000000000000000000000000000000000", 24 | "address": "0x0000000000000000000000000000000000000000", 25 | "coinbase": "0x0000000000000000000000000000000000000000" 26 | } 27 | } 28 | ] -------------------------------------------------------------------------------- /tests/opcode/mul.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "MUL", 4 | "value": "0x02", 5 | "description": "2^255 * 2^255", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000001" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "MUL", 26 | "value": "0x02", 27 | "description": "2^255 * 0", 28 | "in": { 29 | "stack": [ 30 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31 | "0x0000000000000000000000000000000000000000000000000000000000000000" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000000" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "MUL", 48 | "value": "0x02", 49 | "descrittion": "2 * 2", 50 | "in": { 51 | "stack": [ 52 | "0x0000000000000000000000000000000000000000000000000000000000000002", 53 | "0x0000000000000000000000000000000000000000000000000000000000000002" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x0000000000000000000000000000000000000000000000000000000000000004" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "MUL", 70 | "value": "0x02", 71 | "descrittion": "(2^32 - 1) * (2^32 - 1)", 72 | "in": { 73 | "stack": [ 74 | "0x00000000000000000000000000000000000000000000000000000000ffffffff", 75 | "0x00000000000000000000000000000000000000000000000000000000ffffffff" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0x000000000000000000000000000000000000000000000000fffffffe00000001" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | } 90 | ] -------------------------------------------------------------------------------- /tests/opcode/mulmod.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "MULMOD", 4 | "value": "0x09", 5 | "description": "0 * 0 % 0", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000000000", 9 | "0x0000000000000000000000000000000000000000000000000000000000000000", 10 | "0x0000000000000000000000000000000000000000000000000000000000000000" 11 | ] 12 | }, 13 | "out": { 14 | "stack": [ 15 | "0x0000000000000000000000000000000000000000000000000000000000000000" 16 | ] 17 | }, 18 | "environment": { 19 | "callData": "0x00", 20 | "caller": "0x0000000000000000000000000000000000000000", 21 | "address": "0x0000000000000000000000000000000000000000", 22 | "coinbase": "0x0000000000000000000000000000000000000000" 23 | } 24 | }, 25 | { 26 | "op": "MULMOD", 27 | "value": "0x09", 28 | "description": "(2^256 -1) * (2^256 -1) % (2^256 -1)", 29 | "in": { 30 | "stack": [ 31 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 33 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 34 | ] 35 | }, 36 | "out": { 37 | "stack": [ 38 | "0x0000000000000000000000000000000000000000000000000000000000000000" 39 | ] 40 | }, 41 | "environment": { 42 | "callData": "0x00", 43 | "caller": "0x0000000000000000000000000000000000000000", 44 | "address": "0x0000000000000000000000000000000000000000", 45 | "coinbase": "0x0000000000000000000000000000000000000000" 46 | } 47 | }, 48 | { 49 | "op": "MULMOD", 50 | "value": "0x09", 51 | "description": "(2^256 -1) * (2^256 -1) % 0", 52 | "in": { 53 | "stack": [ 54 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 55 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 56 | "0x0000000000000000000000000000000000000000000000000000000000000000" 57 | ] 58 | }, 59 | "out": { 60 | "stack": [ 61 | "0x0000000000000000000000000000000000000000000000000000000000000000" 62 | ] 63 | }, 64 | "environment": { 65 | "callData": "0x00", 66 | "caller": "0x0000000000000000000000000000000000000000", 67 | "address": "0x0000000000000000000000000000000000000000", 68 | "coinbase": "0x0000000000000000000000000000000000000000" 69 | } 70 | } 71 | ] -------------------------------------------------------------------------------- /tests/opcode/not.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "NOT", 4 | "value": "0x19", 5 | "description": "~0x33...", 6 | "in": { 7 | "stack": [ 8 | "0x3333333333333333333333333333333333333333333333333333333333333333" 9 | ] 10 | }, 11 | "out": { 12 | "stack": [ 13 | "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" 14 | ] 15 | }, 16 | "environment": { 17 | "callData": "0x00", 18 | "caller": "0x0000000000000000000000000000000000000000", 19 | "address": "0x0000000000000000000000000000000000000000", 20 | "coinbase": "0x0000000000000000000000000000000000000000" 21 | } 22 | }, 23 | { 24 | "op": "NOT", 25 | "value": "0x19", 26 | "description": "~0x00..", 27 | "in": { 28 | "stack": [ 29 | "0x0000000000000000000000000000000000000000000000000000000000000000" 30 | ] 31 | }, 32 | "out": { 33 | "stack": [ 34 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 35 | ] 36 | }, 37 | "environment": { 38 | "callData": "0x00", 39 | "caller": "0x0000000000000000000000000000000000000000", 40 | "address": "0x0000000000000000000000000000000000000000", 41 | "coinbase": "0x0000000000000000000000000000000000000000" 42 | } 43 | }, 44 | { 45 | "op": "NOT", 46 | "value": "0x19", 47 | "description": "~0xaa..", 48 | "in": { 49 | "stack": [ 50 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 51 | ] 52 | }, 53 | "out": { 54 | "stack": [ 55 | "0x0000000000000000000000000000000000000000000000000000000000000000" 56 | ] 57 | }, 58 | "environment": { 59 | "callData": "0x00", 60 | "caller": "0x0000000000000000000000000000000000000000", 61 | "address": "0x0000000000000000000000000000000000000000", 62 | "coinbase": "0x0000000000000000000000000000000000000000" 63 | } 64 | } 65 | ] -------------------------------------------------------------------------------- /tests/opcode/or.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "OR", 4 | "value": "0x17", 5 | "description": "0xcc... | 0x33...", 6 | "in": { 7 | "stack": [ 8 | "0x3333333333333333333333333333333333333333333333333333333333333333", 9 | "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "OR", 26 | "value": "0x17", 27 | "description": "0xcc00.. | 0x0033..", 28 | "in": { 29 | "stack": [ 30 | "0x0033003300330033003300330033003300330033003300330033003300330033", 31 | "0xcc00cc00cc00cc00cc00cc00cc00cc00cc00cc00cc00cc00cc00cc00cc00cc00" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0xcc33cc33cc33cc33cc33cc33cc33cc33cc33cc33cc33cc33cc33cc33cc33cc33" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "OR", 48 | "value": "0x17", 49 | "description": "0xaa | 0x00", 50 | "in": { 51 | "stack": [ 52 | "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000", 53 | "0x00000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | } 68 | ] -------------------------------------------------------------------------------- /tests/opcode/return.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "RETURN", 4 | "value": "0xf3", 5 | "description": "return 0x42", 6 | "in": { 7 | "memory": { 8 | "512": "0x000000000000000000000000000000000000000000000000000000000000002a" 9 | }, 10 | "stack": [ 11 | "0x0000000000000000000000000000000000000000000000000000000000000020", 12 | "0x0000000000000000000000000000000000000000000000000000000000000200" 13 | ] 14 | }, 15 | "out": { 16 | "stack": [], 17 | "memory": { 18 | "512": "0x000000000000000000000000000000000000000000000000000000000000002a" 19 | }, 20 | "return": "0x2a00000000000000000000000000000000000000000000000000000000000000" 21 | }, 22 | "environment": { 23 | "callData": "0x00", 24 | "caller": "0x0000000000000000000000000000000000000000", 25 | "address": "0x0000000000000000000000000000000000000000", 26 | "coinbase": "0x0000000000000000000000000000000000000000" 27 | } 28 | } 29 | ] -------------------------------------------------------------------------------- /tests/opcode/rewriter.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const files = fs.readdirSync(__dirname).filter((file) => file.endsWith('.json')) 5 | 6 | files.forEach((file) => { 7 | const json = require(path.join(__dirname, '/') + file) 8 | for (let testKey in json) { 9 | const test = json[testKey] 10 | delete test.state 11 | if (test.stack) { 12 | test.in = { 13 | 'stack': test.stack.in 14 | } 15 | test.out = { 16 | 'stack': test.stack.out 17 | } 18 | delete test.stack 19 | } 20 | if (test.memory) { 21 | test.in['memory'] = test.memory.in 22 | test.out['memory'] = test.memory.out 23 | delete test.memory 24 | } 25 | 26 | if (!test.environment) { 27 | test.environment = {} 28 | } 29 | 30 | const evn = test.environment 31 | 32 | if (!evn.callData) { 33 | evn.callData = '0x00' 34 | } 35 | 36 | if (!evn.caller) { 37 | evn.caller = '0x0000000000000000000000000000000000000000' 38 | } 39 | if (!evn.address) { 40 | evn.address = '0x0000000000000000000000000000000000000000' 41 | } 42 | if (!evn.coinbase) { 43 | evn.coinbase = '0x0000000000000000000000000000000000000000' 44 | } 45 | } 46 | console.log(file) 47 | fs.writeFileSync(path.join(__dirname, '/') + file, JSON.stringify(json, null, 2)) 48 | }) 49 | -------------------------------------------------------------------------------- /tests/opcode/sdiv.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "SDIV", 4 | "value": "0x05", 5 | "description": "-1 / -1", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000001" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "SDIV", 26 | "value": "0x05", 27 | "description": "-1 / 0", 28 | "in": { 29 | "stack": [ 30 | "0x0000000000000000000000000000000000000000000000000000000000000000", 31 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000000" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "SDIV", 48 | "value": "0x05", 49 | "description": "-1 / 2", 50 | "in": { 51 | "stack": [ 52 | "0x0000000000000000000000000000000000000000000000000000000000000002", 53 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x0000000000000000000000000000000000000000000000000000000000000000" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "SDIV", 70 | "value": "0x05", 71 | "description": "2 / -1", 72 | "in": { 73 | "stack": [ 74 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 75 | "0x0000000000000000000000000000000000000000000000000000000000000002" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | }, 90 | { 91 | "op": "SDIV", 92 | "value": "0x05", 93 | "description": "1/2", 94 | "in": { 95 | "stack": [ 96 | "0x0000000000000000000000000000000000000000000000000000000000000002", 97 | "0x0000000000000000000000000000000000000000000000000000000000000001" 98 | ] 99 | }, 100 | "out": { 101 | "stack": [ 102 | "0x0000000000000000000000000000000000000000000000000000000000000000" 103 | ] 104 | }, 105 | "environment": { 106 | "callData": "0x00", 107 | "caller": "0x0000000000000000000000000000000000000000", 108 | "address": "0x0000000000000000000000000000000000000000", 109 | "coinbase": "0x0000000000000000000000000000000000000000" 110 | } 111 | }, 112 | { 113 | "op": "SDIV", 114 | "value": "0x05", 115 | "description": "19/2", 116 | "in": { 117 | "stack": [ 118 | "0x0000000000000000000000000000000000000000000000000000000000000002", 119 | "0x0000000000000000000000000000000000000000000000000000000000000013" 120 | ] 121 | }, 122 | "out": { 123 | "stack": [ 124 | "0x0000000000000000000000000000000000000000000000000000000000000009" 125 | ] 126 | }, 127 | "environment": { 128 | "callData": "0x00", 129 | "caller": "0x0000000000000000000000000000000000000000", 130 | "address": "0x0000000000000000000000000000000000000000", 131 | "coinbase": "0x0000000000000000000000000000000000000000" 132 | } 133 | }, 134 | { 135 | "op": "SDIV", 136 | "value": "0x05", 137 | "description": "sdiv_i256min", 138 | "in": { 139 | "stack": [ 140 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 141 | "0x8000000000000000000000000000000000000000000000000000000000000001" 142 | ] 143 | }, 144 | "out": { 145 | "stack": [ 146 | "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 147 | ] 148 | }, 149 | "environment": { 150 | "callData": "0x00", 151 | "caller": "0x0000000000000000000000000000000000000000", 152 | "address": "0x0000000000000000000000000000000000000000", 153 | "coinbase": "0x0000000000000000000000000000000000000000" 154 | } 155 | } 156 | ] -------------------------------------------------------------------------------- /tests/opcode/sgt.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /tests/opcode/sha3.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "SHA3", 4 | "value": "0x16", 5 | "description": "0 bytes", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000000000", 9 | "0x0000000000000000000000000000000000000000000000000000000000000000" 10 | ], 11 | "memory": { 12 | "0": [ 13 | "0x0000000000000000000000000000000000000000000000000000000000000000" 14 | ] 15 | } 16 | }, 17 | "out": { 18 | "stack": [ 19 | "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" 20 | ], 21 | "memory": {}, 22 | "gasUsed": 0 23 | }, 24 | "environment": { 25 | "callData": "0x00", 26 | "caller": "0x0000000000000000000000000000000000000000", 27 | "address": "0x0000000000000000000000000000000000000000", 28 | "coinbase": "0x0000000000000000000000000000000000000000" 29 | } 30 | }, 31 | { 32 | "op": "SHA3", 33 | "value": "0x16", 34 | "description": "32 bytes of zeroes", 35 | "in": { 36 | "stack": [ 37 | "0x0000000000000000000000000000000000000000000000000000000000000020", 38 | "0x0000000000000000000000000000000000000000000000000000000000000000" 39 | ], 40 | "memory": { 41 | "0": [ 42 | "0x0000000000000000000000000000000000000000000000000000000000000000" 43 | ] 44 | } 45 | }, 46 | "out": { 47 | "stack": [ 48 | "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563" 49 | ], 50 | "memory": {}, 51 | "gasUsed": 9 52 | }, 53 | "environment": { 54 | "callData": "0x00", 55 | "caller": "0x0000000000000000000000000000000000000000", 56 | "address": "0x0000000000000000000000000000000000000000", 57 | "coinbase": "0x0000000000000000000000000000000000000000" 58 | } 59 | }, 60 | { 61 | "op": "SHA3", 62 | "value": "0x16", 63 | "description": "256 bytes of zeroes", 64 | "in": { 65 | "stack": [ 66 | "0x0000000000000000000000000000000000000000000000000000000000000100", 67 | "0x0000000000000000000000000000000000000000000000000000000000000000" 68 | ], 69 | "memory": { 70 | "0": [ 71 | "0x0000000000000000000000000000000000000000000000000000000000000000", 72 | "0x0000000000000000000000000000000000000000000000000000000000000000", 73 | "0x0000000000000000000000000000000000000000000000000000000000000000", 74 | "0x0000000000000000000000000000000000000000000000000000000000000000", 75 | "0x0000000000000000000000000000000000000000000000000000000000000000", 76 | "0x0000000000000000000000000000000000000000000000000000000000000000", 77 | "0x0000000000000000000000000000000000000000000000000000000000000000", 78 | "0x0000000000000000000000000000000000000000000000000000000000000000" 79 | ] 80 | } 81 | }, 82 | "out": { 83 | "stack": [ 84 | "0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5" 85 | ], 86 | "memory": {}, 87 | "gasUsed": 72 88 | }, 89 | "environment": { 90 | "callData": "0x00", 91 | "caller": "0x0000000000000000000000000000000000000000", 92 | "address": "0x0000000000000000000000000000000000000000", 93 | "coinbase": "0x0000000000000000000000000000000000000000" 94 | } 95 | }, 96 | { 97 | "op": "SHA3", 98 | "value": "0x16", 99 | "description": "32 bytes of zeroes (with memory expansion)", 100 | "in": { 101 | "stack": [ 102 | "0x0000000000000000000000000000000000000000000000000000000000000020", 103 | "0x0000000000000000000000000000000000000000000000000000000000000000" 104 | ], 105 | "memory": {} 106 | }, 107 | "out": { 108 | "stack": [ 109 | "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563" 110 | ], 111 | "memory": {}, 112 | "gasUsed": 9 113 | }, 114 | "environment": { 115 | "callData": "0x00", 116 | "caller": "0x0000000000000000000000000000000000000000", 117 | "address": "0x0000000000000000000000000000000000000000", 118 | "coinbase": "0x0000000000000000000000000000000000000000" 119 | } 120 | } 121 | ] -------------------------------------------------------------------------------- /tests/opcode/signextend.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "SIGNEXTEND", 4 | "value": "0x0b", 5 | "description": "basic", 6 | "in": { 7 | "stack": [ 8 | "0x0000000000000000000000000000000000000000000000000000000000126af4", 9 | "0x0000000000000000000000000000000000000000000000000000000000000050" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000126af4" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "SIGNEXTEND", 26 | "value": "0x0b", 27 | "description": "signextend_BitIsNotSet", 28 | "in": { 29 | "stack": [ 30 | "0x0000000000000000000000000000000000000000000000000000000000122f6a", 31 | "0x0000000000000000000000000000000000000000000000000000000000000000" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x000000000000000000000000000000000000000000000000000000000000006a" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "SIGNEXTEND", 48 | "value": "0x0b", 49 | "description": "signextend_BitIsSetInHigherByte", 50 | "in": { 51 | "stack": [ 52 | "0x000000000000000000000000000000000000000000000000000000000012faf4", 53 | "0x0000000000000000000000000000000000000000000000000000000000000001" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaf4" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | } 68 | ] -------------------------------------------------------------------------------- /tests/opcode/slt.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /tests/opcode/smod.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "SMOD", 4 | "value": "0x07", 5 | "description": "-1 mod -1", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000000" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "SMOD", 26 | "value": "0x07", 27 | "description": "-1 mod 0", 28 | "in": { 29 | "stack": [ 30 | "0x0000000000000000000000000000000000000000000000000000000000000000", 31 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000000" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "SMOD", 48 | "value": "0x07", 49 | "description": "-1 mod 2", 50 | "in": { 51 | "stack": [ 52 | "0x0000000000000000000000000000000000000000000000000000000000000002", 53 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "SMOD", 70 | "value": "0x07", 71 | "description": "2 mod -1", 72 | "in": { 73 | "stack": [ 74 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 75 | "0x0000000000000000000000000000000000000000000000000000000000000002" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0x0000000000000000000000000000000000000000000000000000000000000000" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | }, 90 | { 91 | "op": "SMOD", 92 | "value": "0x07", 93 | "description": "1 mod 2", 94 | "in": { 95 | "stack": [ 96 | "0x0000000000000000000000000000000000000000000000000000000000000002", 97 | "0x0000000000000000000000000000000000000000000000000000000000000001" 98 | ] 99 | }, 100 | "out": { 101 | "stack": [ 102 | "0x0000000000000000000000000000000000000000000000000000000000000001" 103 | ] 104 | }, 105 | "environment": { 106 | "callData": "0x00", 107 | "caller": "0x0000000000000000000000000000000000000000", 108 | "address": "0x0000000000000000000000000000000000000000", 109 | "coinbase": "0x0000000000000000000000000000000000000000" 110 | } 111 | } 112 | ] -------------------------------------------------------------------------------- /tests/opcode/sub.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "SUB", 4 | "value": "0x03", 5 | "description": "2^255 - 2^255", 6 | "in": { 7 | "stack": [ 8 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 9 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0x0000000000000000000000000000000000000000000000000000000000000000" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "SUB", 26 | "value": "0x03", 27 | "description": "0 - 2^255 = 1 checks overflow ", 28 | "in": { 29 | "stack": [ 30 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31 | "0x0000000000000000000000000000000000000000000000000000000000000000" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000001" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | } 46 | ] -------------------------------------------------------------------------------- /tests/opcode/swap.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "SWAP", 4 | "value": "0x90", 5 | "description": "SWAP0", 6 | "params": [ 7 | 0 8 | ], 9 | "in": { 10 | "stack": [ 11 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 12 | "0x4242000000000000000000000000000000000000000000000000000000004242" 13 | ] 14 | }, 15 | "out": { 16 | "stack": [ 17 | "0x4242000000000000000000000000000000000000000000000000000000004242", 18 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 19 | ] 20 | }, 21 | "environment": { 22 | "callData": "0x00", 23 | "caller": "0x0000000000000000000000000000000000000000", 24 | "address": "0x0000000000000000000000000000000000000000", 25 | "coinbase": "0x0000000000000000000000000000000000000000" 26 | } 27 | }, 28 | { 29 | "op": "SWAP", 30 | "value": "0x91", 31 | "description": "SWAP1", 32 | "params": [ 33 | 1 34 | ], 35 | "in": { 36 | "stack": [ 37 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 38 | "0x4242000000000000000000000000000000000000000000000000000000004242", 39 | "0x0000000000000000000000000000000000000000000000000000000000000000" 40 | ] 41 | }, 42 | "out": { 43 | "stack": [ 44 | "0x0000000000000000000000000000000000000000000000000000000000000000", 45 | "0x4242000000000000000000000000000000000000000000000000000000004242", 46 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 47 | ] 48 | }, 49 | "environment": { 50 | "callData": "0x00", 51 | "caller": "0x0000000000000000000000000000000000000000", 52 | "address": "0x0000000000000000000000000000000000000000", 53 | "coinbase": "0x0000000000000000000000000000000000000000" 54 | } 55 | } 56 | ] -------------------------------------------------------------------------------- /tests/opcode/xor.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "XOR", 4 | "value": "0x18", 5 | "description": "0xcc ^ 0x33", 6 | "in": { 7 | "stack": [ 8 | "0x3333333333333333333333333333333333333333333333333333333333333333", 9 | "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" 10 | ] 11 | }, 12 | "out": { 13 | "stack": [ 14 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 15 | ] 16 | }, 17 | "environment": { 18 | "callData": "0x00", 19 | "caller": "0x0000000000000000000000000000000000000000", 20 | "address": "0x0000000000000000000000000000000000000000", 21 | "coinbase": "0x0000000000000000000000000000000000000000" 22 | } 23 | }, 24 | { 25 | "op": "XOR", 26 | "value": "0x18", 27 | "description": "0xff ^ 0xff", 28 | "in": { 29 | "stack": [ 30 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 32 | ] 33 | }, 34 | "out": { 35 | "stack": [ 36 | "0x0000000000000000000000000000000000000000000000000000000000000000" 37 | ] 38 | }, 39 | "environment": { 40 | "callData": "0x00", 41 | "caller": "0x0000000000000000000000000000000000000000", 42 | "address": "0x0000000000000000000000000000000000000000", 43 | "coinbase": "0x0000000000000000000000000000000000000000" 44 | } 45 | }, 46 | { 47 | "op": "XOR", 48 | "value": "0x18", 49 | "description": "0xaa ^ 0xbb", 50 | "in": { 51 | "stack": [ 52 | "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 53 | "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 54 | ] 55 | }, 56 | "out": { 57 | "stack": [ 58 | "0x1111111111111111111111111111111111111111111111111111111111111111" 59 | ] 60 | }, 61 | "environment": { 62 | "callData": "0x00", 63 | "caller": "0x0000000000000000000000000000000000000000", 64 | "address": "0x0000000000000000000000000000000000000000", 65 | "coinbase": "0x0000000000000000000000000000000000000000" 66 | } 67 | }, 68 | { 69 | "op": "XOR", 70 | "value": "0x18", 71 | "description": "0xaa00 ^ 0xbb00", 72 | "in": { 73 | "stack": [ 74 | "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000", 75 | "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb00000000000000000000000000000000" 76 | ] 77 | }, 78 | "out": { 79 | "stack": [ 80 | "0x1111111111111111111111111111111100000000000000000000000000000000" 81 | ] 82 | }, 83 | "environment": { 84 | "callData": "0x00", 85 | "caller": "0x0000000000000000000000000000000000000000", 86 | "address": "0x0000000000000000000000000000000000000000", 87 | "coinbase": "0x0000000000000000000000000000000000000000" 88 | } 89 | } 90 | ] -------------------------------------------------------------------------------- /tests/opcodeRunnerJSVM.js: -------------------------------------------------------------------------------- 1 | // var runState = { 2 | // stateManager: stateManager, 3 | // returnValue: false, 4 | // stopped: false, 5 | // vmError: false, 6 | // suicideTo: undefined, 7 | // programCounter: 0, 8 | // opCode: undefined, 9 | // opName: undefined, 10 | // gasLeft: new BN(opts.gasLimit), 11 | // gasLimit: new BN(opts.gasLimit), 12 | // gasPrice: opts.gasPrice, 13 | // memory: [], 14 | // memoryWordCount: 0, 15 | // stack: [], 16 | // logs: [], 17 | // validJumps: [], 18 | // gasRefund: new BN(0), 19 | // highestMemCost: new BN(0), 20 | // depth: opts.depth || 0, 21 | // suicides: opts.suicides || {}, 22 | // block: block, 23 | // callValue: opts.value || new BN(0), 24 | // address: opts.address || utils.zeros(32), 25 | // caller: opts.caller || utils.zeros(32), 26 | // origin: opts.origin || opts.caller || utils.zeros(32), 27 | // callData: opts.data || Buffer.from([0]), 28 | // code: opts.code, 29 | // populateCache: opts.populateCache === undefined ? true : opts.populateCache, 30 | // enableHomestead: this.opts.enableHomestead === undefined ? block.isHomestead() : this.opts.enableHomestead // this == vm 31 | // } 32 | const fs = require('fs') 33 | const tape = require('tape') 34 | const ethUtil = require('ethereumjs-util') 35 | const dir = `${__dirname}/opcode` 36 | const opFunc = require('ethereumjs-vm/lib/opFns.js') 37 | const BN = require('bn.js') 38 | const argv = require('minimist')(process.argv.slice(2)) 39 | 40 | let testFiles = fs.readdirSync(dir).filter((name) => name.endsWith('.json')) 41 | 42 | // run a single file 43 | if (argv.file) { 44 | testFiles = [argv.file] 45 | } 46 | 47 | tape('testing EVM1 Ops', (t) => { 48 | testFiles.forEach((path) => { 49 | let opTest = require(`${dir}/${path}`) 50 | opTest.forEach((test) => { 51 | // FIXME: have separate `t.test()` for better grouping 52 | t.comment(`testing ${test.op} ${test.description}`) 53 | 54 | // populate the stack with predefined values 55 | const stack = test.in.stack.map((i) => Buffer.from(i.slice(2), 'hex')) 56 | const startGas = '100000000000000000' 57 | 58 | const runState = { 59 | memoryWordCount: 0, 60 | memory: [], 61 | stack: stack, 62 | opCode: parseInt(test.value), 63 | highestMemCost: new BN(0), 64 | gasLeft: new BN(startGas), 65 | caller: test.environment.caller, 66 | callData: ethUtil.toBuffer(test.environment.callData) 67 | } 68 | 69 | // populate the memory 70 | if (test.in.memory) { 71 | for (let item in test.in.memory) { 72 | const memIn = Buffer.from(test.in.memory[item].slice(2), 'hex') 73 | runState.memory.splice(item, 32, ...memIn) 74 | } 75 | } 76 | 77 | // Runs the opcode. 78 | const noStack = new Set(['DUP', 'SWAP']) 79 | let args = [] 80 | if (noStack.has(test.op)) { 81 | args = [runState] 82 | } else { 83 | args = stack.slice() 84 | args.reverse() 85 | args.push(runState) 86 | runState.stack = [] 87 | } 88 | 89 | let result 90 | try { 91 | result = opFunc[test.op](...args) 92 | } catch (e) { 93 | t.fail('JSVM exception: ' + e) 94 | return 95 | } 96 | 97 | if (result) { 98 | runState.stack.push(result) 99 | } 100 | 101 | // check that gasUsed 102 | if (test.out.gasUsed) { 103 | t.equals(new BN(startGas).sub(runState.gasLeft).toNumber(), test.out.gasUsed, 'should use the correct amount of gas') 104 | } 105 | 106 | test.out.stack.forEach((item, index) => { 107 | t.equals('0x' + ethUtil.setLength(runState.stack[index], 32).toString('hex'), item, 'stack items should be equal') 108 | }) 109 | 110 | // check the memory 111 | if (test.out.memory) { 112 | // TODO 113 | } 114 | 115 | // check for EVM return value 116 | if (test.out.return) { 117 | // TODO 118 | } 119 | }) 120 | }) 121 | t.end() 122 | }) 123 | -------------------------------------------------------------------------------- /tests/runVmTests.js: -------------------------------------------------------------------------------- 1 | const argv = require('minimist')(process.argv.slice(2)) 2 | const tape = require('tape') 3 | const ethUtil = require('ethereumjs-util') 4 | const testing = require('ethereumjs-testing') 5 | const Kernel = require('ewasm-kernel') 6 | const Environment = require('ewasm-kernel/environment.js') 7 | const Address = require('ewasm-kernel/deps/address.js') 8 | const U256 = require('ewasm-kernel/deps/u256.js') 9 | const evm2wasm = require('../index.js') 10 | 11 | const Interface = require('ewasm-kernel/EVMimports') 12 | const DebugInterface = require('ewasm-kernel/debugInterface') 13 | 14 | const skipList = [ 15 | // slow performance tests 16 | 'loop-mul', 17 | 'loop-add-10M', 18 | 'loop-divadd-10M', 19 | 'loop-divadd-unr100-10M', 20 | 'loop-exp-16b-100k', 21 | 'loop-exp-1b-1M', 22 | 'loop-exp-2b-100k', 23 | 'loop-exp-32b-100k', 24 | 'loop-exp-4b-100k', 25 | 'loop-exp-8b-100k', 26 | 'loop-exp-nop-1M', 27 | 'loop-mulmod-2M', 28 | 29 | // these failures might be due to evm2wasm 30 | // TODO: fix these 31 | 'JDfromStorageDynamicJump0_jumpdest0', 32 | 'JDfromStorageDynamicJump0_jumpdest2', 33 | 'JDfromStorageDynamicJumpi1', 34 | 'JDfromStorageDynamicJumpiAfterStop', 35 | 36 | // failures probably due to broken ewasm-kernel 37 | 'coinbase', 38 | 'calldatacopy_DataIndexTooHigh', 39 | 'calldatacopy_DataIndexTooHigh_return', 40 | '201503102037PYTHON', 41 | '201503102148PYTHON', 42 | '201503102300PYTHON', 43 | '201503120547PYTHON', 44 | 'CallToPrecompiledContract' 45 | ] 46 | 47 | async function runner (testName, testData, t) { 48 | const code = Buffer.from(testData.exec.code.slice(2), 'hex') 49 | const { 50 | buffer: evm 51 | } = await evm2wasm.evm2wasm(code, { 52 | stackTrace: argv.trace, 53 | useAsyncAPI: true, 54 | testName: testName, 55 | inlineOps: true 56 | }) 57 | 58 | const environment = setupEnviroment(testData) 59 | let instance 60 | let vmExceptionErr = null 61 | try { 62 | const kernel = new Kernel({ 63 | code: evm, 64 | interfaces: [Interface, DebugInterface] 65 | }) 66 | instance = await kernel.run(environment) 67 | } catch (e) { 68 | vmExceptionErr = e 69 | } finally { 70 | await checkResults(testData, t, instance, environment, vmExceptionErr) 71 | } 72 | } 73 | 74 | function setupEnviroment (testData) { 75 | const env = new Environment() 76 | 77 | env.gasLeft = parseInt(testData.exec.gas.slice(2), 16) 78 | env.callData = new Uint8Array(Buffer.from(testData.exec.data.slice(2), 'hex')) 79 | env.gasPrice = ethUtil.bufferToInt(Buffer.from(testData.exec.gasPrice.slice(2), 'hex')) 80 | 81 | env.address = new Address(testData.exec.address) 82 | env.caller = new Address(testData.exec.caller) 83 | env.origin = new Address(testData.exec.origin) 84 | env.value = new U256(testData.exec.value) 85 | 86 | env.callValue = new U256(testData.exec.value) 87 | env.code = new Uint8Array(Buffer.from(testData.exec.code.slice(2), 'hex')) 88 | 89 | // setup block 90 | env.block.header.number = testData.env.currentNumber 91 | env.block.header.coinbase = Buffer.from(testData.env.currentCoinbase.slice(2), 'hex') 92 | env.block.header.difficulty = testData.env.currentDifficulty 93 | env.block.header.gasLimit = Buffer.from(testData.env.currentGasLimit.slice(2), 'hex') 94 | env.block.header.number = Buffer.from(testData.env.currentNumber.slice(2), 'hex') 95 | env.block.header.timestamp = Buffer.from(testData.env.currentTimestamp.slice(2), 'hex') 96 | 97 | env.state = {} 98 | for (let address in testData.pre) { 99 | const testAccount = testData.pre[address] 100 | let envAccount = { 101 | code: testAccount.code, 102 | balance: testAccount.balance, 103 | storage: testAccount.storage 104 | } 105 | 106 | env.state[address] = envAccount 107 | } 108 | 109 | return env 110 | } 111 | 112 | async function checkResults (testData, t, instance, environment, vmExceptionErr) { 113 | // https://github.com/ethereum/tests/wiki/VM-Tests 114 | // > It is generally expected that the test implementer will read env, exec 115 | // and pre then check their results against gas, logs, out, post and 116 | // callcreates. If an exception is expected, then latter sections are absent 117 | // in the test. 118 | 119 | if ((testData.gas && testData.out && testData.post)) { 120 | if (vmExceptionErr) { 121 | t.fail('should not have VM exception') 122 | console.log('vmExceptionErr:', vmExceptionErr) 123 | } 124 | } else { 125 | // if any of the expected fields are missing then a VM exception is expected 126 | t.true(vmExceptionErr, 'should have VM exception') 127 | } 128 | 129 | if (testData.gas) { 130 | t.equals(ethUtil.intToHex(environment.gasLeft), testData.gas, 'should have the correct gas') 131 | } 132 | 133 | // check return value 134 | if (testData.out) { 135 | t.equals(Buffer.from(environment.returnValue).toString('hex'), testData.out.slice(2), 'return value') 136 | } 137 | 138 | // check storage 139 | if (testData.post) { 140 | const expectedAccount = testData.post[testData.exec.address] 141 | // TODO: check all accounts 142 | if (expectedAccount) { 143 | const expectedStorage = expectedAccount.storage 144 | if (expectedStorage) { 145 | for (let key in expectedStorage) { 146 | const keyHex = (new U256(key)).toString(16) 147 | // pad values to get consistent hex strings for comparison 148 | let expectedValue = ethUtil.setLengthLeft(ethUtil.toBuffer(expectedStorage[key]), 32) 149 | expectedValue = '0x' + expectedValue.toString('hex') 150 | let actualValue = environment.state[testData.exec.address]['storage'][keyHex] 151 | if (actualValue) { 152 | actualValue = '0x' + ethUtil.setLengthLeft(ethUtil.toBuffer(actualValue), 32).toString('hex') 153 | } else { 154 | actualValue = '0x' + ethUtil.setLengthLeft(ethUtil.toBuffer(0), 32).toString('hex') 155 | } 156 | t.equals(actualValue, expectedValue, `should have correct storage value at key ${key}`) 157 | } 158 | } 159 | } 160 | } 161 | } 162 | 163 | let testGetterArgs = {} 164 | testGetterArgs.skipVM = skipList 165 | 166 | tape('VMTESTS', t => { 167 | testing.getTestsFromArgs('VMTests', (fileName, testName, tests) => { 168 | t.comment(fileName + ' ' + testName) 169 | return runner(testName, tests, t).catch(err => { 170 | t.fail(err) 171 | }) 172 | }, testGetterArgs).then(() => { 173 | t.end() 174 | }) 175 | }) 176 | -------------------------------------------------------------------------------- /tmp/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ewasm/evm2wasm/0491f28cc0f1b516e0b5e85b93761d91d44d87c6/tmp/.gitkeep -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(evm2wasm) 2 | add_subdirectory(wast2wasm) 3 | -------------------------------------------------------------------------------- /tools/evm2wasm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(evm2wasm main.cpp) 2 | target_link_libraries(evm2wasm PRIVATE libevm2wasm) -------------------------------------------------------------------------------- /tools/evm2wasm/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | using namespace std; 10 | 11 | 12 | int main(int argc, char **argv) { 13 | if (argc < 2) { 14 | cerr << "Usage: " << argv[0] << " [--wast]" << endl; 15 | return 1; 16 | } 17 | 18 | bool wast = false; 19 | if (argc == 3) { 20 | wast = (string(argv[2]) == "--wast"); 21 | if (!wast) { 22 | cerr << "Usage: " << argv[0] << " [--wast]" << endl; 23 | return 1; 24 | } 25 | } 26 | 27 | ifstream input(argv[1]); 28 | if (!input.is_open()) { 29 | cerr << "File not found: " << argv[1] << endl; 30 | return 1; 31 | } 32 | 33 | string str( 34 | (std::istreambuf_iterator(input)), 35 | std::istreambuf_iterator() 36 | ); 37 | 38 | // clean input of any whitespace (including space and new lines) 39 | str.erase(remove_if(str.begin(), str.end(), [](unsigned char x){return std::isspace(x);}), str.end()); 40 | 41 | if (wast) { 42 | cout << evm2wasm::evmhex2wast(str); 43 | } else { 44 | cout << evm2wasm::evmhex2wasm(str); 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /tools/wast2wasm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(wast2wasm main.cpp) 2 | target_link_libraries(wast2wasm PRIVATE libevm2wasm) -------------------------------------------------------------------------------- /tools/wast2wasm/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace std; 9 | 10 | int main(int argc, char **argv) { 11 | (void)argc; 12 | (void)argv; 13 | 14 | string input; 15 | while (!cin.eof()) 16 | { 17 | string tmp; 18 | // NOTE: this will read until EOF or NL 19 | getline(cin, tmp); 20 | input.append(tmp); 21 | input.append("\n"); 22 | } 23 | 24 | if (!input.size()) 25 | return 1; 26 | 27 | string output = evm2wasm::wast2wasm(input); 28 | 29 | if (!output.size()) 30 | return 1; 31 | 32 | cout << output << endl; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /wasm/ADD.wast: -------------------------------------------------------------------------------- 1 | (func $ADD 2 | (local $sp i32) 3 | 4 | (local $a i64) 5 | (local $c i64) 6 | (local $d i64) 7 | (local $carry i64) 8 | 9 | (set_local $sp (get_global $sp)) 10 | 11 | ;; d c b a 12 | ;; pop the stack 13 | (set_local $a (i64.load (i32.add (get_local $sp) (i32.const 24)))) 14 | (set_local $c (i64.load (i32.add (get_local $sp) (i32.const 8)))) 15 | (set_local $d (i64.load (get_local $sp))) 16 | ;; decement the stack pointer 17 | (set_local $sp (i32.sub (get_local $sp) (i32.const 8))) 18 | 19 | ;; d 20 | (set_local $carry (i64.add (get_local $d) (i64.load (i32.sub (get_local $sp) (i32.const 24))))) 21 | ;; save d to mem 22 | (i64.store (i32.sub (get_local $sp) (i32.const 24)) (get_local $carry)) 23 | ;; check for overflow 24 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $carry) (get_local $d)))) 25 | 26 | ;; c use $d as reg 27 | (set_local $d (i64.add (i64.load (i32.sub (get_local $sp) (i32.const 16))) (get_local $carry))) 28 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $d) (get_local $carry)))) 29 | (set_local $d (i64.add (get_local $c) (get_local $d))) 30 | ;; store the result 31 | (i64.store (i32.sub (get_local $sp) (i32.const 16)) (get_local $d)) 32 | ;; check overflow 33 | (set_local $carry (i64.or (i64.extend_u/i32 (i64.lt_u (get_local $d) (get_local $c))) (get_local $carry))) 34 | 35 | ;; b 36 | ;; add carry 37 | (set_local $d (i64.add (i64.load (i32.sub (get_local $sp) (i32.const 8))) (get_local $carry))) 38 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $d) (get_local $carry)))) 39 | 40 | ;; use reg c 41 | (set_local $c (i64.load (i32.add (get_local $sp) (i32.const 24)))) 42 | (set_local $d (i64.add (get_local $c) (get_local $d))) 43 | (i64.store (i32.sub (get_local $sp) (i32.const 8)) (get_local $d)) 44 | ;; a 45 | (i64.store (get_local $sp) 46 | (i64.add ;; add a 47 | (get_local $a) 48 | (i64.add 49 | (i64.load (get_local $sp)) ;; load the operand 50 | (i64.or ;; carry 51 | (i64.extend_u/i32 (i64.lt_u (get_local $d) (get_local $c))) 52 | (get_local $carry))))) 53 | ) 54 | -------------------------------------------------------------------------------- /wasm/ADDMOD.wast: -------------------------------------------------------------------------------- 1 | ;; stack: 2 | ;; 0: A 3 | ;; -1: B 4 | ;; -2: MOD 5 | (func $ADDMOD 6 | (local $sp i32) 7 | 8 | (local $a i64) 9 | (local $b i64) 10 | (local $c i64) 11 | (local $d i64) 12 | 13 | (local $a1 i64) 14 | (local $b1 i64) 15 | (local $c1 i64) 16 | (local $d1 i64) 17 | 18 | (local $moda i64) 19 | (local $modb i64) 20 | (local $modc i64) 21 | (local $modd i64) 22 | 23 | (local $carry i64) 24 | 25 | (set_local $sp (get_global $sp)) 26 | 27 | ;; load args from the stack 28 | (set_local $a (i64.load (i32.add (get_local $sp) (i32.const 24)))) 29 | (set_local $b (i64.load (i32.add (get_local $sp) (i32.const 16)))) 30 | (set_local $c (i64.load (i32.add (get_local $sp) (i32.const 8)))) 31 | (set_local $d (i64.load (get_local $sp))) 32 | 33 | (set_local $sp (i32.sub (get_local $sp) (i32.const 32))) 34 | 35 | (set_local $a1 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 36 | (set_local $b1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 37 | (set_local $c1 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 38 | (set_local $d1 (i64.load (get_local $sp))) 39 | 40 | (set_local $sp (i32.sub (get_local $sp) (i32.const 32))) 41 | 42 | (set_local $moda (i64.load (i32.add (get_local $sp) (i32.const 24)))) 43 | (set_local $modb (i64.load (i32.add (get_local $sp) (i32.const 16)))) 44 | (set_local $modc (i64.load (i32.add (get_local $sp) (i32.const 8)))) 45 | (set_local $modd (i64.load (get_local $sp))) 46 | 47 | ;; a * 64^3 + b*64^2 + c*64 + d 48 | ;; d 49 | (set_local $d (i64.add (get_local $d1) (get_local $d))) 50 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $d) (get_local $d1)))) 51 | ;; c 52 | (set_local $c (i64.add (get_local $c) (get_local $carry))) 53 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $c) (get_local $carry)))) 54 | (set_local $c (i64.add (get_local $c1) (get_local $c))) 55 | (set_local $carry (i64.or (i64.extend_u/i32 (i64.lt_u (get_local $c) (get_local $c1))) (get_local $carry))) 56 | ;; b 57 | (set_local $b (i64.add (get_local $b) (get_local $carry))) 58 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $b) (get_local $carry)))) 59 | (set_local $b (i64.add (get_local $b1) (get_local $b))) 60 | (set_local $carry (i64.or (i64.extend_u/i32 (i64.lt_u (get_local $b) (get_local $b1))) (get_local $carry))) 61 | ;; a 62 | (set_local $a (i64.add (get_local $a) (get_local $carry))) 63 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $a) (get_local $carry)))) 64 | (set_local $a (i64.add (get_local $a1) (get_local $a))) 65 | (set_local $carry (i64.or (i64.extend_u/i32 (i64.lt_u (get_local $a) (get_local $a1))) (get_local $carry))) 66 | 67 | (call $mod_320 68 | (get_local $carry) (get_local $a) (get_local $b) (get_local $c) (get_local $d) 69 | (i64.const 0) (get_local $moda) (get_local $modb) (get_local $modc) (get_local $modd) (get_local $sp)) 70 | ) 71 | -------------------------------------------------------------------------------- /wasm/AND.wast: -------------------------------------------------------------------------------- 1 | (func $AND 2 | (i64.store (i32.sub (get_global $sp) (i32.const 8)) (i64.and (i64.load (i32.sub (get_global $sp) (i32.const 8))) (i64.load (i32.add (get_global $sp) (i32.const 24))))) 3 | (i64.store (i32.sub (get_global $sp) (i32.const 16)) (i64.and (i64.load (i32.sub (get_global $sp) (i32.const 16))) (i64.load (i32.add (get_global $sp) (i32.const 16))))) 4 | (i64.store (i32.sub (get_global $sp) (i32.const 24)) (i64.and (i64.load (i32.sub (get_global $sp) (i32.const 24))) (i64.load (i32.add (get_global $sp) (i32.const 8))))) 5 | (i64.store (i32.sub (get_global $sp) (i32.const 32)) (i64.and (i64.load (i32.sub (get_global $sp) (i32.const 32))) (i64.load (get_global $sp)))) 6 | ) 7 | -------------------------------------------------------------------------------- /wasm/BYTE.wast: -------------------------------------------------------------------------------- 1 | ;; stack: 2 | ;; 0: offset 3 | ;; -1: value 4 | (func $BYTE 5 | (local $sp i32) 6 | 7 | (local $a0 i64) 8 | (local $a1 i64) 9 | (local $a2 i64) 10 | (local $a3 i64) 11 | (set_local $sp (get_global $sp)) 12 | 13 | (set_local $a0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 14 | (set_local $a1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 15 | (set_local $a2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 16 | (set_local $a3 (i64.load (get_local $sp))) 17 | 18 | (set_local $sp (i32.sub (get_local $sp) (i32.const 32))) 19 | 20 | (i64.store (get_local $sp) 21 | (if (result i64) 22 | (i32.and 23 | (i32.and 24 | (i32.and 25 | (i64.lt_u (get_local $a3) (i64.const 32)) 26 | (i64.eqz (get_local $a2))) 27 | (i64.eqz (get_local $a1))) 28 | (i64.eqz (get_local $a0))) 29 | (i64.load8_u (i32.sub (i32.const 31)(i32.wrap/i64 (get_local $a3)))) 30 | (i64.const 0))) 31 | 32 | ;; zero out the rest of the stack 33 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 34 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 35 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 36 | ) 37 | -------------------------------------------------------------------------------- /wasm/CALLDATALOAD.wast: -------------------------------------------------------------------------------- 1 | ;; stack: 2 | ;; 0: dataOffset 3 | (func $CALLDATALOAD 4 | (local $writeOffset i32) 5 | (local $writeOffset0 i64) 6 | (local $writeOffset1 i64) 7 | (local $writeOffset2 i64) 8 | (local $writeOffset3 i64) 9 | 10 | (set_local $writeOffset0 (i64.load (i32.add (get_global $sp) (i32.const 0)))) 11 | (set_local $writeOffset1 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 12 | (set_local $writeOffset2 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 13 | (set_local $writeOffset3 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 14 | 15 | (i64.store (i32.add (get_global $sp) (i32.const 0)) (i64.const 0)) 16 | (i64.store (i32.add (get_global $sp) (i32.const 8)) (i64.const 0)) 17 | (i64.store (i32.add (get_global $sp) (i32.const 16)) (i64.const 0)) 18 | (i64.store (i32.add (get_global $sp) (i32.const 24)) (i64.const 0)) 19 | 20 | (set_local $writeOffset 21 | (call $check_overflow (get_local $writeOffset0) 22 | (get_local $writeOffset1) 23 | (get_local $writeOffset2) 24 | (get_local $writeOffset3))) 25 | 26 | (call $callDataCopy (get_global $sp) (get_local $writeOffset) (i32.const 32)) 27 | ;; swap top stack item 28 | (drop (call $bswap_m256 (get_global $sp))) 29 | ) 30 | -------------------------------------------------------------------------------- /wasm/DUP.wast: -------------------------------------------------------------------------------- 1 | (func $DUP 2 | (param $a0 i32) 3 | (local $sp i32) 4 | 5 | (local $sp_ref i32) 6 | 7 | (set_local $sp (i32.add (get_global $sp) (i32.const 32))) 8 | (set_local $sp_ref (i32.sub (i32.sub (get_local $sp) (i32.const 8)) (i32.mul (get_local $a0) (i32.const 32)))) 9 | 10 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.load (get_local $sp_ref))) 11 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.load (i32.sub (get_local $sp_ref) (i32.const 8)))) 12 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.load (i32.sub (get_local $sp_ref) (i32.const 16)))) 13 | (i64.store (get_local $sp) (i64.load (i32.sub (get_local $sp_ref) (i32.const 24)))) 14 | ) 15 | -------------------------------------------------------------------------------- /wasm/EQ.wast: -------------------------------------------------------------------------------- 1 | (func $EQ 2 | (local $sp i32) 3 | 4 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 5 | (i64.store (get_local $sp) 6 | (i64.extend_u/i32 7 | (i32.and (i64.eq (i64.load (i32.add (get_local $sp) (i32.const 56))) (i64.load (i32.add (get_local $sp) (i32.const 24)))) 8 | (i32.and (i64.eq (i64.load (i32.add (get_local $sp) (i32.const 48))) (i64.load (i32.add (get_local $sp) (i32.const 16)))) 9 | (i32.and (i64.eq (i64.load (i32.add (get_local $sp) (i32.const 40))) (i64.load (i32.add (get_local $sp) (i32.const 8)))) 10 | (i64.eq (i64.load (i32.add (get_local $sp) (i32.const 32))) (i64.load (get_local $sp)))))))) 11 | 12 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 13 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 14 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 15 | ) 16 | -------------------------------------------------------------------------------- /wasm/EXP.wast: -------------------------------------------------------------------------------- 1 | (func $EXP 2 | (local $sp i32) 3 | 4 | ;; base 5 | (local $base0 i64) 6 | (local $base1 i64) 7 | (local $base2 i64) 8 | (local $base3 i64) 9 | 10 | ;; exp 11 | (local $exp0 i64) 12 | (local $exp1 i64) 13 | (local $exp2 i64) 14 | (local $exp3 i64) 15 | 16 | (local $r0 i64) 17 | (local $r1 i64) 18 | (local $r2 i64) 19 | (local $r3 i64) 20 | 21 | (local $gasCounter i32) 22 | (set_local $sp (get_global $sp)) 23 | 24 | ;; load args from the stack 25 | (set_local $base0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 26 | (set_local $base1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 27 | (set_local $base2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 28 | (set_local $base3 (i64.load (get_local $sp))) 29 | 30 | (set_local $sp (i32.sub (get_local $sp) (i32.const 32))) 31 | 32 | (set_local $exp0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 33 | (set_local $exp1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 34 | (set_local $exp2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 35 | (set_local $exp3 (i64.load (get_local $sp))) 36 | 37 | ;; let result = new BN[1] 38 | (set_local $r3 (i64.const 1)) 39 | 40 | (block $done 41 | (loop $loop 42 | ;; while [exp > 0] { 43 | (if (call $iszero_256 (get_local $exp0) (get_local $exp1) (get_local $exp2) (get_local $exp3)) 44 | (br $done) 45 | ) 46 | 47 | ;; if[exp.modn[2] === 1] 48 | ;; is odd? 49 | (if (i64.eqz (i64.ctz (get_local $exp3))) 50 | 51 | ;; result = result.mul[base].mod[TWO_POW256] 52 | ;; r = r * a 53 | (then 54 | (call $mul_256 (get_local $r0) (get_local $r1) (get_local $r2) (get_local $r3) (get_local $base0) (get_local $base1) (get_local $base2) (get_local $base3) (i32.add (get_local $sp) (i32.const 24))) 55 | (set_local $r0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 56 | (set_local $r1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 57 | (set_local $r2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 58 | (set_local $r3 (i64.load (get_local $sp))) 59 | ) 60 | ) 61 | ;; exp = exp.shrn 1 62 | (set_local $exp3 (i64.add (i64.shr_u (get_local $exp3) (i64.const 1)) (i64.shl (get_local $exp2) (i64.const 63)))) 63 | (set_local $exp2 (i64.add (i64.shr_u (get_local $exp2) (i64.const 1)) (i64.shl (get_local $exp1) (i64.const 63)))) 64 | (set_local $exp1 (i64.add (i64.shr_u (get_local $exp1) (i64.const 1)) (i64.shl (get_local $exp0) (i64.const 63)))) 65 | (set_local $exp0 (i64.shr_u (get_local $exp0) (i64.const 1))) 66 | 67 | ;; base = base.mulr[baser].modr[TWO_POW256] 68 | (call $mul_256 (get_local $base0) (get_local $base1) (get_local $base2) (get_local $base3) (get_local $base0) (get_local $base1) (get_local $base2) (get_local $base3) (i32.add (get_local $sp) (i32.const 24))) 69 | (set_local $base0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 70 | (set_local $base1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 71 | (set_local $base2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 72 | (set_local $base3 (i64.load (get_local $sp))) 73 | 74 | (set_local $gasCounter (i32.add (get_local $gasCounter) (i32.const 1))) 75 | (br $loop) 76 | ) 77 | ) 78 | 79 | ;; use gas 80 | ;; Log256[Exponent] * 10 81 | (call $useGas 82 | (i64.extend_u/i32 83 | (i32.mul 84 | (i32.const 10) 85 | (i32.div_u 86 | (i32.add (get_local $gasCounter) (i32.const 7)) 87 | (i32.const 8))))) 88 | 89 | ;; decement the stack pointer 90 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (get_local $r0)) 91 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (get_local $r1)) 92 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (get_local $r2)) 93 | (i64.store (get_local $sp) (get_local $r3)) 94 | ) 95 | -------------------------------------------------------------------------------- /wasm/GT.wast: -------------------------------------------------------------------------------- 1 | (func $GT 2 | (local $sp i32) 3 | 4 | (local $a0 i64) 5 | (local $a1 i64) 6 | (local $a2 i64) 7 | (local $a3 i64) 8 | (local $b0 i64) 9 | (local $b1 i64) 10 | (local $b2 i64) 11 | (local $b3 i64) 12 | 13 | (set_local $sp (get_global $sp)) 14 | 15 | ;; load args from the stack 16 | (set_local $a0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 17 | (set_local $a1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 18 | (set_local $a2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 19 | (set_local $a3 (i64.load (get_local $sp))) 20 | 21 | (set_local $sp (i32.sub (get_local $sp) (i32.const 32))) 22 | 23 | (set_local $b0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 24 | (set_local $b1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 25 | (set_local $b2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 26 | (set_local $b3 (i64.load (get_local $sp))) 27 | 28 | (i64.store (get_local $sp) (i64.extend_u/i32 29 | (i32.or (i64.gt_u (get_local $a0) (get_local $b0)) ;; a0 > b0 30 | (i32.and (i64.eq (get_local $a0) (get_local $b0)) ;; a0 == a1 31 | (i32.or (i64.gt_u (get_local $a1) (get_local $b1)) ;; a1 > b1 32 | (i32.and (i64.eq (get_local $a1) (get_local $b1)) ;; a1 == b1 33 | (i32.or (i64.gt_u (get_local $a2) (get_local $b2)) ;; a2 > b2 34 | (i32.and (i64.eq (get_local $a2) (get_local $b2)) ;; a2 == b2 35 | (i64.gt_u (get_local $a3) (get_local $b3)))))))))) ;; a3 > b3 36 | 37 | ;; zero out the rest of the stack item 38 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 39 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 40 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 41 | ) 42 | -------------------------------------------------------------------------------- /wasm/ISZERO.wast: -------------------------------------------------------------------------------- 1 | (func $ISZERO 2 | (local $a0 i64) 3 | (local $a1 i64) 4 | (local $a2 i64) 5 | (local $a3 i64) 6 | 7 | ;; load args from the stack 8 | (set_local $a0 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 9 | (set_local $a1 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 10 | (set_local $a2 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 11 | (set_local $a3 (i64.load (get_global $sp))) 12 | 13 | (i64.store (get_global $sp) 14 | (i64.extend_u/i32 15 | (call $iszero_256 (get_local $a0) (get_local $a1) (get_local $a2) (get_local $a3)) 16 | ) 17 | ) 18 | 19 | ;; zero out the rest of memory 20 | (i64.store (i32.add (get_global $sp) (i32.const 8)) (i64.const 0)) 21 | (i64.store (i32.add (get_global $sp) (i32.const 16)) (i64.const 0)) 22 | (i64.store (i32.add (get_global $sp) (i32.const 24)) (i64.const 0)) 23 | ) 24 | -------------------------------------------------------------------------------- /wasm/LOG.wast: -------------------------------------------------------------------------------- 1 | (func $LOG 2 | (param $number i32) 3 | 4 | (local $offset i32) 5 | (local $offset0 i64) 6 | (local $offset1 i64) 7 | (local $offset2 i64) 8 | (local $offset3 i64) 9 | 10 | (local $length i32) 11 | (local $length0 i64) 12 | (local $length1 i64) 13 | (local $length2 i64) 14 | (local $length3 i64) 15 | 16 | (set_local $offset0 (i64.load (get_global $sp))) 17 | (set_local $offset1 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 18 | (set_local $offset2 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 19 | (set_local $offset3 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 20 | 21 | (set_local $length0 (i64.load (i32.sub (get_global $sp) (i32.const 32)))) 22 | (set_local $length1 (i64.load (i32.sub (get_global $sp) (i32.const 24)))) 23 | (set_local $length2 (i64.load (i32.sub (get_global $sp) (i32.const 16)))) 24 | (set_local $length3 (i64.load (i32.sub (get_global $sp) (i32.const 8)))) 25 | 26 | (set_local $offset 27 | (call $check_overflow (get_local $offset0) 28 | (get_local $offset1) 29 | (get_local $offset2) 30 | (get_local $offset3))) 31 | 32 | (set_local $length 33 | (call $check_overflow (get_local $length0) 34 | (get_local $length1) 35 | (get_local $length2) 36 | (get_local $length3))) 37 | 38 | (call $memusegas (get_local $offset) (get_local $length)) 39 | 40 | (call $log 41 | (get_local $offset) 42 | (get_local $length) 43 | (get_local $number) 44 | (i32.sub (get_global $sp) (i32.const 64)) 45 | (i32.sub (get_global $sp) (i32.const 96)) 46 | (i32.sub (get_global $sp) (i32.const 128)) 47 | (i32.sub (get_global $sp) (i32.const 160))) 48 | ) 49 | -------------------------------------------------------------------------------- /wasm/LT.wast: -------------------------------------------------------------------------------- 1 | (func $LT 2 | (local $sp i32) 3 | 4 | (local $a0 i64) 5 | (local $a1 i64) 6 | (local $a2 i64) 7 | (local $a3 i64) 8 | (local $b0 i64) 9 | (local $b1 i64) 10 | (local $b2 i64) 11 | (local $b3 i64) 12 | 13 | (set_local $sp (get_global $sp)) 14 | 15 | ;; load args from the stack 16 | (set_local $a0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 17 | (set_local $a1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 18 | (set_local $a2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 19 | (set_local $a3 (i64.load (get_local $sp))) 20 | 21 | (set_local $sp (i32.sub (get_local $sp) (i32.const 32))) 22 | 23 | (set_local $b0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 24 | (set_local $b1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 25 | (set_local $b2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 26 | (set_local $b3 (i64.load (get_local $sp))) 27 | 28 | (i64.store (get_local $sp) (i64.extend_u/i32 29 | (i32.or (i64.lt_u (get_local $a0) (get_local $b0)) ;; a0 < b0 30 | (i32.and (i64.eq (get_local $a0) (get_local $b0)) ;; a0 == b0 31 | (i32.or (i64.lt_u (get_local $a1) (get_local $b1)) ;; a1 < b1 32 | (i32.and (i64.eq (get_local $a1) (get_local $b1)) ;; a1 == b1 33 | (i32.or (i64.lt_u (get_local $a2) (get_local $b2)) ;; a2 < b2 34 | (i32.and (i64.eq (get_local $a2) (get_local $b2)) ;; a2 == b2 35 | (i64.lt_u (get_local $a3) (get_local $b3)))))))))) ;; a3 < b3 36 | 37 | ;; zero out the rest of the stack item 38 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 39 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 40 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 41 | ) 42 | -------------------------------------------------------------------------------- /wasm/MLOAD.wast: -------------------------------------------------------------------------------- 1 | ;; stack: 2 | ;; 0: offset 3 | (func $MLOAD 4 | (local $offset i32) 5 | (local $offset0 i64) 6 | (local $offset1 i64) 7 | (local $offset2 i64) 8 | (local $offset3 i64) 9 | 10 | ;; load args from the stack 11 | (set_local $offset0 (i64.load (get_global $sp))) 12 | (set_local $offset1 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 13 | (set_local $offset2 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 14 | (set_local $offset3 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 15 | 16 | (set_local $offset 17 | (call $check_overflow (get_local $offset0) 18 | (get_local $offset1) 19 | (get_local $offset2) 20 | (get_local $offset3))) 21 | ;; subttract gas useage 22 | (call $memusegas (get_local $offset) (i32.const 32)) 23 | 24 | ;; FIXME: how to deal with overflow? 25 | (set_local $offset (i32.add (get_local $offset) (get_global $memstart))) 26 | 27 | (i64.store (i32.add (get_global $sp) (i32.const 24)) (i64.load (i32.add (get_local $offset) (i32.const 24)))) 28 | (i64.store (i32.add (get_global $sp) (i32.const 16)) (i64.load (i32.add (get_local $offset) (i32.const 16)))) 29 | (i64.store (i32.add (get_global $sp) (i32.const 8)) (i64.load (i32.add (get_local $offset) (i32.const 8)))) 30 | (i64.store (get_global $sp) (i64.load (get_local $offset))) 31 | 32 | ;; swap 33 | (drop (call $bswap_m256 (get_global $sp))) 34 | ) 35 | -------------------------------------------------------------------------------- /wasm/MOD.wast: -------------------------------------------------------------------------------- 1 | (func $MOD 2 | (local $sp i32) 3 | 4 | ;; dividend 5 | (local $a i64) 6 | (local $b i64) 7 | (local $c i64) 8 | (local $d i64) 9 | 10 | ;; divisor 11 | (local $a1 i64) 12 | (local $b1 i64) 13 | (local $c1 i64) 14 | (local $d1 i64) 15 | 16 | ;; quotient 17 | (local $aq i64) 18 | (local $bq i64) 19 | (local $cq i64) 20 | (local $dq i64) 21 | 22 | ;; mask 23 | (local $maska i64) 24 | (local $maskb i64) 25 | (local $maskc i64) 26 | (local $maskd i64) 27 | (local $carry i32) 28 | (local $temp i64) 29 | 30 | (set_local $maskd (i64.const 1)) 31 | 32 | ;; load args from the stack 33 | (set_local $a (i64.load (i32.add (get_global $sp) (i32.const 24)))) 34 | (set_local $b (i64.load (i32.add (get_global $sp) (i32.const 16)))) 35 | (set_local $c (i64.load (i32.add (get_global $sp) (i32.const 8)))) 36 | (set_local $d (i64.load (get_global $sp))) 37 | ;; decement the stack pointer 38 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 39 | 40 | (set_local $a1 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 41 | (set_local $b1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 42 | (set_local $c1 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 43 | (set_local $d1 (i64.load (get_local $sp))) 44 | 45 | 46 | (block $main 47 | ;; check div by 0 48 | (if (call $iszero_256 (get_local $a1) (get_local $b1) (get_local $c1) (get_local $d1)) 49 | (then 50 | (set_local $a (i64.const 0)) 51 | (set_local $b (i64.const 0)) 52 | (set_local $c (i64.const 0)) 53 | (set_local $d (i64.const 0)) 54 | (br $main) 55 | ) 56 | ) 57 | 58 | ;; align bits 59 | (block $done 60 | (loop $loop 61 | ;; align bits; 62 | (if (i32.or (i64.eqz (i64.clz (get_local $a1))) (call $gte_256 (get_local $a1) (get_local $b1) (get_local $c1) (get_local $d1) (get_local $a) (get_local $b) (get_local $c) (get_local $d))) 63 | (br $done) 64 | ) 65 | 66 | ;; divisor = divisor << 1 67 | (set_local $a1 (i64.add (i64.shl (get_local $a1) (i64.const 1)) (i64.shr_u (get_local $b1) (i64.const 63)))) 68 | (set_local $b1 (i64.add (i64.shl (get_local $b1) (i64.const 1)) (i64.shr_u (get_local $c1) (i64.const 63)))) 69 | (set_local $c1 (i64.add (i64.shl (get_local $c1) (i64.const 1)) (i64.shr_u (get_local $d1) (i64.const 63)))) 70 | (set_local $d1 (i64.shl (get_local $d1) (i64.const 1))) 71 | 72 | ;; mask = mask << 1 73 | (set_local $maska (i64.add (i64.shl (get_local $maska) (i64.const 1)) (i64.shr_u (get_local $maskb) (i64.const 63)))) 74 | (set_local $maskb (i64.add (i64.shl (get_local $maskb) (i64.const 1)) (i64.shr_u (get_local $maskc) (i64.const 63)))) 75 | (set_local $maskc (i64.add (i64.shl (get_local $maskc) (i64.const 1)) (i64.shr_u (get_local $maskd) (i64.const 63)))) 76 | (set_local $maskd (i64.shl (get_local $maskd) (i64.const 1))) 77 | 78 | (br $loop) 79 | ) 80 | ) 81 | 82 | (block $done 83 | (loop $loop 84 | ;; loop while mask != 0 85 | (if (call $iszero_256 (get_local $maska) (get_local $maskb) (get_local $maskc) (get_local $maskd)) 86 | (br $done) 87 | ) 88 | ;; if dividend >= divisor 89 | (if (call $gte_256 (get_local $a) (get_local $b) (get_local $c) (get_local $d) (get_local $a1) (get_local $b1) (get_local $c1) (get_local $d1)) 90 | (then 91 | ;; dividend = dividend - divisor 92 | (set_local $carry (i64.lt_u (get_local $d) (get_local $d1))) 93 | (set_local $d (i64.sub (get_local $d) (get_local $d1))) 94 | (set_local $temp (i64.sub (get_local $c) (i64.extend_u/i32 (get_local $carry)))) 95 | (set_local $carry (i64.gt_u (get_local $temp) (get_local $c))) 96 | (set_local $c (i64.sub (get_local $temp) (get_local $c1))) 97 | (set_local $carry (i32.or (i64.gt_u (get_local $c) (get_local $temp)) (get_local $carry))) 98 | (set_local $temp (i64.sub (get_local $b) (i64.extend_u/i32 (get_local $carry)))) 99 | (set_local $carry (i64.gt_u (get_local $temp) (get_local $b))) 100 | (set_local $b (i64.sub (get_local $temp) (get_local $b1))) 101 | (set_local $carry (i32.or (i64.gt_u (get_local $b) (get_local $temp)) (get_local $carry))) 102 | (set_local $a (i64.sub (i64.sub (get_local $a) (i64.extend_u/i32 (get_local $carry))) (get_local $a1))) 103 | ) 104 | ) 105 | ;; divisor = divisor >> 1 106 | (set_local $d1 (i64.add (i64.shr_u (get_local $d1) (i64.const 1)) (i64.shl (get_local $c1) (i64.const 63)))) 107 | (set_local $c1 (i64.add (i64.shr_u (get_local $c1) (i64.const 1)) (i64.shl (get_local $b1) (i64.const 63)))) 108 | (set_local $b1 (i64.add (i64.shr_u (get_local $b1) (i64.const 1)) (i64.shl (get_local $a1) (i64.const 63)))) 109 | (set_local $a1 (i64.shr_u (get_local $a1) (i64.const 1))) 110 | 111 | ;; mask = mask >> 1 112 | (set_local $maskd (i64.add (i64.shr_u (get_local $maskd) (i64.const 1)) (i64.shl (get_local $maskc) (i64.const 63)))) 113 | (set_local $maskc (i64.add (i64.shr_u (get_local $maskc) (i64.const 1)) (i64.shl (get_local $maskb) (i64.const 63)))) 114 | (set_local $maskb (i64.add (i64.shr_u (get_local $maskb) (i64.const 1)) (i64.shl (get_local $maska) (i64.const 63)))) 115 | (set_local $maska (i64.shr_u (get_local $maska) (i64.const 1))) 116 | (br $loop) 117 | ) 118 | ) 119 | );; end of main 120 | 121 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (get_local $a)) 122 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (get_local $b)) 123 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (get_local $c)) 124 | (i64.store (get_local $sp) (get_local $d)) 125 | ) 126 | -------------------------------------------------------------------------------- /wasm/MSIZE.wast: -------------------------------------------------------------------------------- 1 | (func $MSIZE 2 | (local $sp i32) 3 | 4 | ;; there's no input item for us to overwrite 5 | (set_local $sp (i32.add (get_global $sp) (i32.const 32))) 6 | 7 | (i64.store (i32.add (get_local $sp) (i32.const 0)) 8 | (i64.mul (get_global $wordCount) (i64.const 32))) 9 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 10 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 11 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 12 | ) 13 | -------------------------------------------------------------------------------- /wasm/MSTORE.wast: -------------------------------------------------------------------------------- 1 | ;; stack: 2 | ;; 0: word 3 | ;; -1: offset 4 | (func $MSTORE 5 | (local $sp i32) 6 | 7 | (local $offset i32) 8 | 9 | (local $offset0 i64) 10 | (local $offset1 i64) 11 | (local $offset2 i64) 12 | (local $offset3 i64) 13 | 14 | ;; load args from the stack 15 | (set_local $offset0 (i64.load (get_global $sp))) 16 | (set_local $offset1 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 17 | (set_local $offset2 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 18 | (set_local $offset3 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 19 | 20 | (set_local $offset 21 | (call $check_overflow (get_local $offset0) 22 | (get_local $offset1) 23 | (get_local $offset2) 24 | (get_local $offset3))) 25 | ;; subtrace gas useage 26 | (call $memusegas (get_local $offset) (i32.const 32)) 27 | 28 | ;; pop item from the stack 29 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 30 | 31 | ;; swap top stack item 32 | (drop (call $bswap_m256 (get_local $sp))) 33 | 34 | (set_local $offset (i32.add (get_local $offset) (get_global $memstart))) 35 | ;; store word to memory 36 | (i64.store (get_local $offset) (i64.load (get_local $sp))) 37 | (i64.store (i32.add (get_local $offset) (i32.const 8)) (i64.load (i32.add (get_local $sp) (i32.const 8)))) 38 | (i64.store (i32.add (get_local $offset) (i32.const 16)) (i64.load (i32.add (get_local $sp) (i32.const 16)))) 39 | (i64.store (i32.add (get_local $offset) (i32.const 24)) (i64.load (i32.add (get_local $sp) (i32.const 24)))) 40 | ) 41 | -------------------------------------------------------------------------------- /wasm/MSTORE8.wast: -------------------------------------------------------------------------------- 1 | ;; stack: 2 | ;; 0: word 3 | ;; -1: offset 4 | (func $MSTORE8 5 | (local $sp i32) 6 | 7 | (local $offset i32) 8 | 9 | (local $offset0 i64) 10 | (local $offset1 i64) 11 | (local $offset2 i64) 12 | (local $offset3 i64) 13 | 14 | ;; load args from the stack 15 | (set_local $offset0 (i64.load (get_global $sp))) 16 | (set_local $offset1 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 17 | (set_local $offset2 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 18 | (set_local $offset3 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 19 | 20 | (set_local $offset 21 | (call $check_overflow (get_local $offset0) 22 | (get_local $offset1) 23 | (get_local $offset2) 24 | (get_local $offset3))) 25 | 26 | (call $memusegas (get_local $offset) (i32.const 1)) 27 | 28 | ;; pop stack 29 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 30 | (set_local $offset (i32.add (get_local $offset) (get_global $memstart))) 31 | (i32.store8 (i32.add (get_local $offset) (i32.const 0)) (i32.load (get_local $sp))) 32 | ) 33 | -------------------------------------------------------------------------------- /wasm/MUL.wast: -------------------------------------------------------------------------------- 1 | (func $MUL 2 | (call $mul_256 3 | (i64.load (i32.add (get_global $sp) (i32.const 24))) 4 | (i64.load (i32.add (get_global $sp) (i32.const 16))) 5 | (i64.load (i32.add (get_global $sp) (i32.const 8))) 6 | (i64.load (get_global $sp)) 7 | (i64.load (i32.sub (get_global $sp) (i32.const 8))) 8 | (i64.load (i32.sub (get_global $sp) (i32.const 16))) 9 | (i64.load (i32.sub (get_global $sp) (i32.const 24))) 10 | (i64.load (i32.sub (get_global $sp) (i32.const 32))) 11 | (i32.sub (get_global $sp) (i32.const 8)) 12 | ) 13 | ) 14 | -------------------------------------------------------------------------------- /wasm/NOT.wast: -------------------------------------------------------------------------------- 1 | (func $NOT 2 | ;; FIXME: consider using 0xffffffffffffffff instead of -1? 3 | (i64.store (i32.add (get_global $sp) (i32.const 24)) (i64.xor (i64.load (i32.add (get_global $sp) (i32.const 24))) (i64.const -1))) 4 | (i64.store (i32.add (get_global $sp) (i32.const 16)) (i64.xor (i64.load (i32.add (get_global $sp) (i32.const 16))) (i64.const -1))) 5 | (i64.store (i32.add (get_global $sp) (i32.const 8)) (i64.xor (i64.load (i32.add (get_global $sp) (i32.const 8))) (i64.const -1))) 6 | (i64.store (i32.add (get_global $sp) (i32.const 0)) (i64.xor (i64.load (i32.add (get_global $sp) (i32.const 0))) (i64.const -1))) 7 | ) 8 | -------------------------------------------------------------------------------- /wasm/OR.wast: -------------------------------------------------------------------------------- 1 | (func $OR 2 | (i64.store (i32.sub (get_global $sp) (i32.const 8)) (i64.or (i64.load (i32.sub (get_global $sp) (i32.const 8))) (i64.load (i32.add (get_global $sp) (i32.const 24))))) 3 | (i64.store (i32.sub (get_global $sp) (i32.const 16)) (i64.or (i64.load (i32.sub (get_global $sp) (i32.const 16))) (i64.load (i32.add (get_global $sp) (i32.const 16))))) 4 | (i64.store (i32.sub (get_global $sp) (i32.const 24)) (i64.or (i64.load (i32.sub (get_global $sp) (i32.const 24))) (i64.load (i32.add (get_global $sp) (i32.const 8))))) 5 | (i64.store (i32.sub (get_global $sp) (i32.const 32)) (i64.or (i64.load (i32.sub (get_global $sp) (i32.const 32))) (i64.load (get_global $sp)))) 6 | ) 7 | -------------------------------------------------------------------------------- /wasm/PC.wast: -------------------------------------------------------------------------------- 1 | (func $PC 2 | (param $pc i32) 3 | (local $sp i32) 4 | 5 | ;; add one to the stack 6 | (set_local $sp (i32.add (get_global $sp) (i32.const 32))) 7 | (i64.store (get_local $sp) (i64.extend_u/i32 (get_local $pc))) 8 | 9 | ;; zero out rest of stack 10 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 11 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 12 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 13 | ) 14 | -------------------------------------------------------------------------------- /wasm/PUSH.wast: -------------------------------------------------------------------------------- 1 | (func $PUSH 2 | (param $a0 i64) 3 | (param $a1 i64) 4 | (param $a2 i64) 5 | (param $a3 i64) 6 | (local $sp i32) 7 | 8 | ;; increament stack pointer 9 | (set_local $sp (i32.add (get_global $sp) (i32.const 32))) 10 | 11 | (i64.store (get_local $sp) (get_local $a3)) 12 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (get_local $a2)) 13 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (get_local $a1)) 14 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (get_local $a0)) 15 | ) 16 | -------------------------------------------------------------------------------- /wasm/SGT.wast: -------------------------------------------------------------------------------- 1 | (func $SGT 2 | (local $sp i32) 3 | 4 | (local $a0 i64) 5 | (local $a1 i64) 6 | (local $a2 i64) 7 | (local $a3 i64) 8 | (local $b0 i64) 9 | (local $b1 i64) 10 | (local $b2 i64) 11 | (local $b3 i64) 12 | 13 | ;; load args from the stack 14 | (set_local $a0 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 15 | (set_local $a1 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 16 | (set_local $a2 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 17 | (set_local $a3 (i64.load (get_global $sp))) 18 | 19 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 20 | 21 | (set_local $b0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 22 | (set_local $b1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 23 | (set_local $b2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 24 | (set_local $b3 (i64.load (get_local $sp))) 25 | 26 | (i64.store (get_local $sp) (i64.extend_u/i32 27 | (i32.or (i64.gt_s (get_local $a0) (get_local $b0)) ;; a0 > b0 28 | (i32.and (i64.eq (get_local $a0) (get_local $b0)) ;; a0 == a1 29 | (i32.or (i64.gt_u (get_local $a1) (get_local $b1)) ;; a1 > b1 30 | (i32.and (i64.eq (get_local $a1) (get_local $b1)) ;; a1 == b1 31 | (i32.or (i64.gt_u (get_local $a2) (get_local $b2)) ;; a2 > b2 32 | (i32.and (i64.eq (get_local $a2) (get_local $b2)) ;; a2 == b2 33 | (i64.gt_u (get_local $a3) (get_local $b3)))))))))) ;; a3 > b3 34 | 35 | ;; zero out the rest of the stack item 36 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 37 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 38 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 39 | ) 40 | -------------------------------------------------------------------------------- /wasm/SHA3.wast: -------------------------------------------------------------------------------- 1 | (func $SHA3 2 | (local $dataOffset i32) 3 | (local $dataOffset0 i64) 4 | (local $dataOffset1 i64) 5 | (local $dataOffset2 i64) 6 | (local $dataOffset3 i64) 7 | 8 | (local $length i32) 9 | (local $length0 i64) 10 | (local $length1 i64) 11 | (local $length2 i64) 12 | (local $length3 i64) 13 | 14 | (local $contextOffset i32) 15 | (local $outputOffset i32) 16 | 17 | (set_local $length0 (i64.load (i32.sub (get_global $sp) (i32.const 32)))) 18 | (set_local $length1 (i64.load (i32.sub (get_global $sp) (i32.const 24)))) 19 | (set_local $length2 (i64.load (i32.sub (get_global $sp) (i32.const 16)))) 20 | (set_local $length3 (i64.load (i32.sub (get_global $sp) (i32.const 8)))) 21 | 22 | (set_local $dataOffset0 (i64.load (i32.add (get_global $sp) (i32.const 0)))) 23 | (set_local $dataOffset1 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 24 | (set_local $dataOffset2 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 25 | (set_local $dataOffset3 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 26 | 27 | (set_local $length 28 | (call $check_overflow (get_local $length0) 29 | (get_local $length1) 30 | (get_local $length2) 31 | (get_local $length3))) 32 | (set_local $dataOffset 33 | (call $check_overflow (get_local $dataOffset0) 34 | (get_local $dataOffset1) 35 | (get_local $dataOffset2) 36 | (get_local $dataOffset3))) 37 | 38 | ;; charge copy fee ceil(words/32) * 6 39 | (call $useGas (i64.extend_u/i32 (i32.mul (i32.div_u (i32.add (get_local $length) (i32.const 31)) (i32.const 32)) (i32.const 6)))) 40 | (call $memusegas (get_local $dataOffset) (get_local $length)) 41 | 42 | (set_local $dataOffset (i32.add (get_global $memstart) (get_local $dataOffset))) 43 | 44 | (set_local $contextOffset (i32.const 32808)) 45 | (set_local $outputOffset (i32.sub (get_global $sp) (i32.const 32))) 46 | 47 | (call $keccak (get_local $contextOffset) (get_local $dataOffset) (get_local $length) (get_local $outputOffset)) 48 | 49 | (drop (call $bswap_m256 (get_local $outputOffset))) 50 | ) 51 | -------------------------------------------------------------------------------- /wasm/SIGNEXTEND.wast: -------------------------------------------------------------------------------- 1 | (func $SIGNEXTEND 2 | (local $sp i32) 3 | 4 | (local $a0 i64) 5 | (local $a1 i64) 6 | (local $a2 i64) 7 | (local $a3 i64) 8 | 9 | (local $b0 i64) 10 | (local $b1 i64) 11 | (local $b2 i64) 12 | (local $b3 i64) 13 | (local $sign i64) 14 | (local $t i32) 15 | (local $end i32) 16 | 17 | (set_local $a0 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 18 | (set_local $a1 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 19 | (set_local $a2 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 20 | (set_local $a3 (i64.load (get_global $sp))) 21 | 22 | (set_local $end (get_global $sp)) 23 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 24 | 25 | (if (i32.and 26 | (i32.and 27 | (i32.and 28 | (i64.lt_u (get_local $a3) (i64.const 32)) 29 | (i64.eqz (get_local $a2))) 30 | (i64.eqz (get_local $a1))) 31 | (i64.eqz (get_local $a0))) 32 | (then 33 | (set_local $t (i32.add (i32.wrap/i64 (get_local $a3)) (get_local $sp))) 34 | (set_local $sign (i64.shr_s (i64.load8_s (get_local $t)) (i64.const 8))) 35 | (set_local $t (i32.add (get_local $t) (i32.const 1))) 36 | (block $done 37 | (loop $loop 38 | (if (i32.lt_u (get_local $end) (get_local $t)) 39 | (br $done) 40 | ) 41 | (i64.store (get_local $t) (get_local $sign)) 42 | (set_local $t (i32.add (get_local $t) (i32.const 8))) 43 | (br $loop) 44 | ) 45 | ) 46 | ) 47 | ) 48 | ) 49 | 50 | -------------------------------------------------------------------------------- /wasm/SLT.wast: -------------------------------------------------------------------------------- 1 | (func $SLT 2 | (local $sp i32) 3 | 4 | (local $a0 i64) 5 | (local $a1 i64) 6 | (local $a2 i64) 7 | (local $a3 i64) 8 | (local $b0 i64) 9 | (local $b1 i64) 10 | (local $b2 i64) 11 | (local $b3 i64) 12 | 13 | ;; load args from the stack 14 | (set_local $a0 (i64.load (i32.add (get_global $sp) (i32.const 24)))) 15 | (set_local $a1 (i64.load (i32.add (get_global $sp) (i32.const 16)))) 16 | (set_local $a2 (i64.load (i32.add (get_global $sp) (i32.const 8)))) 17 | (set_local $a3 (i64.load (get_global $sp))) 18 | 19 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 20 | 21 | (set_local $b0 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 22 | (set_local $b1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 23 | (set_local $b2 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 24 | (set_local $b3 (i64.load (get_local $sp))) 25 | 26 | (i64.store (get_local $sp) (i64.extend_u/i32 27 | (i32.or (i64.lt_s (get_local $a0) (get_local $b0)) ;; a0 < b0 28 | (i32.and (i64.eq (get_local $a0) (get_local $b0)) ;; a0 == b0 29 | (i32.or (i64.lt_u (get_local $a1) (get_local $b1)) ;; a1 < b1 30 | (i32.and (i64.eq (get_local $a1) (get_local $b1)) ;; a1 == b1 31 | (i32.or (i64.lt_u (get_local $a2) (get_local $b2)) ;; a2 < b2 32 | (i32.and (i64.eq (get_local $a2) (get_local $b2)) ;; a2 == b2 33 | (i64.lt_u (get_local $a3) (get_local $b3)))))))))) ;; a3 < b3 34 | 35 | ;; zero out the rest of the stack item 36 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (i64.const 0)) 37 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (i64.const 0)) 38 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (i64.const 0)) 39 | ) 40 | -------------------------------------------------------------------------------- /wasm/SUB.wast: -------------------------------------------------------------------------------- 1 | (func $SUB 2 | (local $sp i32) 3 | 4 | (local $a i64) 5 | (local $b i64) 6 | (local $c i64) 7 | (local $d i64) 8 | 9 | (local $a1 i64) 10 | (local $b1 i64) 11 | (local $c1 i64) 12 | (local $d1 i64) 13 | 14 | (local $carry i64) 15 | (local $temp i64) 16 | 17 | (set_local $a (i64.load (i32.add (get_global $sp) (i32.const 24)))) 18 | (set_local $b (i64.load (i32.add (get_global $sp) (i32.const 16)))) 19 | (set_local $c (i64.load (i32.add (get_global $sp) (i32.const 8)))) 20 | (set_local $d (i64.load (get_global $sp))) 21 | ;; decement the stack pointer 22 | (set_local $sp (i32.sub (get_global $sp) (i32.const 32))) 23 | 24 | (set_local $a1 (i64.load (i32.add (get_local $sp) (i32.const 24)))) 25 | (set_local $b1 (i64.load (i32.add (get_local $sp) (i32.const 16)))) 26 | (set_local $c1 (i64.load (i32.add (get_local $sp) (i32.const 8)))) 27 | (set_local $d1 (i64.load (get_local $sp))) 28 | 29 | ;; a * 64^3 + b*64^2 + c*64 + d 30 | ;; d 31 | (set_local $carry (i64.extend_u/i32 (i64.lt_u (get_local $d) (get_local $d1)))) 32 | (set_local $d (i64.sub (get_local $d) (get_local $d1))) 33 | 34 | ;; c 35 | (set_local $temp (i64.sub (get_local $c) (get_local $carry))) 36 | (set_local $carry (i64.extend_u/i32 (i64.gt_u (get_local $temp) (get_local $c)))) 37 | (set_local $c (i64.sub (get_local $temp) (get_local $c1))) 38 | (set_local $carry (i64.or (i64.extend_u/i32 (i64.gt_u (get_local $c) (get_local $temp))) (get_local $carry))) 39 | 40 | ;; b 41 | (set_local $temp (i64.sub (get_local $b) (get_local $carry))) 42 | (set_local $carry (i64.extend_u/i32 (i64.gt_u (get_local $temp) (get_local $b)))) 43 | (set_local $b (i64.sub (get_local $temp) (get_local $b1))) 44 | 45 | ;; a 46 | (set_local $a (i64.sub (i64.sub (get_local $a) (i64.or (i64.extend_u/i32 (i64.gt_u (get_local $b) (get_local $temp))) (get_local $carry))) (get_local $a1))) 47 | 48 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (get_local $a)) 49 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (get_local $b)) 50 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (get_local $c)) 51 | (i64.store (get_local $sp) (get_local $d)) 52 | ) 53 | -------------------------------------------------------------------------------- /wasm/SWAP.wast: -------------------------------------------------------------------------------- 1 | (func $SWAP 2 | (param $a0 i32) 3 | (local $sp_ref i32) 4 | 5 | (local $topa i64) 6 | (local $topb i64) 7 | (local $topc i64) 8 | (local $topd i64) 9 | 10 | (set_local $sp_ref (i32.sub (i32.add (get_global $sp) (i32.const 24)) (i32.mul (i32.add (get_local $a0) (i32.const 1)) (i32.const 32)))) 11 | 12 | (set_local $topa (i64.load (i32.add (get_global $sp) (i32.const 24)))) 13 | (set_local $topb (i64.load (i32.add (get_global $sp) (i32.const 16)))) 14 | (set_local $topc (i64.load (i32.add (get_global $sp) (i32.const 8)))) 15 | (set_local $topd (i64.load (get_global $sp))) 16 | 17 | ;; replace the top element 18 | (i64.store (i32.add (get_global $sp) (i32.const 24)) (i64.load (get_local $sp_ref))) 19 | (i64.store (i32.add (get_global $sp) (i32.const 16)) (i64.load (i32.sub (get_local $sp_ref) (i32.const 8)))) 20 | (i64.store (i32.add (get_global $sp) (i32.const 8)) (i64.load (i32.sub (get_local $sp_ref) (i32.const 16)))) 21 | (i64.store (get_global $sp) (i64.load (i32.sub (get_local $sp_ref) (i32.const 24)))) 22 | 23 | ;; store the old top element 24 | (i64.store (get_local $sp_ref) (get_local $topa)) 25 | (i64.store (i32.sub (get_local $sp_ref) (i32.const 8)) (get_local $topb)) 26 | (i64.store (i32.sub (get_local $sp_ref) (i32.const 16)) (get_local $topc)) 27 | (i64.store (i32.sub (get_local $sp_ref) (i32.const 24)) (get_local $topd)) 28 | ) 29 | -------------------------------------------------------------------------------- /wasm/XOR.wast: -------------------------------------------------------------------------------- 1 | (func $XOR 2 | (i64.store (i32.sub (get_global $sp) (i32.const 8)) (i64.xor (i64.load (i32.sub (get_global $sp) (i32.const 8))) (i64.load (i32.add (get_global $sp) (i32.const 24))))) 3 | (i64.store (i32.sub (get_global $sp) (i32.const 16)) (i64.xor (i64.load (i32.sub (get_global $sp) (i32.const 16))) (i64.load (i32.add (get_global $sp) (i32.const 16))))) 4 | (i64.store (i32.sub (get_global $sp) (i32.const 24)) (i64.xor (i64.load (i32.sub (get_global $sp) (i32.const 24))) (i64.load (i32.add (get_global $sp) (i32.const 8))))) 5 | (i64.store (i32.sub (get_global $sp) (i32.const 32)) (i64.xor (i64.load (i32.sub (get_global $sp) (i32.const 32))) (i64.load (i32.add (get_global $sp) (i32.const 0))))) 6 | ) 7 | -------------------------------------------------------------------------------- /wasm/bswap_i32.wast: -------------------------------------------------------------------------------- 1 | (func $bswap_i32 2 | (param $int i32) 3 | (result i32) 4 | 5 | (i32.or 6 | (i32.or 7 | (i32.and (i32.shr_u (get_local $int) (i32.const 24)) (i32.const 0xff)) ;; 7 -> 0 8 | (i32.and (i32.shr_u (get_local $int) (i32.const 8)) (i32.const 0xff00))) ;; 6 -> 1 9 | (i32.or 10 | (i32.and (i32.shl (get_local $int) (i32.const 8)) (i32.const 0xff0000)) ;; 5 -> 2 11 | (i32.and (i32.shl (get_local $int) (i32.const 24)) (i32.const 0xff000000)))) ;; 4 -> 3 12 | ) 13 | -------------------------------------------------------------------------------- /wasm/bswap_i64.wast: -------------------------------------------------------------------------------- 1 | (func $bswap_i64 2 | (param $int i64) 3 | (result i64) 4 | 5 | (i64.or 6 | (i64.or 7 | (i64.or 8 | (i64.and (i64.shr_u (get_local $int) (i64.const 56)) (i64.const 0xff)) ;; 7 -> 0 9 | (i64.and (i64.shr_u (get_local $int) (i64.const 40)) (i64.const 0xff00))) ;; 6 -> 1 10 | (i64.or 11 | (i64.and (i64.shr_u (get_local $int) (i64.const 24)) (i64.const 0xff0000)) ;; 5 -> 2 12 | (i64.and (i64.shr_u (get_local $int) (i64.const 8)) (i64.const 0xff000000)))) ;; 4 -> 3 13 | (i64.or 14 | (i64.or 15 | (i64.and (i64.shl (get_local $int) (i64.const 8)) (i64.const 0xff00000000)) ;; 3 -> 4 16 | (i64.and (i64.shl (get_local $int) (i64.const 24)) (i64.const 0xff0000000000))) ;; 2 -> 5 17 | (i64.or 18 | (i64.and (i64.shl (get_local $int) (i64.const 40)) (i64.const 0xff000000000000)) ;; 1 -> 6 19 | (i64.and (i64.shl (get_local $int) (i64.const 56)) (i64.const 0xff00000000000000))))) ;; 0 -> 7 20 | ) 21 | -------------------------------------------------------------------------------- /wasm/bswap_m128.wast: -------------------------------------------------------------------------------- 1 | (func $bswap_m128 2 | (param $sp i32) 3 | (result i32) 4 | (local $temp i64) 5 | 6 | (set_local $temp (call $bswap_i64 (i64.load (get_local $sp)))) 7 | (i64.store (get_local $sp) (call $bswap_i64 (i64.load (i32.add (get_local $sp) (i32.const 8))))) 8 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (get_local $temp)) 9 | (get_local $sp) 10 | ) 11 | -------------------------------------------------------------------------------- /wasm/bswap_m160.wast: -------------------------------------------------------------------------------- 1 | (func $bswap_m160 2 | (param $sp i32) 3 | (result i32) 4 | (local $temp i64) 5 | 6 | (set_local $temp (call $bswap_i64 (i64.load (get_local $sp)))) 7 | (i64.store (get_local $sp) (call $bswap_i64 (i64.load (i32.add (get_local $sp) (i32.const 12))))) 8 | (i64.store (i32.add (get_local $sp) (i32.const 12)) (get_local $temp)) 9 | 10 | (i32.store (i32.add (get_local $sp) (i32.const 8)) (call $bswap_i32 (i32.load (i32.add (get_local $sp) (i32.const 8))))) 11 | (get_local $sp) 12 | ) 13 | -------------------------------------------------------------------------------- /wasm/bswap_m256.wast: -------------------------------------------------------------------------------- 1 | (func $bswap_m256 2 | (param $sp i32) 3 | (result i32) 4 | (local $temp i64) 5 | 6 | (set_local $temp (call $bswap_i64 (i64.load (get_local $sp)))) 7 | (i64.store (get_local $sp) (call $bswap_i64 (i64.load (i32.add (get_local $sp) (i32.const 24))))) 8 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (get_local $temp)) 9 | 10 | (set_local $temp (call $bswap_i64 (i64.load (i32.add (get_local $sp) (i32.const 8))))) 11 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (call $bswap_i64 (i64.load (i32.add (get_local $sp) (i32.const 16))))) 12 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (get_local $temp)) 13 | (get_local $sp) 14 | ) 15 | -------------------------------------------------------------------------------- /wasm/callback.wast: -------------------------------------------------------------------------------- 1 | (func $callback 2 | (call $main) 3 | ) 4 | -------------------------------------------------------------------------------- /wasm/callback_128.wast: -------------------------------------------------------------------------------- 1 | (func $callback_128 2 | (param $result i32) 3 | 4 | (drop (call $bswap_m128 (get_global $sp))) 5 | (call $main) 6 | ) 7 | -------------------------------------------------------------------------------- /wasm/callback_160.wast: -------------------------------------------------------------------------------- 1 | (func $callback_160 2 | (param $result i32) 3 | 4 | (drop (call $bswap_m160 (get_global $sp))) 5 | (call $main) 6 | ) 7 | -------------------------------------------------------------------------------- /wasm/callback_256.wast: -------------------------------------------------------------------------------- 1 | (func $callback_256 2 | (param $result i32) 3 | 4 | (drop (call $bswap_m256 (get_global $sp))) 5 | (call $main) 6 | ) 7 | -------------------------------------------------------------------------------- /wasm/callback_32.wast: -------------------------------------------------------------------------------- 1 | (func $callback_32 2 | (param $result i32) 3 | 4 | (i64.store (get_global $sp) (i64.extend_u/i32 (get_local $result))) 5 | ;; zero out mem 6 | (i64.store (i32.add (get_global $sp) (i32.const 24)) (i64.const 0)) 7 | (i64.store (i32.add (get_global $sp) (i32.const 16)) (i64.const 0)) 8 | (i64.store (i32.add (get_global $sp) (i32.const 8)) (i64.const 0)) 9 | 10 | (call $main) 11 | ) 12 | -------------------------------------------------------------------------------- /wasm/check_overflow.wast: -------------------------------------------------------------------------------- 1 | (func $check_overflow 2 | (param $a i64) 3 | (param $b i64) 4 | (param $c i64) 5 | (param $d i64) 6 | (result i32) 7 | 8 | (local $MAX_INT i32) 9 | (set_local $MAX_INT (i32.const -1)) 10 | 11 | (if 12 | (i32.and 13 | (i32.and 14 | (i64.eqz (get_local $d)) 15 | (i64.eqz (get_local $c))) 16 | (i32.and 17 | (i64.eqz (get_local $b)) 18 | (i64.lt_u (get_local $a) (i64.extend_u/i32 (get_local $MAX_INT))))) 19 | (return (i32.wrap/i64 (get_local $a)))) 20 | 21 | (return (get_local $MAX_INT)) 22 | ) 23 | -------------------------------------------------------------------------------- /wasm/check_overflow_i64.wast: -------------------------------------------------------------------------------- 1 | (func $check_overflow_i64 2 | (param $a i64) 3 | (param $b i64) 4 | (param $c i64) 5 | (param $d i64) 6 | (result i64) 7 | 8 | (if 9 | (i32.and 10 | (i32.and 11 | (i64.eqz (get_local $d)) 12 | (i64.eqz (get_local $c))) 13 | (i64.eqz (get_local $b))) 14 | (return (get_local $a))) 15 | 16 | (return (i64.const 0xffffffffffffffff)) 17 | ) 18 | -------------------------------------------------------------------------------- /wasm/gte_256.wast: -------------------------------------------------------------------------------- 1 | ;; is a less than or equal to b // a >= b 2 | (func $gte_256 3 | (param $a0 i64) 4 | (param $a1 i64) 5 | (param $a2 i64) 6 | (param $a3 i64) 7 | 8 | (param $b0 i64) 9 | (param $b1 i64) 10 | (param $b2 i64) 11 | (param $b3 i64) 12 | 13 | (result i32) 14 | 15 | ;; a0 > b0 || [a0 == b0 && [a1 > b1 || [a1 == b1 && [a2 > b2 || [a2 == b2 && a3 >= b3 ]]]] 16 | (i32.or (i64.gt_u (get_local $a0) (get_local $b0)) ;; a0 > b0 17 | (i32.and (i64.eq (get_local $a0) (get_local $b0)) 18 | (i32.or (i64.gt_u (get_local $a1) (get_local $b1)) ;; a1 > b1 19 | (i32.and (i64.eq (get_local $a1) (get_local $b1)) ;; a1 == b1 20 | (i32.or (i64.gt_u (get_local $a2) (get_local $b2)) ;; a2 > b2 21 | (i32.and (i64.eq (get_local $a2) (get_local $b2)) 22 | (i64.ge_u (get_local $a3) (get_local $b3)))))))) 23 | ) 24 | -------------------------------------------------------------------------------- /wasm/gte_320.wast: -------------------------------------------------------------------------------- 1 | (func $gte_320 2 | (param $a0 i64) 3 | (param $a1 i64) 4 | (param $a2 i64) 5 | (param $a3 i64) 6 | (param $a4 i64) 7 | 8 | (param $b0 i64) 9 | (param $b1 i64) 10 | (param $b2 i64) 11 | (param $b3 i64) 12 | (param $b4 i64) 13 | 14 | (result i32) 15 | 16 | ;; a0 > b0 || [a0 == b0 && [a1 > b1 || [a1 == b1 && [a2 > b2 || [a2 == b2 && a3 >= b3 ]]]] 17 | (i32.or (i64.gt_u (get_local $a0) (get_local $b0)) ;; a0 > b0 18 | (i32.and (i64.eq (get_local $a0) (get_local $b0)) 19 | (i32.or (i64.gt_u (get_local $a1) (get_local $b1)) ;; a1 > b1 20 | (i32.and (i64.eq (get_local $a1) (get_local $b1)) ;; a1 == b1 21 | (i32.or (i64.gt_u (get_local $a2) (get_local $b2)) ;; a2 > b2 22 | (i32.and (i64.eq (get_local $a2) (get_local $b2)) 23 | (i32.or (i64.gt_u (get_local $a3) (get_local $b3)) ;; a2 > b2 24 | (i32.and (i64.eq (get_local $a3) (get_local $b3)) 25 | (i64.ge_u (get_local $a4) (get_local $b4)))))))))) 26 | ) 27 | -------------------------------------------------------------------------------- /wasm/gte_512.wast: -------------------------------------------------------------------------------- 1 | (func $gte_512 2 | (param $a0 i64) 3 | (param $a1 i64) 4 | (param $a2 i64) 5 | (param $a3 i64) 6 | (param $a4 i64) 7 | (param $a5 i64) 8 | (param $a6 i64) 9 | (param $a7 i64) 10 | 11 | (param $b0 i64) 12 | (param $b1 i64) 13 | (param $b2 i64) 14 | (param $b3 i64) 15 | (param $b4 i64) 16 | (param $b5 i64) 17 | (param $b6 i64) 18 | (param $b7 i64) 19 | 20 | (result i32) 21 | 22 | ;; a0 > b0 || [a0 == b0 && [a1 > b1 || [a1 == b1 && [a2 > b2 || [a2 == b2 && a3 >= b3 ]]]] 23 | (i32.or (i64.gt_u (get_local $a0) (get_local $b0)) ;; a0 > b0 24 | (i32.and (i64.eq (get_local $a0) (get_local $b0)) 25 | (i32.or (i64.gt_u (get_local $a1) (get_local $b1)) ;; a1 > b1 26 | (i32.and (i64.eq (get_local $a1) (get_local $b1)) ;; a1 == b1 27 | (i32.or (i64.gt_u (get_local $a2) (get_local $b2)) ;; a2 > b2 28 | (i32.and (i64.eq (get_local $a2) (get_local $b2)) 29 | (i32.or (i64.gt_u (get_local $a3) (get_local $b3)) ;; a3 > b3 30 | (i32.and (i64.eq (get_local $a3) (get_local $b3)) 31 | (i32.or (i64.gt_u (get_local $a4) (get_local $b4)) ;; a4 > b4 32 | (i32.and (i64.eq (get_local $a4) (get_local $b4)) 33 | (i32.or (i64.gt_u (get_local $a5) (get_local $b5)) ;; a5 > b5 34 | (i32.and (i64.eq (get_local $a5) (get_local $b5)) 35 | (i32.or (i64.gt_u (get_local $a6) (get_local $b6)) ;; a6 > b6 36 | (i32.and (i64.eq (get_local $a6) (get_local $b6)) 37 | (i64.ge_u (get_local $a7) (get_local $b7)))))))))))))))) 38 | ) 39 | -------------------------------------------------------------------------------- /wasm/iszero_256.wast: -------------------------------------------------------------------------------- 1 | (func $iszero_256 2 | (param i64) 3 | (param i64) 4 | (param i64) 5 | (param i64) 6 | (result i32) 7 | 8 | (i64.eqz (i64.or (i64.or (i64.or (get_local 0) (get_local 1)) (get_local 2)) (get_local 3))) 9 | ) 10 | -------------------------------------------------------------------------------- /wasm/iszero_320.wast: -------------------------------------------------------------------------------- 1 | (func $iszero_320 2 | (param i64) 3 | (param i64) 4 | (param i64) 5 | (param i64) 6 | (param i64) 7 | (result i32) 8 | 9 | (i64.eqz (i64.or (i64.or (i64.or (i64.or (get_local 0) (get_local 1)) (get_local 2)) (get_local 3)) (get_local 4))) 10 | ) 11 | -------------------------------------------------------------------------------- /wasm/iszero_512.wast: -------------------------------------------------------------------------------- 1 | (func $iszero_512 2 | (param i64) 3 | (param i64) 4 | (param i64) 5 | (param i64) 6 | (param i64) 7 | (param i64) 8 | (param i64) 9 | (param i64) 10 | (result i32) 11 | (i64.eqz (i64.or (i64.or (i64.or (i64.or (i64.or (i64.or (i64.or (get_local 0) (get_local 1)) (get_local 2)) (get_local 3)) (get_local 4)) (get_local 5)) (get_local 6)) (get_local 7))) 12 | ) 13 | -------------------------------------------------------------------------------- /wasm/memcpy.wast: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; memcpy from ewasm-libc/ewasm-cleanup 3 | ;; 4 | (func $memcpy 5 | (param $dst i32) 6 | (param $src i32) 7 | (param $length i32) 8 | (result i32) 9 | 10 | (local $i i32) 11 | 12 | (set_local $i (i32.const 0)) 13 | 14 | (block $done 15 | (loop $loop 16 | (if (i32.ge_u (get_local $i) (get_local $length)) 17 | (br $done) 18 | ) 19 | 20 | (i32.store8 (i32.add (get_local $dst) (get_local $i)) (i32.load8_u (i32.add (get_local $src) (get_local $i)))) 21 | 22 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 23 | (br $loop) 24 | ) 25 | ) 26 | 27 | (return (get_local $dst)) 28 | ) 29 | -------------------------------------------------------------------------------- /wasm/memset.wast: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; memcpy from ewasm-libc/ewasm-cleanup 3 | ;; 4 | (func $memset 5 | (param $ptr i32) 6 | (param $value i32) 7 | (param $length i32) 8 | (result i32) 9 | (local $i i32) 10 | 11 | (set_local $i (i32.const 0)) 12 | 13 | (block $done 14 | (loop $loop 15 | (if (i32.ge_u (get_local $i) (get_local $length)) 16 | (br $done) 17 | ) 18 | 19 | (i32.store8 (i32.add (get_local $ptr) (get_local $i)) (get_local $value)) 20 | 21 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 22 | (br $loop) 23 | ) 24 | ) 25 | (get_local $ptr) 26 | ) 27 | -------------------------------------------------------------------------------- /wasm/memusegas.wast: -------------------------------------------------------------------------------- 1 | (func $memusegas 2 | (param $offset i32) 3 | (param $length i32) 4 | 5 | (local $cost i64) 6 | ;; the number of new words being allocated 7 | (local $newWordCount i64) 8 | 9 | (if (i32.eqz (get_local $length)) 10 | (then (return)) 11 | ) 12 | 13 | ;; const newMemoryWordCount = Math.ceil[[offset + length] / 32] 14 | (set_local $newWordCount 15 | (i64.div_u (i64.add (i64.const 31) (i64.add (i64.extend_u/i32 (get_local $offset)) (i64.extend_u/i32 (get_local $length)))) 16 | (i64.const 32))) 17 | 18 | ;;if [runState.highestMem >= highestMem] return 19 | (if (i64.le_u (get_local $newWordCount) (get_global $wordCount)) 20 | (then (return)) 21 | ) 22 | 23 | ;; words * 3 + words ^2 / 512 24 | (set_local $cost 25 | (i64.add 26 | (i64.mul (get_local $newWordCount) (i64.const 3)) 27 | (i64.div_u 28 | (i64.mul (get_local $newWordCount) 29 | (get_local $newWordCount)) 30 | (i64.const 512)))) 31 | 32 | (call $useGas (i64.sub (get_local $cost) (get_global $prevMemCost))) 33 | (set_global $prevMemCost (get_local $cost)) 34 | (set_global $wordCount (get_local $newWordCount)) 35 | 36 | ;; grow actual memory 37 | ;; the first 31704 bytes are guaranteed to be available 38 | ;; adjust for 32 bytes - the maximal size of MSTORE write 39 | ;; TODO it should be current_memory * page_size 40 | (set_local $offset (i32.add (get_local $length) (i32.add (get_local $offset) (get_global $memstart)))) 41 | (if (i32.gt_u (get_local $offset) (i32.mul (i32.const 65536) (current_memory))) 42 | (then 43 | (drop (grow_memory 44 | (i32.div_u (i32.add (i32.const 65535) (i32.sub (get_local $offset) (current_memory))) (i32.const 65536)))) 45 | ) 46 | ) 47 | ) 48 | -------------------------------------------------------------------------------- /wasm/mod_320.wast: -------------------------------------------------------------------------------- 1 | (func $mod_320 2 | ;; dividend 3 | (param $a i64) 4 | (param $b i64) 5 | (param $c i64) 6 | (param $d i64) 7 | (param $e i64) 8 | 9 | ;; divisor 10 | (param $a1 i64) 11 | (param $b1 i64) 12 | (param $c1 i64) 13 | (param $d1 i64) 14 | (param $e1 i64) 15 | 16 | ;; stack pointer 17 | (param $sp i32) 18 | 19 | ;; quotient 20 | (local $aq i64) 21 | (local $bq i64) 22 | (local $cq i64) 23 | (local $dq i64) 24 | (local $eq i64) 25 | 26 | ;; mask 27 | (local $maska i64) 28 | (local $maskb i64) 29 | (local $maskc i64) 30 | (local $maskd i64) 31 | (local $maske i64) 32 | 33 | (local $carry i32) 34 | (local $temp i64) 35 | 36 | (set_local $maske (i64.const 1)) 37 | (block $main 38 | ;; check div by 0 39 | (if (call $iszero_320 (get_local $a1) (get_local $b1) (get_local $c1) (get_local $d1) (get_local $e1)) 40 | (then 41 | (set_local $a (i64.const 0)) 42 | (set_local $b (i64.const 0)) 43 | (set_local $c (i64.const 0)) 44 | (set_local $d (i64.const 0)) 45 | (set_local $e (i64.const 0)) 46 | (br $main) 47 | ) 48 | ) 49 | 50 | (block $done 51 | ;; align bits 52 | (loop $loop 53 | ;; align bits; 54 | (if (i32.or (i64.eqz (i64.clz (get_local $a1))) (call $gte_320 55 | (get_local $a1) (get_local $b1) (get_local $c1) (get_local $d1) (get_local $e1) 56 | (get_local $a) (get_local $b) (get_local $c) (get_local $d) (get_local $e))) 57 | (br $done) 58 | ) 59 | 60 | ;; divisor = divisor << 1 61 | (set_local $a1 (i64.add (i64.shl (get_local $a1) (i64.const 1)) (i64.shr_u (get_local $b1) (i64.const 63)))) 62 | (set_local $b1 (i64.add (i64.shl (get_local $b1) (i64.const 1)) (i64.shr_u (get_local $c1) (i64.const 63)))) 63 | (set_local $c1 (i64.add (i64.shl (get_local $c1) (i64.const 1)) (i64.shr_u (get_local $d1) (i64.const 63)))) 64 | (set_local $d1 (i64.add (i64.shl (get_local $d1) (i64.const 1)) (i64.shr_u (get_local $e1) (i64.const 63)))) 65 | (set_local $e1 (i64.shl (get_local $e1) (i64.const 1))) 66 | 67 | ;; mask = mask << 1 68 | (set_local $maska (i64.add (i64.shl (get_local $maska) (i64.const 1)) (i64.shr_u (get_local $maskb) (i64.const 63)))) 69 | (set_local $maskb (i64.add (i64.shl (get_local $maskb) (i64.const 1)) (i64.shr_u (get_local $maskc) (i64.const 63)))) 70 | (set_local $maskc (i64.add (i64.shl (get_local $maskc) (i64.const 1)) (i64.shr_u (get_local $maskd) (i64.const 63)))) 71 | (set_local $maskd (i64.add (i64.shl (get_local $maskd) (i64.const 1)) (i64.shr_u (get_local $maske) (i64.const 63)))) 72 | (set_local $maske (i64.shl (get_local $maske) (i64.const 1))) 73 | (br $loop) 74 | ) 75 | ) 76 | 77 | (block $done 78 | (loop $loop 79 | ;; loop while mask != 0 80 | (if (call $iszero_320 (get_local $maska) (get_local $maskb) (get_local $maskc) (get_local $maskd) (get_local $maske)) 81 | (br $done) 82 | ) 83 | ;; if dividend >= divisor 84 | (if (call $gte_320 (get_local $a) (get_local $b) (get_local $c) (get_local $d) (get_local $e) (get_local $a1) (get_local $b1) (get_local $c1) (get_local $d1) (get_local $e1)) 85 | (then 86 | ;; dividend = dividend - divisor 87 | (set_local $carry (i64.lt_u (get_local $e) (get_local $e1))) 88 | (set_local $e (i64.sub (get_local $e) (get_local $e1))) 89 | 90 | (set_local $temp (i64.sub (get_local $d) (i64.extend_u/i32 (get_local $carry)))) 91 | (set_local $carry (i64.gt_u (get_local $temp) (get_local $d))) 92 | (set_local $d (i64.sub (get_local $temp) (get_local $d1))) 93 | (set_local $carry (i32.or (i64.gt_u (get_local $d) (get_local $temp)) (get_local $carry))) 94 | 95 | (set_local $temp (i64.sub (get_local $c) (i64.extend_u/i32 (get_local $carry)))) 96 | (set_local $carry (i64.gt_u (get_local $temp) (get_local $c))) 97 | (set_local $c (i64.sub (get_local $temp) (get_local $c1))) 98 | (set_local $carry (i32.or (i64.gt_u (get_local $c) (get_local $temp)) (get_local $carry))) 99 | 100 | (set_local $temp (i64.sub (get_local $b) (i64.extend_u/i32 (get_local $carry)))) 101 | (set_local $carry (i64.gt_u (get_local $temp) (get_local $b))) 102 | (set_local $b (i64.sub (get_local $temp) (get_local $b1))) 103 | (set_local $carry (i32.or (i64.gt_u (get_local $b) (get_local $temp)) (get_local $carry))) 104 | 105 | (set_local $a (i64.sub (i64.sub (get_local $a) (i64.extend_u/i32 (get_local $carry))) (get_local $a1))) 106 | ) 107 | ) 108 | ;; divisor = divisor >> 1 109 | (set_local $e1 (i64.add (i64.shr_u (get_local $e1) (i64.const 1)) (i64.shl (get_local $d1) (i64.const 63)))) 110 | (set_local $d1 (i64.add (i64.shr_u (get_local $d1) (i64.const 1)) (i64.shl (get_local $c1) (i64.const 63)))) 111 | (set_local $c1 (i64.add (i64.shr_u (get_local $c1) (i64.const 1)) (i64.shl (get_local $b1) (i64.const 63)))) 112 | (set_local $b1 (i64.add (i64.shr_u (get_local $b1) (i64.const 1)) (i64.shl (get_local $a1) (i64.const 63)))) 113 | (set_local $a1 (i64.shr_u (get_local $a1) (i64.const 1))) 114 | 115 | ;; mask = mask >> 1 116 | (set_local $maske (i64.add (i64.shr_u (get_local $maske) (i64.const 1)) (i64.shl (get_local $maskd) (i64.const 63)))) 117 | (set_local $maskd (i64.add (i64.shr_u (get_local $maskd) (i64.const 1)) (i64.shl (get_local $maskc) (i64.const 63)))) 118 | (set_local $maskc (i64.add (i64.shr_u (get_local $maskc) (i64.const 1)) (i64.shl (get_local $maskb) (i64.const 63)))) 119 | (set_local $maskb (i64.add (i64.shr_u (get_local $maskb) (i64.const 1)) (i64.shl (get_local $maska) (i64.const 63)))) 120 | (set_local $maska (i64.shr_u (get_local $maska) (i64.const 1))) 121 | (br $loop) 122 | ) 123 | ) 124 | );; end of main 125 | (i64.store (i32.add (get_local $sp) (i32.const 24)) (get_local $b)) 126 | (i64.store (i32.add (get_local $sp) (i32.const 16)) (get_local $c)) 127 | (i64.store (i32.add (get_local $sp) (i32.const 8)) (get_local $d)) 128 | (i64.store (get_local $sp) (get_local $e)) 129 | ) 130 | --------------------------------------------------------------------------------