From bd0ad381c16c919de042d4b9cee5ac7e94f0a095 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Sat, 12 Jun 2021 22:37:56 +0530 Subject: [PATCH 1/6] Execute shared library. Do away with LLVM JIT --- CMakeLists.txt | 5 +- include/ScillaVM/Errors.h | 2 + include/ScillaVM/JITD.h | 211 ------- include/ScillaVM/ScillaExec.h | 123 ++++ include/ScillaVM/Utils.h | 20 +- libjitd/CMakeLists.txt | 9 - libjitd/JITD.cpp | 577 ------------------ libsrtl/CMakeLists.txt | 2 + {libjitd => libsrtl}/Debug.cpp | 0 .../ScillaVM/SRTL.h => libsrtl/ObjManager.h | 44 +- libsrtl/SRTL.cpp | 17 +- libsrtl/SRTL.h | 64 ++ libsrtl/ScillaBuiltins.cpp | 294 ++++----- libsrtl/ScillaBuiltins.h | 133 ++-- libsrtl/ScillaExecImpl.cpp | 359 +++++++++++ libsrtl/ScillaExecImpl.h | 69 +++ libsrtl/ScillaTypes.h | 2 +- libsrtl/ScillaValue.cpp | 5 +- libsrtl/ScillaValue.h | 2 +- {libjitd => libsrtl}/SharedObject.h | 4 +- libsrtl/Utils.cpp | 23 + runners/CMakeLists.txt | 4 +- runners/expr-runner.cpp | 28 +- runners/scilla-runner.cpp | 23 +- testsuite/CMakeLists.txt | 2 +- testsuite/ContrTests.cpp | 37 +- testsuite/ExprExecTests.cpp | 66 +- testsuite/StateJsonTests.cpp | 3 +- 28 files changed, 923 insertions(+), 1205 deletions(-) delete mode 100644 include/ScillaVM/JITD.h create mode 100644 include/ScillaVM/ScillaExec.h delete mode 100644 libjitd/CMakeLists.txt delete mode 100644 libjitd/JITD.cpp rename {libjitd => libsrtl}/Debug.cpp (100%) rename include/ScillaVM/SRTL.h => libsrtl/ObjManager.h (63%) create mode 100644 libsrtl/SRTL.h create mode 100644 libsrtl/ScillaExecImpl.cpp create mode 100644 libsrtl/ScillaExecImpl.h rename {libjitd => libsrtl}/SharedObject.h (94%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9629253..dc364629 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # C++ standard set(CMAKE_CXX_STANDARD 14) -add_subdirectory(libjitd) add_subdirectory(libsrtl) add_subdirectory(runners) add_subdirectory(testsuite) @@ -67,14 +66,12 @@ set_target_properties(expr-runner PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set_target_properties(ScillaRTL PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set_target_properties(ScillaJITD - PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) install( TARGETS scilla-runner expr-runner DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) install( - TARGETS ScillaRTL ScillaJITD CryptoUtils Schnorr ff + TARGETS ScillaRTL CryptoUtils Schnorr ff DESTINATION ${CMAKE_INSTALL_PREFIX}/lib ) install( diff --git a/include/ScillaVM/Errors.h b/include/ScillaVM/Errors.h index 169b92a0..9498fa07 100644 --- a/include/ScillaVM/Errors.h +++ b/include/ScillaVM/Errors.h @@ -15,6 +15,8 @@ * along with this program. If not, see . */ +#pragma once + #include namespace ScillaVM { diff --git a/include/ScillaVM/JITD.h b/include/ScillaVM/JITD.h deleted file mode 100644 index 30ab3589..00000000 --- a/include/ScillaVM/JITD.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2019 Zilliqa - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include -#include -#include - -#include -#include - -// Forward declarations. -namespace llvm { -namespace orc { -class LLJIT; -} -class MemoryBuffer; -} // namespace llvm - -namespace ScillaVM { - -class ScillaJIT; -class ScillaObjCache; -class TransitionState; -class ObjManager; - -namespace ScillaTypes { -class TypParserPartialCache; -class Typ; -} // namespace ScillaTypes - -// An opaque object for use from outside the ScillaJIT object. -class ScillaCacheManager { - friend class ScillaJIT; - std::unique_ptr SOC; - -public: - // Constructor for memory + disk cache. - ScillaCacheManager(const std::string &CacheDir); - // Constructor for memory only cache. - ScillaCacheManager(); - ~ScillaCacheManager(); -}; - -// Information that Scilla will need to execute contracts. -struct ScillaParams { - struct StateQuery { - std::string Name; - int MapDepth; - std::vector Indices; - bool IgnoreVal; - }; - // A Scilla state contains either std::string or a MapValueT - // We use boost::any to capture this. Using std::variant is - // cumbersome because of the recursive type definition required. - // https://stackoverflow.com/questions/43309468/recursive-data-structure-with-variant - using MapValueT = std::unordered_map; - - using FetchState_Type = std::function; - using FetchRemoteState_Type = - std::function; - using UpdateState_Type = - std::function; - - FetchState_Type fetchStateValue; - FetchRemoteState_Type fetchRemoteStateValue; - UpdateState_Type updateStateValue; - - ScillaParams() - : fetchStateValue(nullptr), fetchRemoteStateValue(nullptr), - updateStateValue(nullptr){}; - ScillaParams(FetchState_Type FS, FetchRemoteState_Type FRS, - UpdateState_Type US) - : fetchStateValue(FS), fetchRemoteStateValue(FRS), updateStateValue(US){}; -}; - -// Each ScillaJIT object compiles an LLVM-IR module and provides access -// to the symbols inside it. It is recommended use ScillaJIT_Safe, -// which hides many private methods in this class and makes it safer. -class ScillaJIT { -private: - // Use the Create method to build a ScillaJIT object. - ScillaJIT(const ScillaParams &SPs, std::unique_ptr &&J); - // JIT Compile LLVM-IR from MemBuf, affixing @ModuleID to it. - // Optionally, a cache manager can be provided. - static std::unique_ptr create(const ScillaParams &SPs, - llvm::MemoryBuffer *MemBuf, - const std::string &ModuleID, - ScillaCacheManager * = nullptr); - - void initContrParams(const Json::Value &CP, bool DoDynamicTypechecks); - std::unique_ptr Jitter; - // An opaque pointer to the type parser partial cache. - std::unique_ptr TPPC; - -public: - // One time initialization. - static void init(); - // JIT Compile LLVM-IR @FileName. ModuleID is derived from @FileName. - // Optionally, a cache manager can be provided. - static std::unique_ptr create(const ScillaParams &SPs, - const std::string &FileName, - ScillaCacheManager * = nullptr); - // JIT Compile LLVM-IR in @IR, affixing @ModuleID to it. - // Optionally, a cache manager can be provided. - static std::unique_ptr create(const ScillaParams &SPs, - const std::string &IR, - const std::string &ModuleID, - ScillaCacheManager * = nullptr); - // Get address for @Symbol inside the compiled IR, ready to be used. - void *getAddressFor(const std::string &Symbol) const; - - // Get the type descriptors table and its length. - std::pair getTypeDescrTable() const; - - // Initialize gas-remaining field in the code and initialize libraries. - uint64_t *initGasAndLibs(uint64_t GasRem); - // Execute a message. - Json::Value execMsg(const std::string &Balance, uint64_t GasLimit, - const Json::Value &InitJ, const Json::Value &Msg); - // Initialize the contract state to field initialization values in the source. - // This is to be called only during deployment of the contract. Never again. - Json::Value deploy(const Json::Value &InitJ, uint64_t GasLimit); - // What's the gas remaining from previous execution (deploy / execMsg). - // Useful if execution was interrupted due to an exception. - // Use with care if you don't want to end up with a stale value. - uint64_t getGasRem() const; - // Parse a string into a Scilla type. Raises error on failure. - const ScillaTypes::Typ *parseTypeString(const std::string &) const; - - // Scilla values dynamically allocated and owned by the JIT engine. - std::unique_ptr OM; - // Scilla configuration parameters. - const ScillaParams SPs; - // The state of execution specific to a transition. - std::unique_ptr TS; - - ~ScillaJIT(); -}; - -// Typical usage: -// ScillaJIT_Safe::init(); : One time ever -// 1. auto SJ = ScillaJIT_Safe::create(...); -// 2. (a) Deployment (b) Transition execution -// a. auto Output = ScillaJIT_Safe::deploy(...); -// OR -// b. auto Output = ScillaJIT_Safe::execMsg(...); -// 3. If ScillaError exception, check remaining gas with getGasRem(). -class ScillaJIT_Safe : private ScillaJIT { -public: - // One time initialization. - static void init() { ScillaJIT::init(); } - // JIT Compile LLVM-IR @FileName. ModuleID is derived from @FileName. - // Optionally, a cache manager can be provided. - static std::unique_ptr - create(const ScillaParams &SPs, const std::string &FileName, - ScillaCacheManager *SCM = nullptr) { - ScillaJIT *Ptr = ScillaJIT::create(SPs, FileName, SCM).release(); - return std::unique_ptr(static_cast(Ptr)); - } - // JIT Compile LLVM-IR in @IR, affixing @ModuleID to it. - // Optionally, a cache manager can be provided. - static std::unique_ptr - create(const ScillaParams &SPs, const std::string &IR, - const std::string &ModuleID, ScillaCacheManager *SCM = nullptr) { - ScillaJIT *Ptr = ScillaJIT::create(SPs, IR, ModuleID, SCM).release(); - return std::unique_ptr(static_cast(Ptr)); - } - // Execute a message. - Json::Value execMsg(const std::string &Balance, uint64_t GasLimit, - const Json::Value &InitJ, const Json::Value &Msg) { - return ScillaJIT::execMsg(Balance, GasLimit, InitJ, Msg); - } - // Initialize the contract state to field initialization values in the source. - // This is to be called only during deployment of the contract. Never again. - Json::Value deploy(const Json::Value &InitJ, uint64_t GasLimit) { - return ScillaJIT::deploy(InitJ, GasLimit); - } - // What's the gas remaining from previous execution (deploy / execMsg). - // Useful if execution was interrupted due to an exception. - // Use with care if you don't want to end up with a stale value. - uint64_t getGasRem() const { return ScillaJIT::getGasRem(); } - - // Parse a string into a Scilla type. Raises error on failure. - const ScillaTypes::Typ *parseTypeString(const std::string &) const; - - // Get the type descriptors table and its length. - std::pair getTypeDescrTable() const { - return ScillaJIT::getTypeDescrTable(); - } -}; - -} // namespace ScillaVM diff --git a/include/ScillaVM/ScillaExec.h b/include/ScillaVM/ScillaExec.h new file mode 100644 index 00000000..ab4da8c9 --- /dev/null +++ b/include/ScillaVM/ScillaExec.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2019 Zilliqa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +// Forward declarations. +namespace ScillaVM { + +// Information that Scilla will need to execute contracts. +struct ScillaParams { + struct StateQuery { + std::string Name; + int MapDepth; + std::vector Indices; + bool IgnoreVal; + }; + // A Scilla state contains either std::string or a MapValueT + // We use boost::any to capture this. Using std::variant is + // cumbersome because of the recursive type definition required. + // https://stackoverflow.com/questions/43309468/recursive-data-structure-with-variant + using MapValueT = std::unordered_map; + + using FetchState_Type = std::function; + using FetchRemoteState_Type = + std::function; + using UpdateState_Type = + std::function; + + FetchState_Type fetchStateValue; + FetchRemoteState_Type fetchRemoteStateValue; + UpdateState_Type updateStateValue; + + ScillaParams() + : fetchStateValue(nullptr), fetchRemoteStateValue(nullptr), + updateStateValue(nullptr){}; + ScillaParams(FetchState_Type FS, FetchRemoteState_Type FRS, + UpdateState_Type US) + : fetchStateValue(FS), fetchRemoteStateValue(FRS), updateStateValue(US){}; +}; + +class ScillaExecImpl; + +// Typical usage: +// 1. ScillaContrExec SJ(...); +// 2. (a) Deployment (b) Transition execution +// a. auto Output = SJ.deploy(...); +// OR +// b. auto Output = SJ.execMsg(...); +// 3. If ScillaError exception, check remaining gas with SJ.getGasRem(). +class ScillaContrExec { +private: + std::unique_ptr PImpl; + +public: + // @ContrBin is the path to a contract's shared object `foo.so` + // generated by compiling `foo.scilla` with scilla-llvm into `foo.bc` + // and compiling this LLVM bitcode with `clang -shared foo.bc -o foo.so`. + ScillaContrExec(const ScillaParams &SPs, const std::string &ContrBin); + ~ScillaContrExec(); + + // Execute a message. + Json::Value execMsg(const std::string &Balance, uint64_t GasLimit, + const Json::Value &InitJ, const Json::Value &Msg); + + // Initialize the contract state to field initialization values in the source. + // This is to be called only during deployment of the contract. Never again. + Json::Value deploy(const Json::Value &InitJ, uint64_t GasLimit); + + // What's the gas remaining from previous execution (deploy / execMsg). + // Useful if execution was interrupted due to an exception. + // Use with care if you don't want to end up with a stale value. + uint64_t getGasRem() const; +}; + +// Typical usage: +// 1. ScillaExprExec SJ(...); +// 2. auto Output = SJ.exec(); +// 3. If ScillaError exception, check remaining gas with SJ.getGasRem(). +class ScillaExprExec { +private: + std::unique_ptr PImpl; + +public: + // @ExprBin is the path to a pure scilla expressions's shared object `foo.so` + // generated by compiling `foo.scilexp` with expr-llvm into `foo.bc` + // and compiling this LLVM bitcode with `clang -shared foo.bc -o foo.so`. + ScillaExprExec(const ScillaParams &SPs, const std::string &ExprBin); + ~ScillaExprExec(); + + // Execute the expression. + std::string exec(uint64_t GasLimit); + + // What's the gas remaining from previous execution of exec(). + // Useful if execution was interrupted due to an exception. + // Use with care if you don't want to end up with a stale value. + uint64_t getGasRem() const; +}; + +} // namespace ScillaVM diff --git a/include/ScillaVM/Utils.h b/include/ScillaVM/Utils.h index f8dd0033..7dfaeee5 100644 --- a/include/ScillaVM/Utils.h +++ b/include/ScillaVM/Utils.h @@ -15,14 +15,17 @@ * along with this program. If not, see . */ +#pragma once + #include #include #include +#include #include #include -#include "JITD.h" +#include "ScillaExec.h" namespace boost { // Does a boost::any object hold a value of type T. @@ -35,6 +38,7 @@ template bool has_type(const boost::any *a) { } // namespace boost namespace ScillaVM { + std::string readFile(const std::string &Filename); Json::Value parseJSONString(const std::string &JS); Json::Value parseJSONFile(const std::string &Filename); @@ -43,6 +47,20 @@ boost::optional mapDepthOfTypeString(const std::string &TypeStr); // Serialize a JSON for storage. std::string serializeJSON(const Json::Value &J); +// Compile an LLVM IR/bitcode file and return path to binary shared object. +// The shared object's lifetime is that of this object. +class CompileToSO { + const boost::filesystem::path SOFile; + const std::string InputFile; + +public: + CompileToSO(const std::string &Filename); + // Compile the file to a shared object and return the .so filename. + // Raises an error if compilation fails. + std::string compile() const; + ~CompileToSO(); +}; + namespace ScillaTypes { class Typ; } // namespace ScillaTypes diff --git a/libjitd/CMakeLists.txt b/libjitd/CMakeLists.txt deleted file mode 100644 index bc547c34..00000000 --- a/libjitd/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(TARGET ScillaJITD) -add_library(${TARGET} SHARED JITD.cpp Debug.cpp) - -target_compile_definitions(${TARGET} PUBLIC ${LLVM_DEFINITIONS}) -target_include_directories(${TARGET} PUBLIC ${PROJECT_SOURCE_DIR}/include) -target_include_directories(${TARGET} PUBLIC ${json_INCLUDE_DIRS}) -# We include LLVM includes as system includes to avoid warnings from there. -target_include_directories(${TARGET} SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) -target_link_libraries (${TARGET} PUBLIC ${llvm_libs} ScillaRTL jsoncpp secp256k1) diff --git a/libjitd/JITD.cpp b/libjitd/JITD.cpp deleted file mode 100644 index d9947d65..00000000 --- a/libjitd/JITD.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (C) 2019 Zilliqa - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/JITEventListener.h" -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/ObjectCache.h" -#include "llvm/ExecutionEngine/Orc/CompileUtils.h" -#include "llvm/ExecutionEngine/Orc/Core.h" -#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" -#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" -#include "llvm/ExecutionEngine/Orc/LLJIT.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IRReader/IRReader.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/InstCombine/InstCombine.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Scalar/GVN.h" -#include "llvm/Transforms/Utils.h" - -#include "../libsrtl/ScillaBuiltins.h" -#include "../libsrtl/ScillaTypes.h" -#include "ScillaVM/Debug.h" -#include "ScillaVM/Errors.h" -#include "ScillaVM/JITD.h" -#include "ScillaVM/SRTL.h" - -using namespace llvm; - -namespace { - -// Add functions in SRTL that the JIT'ed code can access. -Error addScillaBuiltins(orc::LLJIT &LLJitter, const DataLayout &DL) { - orc::SymbolMap M; - orc::MangleAndInterner Mangle(LLJitter.getExecutionSession(), DL); - // Register every symbol that can be accessed from the JIT'ed code. - auto ScillaFuncs = ScillaVM::getAllScillaBuiltins(); - for (auto fa : ScillaFuncs) { - M[Mangle(fa.FName)] = JITEvaluatedSymbol( - pointerToJITTargetAddress(fa.FAddr), JITSymbolFlags()); - } - - if (auto Err = (LLJitter.getMainJITDylib().define(absoluteSymbols(M)))) - return Err; - - return Error::success(); -} - -} // end of anonymous namespace - -namespace ScillaVM { - -namespace ph = std::placeholders; - -#define DEBUG_TYPE "obj_cache" - -// Caching mechanism for compiled files. Not thread safe. -class ScillaObjCache : public llvm::ObjectCache { -public: - // Constructor for memory + disk cache. - ScillaObjCache(const std::string &CacheDir) : CacheDir(CacheDir){}; - // Constructor for memory only cache. - ScillaObjCache(){}; - void notifyObjectCompiled(const llvm::Module *M, - llvm::MemoryBufferRef ObjBuffer) override; - - std::unique_ptr getObject(const llvm::Module *M) override; - std::unique_ptr getObject(const std::string &ModuleID); - -private: - llvm::StringMap> CachedObjects; - const std::string CacheDir; -}; - -void ScillaObjCache::notifyObjectCompiled(const Module *M, - MemoryBufferRef ObjBuffer) { - auto ModuleID = M->getModuleIdentifier(); - - CachedObjects[ModuleID] = MemoryBuffer::getMemBufferCopy( - ObjBuffer.getBuffer(), ObjBuffer.getBufferIdentifier()); - SVM_DEBUG(dbgs() << ModuleID << " added to memory cache\n"); - - // If there's a cache directory specified, write to disk. - if (!CacheDir.empty()) { - if (!sys::fs::exists(CacheDir) && sys::fs::create_directory(CacheDir)) { - CREATE_ERROR("Cache directory " + CacheDir + - " does not exist and cannot be created"); - } - SmallString<64> CacheFilename(CacheDir); - sys::path::append(CacheFilename, ModuleID); - std::error_code EC; - raw_fd_ostream ObjFile(CacheFilename.c_str(), EC); - if (EC) { - CREATE_ERROR(std::string("Cannot write to cache file ") + - CacheFilename.c_str() + ": " + EC.message()); - } - ObjFile << ObjBuffer.getBuffer(); - SVM_DEBUG(dbgs() << ModuleID << " added to disk cache " - << CacheFilename.c_str() << "\n"); - } -} - -std::unique_ptr -ScillaObjCache::getObject(const std::string &ModuleID) { - auto I = CachedObjects.find(ModuleID); - if (I == CachedObjects.end()) { - SVM_DEBUG(dbgs() << "Object file for " << ModuleID - << " not cached in memory.\n"); - - if (CacheDir.empty()) - return nullptr; - - SmallString<64> CacheFilename(CacheDir); - sys::path::append(CacheFilename, ModuleID); - if (sys::fs::exists(CacheFilename)) { - auto MB = MemoryBuffer::getFile(CacheFilename); - if (auto Err = MB.getError()) { - SVM_DEBUG(dbgs() << "Error loading object file from " - << CacheFilename.c_str() << "\n"); - return nullptr; - } - SVM_DEBUG(dbgs() << "Loaded object file from file " - << CacheFilename.c_str() << "\n"); - CachedObjects[ModuleID] = MemoryBuffer::getMemBufferCopy( - (*MB)->getBuffer(), (*MB)->getBufferIdentifier()); - return std::move(*MB); - } - SVM_DEBUG(dbgs() << "Object file for " << ModuleID - << " not cached on disk.\n"); - return nullptr; - } - - SVM_DEBUG(dbgs() << "Object for " << ModuleID - << " loaded from memory cache.\n"); - return MemoryBuffer::getMemBufferCopy(I->second->getBuffer()); -} - -std::unique_ptr ScillaObjCache::getObject(const Module *M) { - return getObject(M->getModuleIdentifier()); -} - -#undef DEBUG_TYPE - -// Constructor for memory + disk cache. -ScillaCacheManager::ScillaCacheManager(const std::string &CacheDir) - : SOC(std::make_unique(CacheDir)) {} -// Constructor for memory only cache. -ScillaCacheManager::ScillaCacheManager() - : SOC(std::make_unique()) {} -ScillaCacheManager::~ScillaCacheManager() = default; - -using namespace orc; - -void ScillaJIT::init() { - InitializeNativeTarget(); - InitializeNativeTargetAsmPrinter(); -} - -std::unique_ptr ScillaJIT::create(const ScillaParams &SPs, - const std::string &FileName, - ScillaCacheManager *OC) { - - auto MemBuf = MemoryBuffer::getFile(FileName); - if (auto Err = MemBuf.getError()) { - CREATE_ERROR(Err.message()); - } - - // Let's build the ModuleID, which will be the filename without - // any path prefixes, but extension replace with ".scilla_cache". - SmallString<64> FNSS(FileName); - sys::path::replace_extension(FNSS, ".scilla_cache"); - std::string ModuleID = sys::path::filename(FNSS.c_str()).str(); - - return create(SPs, (*MemBuf).get(), ModuleID, OC); -} - -std::unique_ptr ScillaJIT::create(const ScillaParams &SPs, - const std::string &IR, - const std::string &ModuleID, - ScillaCacheManager *OC) { - auto MemBuf = MemoryBuffer::getMemBuffer(IR); - return create(SPs, MemBuf.get(), ModuleID, OC); -} - -std::unique_ptr ScillaJIT::create(const ScillaParams &SPs, - llvm::MemoryBuffer *MemBuf, - const std::string &ModuleID, - ScillaCacheManager *SCM) { - - ScillaObjCache *OC = SCM ? SCM->SOC.get() : nullptr; - - // Create an LLJIT instance with a custom CompileFunction and - // ObjectLinkingLayer. - auto J = - LLJITBuilder() - .setCompileFunctionCreator( - [&](JITTargetMachineBuilder JTMB) - -> Expected> { - auto TM = JTMB.createTargetMachine(); - if (!TM) - return TM.takeError(); - return std::make_unique(std::move(*TM), - OC); - }) - .setObjectLinkingLayerCreator([&](ExecutionSession &ES, - const Triple &TT) - -> std::unique_ptr { - // Except for the GDBListener registration, the rest of - // the code is taken from LLJIT.cpp. - auto GetMemMgr = []() { - return std::make_unique(); - }; - auto ObjLinkingLayer = std::make_unique( - ES, std::move(GetMemMgr)); - if (TT.isOSBinFormatCOFF()) { - ObjLinkingLayer->setOverrideObjectFlagsWithResponsibilityFlags( - true); - ObjLinkingLayer->setAutoClaimResponsibilityForObjectSymbols(true); - } - auto GDBListener = - JITEventListener::createGDBRegistrationListener(); - ObjLinkingLayer->setNotifyLoaded( - std::bind(&JITEventListener::notifyObjectLoaded, GDBListener, - ph::_1, ph::_2, ph::_3)); - return ObjLinkingLayer; - }) - .create(); - - if (auto Err = J.takeError()) - CREATE_ERROR(llvm::toString(std::move(Err))); - - if (auto Err = addScillaBuiltins(*(*J), (*J)->getDataLayout())) - CREATE_ERROR(llvm::toString(std::move(Err))); - - std::unique_ptr THIS(new ScillaJIT(SPs, std::move(*J))); - auto Ctx = std::make_unique(); - - std::unique_ptr Obj = - OC ? OC->getObject(ModuleID) : nullptr; - if (Obj) { - // We have the object file for this IR module in cache. - if (auto Err = THIS->Jitter->addObjectFile(std::move(Obj))) { - CREATE_ERROR(llvm::toString(std::move(Err))); - } - } else { - // IR module not in cache. Parse and compile it. - SMDiagnostic Smd; - std::unique_ptr M = - parseIR(MemBuf->getMemBufferRef(), Smd, *Ctx); - if (!M) { - std::string ErrMsg; - raw_string_ostream OS(ErrMsg); - Smd.print("scilla-vm", OS); - auto Err = createStringError(inconvertibleErrorCode(), OS.str().c_str()); - CREATE_ERROR(llvm::toString(std::move(Err))); - } - M->setModuleIdentifier(ModuleID); - ThreadSafeModule TSM(std::move(M), std::move(Ctx)); - if (auto Err = THIS->Jitter->addIRModule(std::move(TSM))) { - CREATE_ERROR(llvm::toString(std::move(Err))); - } - } - - // Create an empty type parser partial cache. - THIS->TPPC = std::make_unique(); - // Create an object manager. - THIS->OM = std::make_unique(); - - // Set execptr in the generated code to THIS - auto ExecPtr = THIS->getAddressFor("_execptr"); - *reinterpret_cast(ExecPtr) = THIS.get(); - - return THIS; -} - -void ScillaJIT::initContrParams(const Json::Value &CP, - bool DoDynamicTypechecks) { - - // First get the name and types of contract parameters. - auto CParams = reinterpret_cast( - getAddressFor("_contract_parameters")); - auto NCParams = *reinterpret_cast( - getAddressFor("_contract_parameters_length")); - - auto ErrMsg = "Invalid init JSON when initializing contract parameters"; - if (!CP.isArray()) { - CREATE_ERROR(ErrMsg); - } - - // TODO: Remove this when BNum types are supported. - uint32_t CPSize = std::accumulate( - CP.begin(), CP.end(), 0, [](uint32_t Acc, const Json::Value &IV) { - const Json::Value &VName = IV["vname"]; - return Acc + (VName.isString() && VName.asString() == "_creation_block" - ? 0 - : 1); - }); - - if (CPSize != NCParams) { - CREATE_ERROR("Expected " + std::to_string(NCParams) + - " contract parameters, but got " + std::to_string(CPSize)); - } - // Let's put the expected contract parameters into a map for fast access. - std::unordered_map ParamMap; - std::for_each(CParams, CParams + NCParams, - [&ParamMap](const ScillaTypes::ParamDescr &PD) { - ParamMap[std::string(PD.m_PName)] = PD.m_PTy; - }); - - for (const auto &PJ : CP) { - if (!PJ.isObject()) { - CREATE_ERROR(ErrMsg); - } - auto &VName = PJ["vname"]; - auto &Type = PJ["type"]; - auto &Value = PJ["value"]; - if (!VName.isString() || !Type.isString() || Value.isNull()) { - CREATE_ERROR(ErrMsg); - } - - // TODO: The compiler doesn't yet support BNum types. - if (VName.asString() == "_creation_block") - continue; - - auto ExpectedT = ParamMap.find(VName.asString()); - if (ExpectedT == ParamMap.end()) { - CREATE_ERROR("Unknown contract parameter in JSON " + VName.asString()); - } - auto *T = parseTypeString(Type.asString()); - // Before we parse the value into memory (which is already allocated - // and of fixed length), ensure that the value is safe. - if (!ScillaTypes::Typ::valueCompatible(T, ExpectedT->second)) { - CREATE_ERROR(VName.asString() + ": Type " + - ScillaTypes::Typ::toString(T) + - " is incompatible with type " + - ScillaTypes::Typ::toString(ExpectedT->second) + - " specified in the contract."); - } - void *P = (getAddressFor(VName.asString())); - void *ValP; - if (ScillaTypes::Typ::isBoxed(T)) { - // Boxed types are just pointers. - ValP = ScillaValues::fromJSON(*OM, T, Value); - *reinterpret_cast(P) = ValP; - } else { - ValP = P; - // We create the ScillaValue in place. - ScillaValues::fromJSONToMem(*OM, ValP, ScillaTypes::Typ::sizeOf(T), T, - Value); - } - if (DoDynamicTypechecks && - !dynamicTypecheck(this, ExpectedT->second, T, ValP)) { - CREATE_ERROR("Dynamic typecheck failed: " + VName.asString()); - } - } -} - -uint64_t *ScillaJIT::initGasAndLibs(uint64_t GasLimit) { - // Set gas limit in the JIT'ed code module. - auto GasRemPtr = reinterpret_cast(getAddressFor("_gasrem")); - *GasRemPtr = GasLimit; - - // Call the library initialisation function. - auto initLibs = reinterpret_cast(getAddressFor("_init_libs")); - initLibs(); - - return GasRemPtr; -} - -Json::Value ScillaJIT::deploy(const Json::Value &InitJ, uint64_t GasLimit) { - - // Initialize contract parameters. - initContrParams(InitJ, true /* DoDynamicTypechecks */); - - auto GasRemPtr = initGasAndLibs(GasLimit); - - // Let's setup the TransitionState for this transition. - TS = std::make_unique("0", "0", GasRemPtr); - auto fIS = reinterpret_cast(getAddressFor("_init_state")); - fIS(); - - Json::Value Result = TS->finalize(); - OM->deleteAll(); - return Result; -} - -uint64_t ScillaJIT::getGasRem() const { - return *reinterpret_cast(getAddressFor("_gasrem")); -} - -const ScillaTypes::Typ * -ScillaJIT::parseTypeString(const std::string &TStr) const { - auto TyDescrs = getTypeDescrTable(); - return ScillaTypes::Typ::fromString(TPPC.get(), TyDescrs.first, - TyDescrs.second, TStr); -} - -void *ScillaJIT::getAddressFor(const std::string &Symbol) const { - - auto SA = Jitter->lookup(Symbol); - if (auto Err = SA.takeError()) { - CREATE_ERROR(llvm::toString(std::move(Err))); - } - - return reinterpret_cast((*SA).getAddress()); -} - -std::pair ScillaJIT::getTypeDescrTable() const { - auto AllTyDescrs = reinterpret_cast( - getAddressFor("_tydescr_table")); - auto TyDescrsLen = - *reinterpret_cast(getAddressFor("_tydescr_table_length")); - return std::make_pair(AllTyDescrs, TyDescrsLen); -} - -ScillaJIT::ScillaJIT(const ScillaParams &SPs, std::unique_ptr &&J) - : Jitter(std::move(J)), SPs(SPs) {} - -ScillaJIT::~ScillaJIT() {} - -Json::Value ScillaJIT::execMsg(const std::string &Balance, uint64_t GasLimit, - const Json::Value &InitJ, - const Json::Value &Msg) { - - initContrParams(InitJ, false /* DoDynamicTypechecks */); - - Json::Value TransNameJ = Msg.get("_tag", Json::nullValue); - Json::Value ParamsJ = Msg.get("params", Json::nullValue); - Json::Value OriginJ = Msg.get("_origin", Json::nullValue); - Json::Value SenderJ = Msg.get("_sender", Json::nullValue); - Json::Value AmountJ = Msg.get("_amount", Json::nullValue); - if (!TransNameJ.isString() || !ParamsJ.isArray() || !SenderJ.isString() || - !OriginJ.isString() || !AmountJ.isString()) - CREATE_ERROR("Invalid Message"); - - auto GasRemPtr = initGasAndLibs(GasLimit); - - // Let's setup the TransitionState for this transition. - TS = - std::make_unique(Balance, AmountJ.asString(), GasRemPtr); - - // Amount and Sender need to be prepended to the parameter list. - Json::Value AmountParam; - { - AmountParam["vname"] = "_amount"; - AmountParam["type"] = "Uint128"; - AmountParam["value"] = AmountJ; - } - Json::Value OriginParam; - { - OriginParam["vname"] = "_origin"; - OriginParam["type"] = "ByStr20"; - OriginParam["value"] = OriginJ; - } - Json::Value SenderParam; - { - SenderParam["vname"] = "_sender"; - SenderParam["type"] = "ByStr20"; - SenderParam["value"] = SenderJ; - } - std::vector AllParamsJ; - AllParamsJ.push_back(AmountParam); - AllParamsJ.push_back(OriginParam); - AllParamsJ.push_back(SenderParam); - AllParamsJ.insert(AllParamsJ.end(), ParamsJ.begin(), ParamsJ.end()); - - std::string TransName = TransNameJ.asString(); - auto Transition = - reinterpret_cast(getAddressFor(TransName)); - - // We have all transition paramters as per the JSON in AllParamsJ. - // Time to get the same info from the contract for corroboration. - auto TParams = reinterpret_cast( - getAddressFor("_transition_parameters")); - auto TCParams = *reinterpret_cast( - getAddressFor("_transition_parameters_length")); - // Note down all parameters of this transition. - const auto ThisTParams = - std::find_if(TParams, TParams + TCParams, - [&TransName](const ScillaTypes::TransDescr &TD) { - return std::string(TD.m_TName) == TransName; - }); - if (ThisTParams == TParams + TCParams) { - CREATE_ERROR("Unknown transition " + TransName); - } - ScillaTypes::ParamDescr *PD = ThisTParams->m_Params; - uint32_t NPD = ThisTParams->m_NParams; - if (NPD != AllParamsJ.size()) { - CREATE_ERROR("Incorrect number of parameters to transition " + TransName); - } - std::unordered_map TParamsMap; - std::for_each(PD, PD + NPD, [&TParamsMap](const ScillaTypes::ParamDescr &PD) { - TParamsMap[std::string(PD.m_PName)] = PD.m_PTy; - }); - - std::vector ParamNames; - std::vector ParamTypes; - std::vector ParamValues; - for (auto &P : AllParamsJ) { - Json::Value VNameJ, TypeJ, ValueJ; - if (!P.isObject() || - (VNameJ = P.get("vname", Json::nullValue)) == Json::nullValue || - (TypeJ = P.get("type", Json::nullValue)) == Json::nullValue || - (ValueJ = P.get("value", Json::nullValue)) == Json::nullValue || - !VNameJ.isString() || !TypeJ.isString()) { - CREATE_ERROR("Incorrect paramter format in message JSON."); - } - auto *T = parseTypeString(TypeJ.asString()); - ParamTypes.push_back(T); - ParamValues.push_back(ValueJ); - ParamNames.push_back(VNameJ.asString()); - } - int MemSize = std::accumulate(ParamTypes.begin(), ParamTypes.end(), 0, - [](int acc, const ScillaTypes::Typ *T) { - return acc + ScillaTypes::Typ::sizeOf(T); - }); - - ASSERT(MemSize > 0); - auto *Mem = reinterpret_cast(OM->allocBytes(MemSize)); - for (size_t I = 0, Off = 0; I < ParamTypes.size(); I++) { - const ScillaTypes::Typ *T = ParamTypes[I]; - int Size = ScillaTypes::Typ::sizeOf(T); - auto *ThisMemP = Mem + Off; - void *ValP; - if (ScillaTypes::Typ::isBoxed(T)) { - ValP = ScillaValues::fromJSON(*OM, T, ParamValues[I]); - *reinterpret_cast(ThisMemP) = ValP; - } else { - ValP = ThisMemP; - ScillaValues::fromJSONToMem(*OM, ValP, Size, T, ParamValues[I]); - } - auto ExpectedT = TParamsMap.find(ParamNames[I]); - if (ExpectedT == TParamsMap.end()) { - CREATE_ERROR("Unknown transition parameter " + ParamNames[I]); - } - // _sender and _origin are trusted addresses. Otherwise, we must verify. - if (ParamNames[I] != "_sender" && ParamNames[I] != "_origin" && - !dynamicTypecheck(this, ExpectedT->second, T, ValP)) { - CREATE_ERROR("Dyanamic typecheck failed: " + ParamNames[I]); - } - - Off += Size; - } - - Transition(Mem); - - Json::Value Result = TS->finalize(); - OM->deleteAll(); - return Result; -} - -} // namespace ScillaVM \ No newline at end of file diff --git a/libsrtl/CMakeLists.txt b/libsrtl/CMakeLists.txt index 43d6f627..dd9c1f26 100644 --- a/libsrtl/CMakeLists.txt +++ b/libsrtl/CMakeLists.txt @@ -1,11 +1,13 @@ set(TARGET ScillaRTL) add_library(${TARGET} SHARED + ScillaExecImpl.cpp SRTL.cpp ScillaBuiltins.cpp ScillaTypes.cpp ScillaValue.cpp SafeInt.cpp Utils.cpp + Debug.cpp ) target_compile_definitions(${TARGET} PUBLIC ${LLVM_DEFINITIONS}) diff --git a/libjitd/Debug.cpp b/libsrtl/Debug.cpp similarity index 100% rename from libjitd/Debug.cpp rename to libsrtl/Debug.cpp diff --git a/include/ScillaVM/SRTL.h b/libsrtl/ObjManager.h similarity index 63% rename from include/ScillaVM/SRTL.h rename to libsrtl/ObjManager.h index 157fc587..3476fd24 100644 --- a/include/ScillaVM/SRTL.h +++ b/libsrtl/ObjManager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Zilliqa + * Copyright (C) 2021 Zilliqa * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,36 +17,12 @@ #pragma once -#include -#include -#include #include -#include - #include namespace ScillaVM { -class ScillaJIT; -namespace ScillaTypes { -struct Typ; -} - -using ByteVec = std::vector; - -// A global that accummulates messages printed from the JIT'ed code. -extern std::string ScillaStdout; - -const auto Schnorr_Pubkey_Len = 33; -const auto Schnorr_Signature_Len = 64; - -const auto Ecdsa_Pubkey_Len = 33; -const auto Ecdsa_Signature_Len = 64; -const auto Ecdsa_Pubkey_Uncompressed_Len = 65; - -const auto Zilliqa_Address_Len = 20; - // Allocates, constructs, owns and destructs objects. // Objects of any type can be managed. It works similar to how // std::any works. https://stackoverflow.com/a/4989141/2128804 @@ -106,20 +82,4 @@ class ObjManager { ~ObjManager() { deleteAll(); }; }; -// Fetch the type of a remote field, if it exists. -boost::optional -remoteFieldType(const ScillaJIT *SJ, const std::string &Addr, - const std::string &FName); - -// Is the given address a contract? -bool isContrAddr(const ScillaJIT *SJ, const std::string &Addr); -// Check if the given address has balance > 0 || nonce > 0 -bool isUserAddr(const ScillaJIT *SJ, const std::string &Addr); - -// Check that @Val is of type @Target. Asserts valueCompatible(Target, ParsedT). -// @ParsedT is the type specified in the JSON from which @Val is parsed. -// The dynamic typecheck itself is essentially ensuring that Addresses conform. -bool dynamicTypecheck(const ScillaJIT *SJ, const ScillaTypes::Typ *Target, - const ScillaTypes::Typ *ParsedT, void *Val); - -} // namespace ScillaVM +} // namespace ScillaVM \ No newline at end of file diff --git a/libsrtl/SRTL.cpp b/libsrtl/SRTL.cpp index fb37d334..261835be 100644 --- a/libsrtl/SRTL.cpp +++ b/libsrtl/SRTL.cpp @@ -17,12 +17,13 @@ #include -#include "SafeInt.h" -#include "ScillaTypes.h" #include "ScillaVM/Errors.h" -#include "ScillaVM/JITD.h" -#include "ScillaVM/SRTL.h" #include "ScillaVM/Utils.h" + +#include "SRTL.h" +#include "SafeInt.h" +#include "ScillaExecImpl.h" +#include "ScillaTypes.h" #include "ScillaValue.h" namespace { @@ -44,7 +45,7 @@ namespace ScillaVM { std::string ScillaStdout = ""; boost::optional -remoteFieldType(const ScillaJIT *SJ, const std::string &Addr, +remoteFieldType(const ScillaExecImpl *SJ, const std::string &Addr, const std::string &FName) { ScillaParams::StateQuery Q = {FName, 0, {}, true}; @@ -59,11 +60,11 @@ remoteFieldType(const ScillaJIT *SJ, const std::string &Addr, : boost::none); } -bool isContrAddr(const ScillaJIT *SJ, const std::string &Addr) { +bool isContrAddr(const ScillaExecImpl *SJ, const std::string &Addr) { return static_cast(remoteFieldType(SJ, Addr, "_this_address")); } -bool isUserAddr(const ScillaJIT *SJ, const std::string &Addr) { +bool isUserAddr(const ScillaExecImpl *SJ, const std::string &Addr) { ScillaParams::StateQuery SQBalance = {"_balance", 0, {}, false}; ScillaParams::StateQuery SQNonce = {"_nonce", 0, {}, false}; boost::any BalanceVal, NonceVal; @@ -98,7 +99,7 @@ bool isUserAddr(const ScillaJIT *SJ, const std::string &Addr) { return Balance > SafeUint128::min() || Nonce > SafeUint64::min(); } -bool dynamicTypecheck(const ScillaJIT *SJ, const ScillaTypes::Typ *TargetT, +bool dynamicTypecheck(const ScillaExecImpl *SJ, const ScillaTypes::Typ *TargetT, const ScillaTypes::Typ *ParsedT, void *Val) { if (!ScillaTypes::Typ::valueCompatible(ParsedT, TargetT)) { diff --git a/libsrtl/SRTL.h b/libsrtl/SRTL.h new file mode 100644 index 00000000..8e5d53c5 --- /dev/null +++ b/libsrtl/SRTL.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 Zilliqa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace ScillaVM { + +class ScillaExecImpl; +namespace ScillaTypes { +struct Typ; +} + +using ByteVec = std::vector; + +// A global that accummulates messages printed from the JIT'ed code. +extern std::string ScillaStdout; + +const auto Schnorr_Pubkey_Len = 33; +const auto Schnorr_Signature_Len = 64; + +const auto Ecdsa_Pubkey_Len = 33; +const auto Ecdsa_Signature_Len = 64; +const auto Ecdsa_Pubkey_Uncompressed_Len = 65; + +const auto Zilliqa_Address_Len = 20; + +// Fetch the type of a remote field, if it exists. +boost::optional +remoteFieldType(const ScillaExecImpl *SJ, const std::string &Addr, + const std::string &FName); + +// Is the given address a contract? +bool isContrAddr(const ScillaExecImpl *SJ, const std::string &Addr); +// Check if the given address has balance > 0 || nonce > 0 +bool isUserAddr(const ScillaExecImpl *SJ, const std::string &Addr); + +// Check that @Val is of type @Target. Asserts valueCompatible(Target, ParsedT). +// @ParsedT is the type specified in the JSON from which @Val is parsed. +// The dynamic typecheck itself is essentially ensuring that Addresses conform. +bool dynamicTypecheck(const ScillaExecImpl *SJ, const ScillaTypes::Typ *Target, + const ScillaTypes::Typ *ParsedT, void *Val); + +} // namespace ScillaVM diff --git a/libsrtl/ScillaBuiltins.cpp b/libsrtl/ScillaBuiltins.cpp index c5a10f27..9c3d1613 100644 --- a/libsrtl/ScillaBuiltins.cpp +++ b/libsrtl/ScillaBuiltins.cpp @@ -23,91 +23,18 @@ #include #include +#include "ObjManager.h" +#include "SRTL.h" #include "SafeInt.h" #include "ScillaBuiltins.h" +#include "ScillaExecImpl.h" #include "ScillaTypes.h" #include "ScillaVM/Errors.h" -#include "ScillaVM/SRTL.h" #include "ScillaVM/Utils.h" #include "ScillaValue.h" namespace ScillaVM { -std::vector getAllScillaBuiltins(void) { - // clang-format off - ScillaFunctionsMap m[] = { - {"_print_scilla_val", (void *) _print_scilla_val}, - {"_salloc", (void *) _salloc}, - {"_out_of_gas", (void *) _out_of_gas}, - {"_add_Int32", (void *) _add_Int32}, - {"_add_Int64", (void *) _add_Int64}, - {"_add_Int128", (void *) _add_Int128}, - {"_add_Int256", (void *) _add_Int256}, - {"_add_Uint32", (void *) _add_Uint32}, - {"_add_Uint64", (void *) _add_Uint64}, - {"_add_Uint128", (void *) _add_Uint128}, - {"_add_Uint256", (void *) _add_Uint256}, - {"_fetch_field", (void *) _fetch_field}, - {"_fetch_remote_field", (void *) _fetch_remote_field}, - {"_update_field", (void *) _update_field}, - {"_to_nat", (void *) _to_nat}, - {"_send", (void *) _send}, - {"_event", (void *) _event}, - {"_throw", (void *) _throw}, - {"_eq_Int32", (void *) _eq_Int32}, - {"_eq_Int64", (void *) _eq_Int64}, - {"_eq_Int128", (void *) _eq_Int128}, - {"_eq_Int256", (void *) _eq_Int256}, - {"_eq_Uint32", (void *) _eq_Uint32}, - {"_eq_Uint64", (void *) _eq_Uint64}, - {"_eq_Uint128", (void *) _eq_Uint128}, - {"_eq_Uint256", (void *) _eq_Uint256}, - {"_eq_String", (void *) _eq_String}, - {"_eq_ByStr", (void *) _eq_ByStr}, - {"_eq_ByStrX", (void *) _eq_ByStrX}, - {"_to_bystr", (void *) _to_bystr}, - {"_to_string", (void *) _to_string}, - {"_to_ascii", (void *) _to_ascii}, - {"_bystr_to_bystrx", (void *) _bystr_to_bystrx}, - {"_bech32_to_bystr20", (void *) _bech32_to_bystr20}, - {"_bystr20_to_bech32", (void *) _bystr20_to_bech32}, - {"_uint32_to_bystrx", (void *) _uint32_to_bystrx}, - {"_uint64_to_bystrx", (void *) _uint64_to_bystrx}, - {"_uint128_to_bystrx", (void *) _uint128_to_bystrx}, - {"_uint256_to_bystrx", (void *)_uint256_to_bystrx}, - {"_bystrx_to_uint32", (void *) _bystrx_to_uint32}, - {"_bystrx_to_uint64", (void *) _bystrx_to_uint64}, - {"_bystrx_to_uint128", (void *) _bystrx_to_uint128}, - {"_bystrx_to_uint256", (void *) _bystrx_to_uint256}, - {"_sha256hash", (void *) _sha256hash}, - {"_keccak256hash", (void *) _keccak256hash}, - {"_ripemd160hash", (void *) _ripemd160hash}, - {"_schnorr_verify", (void *) _schnorr_verify}, - {"_schnorr_get_address", (void *) _schnorr_get_address}, - {"_ecdsa_verify", (void *) _ecdsa_verify}, - {"_ecdsa_recover_pk", (void *) _ecdsa_recover_pk}, - {"_concat_String", (void *) _concat_String}, - {"_concat_ByStr", (void *) _concat_ByStr}, - {"_concat_ByStrX", (void *) _concat_ByStrX}, - {"_substr_String", (void *) _substr_String}, - {"_substr_ByStr", (void *) _substr_ByStr}, - {"_strlen_String", (void *) _strlen_String}, - {"_strlen_ByStr", (void *) _strlen_ByStr}, - {"_accept", (void *) _accept}, - {"_new_empty_map", (void *) _new_empty_map}, - {"_put", (void *) _put}, - {"_get", (void *) _get}, - {"_contains", (void *) _contains}, - {"_remove", (void *) _remove}, - {"_size", (void *) _size}, - {"_literal_cost", (void *) _literal_cost}, - {"_mapsortcost", (void *) _mapsortcost}, - }; - // clang-format on - - return std::vector(std::begin(m), std::end(m)); -} - void TransitionState::processMessage(std::string OutType, Json::Value &M) { if (OutJ.empty()) { OutJ[OutType] = Json::arrayValue; @@ -260,9 +187,10 @@ uint8_t *wrapMapAccessResult(ObjManager &OM, bool Found, } } -void *fetchFieldHelper(ScillaJIT *SJ, const std::string &Addr, const char *Name, - const ScillaTypes::Typ *T, int32_t NumIdx, - const uint8_t *Indices, int32_t FetchVal) { +void *fetchFieldHelper(ScillaExecImpl *SJ, const std::string &Addr, + const char *Name, const ScillaTypes::Typ *T, + int32_t NumIdx, const uint8_t *Indices, + int32_t FetchVal) { std::vector KeyTypes; std::vector SerializedIndices; @@ -279,7 +207,7 @@ void *fetchFieldHelper(ScillaJIT *SJ, const std::string &Addr, const char *Name, boost::any StringOrMapVal; bool Found = false; ASSERT_MSG(SJ->SPs.fetchStateValue && SJ->SPs.fetchRemoteStateValue, - "Incorrect ScillaParams provided to ScillaJIT"); + "Incorrect ScillaParams provided to ScillaExecImpl"); bool Succ; if (Addr.empty()) { Succ = SJ->SPs.fetchStateValue(SQ, StringOrMapVal, Found); @@ -299,29 +227,29 @@ void *fetchFieldHelper(ScillaJIT *SJ, const std::string &Addr, const char *Name, ScillaTypes::Typ::Map_typ); auto &MapVal = boost::any_cast(StringOrMapVal); return reinterpret_cast( - SJ->OM->create(std::move(MapVal))); + SJ->OM.create(std::move(MapVal))); } else { auto Val = boost::any_cast(StringOrMapVal); Json::Value ValJ = parseJSONString(Val); - return ScillaValues::fromJSON(*(SJ->OM), T, ValJ); + return ScillaValues::fromJSON(SJ->OM, T, ValJ); } } // Map access. Returned value must be wrapped with Option / Bool. auto ValT = ScillaTypes::Typ::mapAccessType(T, NumIdx); if (FetchVal) { - return wrapMapAccessResult(*(SJ->OM), Found, StringOrMapVal, ValT); + return wrapMapAccessResult(SJ->OM, Found, StringOrMapVal, ValT); } else { // We need to construct a Scilla Bool ADT based on "found". - auto Mem = toScillaBool(*(SJ->OM), Found); + auto Mem = toScillaBool(SJ->OM, Found); return Mem; } } template -void *uintToByStrX(ScillaJIT *SJ, ScillaTypes::RawInt I) { +void *uintToByStrX(ScillaExecImpl *SJ, ScillaTypes::RawInt I) { auto Len = sizeof(ScillaTypes::RawInt); - auto Mem = SJ->OM->allocBytes(Len); + auto Mem = SJ->OM.allocBytes(Len); std::memcpy(Mem, &I, Len); #if BOOST_ENDIAN_LITTLE_BYTE // Native integer is little-endian. Convert it to big-endian. @@ -352,7 +280,9 @@ void _print_scilla_val(const ScillaTypes::Typ *T, void *V) { ScillaStdout += ScillaValues::toString(true, T, V) + "\n"; } -void *_salloc(ScillaJIT *SJ, size_t size) { return SJ->OM->allocBytes(size); } +void *_salloc(ScillaExecImpl *SJ, size_t size) { + return SJ->OM.allocBytes(size); +} void _out_of_gas() { SCILLA_EXCEPTION("Ran out of gas"); } @@ -369,10 +299,10 @@ ScillaTypes::Int128 _add_Int128(ScillaTypes::Int128 Lhs, return SafeInt128(&Lhs) + SafeInt128(&Rhs); } -ScillaTypes::Int256 *_add_Int256(ScillaJIT *SJ, ScillaTypes::Int256 *Lhs, +ScillaTypes::Int256 *_add_Int256(ScillaExecImpl *SJ, ScillaTypes::Int256 *Lhs, ScillaTypes::Int256 *Rhs) { - auto *Buf = SJ->OM->allocBytes(sizeof(ScillaTypes::Int256)); + auto *Buf = SJ->OM.allocBytes(sizeof(ScillaTypes::Int256)); return new (Buf) ScillaTypes::Int256(SafeInt256(Lhs) + SafeInt256(Rhs)); } @@ -391,69 +321,71 @@ ScillaTypes::Uint128 _add_Uint128(ScillaTypes::Uint128 Lhs, return SafeUint128(&Lhs) + SafeUint128(&Rhs); } -ScillaTypes::Uint256 *_add_Uint256(ScillaJIT *SJ, ScillaTypes::Uint256 *Lhs, +ScillaTypes::Uint256 *_add_Uint256(ScillaExecImpl *SJ, + ScillaTypes::Uint256 *Lhs, ScillaTypes::Uint256 *Rhs) { - auto *Buf = SJ->OM->allocBytes(sizeof(ScillaTypes::Uint256)); + auto *Buf = SJ->OM.allocBytes(sizeof(ScillaTypes::Uint256)); return new (Buf) ScillaTypes::Uint256(SafeUint256(Lhs) + SafeUint256(Rhs)); } -uint8_t *_eq_Int32(ScillaJIT *SJ, ScillaTypes::Int32 Lhs, +uint8_t *_eq_Int32(ScillaExecImpl *SJ, ScillaTypes::Int32 Lhs, ScillaTypes::Int32 Rhs) { - return toScillaBool(*(SJ->OM), SafeInt32(&Lhs) == SafeInt32(&Rhs)); + return toScillaBool(SJ->OM, SafeInt32(&Lhs) == SafeInt32(&Rhs)); } -uint8_t *_eq_Int64(ScillaJIT *SJ, ScillaTypes::Int64 Lhs, +uint8_t *_eq_Int64(ScillaExecImpl *SJ, ScillaTypes::Int64 Lhs, ScillaTypes::Int64 Rhs) { - return toScillaBool(*(SJ->OM), SafeInt64(&Lhs) == SafeInt64(&Rhs)); + return toScillaBool(SJ->OM, SafeInt64(&Lhs) == SafeInt64(&Rhs)); } -uint8_t *_eq_Int128(ScillaJIT *SJ, ScillaTypes::Int128 Lhs, +uint8_t *_eq_Int128(ScillaExecImpl *SJ, ScillaTypes::Int128 Lhs, ScillaTypes::Int128 Rhs) { - return toScillaBool(*(SJ->OM), SafeInt128(&Lhs) == SafeInt128(&Rhs)); + return toScillaBool(SJ->OM, SafeInt128(&Lhs) == SafeInt128(&Rhs)); } -uint8_t *_eq_Int256(ScillaJIT *SJ, ScillaTypes::Int256 *Lhs, +uint8_t *_eq_Int256(ScillaExecImpl *SJ, ScillaTypes::Int256 *Lhs, ScillaTypes::Int256 *Rhs) { - return toScillaBool(*(SJ->OM), SafeInt256(Lhs) == SafeInt256(Rhs)); + return toScillaBool(SJ->OM, SafeInt256(Lhs) == SafeInt256(Rhs)); } -uint8_t *_eq_Uint32(ScillaJIT *SJ, ScillaTypes::Uint32 Lhs, +uint8_t *_eq_Uint32(ScillaExecImpl *SJ, ScillaTypes::Uint32 Lhs, ScillaTypes::Uint32 Rhs) { - return toScillaBool(*(SJ->OM), SafeUint32(&Lhs) == SafeUint32(&Rhs)); + return toScillaBool(SJ->OM, SafeUint32(&Lhs) == SafeUint32(&Rhs)); } -uint8_t *_eq_Uint64(ScillaJIT *SJ, ScillaTypes::Uint64 Lhs, +uint8_t *_eq_Uint64(ScillaExecImpl *SJ, ScillaTypes::Uint64 Lhs, ScillaTypes::Uint64 Rhs) { - return toScillaBool(*(SJ->OM), SafeUint64(&Lhs) == SafeUint64(&Rhs)); + return toScillaBool(SJ->OM, SafeUint64(&Lhs) == SafeUint64(&Rhs)); } -uint8_t *_eq_Uint128(ScillaJIT *SJ, ScillaTypes::Uint128 Lhs, +uint8_t *_eq_Uint128(ScillaExecImpl *SJ, ScillaTypes::Uint128 Lhs, ScillaTypes::Uint128 Rhs) { - return toScillaBool(*(SJ->OM), SafeUint128(&Lhs) == SafeUint128(&Rhs)); + return toScillaBool(SJ->OM, SafeUint128(&Lhs) == SafeUint128(&Rhs)); } -uint8_t *_eq_Uint256(ScillaJIT *SJ, ScillaTypes::Uint256 *Lhs, +uint8_t *_eq_Uint256(ScillaExecImpl *SJ, ScillaTypes::Uint256 *Lhs, ScillaTypes::Uint256 *Rhs) { - return toScillaBool(*(SJ->OM), SafeUint256(Lhs) == SafeUint256(Rhs)); + return toScillaBool(SJ->OM, SafeUint256(Lhs) == SafeUint256(Rhs)); } -void *_fetch_field(ScillaJIT *SJ, const char *Name, const ScillaTypes::Typ *T, - int32_t NumIdx, const uint8_t *Indices, int32_t FetchVal) { +void *_fetch_field(ScillaExecImpl *SJ, const char *Name, + const ScillaTypes::Typ *T, int32_t NumIdx, + const uint8_t *Indices, int32_t FetchVal) { return fetchFieldHelper(SJ, std::string(), Name, T, NumIdx, Indices, FetchVal); } -void *_fetch_remote_field(ScillaJIT *SJ, +void *_fetch_remote_field(ScillaExecImpl *SJ, const uint8_t AddrBytes[ScillaTypes::AddrByStr_Len], const char *Name, const ScillaTypes::Typ *T, int32_t NumIdx, const uint8_t *Indices, @@ -464,7 +396,7 @@ void *_fetch_remote_field(ScillaJIT *SJ, return fetchFieldHelper(SJ, Addr, Name, T, NumIdx, Indices, FetchVal); } -void _update_field(ScillaVM::ScillaJIT *SJ, const char *Name, +void _update_field(ScillaVM::ScillaExecImpl *SJ, const char *Name, const ScillaVM::ScillaTypes::Typ *T, int32_t NumIdx, const uint8_t *Indices, void *Val) { @@ -483,7 +415,7 @@ void _update_field(ScillaVM::ScillaJIT *SJ, const char *Name, if (Val) { ASSERT_MSG(SJ->SPs.updateStateValue, - "Incorrect ScillaParams provided to ScillaJIT"); + "Incorrect ScillaParams provided to ScillaExecImpl"); auto ValT = ScillaTypes::Typ::mapAccessType(T, NumIdx); if (MapValueAccess) { ASSERT(ValT->m_t == ScillaTypes::Typ::Map_typ); @@ -507,7 +439,7 @@ void _update_field(ScillaVM::ScillaJIT *SJ, const char *Name, } } -void *_to_nat(ScillaJIT *SJ, ScillaTypes::Uint32 UI) { +void *_to_nat(ScillaExecImpl *SJ, ScillaTypes::Uint32 UI) { auto I = *reinterpret_cast(&UI); // A Zero object consists of only the i8 tag. @@ -515,7 +447,7 @@ void *_to_nat(ScillaJIT *SJ, ScillaTypes::Uint32 UI) { auto ElSize = 1 + sizeof(uint8_t *); // We allocate all objects in one for (1) fast allocation (2) locality. const auto Mem = - reinterpret_cast(SJ->OM->allocBytes(ElSize * (I + 1))); + reinterpret_cast(SJ->OM.allocBytes(ElSize * (I + 1))); *Mem = ScillaTypes::Nat_Zero_Tag; uint8_t *MemPrev = Mem; for (unsigned II = 1; II <= I; II++) { @@ -527,7 +459,7 @@ void *_to_nat(ScillaJIT *SJ, ScillaTypes::Uint32 UI) { return MemPrev; } -void _send(ScillaJIT *SJ, const ScillaTypes::Typ *T, const void *V) { +void _send(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, const void *V) { auto J = ScillaValues::toJSON(T, V); // J is a Scilla list of Messages. Form a JSON array instead. // TODO: Consider having a Scilla List -> std::vector and calling @@ -582,83 +514,83 @@ uint64_t _mapsortcost(const ScillaParams::MapValueT *M) { return Cost; } -void _event(ScillaJIT *SJ, const ScillaTypes::Typ *T, const void *V) { +void _event(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, const void *V) { auto J = ScillaValues::toJSON(T, V); SJ->TS->processEvent(J); } -void _throw(ScillaJIT *SJ, const ScillaTypes::Typ *T, const void *V) { +void _throw(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, const void *V) { (void)SJ; auto J = ScillaValues::toJSON(T, V); SCILLA_EXCEPTION("Exception thrown: " + J.toStyledString()); } -uint8_t *_eq_String(ScillaJIT *SJ, ScillaTypes::String Lhs, +uint8_t *_eq_String(ScillaExecImpl *SJ, ScillaTypes::String Lhs, ScillaTypes::String Rhs) { auto B = (Lhs.m_length == Rhs.m_length) && (std::memcmp(Lhs.m_buffer, Rhs.m_buffer, Lhs.m_length) == 0); - return toScillaBool(*(SJ->OM), B); + return toScillaBool(SJ->OM, B); } -uint8_t *_eq_ByStr(ScillaJIT *SJ, ScillaTypes::String Lhs, +uint8_t *_eq_ByStr(ScillaExecImpl *SJ, ScillaTypes::String Lhs, ScillaTypes::String Rhs) { auto B = (Lhs.m_length == Rhs.m_length) && (std::memcmp(Lhs.m_buffer, Rhs.m_buffer, Lhs.m_length) == 0); - return toScillaBool(*(SJ->OM), B); + return toScillaBool(SJ->OM, B); } -uint8_t *_eq_ByStrX(ScillaJIT *SJ, int X, uint8_t *Lhs, uint8_t *Rhs) { +uint8_t *_eq_ByStrX(ScillaExecImpl *SJ, int X, uint8_t *Lhs, uint8_t *Rhs) { auto B = (std::memcmp(Lhs, Rhs, X) == 0); - return toScillaBool(*(SJ->OM), B); + return toScillaBool(SJ->OM, B); } -ScillaTypes::String _to_bystr(ScillaJIT *SJ, int X, uint8_t *Buf) { +ScillaTypes::String _to_bystr(ScillaExecImpl *SJ, int X, uint8_t *Buf) { ScillaTypes::String Ret; - auto Mem = SJ->OM->allocBytes(X); + auto Mem = SJ->OM.allocBytes(X); std::memcpy(Mem, Buf, X); Ret.m_length = X; Ret.m_buffer = reinterpret_cast(Mem); return Ret; } -ScillaTypes::String _to_string(ScillaJIT *SJ, const ScillaTypes::Typ *T, +ScillaTypes::String _to_string(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, const void *V) { auto J = ScillaValues::toString(false /* print type */, T, V); - auto Mem = reinterpret_cast(SJ->OM->allocBytes(J.length())); + auto Mem = reinterpret_cast(SJ->OM.allocBytes(J.length())); ScillaTypes::String Ret = {Mem, static_cast(J.length())}; std::memcpy(Mem, J.data(), J.length()); return Ret; } -ScillaTypes::String _to_ascii(ScillaJIT *SJ, const uint8_t *S, int L) { +ScillaTypes::String _to_ascii(ScillaExecImpl *SJ, const uint8_t *S, int L) { if (!ScillaValues::validateStringLiteral(S, L)) { SCILLA_EXCEPTION("String literal not printable"); } - auto Mem = reinterpret_cast(SJ->OM->allocBytes(L)); + auto Mem = reinterpret_cast(SJ->OM.allocBytes(L)); ScillaTypes::String Ret = {Mem, static_cast(L)}; std::memcpy(Mem, S, L); return Ret; } -void *_bystr_to_bystrx(ScillaJIT *SJ, int X, ScillaTypes::String Str) { +void *_bystr_to_bystrx(ScillaExecImpl *SJ, int X, ScillaTypes::String Str) { if (X != Str.m_length) { // Wrap with Scilla object "None", which has only a Tag. int MemSize = 1; - auto Mem = reinterpret_cast(SJ->OM->allocBytes(MemSize)); + auto Mem = reinterpret_cast(SJ->OM.allocBytes(MemSize)); *Mem = ScillaTypes::Option_None_Tag; return Mem; } // Wrap with "Some". // Allocate memory for "Some" = sizeOf (ValT) + 1 byte for Tag. int MemSize = X + 1; - auto Mem = reinterpret_cast(SJ->OM->allocBytes(MemSize)); + auto Mem = reinterpret_cast(SJ->OM.allocBytes(MemSize)); *Mem = ScillaTypes::Option_Some_Tag; // Create Scilla value from JSON and place it in Mem + 1. // i.e., We are constructing a Scilla "Some" object overall. @@ -666,7 +598,7 @@ void *_bystr_to_bystrx(ScillaJIT *SJ, int X, ScillaTypes::String Str) { return Mem; } -uint8_t *_bech32_to_bystr20(ScillaJIT *SJ, ScillaTypes::String Prefix, +uint8_t *_bech32_to_bystr20(ScillaExecImpl *SJ, ScillaTypes::String Prefix, ScillaTypes::String Addr) { std::string PrefixS(reinterpret_cast(Prefix.m_buffer), @@ -684,7 +616,7 @@ uint8_t *_bech32_to_bystr20(ScillaJIT *SJ, ScillaTypes::String Prefix, size_t ProgSize; // We allocate an extra byte for the ADT tag we want to return. - auto Mem = reinterpret_cast(SJ->OM->allocBytes(ProgBufSize + 1)); + auto Mem = reinterpret_cast(SJ->OM.allocBytes(ProgBufSize + 1)); if (bech32_addr_decode(Mem + 1, &ProgSize, reinterpret_cast(PrefixS.c_str()), reinterpret_cast(AddrS.c_str()))) { @@ -702,7 +634,7 @@ uint8_t *_bech32_to_bystr20(ScillaJIT *SJ, ScillaTypes::String Prefix, } } -void *_bystr20_to_bech32(ScillaJIT *SJ, ScillaTypes::String Prefix, +void *_bystr20_to_bech32(ScillaExecImpl *SJ, ScillaTypes::String Prefix, uint8_t *Addr20) { std::string PrefixS(reinterpret_cast(Prefix.m_buffer), @@ -716,7 +648,7 @@ void *_bystr20_to_bech32(ScillaJIT *SJ, ScillaTypes::String Prefix, const int OutputBufSize = 73 + strlen("zil"); const size_t ProgLen = 20; - auto OutputBuf = reinterpret_cast(SJ->OM->allocBytes(OutputBufSize)); + auto OutputBuf = reinterpret_cast(SJ->OM.allocBytes(OutputBufSize)); if (bech32_addr_encode(OutputBuf, reinterpret_cast(PrefixS.c_str()), Addr20, ProgLen)) { @@ -730,7 +662,7 @@ void *_bystr20_to_bech32(ScillaJIT *SJ, ScillaTypes::String Prefix, } // Allocate ScillaTypes::String in an Option type to return. auto Mem = reinterpret_cast( - SJ->OM->allocBytes(sizeof(ScillaTypes::String) + 1)); + SJ->OM.allocBytes(sizeof(ScillaTypes::String) + 1)); auto OutputString = reinterpret_cast(Mem + 1); *Mem = ScillaTypes::Option_Some_Tag; OutputString->m_buffer = reinterpret_cast(OutputBuf); @@ -744,79 +676,79 @@ void *_bystr20_to_bech32(ScillaJIT *SJ, ScillaTypes::String Prefix, } } -void *_uint32_to_bystrx(ScillaJIT *SJ, ScillaTypes::Uint32 I) { +void *_uint32_to_bystrx(ScillaExecImpl *SJ, ScillaTypes::Uint32 I) { return uintToByStrX<32>(SJ, I); } -void *_uint64_to_bystrx(ScillaJIT *SJ, ScillaTypes::Uint64 I) { +void *_uint64_to_bystrx(ScillaExecImpl *SJ, ScillaTypes::Uint64 I) { return uintToByStrX<64>(SJ, I); } -void *_uint128_to_bystrx(ScillaJIT *SJ, ScillaTypes::Uint128 I) { +void *_uint128_to_bystrx(ScillaExecImpl *SJ, ScillaTypes::Uint128 I) { return uintToByStrX<128>(SJ, I); } -void *_uint256_to_bystrx(ScillaJIT *SJ, ScillaTypes::Uint256 *I) { +void *_uint256_to_bystrx(ScillaExecImpl *SJ, ScillaTypes::Uint256 *I) { return uintToByStrX<256>(SJ, *I); } -ScillaTypes::Uint32 _bystrx_to_uint32(ScillaJIT *, int X, void *BS) { +ScillaTypes::Uint32 _bystrx_to_uint32(ScillaExecImpl *, int X, void *BS) { ScillaTypes::Uint32 Ret; byStrXToUint(Ret, BS, X); return Ret; } -ScillaTypes::Uint64 _bystrx_to_uint64(ScillaJIT *, int X, void *BS) { +ScillaTypes::Uint64 _bystrx_to_uint64(ScillaExecImpl *, int X, void *BS) { ScillaTypes::Uint64 Ret; byStrXToUint(Ret, BS, X); return Ret; } -ScillaTypes::Uint128 _bystrx_to_uint128(ScillaJIT *, int X, void *BS) { +ScillaTypes::Uint128 _bystrx_to_uint128(ScillaExecImpl *, int X, void *BS) { ScillaTypes::Uint128 Ret; byStrXToUint(Ret, BS, X); return Ret; } -ScillaTypes::Uint256 *_bystrx_to_uint256(ScillaJIT *SJ, int X, void *BS) { +ScillaTypes::Uint256 *_bystrx_to_uint256(ScillaExecImpl *SJ, int X, void *BS) { auto *Ret = reinterpret_cast( - SJ->OM->allocBytes(sizeof(ScillaTypes::Uint256))); + SJ->OM.allocBytes(sizeof(ScillaTypes::Uint256))); byStrXToUint(*Ret, BS, X); return Ret; } -void *_sha256hash(ScillaJIT *SJ, const ScillaTypes::Typ *T, void *V) { +void *_sha256hash(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, void *V) { ByteVec Serialized; auto *Buf = - reinterpret_cast(SJ->OM->allocBytes(SHA256_DIGEST_LENGTH)); + reinterpret_cast(SJ->OM.allocBytes(SHA256_DIGEST_LENGTH)); ScillaValues::serializeForHashing(Serialized, T, V); SHA256(Serialized.data(), Serialized.size(), Buf); return Buf; } -void *_keccak256hash(ScillaJIT *SJ, const ScillaTypes::Typ *T, void *V) { +void *_keccak256hash(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, void *V) { ByteVec Serialized; const auto HashLength = sizeof(ethash_hash256); - auto *Buf = reinterpret_cast(SJ->OM->allocBytes(HashLength)); + auto *Buf = reinterpret_cast(SJ->OM.allocBytes(HashLength)); ScillaValues::serializeForHashing(Serialized, T, V); auto H = ethash_keccak256(Serialized.data(), Serialized.size()); std::memcpy(Buf, H.bytes, HashLength); return Buf; } -void *_ripemd160hash(ScillaJIT *SJ, const ScillaTypes::Typ *T, void *V) { +void *_ripemd160hash(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, void *V) { ByteVec Serialized; auto *Buf = - reinterpret_cast(SJ->OM->allocBytes(RIPEMD160_DIGEST_LENGTH)); + reinterpret_cast(SJ->OM.allocBytes(RIPEMD160_DIGEST_LENGTH)); ScillaValues::serializeForHashing(Serialized, T, V); RIPEMD160(Serialized.data(), Serialized.size(), Buf); return Buf; } -uint8_t *_schnorr_verify(ScillaJIT *SJ, uint8_t *PubK, ScillaTypes::String Msg, - uint8_t *Sign) { +uint8_t *_schnorr_verify(ScillaExecImpl *SJ, uint8_t *PubK, + ScillaTypes::String Msg, uint8_t *Sign) { ASSERT(Schnorr::PUBKEY_COMPRESSED_SIZE_BYTES == Schnorr_Pubkey_Len); std::vector PubK_Vec(PubK, PubK + Schnorr_Pubkey_Len); PubKey PK(PubK_Vec, 0); @@ -828,23 +760,23 @@ uint8_t *_schnorr_verify(ScillaJIT *SJ, uint8_t *PubK, ScillaTypes::String Msg, auto Res = Schnorr::Verify(M, S, PK); - return toScillaBool(*(SJ->OM), Res); + return toScillaBool(SJ->OM, Res); } -uint8_t *_schnorr_get_address(ScillaJIT *SJ, uint8_t *PubK) { +uint8_t *_schnorr_get_address(ScillaExecImpl *SJ, uint8_t *PubK) { static_assert(SHA256_DIGEST_LENGTH > Zilliqa_Address_Len, "Can't extract Zilliqa address from hash of public key"); // Hash PubK and extract the lower Zilliqa_Address_Len bytes. uint8_t *Buf = - reinterpret_cast(SJ->OM->allocBytes(SHA256_DIGEST_LENGTH)); + reinterpret_cast(SJ->OM.allocBytes(SHA256_DIGEST_LENGTH)); SHA256(PubK, Schnorr_Pubkey_Len, Buf); return (Buf + (SHA256_DIGEST_LENGTH - Zilliqa_Address_Len)); } -uint8_t *_ecdsa_verify(ScillaJIT *SJ, uint8_t *PubK, ScillaTypes::String Msg, - uint8_t *Sign) { +uint8_t *_ecdsa_verify(ScillaExecImpl *SJ, uint8_t *PubK, + ScillaTypes::String Msg, uint8_t *Sign) { secp256k1_pubkey PK; if (!secp256k1_ec_pubkey_parse(SecpCtx.Ctx, &PK, PubK, Ecdsa_Pubkey_Len)) { SCILLA_EXCEPTION("Error parsing ECDSA public key"); @@ -859,10 +791,10 @@ uint8_t *_ecdsa_verify(ScillaJIT *SJ, uint8_t *PubK, ScillaTypes::String Msg, auto Res = static_cast( secp256k1_ecdsa_verify(SecpCtx.Ctx, &Sig, MsgHash, &PK)); - return toScillaBool(*(SJ->OM), Res); + return toScillaBool(SJ->OM, Res); } -uint8_t *_ecdsa_recover_pk(ScillaJIT *SJ, ScillaTypes::String Msg, +uint8_t *_ecdsa_recover_pk(ScillaExecImpl *SJ, ScillaTypes::String Msg, uint8_t *Sign, ScillaTypes::Uint32 RecID) { auto RI = *reinterpret_cast(&RecID); @@ -882,7 +814,7 @@ uint8_t *_ecdsa_recover_pk(ScillaJIT *SJ, ScillaTypes::String Msg, } uint8_t *Buf = reinterpret_cast( - SJ->OM->allocBytes(Ecdsa_Pubkey_Uncompressed_Len)); + SJ->OM.allocBytes(Ecdsa_Pubkey_Uncompressed_Len)); size_t BufLen = Ecdsa_Pubkey_Uncompressed_Len; secp256k1_ec_pubkey_serialize(SecpCtx.Ctx, Buf, &BufLen, &PK, SECP256K1_EC_UNCOMPRESSED); @@ -894,27 +826,27 @@ uint8_t *_ecdsa_recover_pk(ScillaJIT *SJ, ScillaTypes::String Msg, return Buf; } -ScillaTypes::String _concat_String(ScillaJIT *SJ, ScillaTypes::String Lhs, +ScillaTypes::String _concat_String(ScillaExecImpl *SJ, ScillaTypes::String Lhs, ScillaTypes::String Rhs) { ScillaTypes::String Ret; Ret.m_length = Lhs.m_length + Rhs.m_length; - auto Buf = reinterpret_cast(SJ->OM->allocBytes(Ret.m_length)); + auto Buf = reinterpret_cast(SJ->OM.allocBytes(Ret.m_length)); std::memcpy(Buf, Lhs.m_buffer, Lhs.m_length); std::memcpy(Buf + Lhs.m_length, Rhs.m_buffer, Rhs.m_length); Ret.m_buffer = Buf; return Ret; } -ScillaTypes::String _concat_ByStr(ScillaJIT *SJ, ScillaTypes::String Lhs, +ScillaTypes::String _concat_ByStr(ScillaExecImpl *SJ, ScillaTypes::String Lhs, ScillaTypes::String Rhs) { return _concat_String(SJ, Lhs, Rhs); } -void *_concat_ByStrX(ScillaJIT *SJ, int X1, uint8_t *Lhs, int X2, +void *_concat_ByStrX(ScillaExecImpl *SJ, int X1, uint8_t *Lhs, int X2, uint8_t *Rhs) { - auto *Buf = reinterpret_cast(SJ->OM->allocBytes(X1 + X2)); + auto *Buf = reinterpret_cast(SJ->OM.allocBytes(X1 + X2)); std::memcpy(Buf, Lhs, X1); std::memcpy(Buf + X1, Rhs, X2); return Buf; @@ -933,7 +865,7 @@ ScillaTypes::Uint32 _strlen_ByStr(ScillaTypes::String Str) { return _strlen_String(Str); } -ScillaTypes::String _substr_String(ScillaJIT *SJ, ScillaTypes::String Str, +ScillaTypes::String _substr_String(ScillaExecImpl *SJ, ScillaTypes::String Str, ScillaTypes::Uint32 Pos, ScillaTypes::Uint32 Len) { @@ -946,28 +878,28 @@ ScillaTypes::String _substr_String(ScillaJIT *SJ, ScillaTypes::String Str, ScillaTypes::String Ret; Ret.m_length = LenUI; - auto Buf = reinterpret_cast(SJ->OM->allocBytes(LenUI)); + auto Buf = reinterpret_cast(SJ->OM.allocBytes(LenUI)); std::memcpy(Buf, Str.m_buffer + PosUI, LenUI); Ret.m_buffer = Buf; return Ret; } -ScillaTypes::String _substr_ByStr(ScillaJIT *SJ, ScillaTypes::String Str, +ScillaTypes::String _substr_ByStr(ScillaExecImpl *SJ, ScillaTypes::String Str, ScillaTypes::Uint32 Pos, ScillaTypes::Uint32 Len) { return _substr_String(SJ, Str, Pos, Len); } -void _accept(ScillaJIT *SJ) { SJ->TS->processAccept(); } +void _accept(ScillaExecImpl *SJ) { SJ->TS->processAccept(); } -ScillaParams::MapValueT *_new_empty_map(ScillaJIT *SJ) { - return SJ->OM->create(); +ScillaParams::MapValueT *_new_empty_map(ScillaExecImpl *SJ) { + return SJ->OM.create(); } -ScillaParams::MapValueT *_put(ScillaJIT *SJ, const ScillaTypes::Typ *T, +ScillaParams::MapValueT *_put(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, ScillaParams::MapValueT *M, void *K, void *V) { - auto NewM = SJ->OM->create(*M); + auto NewM = SJ->OM.create(*M); switch (T->m_t) { case ScillaTypes::Typ::Map_typ: { @@ -993,7 +925,7 @@ ScillaParams::MapValueT *_put(ScillaJIT *SJ, const ScillaTypes::Typ *T, return NewM; } -void *_get(ScillaJIT *SJ, const ScillaTypes::Typ *T, +void *_get(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, const ScillaParams::MapValueT *M, const void *K) { ASSERT(T->m_t == ScillaTypes::Typ::Map_typ); @@ -1006,26 +938,26 @@ void *_get(ScillaJIT *SJ, const ScillaTypes::Typ *T, const boost::any Dummy; const boost::any &Val = Found ? Itr->second : Dummy; // Wrap with "Option". - return wrapMapAccessResult(*(SJ->OM), Found, Val, ValT); + return wrapMapAccessResult(SJ->OM, Found, Val, ValT); } -void *_contains(ScillaJIT *SJ, const ScillaTypes::Typ *T, +void *_contains(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, const ScillaParams::MapValueT *M, const void *K) { ASSERT(T->m_t == ScillaTypes::Typ::Map_typ); auto *KeyT = T->m_sub.m_mapt->m_keyTyp; auto KeyS = serializeJSON(ScillaValues::toJSON(KeyT, K)); auto Itr = M->find(KeyS); - return toScillaBool(*(SJ->OM), Itr != M->end()); + return toScillaBool(SJ->OM, Itr != M->end()); } -void *_remove(ScillaJIT *SJ, const ScillaTypes::Typ *T, +void *_remove(ScillaExecImpl *SJ, const ScillaTypes::Typ *T, const ScillaParams::MapValueT *M, const void *K) { ASSERT(T->m_t == ScillaTypes::Typ::Map_typ); auto *KeyT = T->m_sub.m_mapt->m_keyTyp; auto KeyS = serializeJSON(ScillaValues::toJSON(KeyT, K)); - auto NewM = SJ->OM->create(*M); + auto NewM = SJ->OM.create(*M); NewM->erase(KeyS); return NewM; } diff --git a/libsrtl/ScillaBuiltins.h b/libsrtl/ScillaBuiltins.h index 28f684c6..d9251bc8 100644 --- a/libsrtl/ScillaBuiltins.h +++ b/libsrtl/ScillaBuiltins.h @@ -21,19 +21,14 @@ * Scilla contract. It is not intended to be called from other C++ * code, and is therefore not a public header. */ +#include "ScillaVM/ScillaExec.h" + #include "SafeInt.h" #include "ScillaTypes.h" -#include "ScillaVM/JITD.h" #include "ScillaValue.h" namespace ScillaVM { -struct ScillaFunctionsMap { - const char *FName; - const void *FAddr; -}; -std::vector getAllScillaBuiltins(void); - // Values that begin with a transition and change as it executes. class TransitionState { SafeUint128 Balance; @@ -70,7 +65,7 @@ extern "C" { void _print_scilla_val(const ScillaVM::ScillaTypes::Typ *T, void *V); // Allocate memory for JIT code owned by @SJ -void *_salloc(ScillaVM::ScillaJIT *SJ, size_t size); +void *_salloc(ScillaVM::ScillaExecImpl *SJ, size_t size); // Handler for out-of-gas during execution void _out_of_gas(); @@ -78,20 +73,20 @@ void _out_of_gas(); // Fetch field @Name whose type is @T. For map accesses, FetchVal can be false, // to indicate that the return value is a Scilla `Bool`, indicating found or // not. -void *_fetch_field(ScillaVM::ScillaJIT *SJ, const char *Name, +void *_fetch_field(ScillaVM::ScillaExecImpl *SJ, const char *Name, const ScillaVM::ScillaTypes::Typ *T, int32_t NumIdx, const uint8_t *Indices, int32_t FetchVal); // Same as _fetch_field, but with an address parameter. void * -_fetch_remote_field(ScillaVM::ScillaJIT *SJ, +_fetch_remote_field(ScillaVM::ScillaExecImpl *SJ, const uint8_t Addr[ScillaVM::ScillaTypes::AddrByStr_Len], const char *Name, const ScillaVM::ScillaTypes::Typ *T, int32_t NumIdx, const uint8_t *Indices, int32_t FetchVal); // Update field @Name whose type is @T with value @Val. If Val is nullptr, // then this is a map update and the keys must be deleted. -void _update_field(ScillaVM::ScillaJIT *SJ, const char *Name, +void _update_field(ScillaVM::ScillaExecImpl *SJ, const char *Name, const ScillaVM::ScillaTypes::Typ *, int32_t NumIdx, const uint8_t *Indices, void *Val); @@ -102,7 +97,7 @@ ScillaVM::ScillaTypes::Int64 _add_Int64(ScillaVM::ScillaTypes::Int64, ScillaVM::ScillaTypes::Int64); ScillaVM::ScillaTypes::Int128 _add_Int128(ScillaVM::ScillaTypes::Int128, ScillaVM::ScillaTypes::Int128); -ScillaVM::ScillaTypes::Int256 *_add_Int256(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::Int256 *_add_Int256(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Int256 *Lhs, ScillaVM::ScillaTypes::Int256 *Rhs); @@ -113,132 +108,141 @@ ScillaVM::ScillaTypes::Uint64 _add_Uint64(ScillaVM::ScillaTypes::Uint64, ScillaVM::ScillaTypes::Uint128 _add_Uint128(ScillaVM::ScillaTypes::Uint128, ScillaVM::ScillaTypes::Uint128); ScillaVM::ScillaTypes::Uint256 * -_add_Uint256(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Uint256 *Lhs, +_add_Uint256(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint256 *Lhs, ScillaVM::ScillaTypes::Uint256 *Rhs); -uint8_t *_eq_Int32(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Int32 Lhs, +uint8_t *_eq_Int32(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::Int32 Lhs, ScillaVM::ScillaTypes::Int32 Rhs); -uint8_t *_eq_Int64(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Int64 Lhs, +uint8_t *_eq_Int64(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::Int64 Lhs, ScillaVM::ScillaTypes::Int64 Rhs); -uint8_t *_eq_Int128(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Int128 Lhs, +uint8_t *_eq_Int128(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::Int128 Lhs, ScillaVM::ScillaTypes::Int128 Rhs); -uint8_t *_eq_Int256(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Int256 *Lhs, +uint8_t *_eq_Int256(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::Int256 *Lhs, ScillaVM::ScillaTypes::Int256 *Rhs); -uint8_t *_eq_Uint32(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Uint32 Lhs, +uint8_t *_eq_Uint32(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::Uint32 Lhs, ScillaVM::ScillaTypes::Uint32 Rhs); -uint8_t *_eq_Uint64(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Uint64 Lhs, +uint8_t *_eq_Uint64(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::Uint64 Lhs, ScillaVM::ScillaTypes::Uint64 Rhs); -uint8_t *_eq_Uint128(ScillaVM::ScillaJIT *SJ, +uint8_t *_eq_Uint128(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint128 Lhs, ScillaVM::ScillaTypes::Uint128 Rhs); -uint8_t *_eq_Uint256(ScillaVM::ScillaJIT *SJ, +uint8_t *_eq_Uint256(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint256 *Lhs, ScillaVM::ScillaTypes::Uint256 *Rhs); -void *_to_nat(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Uint32 UI); +void *_to_nat(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint32 UI); -void _send(ScillaVM::ScillaJIT *SJ, const ScillaVM::ScillaTypes::Typ *T, +void _send(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, const void *V); -void _event(ScillaVM::ScillaJIT *SJ, const ScillaVM::ScillaTypes::Typ *T, +void _event(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, const void *V); -void _throw(ScillaVM::ScillaJIT *SJ, const ScillaVM::ScillaTypes::Typ *T, +void _throw(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, const void *V); -uint8_t *_eq_String(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::String Lhs, +uint8_t *_eq_String(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::String Lhs, ScillaVM::ScillaTypes::String Rhs); -uint8_t *_eq_ByStr(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::String Lhs, +uint8_t *_eq_ByStr(ScillaVM::ScillaExecImpl *SJ, + ScillaVM::ScillaTypes::String Lhs, ScillaVM::ScillaTypes::String Rhs); -uint8_t *_eq_ByStrX(ScillaVM::ScillaJIT *SJ, int X, uint8_t *Lhs, uint8_t *Rhs); +uint8_t *_eq_ByStrX(ScillaVM::ScillaExecImpl *SJ, int X, uint8_t *Lhs, + uint8_t *Rhs); -ScillaVM::ScillaTypes::String _to_bystr(ScillaVM::ScillaJIT *SJ, int X, +ScillaVM::ScillaTypes::String _to_bystr(ScillaVM::ScillaExecImpl *SJ, int X, uint8_t *Buf); -ScillaVM::ScillaTypes::String _to_string(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::String _to_string(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, const void *V); -ScillaVM::ScillaTypes::String _to_ascii(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::String _to_ascii(ScillaVM::ScillaExecImpl *SJ, const uint8_t *S, int L); -void *_bystr_to_bystrx(ScillaVM::ScillaJIT *SJ, int X, +void *_bystr_to_bystrx(ScillaVM::ScillaExecImpl *SJ, int X, ScillaVM::ScillaTypes::String Str); -uint8_t *_bech32_to_bystr20(ScillaVM::ScillaJIT *SJ, +uint8_t *_bech32_to_bystr20(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::String Prefix, ScillaVM::ScillaTypes::String Addr); -void *_bystr20_to_bech32(ScillaVM::ScillaJIT *SJ, +void *_bystr20_to_bech32(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::String Prefix, uint8_t *Addr20); -void *_uint32_to_bystrx(ScillaVM::ScillaJIT *SJ, +void *_uint32_to_bystrx(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint32 I); -void *_uint64_to_bystrx(ScillaVM::ScillaJIT *SJ, +void *_uint64_to_bystrx(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint64 I); -void *_uint128_to_bystrx(ScillaVM::ScillaJIT *SJ, +void *_uint128_to_bystrx(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint128 I); -void *_uint256_to_bystrx(ScillaVM::ScillaJIT *SJ, +void *_uint256_to_bystrx(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint256 *I); -ScillaVM::ScillaTypes::Uint32 _bystrx_to_uint32(ScillaVM::ScillaJIT *, int X, - void *BS); -ScillaVM::ScillaTypes::Uint64 _bystrx_to_uint64(ScillaVM::ScillaJIT *, int X, - void *BS); -ScillaVM::ScillaTypes::Uint128 _bystrx_to_uint128(ScillaVM::ScillaJIT *, int X, - void *BS); -ScillaVM::ScillaTypes::Uint256 *_bystrx_to_uint256(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::Uint32 _bystrx_to_uint32(ScillaVM::ScillaExecImpl *, + int X, void *BS); +ScillaVM::ScillaTypes::Uint64 _bystrx_to_uint64(ScillaVM::ScillaExecImpl *, + int X, void *BS); +ScillaVM::ScillaTypes::Uint128 _bystrx_to_uint128(ScillaVM::ScillaExecImpl *, + int X, void *BS); +ScillaVM::ScillaTypes::Uint256 *_bystrx_to_uint256(ScillaVM::ScillaExecImpl *SJ, int X, void *BS); -void *_sha256hash(ScillaVM::ScillaJIT *SJ, const ScillaVM::ScillaTypes::Typ *T, - void *V); +void *_sha256hash(ScillaVM::ScillaExecImpl *SJ, + const ScillaVM::ScillaTypes::Typ *T, void *V); -void *_keccak256hash(ScillaVM::ScillaJIT *SJ, +void *_keccak256hash(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, void *V); -void *_ripemd160hash(ScillaVM::ScillaJIT *SJ, +void *_ripemd160hash(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, void *V); -uint8_t *_schnorr_verify(ScillaVM::ScillaJIT *SJ, uint8_t *PubK, +uint8_t *_schnorr_verify(ScillaVM::ScillaExecImpl *SJ, uint8_t *PubK, ScillaVM::ScillaTypes::String Msg, uint8_t *Sign); -uint8_t *_schnorr_get_address(ScillaVM::ScillaJIT *SJ, uint8_t *PubK); +uint8_t *_schnorr_get_address(ScillaVM::ScillaExecImpl *SJ, uint8_t *PubK); -uint8_t *_ecdsa_verify(ScillaVM::ScillaJIT *SJ, uint8_t *PubK, +uint8_t *_ecdsa_verify(ScillaVM::ScillaExecImpl *SJ, uint8_t *PubK, ScillaVM::ScillaTypes::String Msg, uint8_t *Sign); -uint8_t *_ecdsa_recover_pk(ScillaVM::ScillaJIT *SJ, +uint8_t *_ecdsa_recover_pk(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::String Msg, uint8_t *Sign, ScillaVM::ScillaTypes::Uint32 RecID); -ScillaVM::ScillaTypes::String _concat_String(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::String _concat_String(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::String Lhs, ScillaVM::ScillaTypes::String Rhs); -ScillaVM::ScillaTypes::String _concat_ByStr(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::String _concat_ByStr(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::String Lhs, ScillaVM::ScillaTypes::String Rhs); -void *_concat_ByStrX(ScillaVM::ScillaJIT *SJ, int X1, uint8_t *Lhs, int X2, +void *_concat_ByStrX(ScillaVM::ScillaExecImpl *SJ, int X1, uint8_t *Lhs, int X2, uint8_t *Rhs); -ScillaVM::ScillaTypes::String _substr_String(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::String _substr_String(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::String Str, ScillaVM::ScillaTypes::Uint32 Pos, ScillaVM::ScillaTypes::Uint32 Len); -ScillaVM::ScillaTypes::String _substr_ByStr(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaTypes::String _substr_ByStr(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::String Str, ScillaVM::ScillaTypes::Uint32 Pos, ScillaVM::ScillaTypes::Uint32 Len); @@ -246,19 +250,20 @@ ScillaVM::ScillaTypes::String _substr_ByStr(ScillaVM::ScillaJIT *SJ, ScillaVM::ScillaTypes::Uint32 _strlen_String(ScillaVM::ScillaTypes::String Str); ScillaVM::ScillaTypes::Uint32 _strlen_ByStr(ScillaVM::ScillaTypes::String Str); -void _accept(ScillaVM::ScillaJIT *SJ); +void _accept(ScillaVM::ScillaExecImpl *SJ); -ScillaVM::ScillaParams::MapValueT *_new_empty_map(ScillaVM::ScillaJIT *SJ); -ScillaVM::ScillaParams::MapValueT *_put(ScillaVM::ScillaJIT *SJ, +ScillaVM::ScillaParams::MapValueT *_new_empty_map(ScillaVM::ScillaExecImpl *SJ); +ScillaVM::ScillaParams::MapValueT *_put(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, ScillaVM::ScillaParams::MapValueT *M, void *K, void *V); -void *_get(ScillaVM::ScillaJIT *SJ, const ScillaVM::ScillaTypes::Typ *T, +void *_get(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, const ScillaVM::ScillaParams::MapValueT *M, const void *K); -void *_contains(ScillaVM::ScillaJIT *SJ, const ScillaVM::ScillaTypes::Typ *T, +void *_contains(ScillaVM::ScillaExecImpl *SJ, + const ScillaVM::ScillaTypes::Typ *T, const ScillaVM::ScillaParams::MapValueT *M, const void *K); -void *_remove(ScillaVM::ScillaJIT *SJ, const ScillaVM::ScillaTypes::Typ *T, +void *_remove(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, const ScillaVM::ScillaParams::MapValueT *M, const void *K); // Scilla builtin _size : The size of a map. diff --git a/libsrtl/ScillaExecImpl.cpp b/libsrtl/ScillaExecImpl.cpp new file mode 100644 index 00000000..9a4dfbe6 --- /dev/null +++ b/libsrtl/ScillaExecImpl.cpp @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2019 Zilliqa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "ScillaVM/Debug.h" +#include "ScillaVM/Errors.h" +#include "ScillaVM/ScillaExec.h" + +#include "ObjManager.h" +#include "SRTL.h" +#include "ScillaBuiltins.h" +#include "ScillaExecImpl.h" +#include "ScillaTypes.h" +#include "SharedObject.h" + +namespace ScillaVM { + +ScillaContrExec::~ScillaContrExec() = default; + +ScillaContrExec::ScillaContrExec(const ScillaParams &SPs, + const std::string &ContrBin) { + PImpl = std::make_unique(SPs, ContrBin); +} + +Json::Value ScillaContrExec::execMsg(const std::string &Balance, + uint64_t GasLimit, + const Json::Value &InitJ, + const Json::Value &Msg) { + return PImpl->execMsg(Balance, GasLimit, InitJ, Msg); +} + +Json::Value ScillaContrExec::deploy(const Json::Value &InitJ, + uint64_t GasLimit) { + return PImpl->deploy(InitJ, GasLimit); +} + +uint64_t ScillaContrExec::getGasRem() const { return PImpl->getGasRem(); } + +ScillaExprExec::~ScillaExprExec() = default; + +ScillaExprExec::ScillaExprExec(const ScillaParams &SPs, + const std::string &ExprBin) { + PImpl = std::make_unique(SPs, ExprBin); +} + +std::string ScillaExprExec::exec(uint64_t GasLimit) { + auto ScillaMainAddr = PImpl->getAddressFor("scilla_main"); + auto ScillaMain = reinterpret_cast(ScillaMainAddr); + // Set gas available in the JIT'ed code and then initialize libraries. + PImpl->initGasAndLibs(GasLimit); + // Clear the output. + ScillaStdout.clear(); + ScillaMain(); + // Collect and print the remaining gas. + ScillaStdout += "Gas remaining: " + std::to_string(PImpl->getGasRem()) + "\n"; + PImpl->OM.deleteAll(); + return ScillaStdout; +} + +uint64_t ScillaExprExec::getGasRem() const { return PImpl->getGasRem(); } + +ScillaExecImpl::ScillaExecImpl(const ScillaParams &SPs, + const std::string &ContrBin) + : SPs(SPs) { + + SO = std::make_unique(ContrBin); + + // Set execptr in the generated code to THIS + auto ExecPtr = getAddressFor("_execptr"); + *reinterpret_cast(ExecPtr) = this; +} + +ScillaExecImpl::~ScillaExecImpl() = default; + +void ScillaExecImpl::initContrParams(const Json::Value &CP, + bool DoDynamicTypechecks) { + + // First get the name and types of contract parameters. + auto CParams = reinterpret_cast( + getAddressFor("_contract_parameters")); + auto NCParams = *reinterpret_cast( + getAddressFor("_contract_parameters_length")); + + auto ErrMsg = "Invalid init JSON when initializing contract parameters"; + if (!CP.isArray()) { + CREATE_ERROR(ErrMsg); + } + + // TODO: Remove this when BNum types are supported. + uint32_t CPSize = std::accumulate( + CP.begin(), CP.end(), 0, [](uint32_t Acc, const Json::Value &IV) { + const Json::Value &VName = IV["vname"]; + return Acc + (VName.isString() && VName.asString() == "_creation_block" + ? 0 + : 1); + }); + + if (CPSize != NCParams) { + CREATE_ERROR("Expected " + std::to_string(NCParams) + + " contract parameters, but got " + std::to_string(CPSize)); + } + // Let's put the expected contract parameters into a map for fast access. + std::unordered_map ParamMap; + std::for_each(CParams, CParams + NCParams, + [&ParamMap](const ScillaTypes::ParamDescr &PD) { + ParamMap[std::string(PD.m_PName)] = PD.m_PTy; + }); + + for (const auto &PJ : CP) { + if (!PJ.isObject()) { + CREATE_ERROR(ErrMsg); + } + auto &VName = PJ["vname"]; + auto &Type = PJ["type"]; + auto &Value = PJ["value"]; + if (!VName.isString() || !Type.isString() || Value.isNull()) { + CREATE_ERROR(ErrMsg); + } + + // TODO: The compiler doesn't yet support BNum types. + if (VName.asString() == "_creation_block") + continue; + + auto ExpectedT = ParamMap.find(VName.asString()); + if (ExpectedT == ParamMap.end()) { + CREATE_ERROR("Unknown contract parameter in JSON " + VName.asString()); + } + auto *T = parseTypeString(Type.asString()); + // Before we parse the value into memory (which is already allocated + // and of fixed length), ensure that the value is safe. + if (!ScillaTypes::Typ::valueCompatible(T, ExpectedT->second)) { + CREATE_ERROR(VName.asString() + ": Type " + + ScillaTypes::Typ::toString(T) + + " is incompatible with type " + + ScillaTypes::Typ::toString(ExpectedT->second) + + " specified in the contract."); + } + void *P = (getAddressFor(VName.asString())); + void *ValP; + if (ScillaTypes::Typ::isBoxed(T)) { + // Boxed types are just pointers. + ValP = ScillaValues::fromJSON(OM, T, Value); + *reinterpret_cast(P) = ValP; + } else { + ValP = P; + // We create the ScillaValue in place. + ScillaValues::fromJSONToMem(OM, ValP, ScillaTypes::Typ::sizeOf(T), T, + Value); + } + if (DoDynamicTypechecks && + !dynamicTypecheck(this, ExpectedT->second, T, ValP)) { + CREATE_ERROR("Dynamic typecheck failed: " + VName.asString()); + } + } +} + +uint64_t *ScillaExecImpl::initGasAndLibs(uint64_t GasLimit) { + // Set gas limit in the JIT'ed code module. + auto GasRemPtr = reinterpret_cast(getAddressFor("_gasrem")); + *GasRemPtr = GasLimit; + + // Call the library initialisation function. + auto initLibs = reinterpret_cast(getAddressFor("_init_libs")); + initLibs(); + + return GasRemPtr; +} + +Json::Value ScillaExecImpl::deploy(const Json::Value &InitJ, + uint64_t GasLimit) { + + // Initialize contract parameters. + initContrParams(InitJ, true /* DoDynamicTypechecks */); + + auto GasRemPtr = initGasAndLibs(GasLimit); + + // Let's setup the TransitionState for this transition. + TS = std::make_unique("0", "0", GasRemPtr); + auto fIS = reinterpret_cast(getAddressFor("_init_state")); + fIS(); + + Json::Value Result = TS->finalize(); + OM.deleteAll(); + return Result; +} + +uint64_t ScillaExecImpl::getGasRem() const { + return *reinterpret_cast(getAddressFor("_gasrem")); +} + +const ScillaTypes::Typ * +ScillaExecImpl::parseTypeString(const std::string &TStr) const { + auto TyDescrs = getTypeDescrTable(); + return ScillaTypes::Typ::fromString(TPPC.get(), TyDescrs.first, + TyDescrs.second, TStr); +} + +void *ScillaExecImpl::getAddressFor(const std::string &Symbol) const { + return SO->getAddressFor(Symbol); +} + +std::pair +ScillaExecImpl::getTypeDescrTable() const { + auto AllTyDescrs = reinterpret_cast( + getAddressFor("_tydescr_table")); + auto TyDescrsLen = + *reinterpret_cast(getAddressFor("_tydescr_table_length")); + return std::make_pair(AllTyDescrs, TyDescrsLen); +} + +Json::Value ScillaExecImpl::execMsg(const std::string &Balance, + uint64_t GasLimit, const Json::Value &InitJ, + const Json::Value &Msg) { + + initContrParams(InitJ, false /* DoDynamicTypechecks */); + + Json::Value TransNameJ = Msg.get("_tag", Json::nullValue); + Json::Value ParamsJ = Msg.get("params", Json::nullValue); + Json::Value OriginJ = Msg.get("_origin", Json::nullValue); + Json::Value SenderJ = Msg.get("_sender", Json::nullValue); + Json::Value AmountJ = Msg.get("_amount", Json::nullValue); + if (!TransNameJ.isString() || !ParamsJ.isArray() || !SenderJ.isString() || + !OriginJ.isString() || !AmountJ.isString()) + CREATE_ERROR("Invalid Message"); + + auto GasRemPtr = initGasAndLibs(GasLimit); + + // Let's setup the TransitionState for this transition. + TS = + std::make_unique(Balance, AmountJ.asString(), GasRemPtr); + + // Amount and Sender need to be prepended to the parameter list. + Json::Value AmountParam; + { + AmountParam["vname"] = "_amount"; + AmountParam["type"] = "Uint128"; + AmountParam["value"] = AmountJ; + } + Json::Value OriginParam; + { + OriginParam["vname"] = "_origin"; + OriginParam["type"] = "ByStr20"; + OriginParam["value"] = OriginJ; + } + Json::Value SenderParam; + { + SenderParam["vname"] = "_sender"; + SenderParam["type"] = "ByStr20"; + SenderParam["value"] = SenderJ; + } + std::vector AllParamsJ; + AllParamsJ.push_back(AmountParam); + AllParamsJ.push_back(OriginParam); + AllParamsJ.push_back(SenderParam); + AllParamsJ.insert(AllParamsJ.end(), ParamsJ.begin(), ParamsJ.end()); + + std::string TransName = TransNameJ.asString(); + auto Transition = + reinterpret_cast(getAddressFor(TransName)); + + // We have all transition paramters as per the JSON in AllParamsJ. + // Time to get the same info from the contract for corroboration. + auto TParams = reinterpret_cast( + getAddressFor("_transition_parameters")); + auto TCParams = *reinterpret_cast( + getAddressFor("_transition_parameters_length")); + // Note down all parameters of this transition. + const auto ThisTParams = + std::find_if(TParams, TParams + TCParams, + [&TransName](const ScillaTypes::TransDescr &TD) { + return std::string(TD.m_TName) == TransName; + }); + if (ThisTParams == TParams + TCParams) { + CREATE_ERROR("Unknown transition " + TransName); + } + ScillaTypes::ParamDescr *PD = ThisTParams->m_Params; + uint32_t NPD = ThisTParams->m_NParams; + if (NPD != AllParamsJ.size()) { + CREATE_ERROR("Incorrect number of parameters to transition " + TransName); + } + std::unordered_map TParamsMap; + std::for_each(PD, PD + NPD, [&TParamsMap](const ScillaTypes::ParamDescr &PD) { + TParamsMap[std::string(PD.m_PName)] = PD.m_PTy; + }); + + std::vector ParamNames; + std::vector ParamTypes; + std::vector ParamValues; + for (auto &P : AllParamsJ) { + Json::Value VNameJ, TypeJ, ValueJ; + if (!P.isObject() || + (VNameJ = P.get("vname", Json::nullValue)) == Json::nullValue || + (TypeJ = P.get("type", Json::nullValue)) == Json::nullValue || + (ValueJ = P.get("value", Json::nullValue)) == Json::nullValue || + !VNameJ.isString() || !TypeJ.isString()) { + CREATE_ERROR("Incorrect paramter format in message JSON."); + } + auto *T = parseTypeString(TypeJ.asString()); + ParamTypes.push_back(T); + ParamValues.push_back(ValueJ); + ParamNames.push_back(VNameJ.asString()); + } + int MemSize = std::accumulate(ParamTypes.begin(), ParamTypes.end(), 0, + [](int acc, const ScillaTypes::Typ *T) { + return acc + ScillaTypes::Typ::sizeOf(T); + }); + + ASSERT(MemSize > 0); + auto *Mem = reinterpret_cast(OM.allocBytes(MemSize)); + for (size_t I = 0, Off = 0; I < ParamTypes.size(); I++) { + const ScillaTypes::Typ *T = ParamTypes[I]; + int Size = ScillaTypes::Typ::sizeOf(T); + auto *ThisMemP = Mem + Off; + void *ValP; + if (ScillaTypes::Typ::isBoxed(T)) { + ValP = ScillaValues::fromJSON(OM, T, ParamValues[I]); + *reinterpret_cast(ThisMemP) = ValP; + } else { + ValP = ThisMemP; + ScillaValues::fromJSONToMem(OM, ValP, Size, T, ParamValues[I]); + } + auto ExpectedT = TParamsMap.find(ParamNames[I]); + if (ExpectedT == TParamsMap.end()) { + CREATE_ERROR("Unknown transition parameter " + ParamNames[I]); + } + // _sender and _origin are trusted addresses. Otherwise, we must verify. + if (ParamNames[I] != "_sender" && ParamNames[I] != "_origin" && + !dynamicTypecheck(this, ExpectedT->second, T, ValP)) { + CREATE_ERROR("Dyanamic typecheck failed: " + ParamNames[I]); + } + + Off += Size; + } + + Transition(Mem); + + Json::Value Result = TS->finalize(); + OM.deleteAll(); + return Result; +} + +} // namespace ScillaVM \ No newline at end of file diff --git a/libsrtl/ScillaExecImpl.h b/libsrtl/ScillaExecImpl.h new file mode 100644 index 00000000..52d76433 --- /dev/null +++ b/libsrtl/ScillaExecImpl.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2021 Zilliqa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "ObjManager.h" +#include "ScillaVM/ScillaExec.h" + +namespace ScillaVM { + +class SharedObject; +class TransitionState; + +class ScillaExecImpl { +private: + void initContrParams(const Json::Value &CP, bool DoDynamicTypechecks); + std::unique_ptr TPPC; + // Get the type descriptors table and its length. + std::pair getTypeDescrTable() const; + std::unique_ptr SO; + +public: + // @ContrBin is the path to a contract's shared object `foo.so` + // generated by compiling `foo.scilla` with scilla-llvm into `foo.bc` + // and compiling this LLVM bitcode with `clang -shared foo.bc -o foo.so`. + ScillaExecImpl(const ScillaParams &SPs, const std::string &ContrBin); + ~ScillaExecImpl(); + + // Get address for @Symbol inside the compiled IR, ready to be used. + void *getAddressFor(const std::string &Symbol) const; + // Initialize gas-remaining field in the code and initialize libraries. + uint64_t *initGasAndLibs(uint64_t GasRem); + // Execute a message. + Json::Value execMsg(const std::string &Balance, uint64_t GasLimit, + const Json::Value &InitJ, const Json::Value &Msg); + // Initialize the contract state to field initialization values in the source. + // This is to be called only during deployment of the contract. Never again. + Json::Value deploy(const Json::Value &InitJ, uint64_t GasLimit); + // What's the gas remaining from previous execution (deploy / execMsg). + // Useful if execution was interrupted due to an exception. + // Use with care if you don't want to end up with a stale value. + uint64_t getGasRem() const; + // Parse a string into a Scilla type. Raises error on failure. + const ScillaTypes::Typ *parseTypeString(const std::string &) const; + + // Scilla values dynamically allocated and owned by the JIT engine. + ObjManager OM; + // Scilla configuration parameters. + const ScillaParams SPs; + // The state of execution specific to a transition. + std::unique_ptr TS; +}; + +} // namespace ScillaVM \ No newline at end of file diff --git a/libsrtl/ScillaTypes.h b/libsrtl/ScillaTypes.h index b40df7d6..e30ac6a2 100644 --- a/libsrtl/ScillaTypes.h +++ b/libsrtl/ScillaTypes.h @@ -21,7 +21,7 @@ #include #include -#include "ScillaVM/SRTL.h" +#include "SRTL.h" namespace ScillaVM { diff --git a/libsrtl/ScillaValue.cpp b/libsrtl/ScillaValue.cpp index b12fc7cd..36c09f89 100644 --- a/libsrtl/ScillaValue.cpp +++ b/libsrtl/ScillaValue.cpp @@ -17,10 +17,11 @@ #include -#include "SafeInt.h" #include "ScillaVM/Errors.h" -#include "ScillaVM/JITD.h" #include "ScillaVM/Utils.h" + +#include "SafeInt.h" +#include "ScillaExecImpl.h" #include "ScillaValue.h" namespace ScillaVM { diff --git a/libsrtl/ScillaValue.h b/libsrtl/ScillaValue.h index d13b5c2f..a0afbfeb 100644 --- a/libsrtl/ScillaValue.h +++ b/libsrtl/ScillaValue.h @@ -22,8 +22,8 @@ #include #include +#include "SRTL.h" #include "ScillaTypes.h" -#include "ScillaVM/SRTL.h" namespace ScillaVM { diff --git a/libjitd/SharedObject.h b/libsrtl/SharedObject.h similarity index 94% rename from libjitd/SharedObject.h rename to libsrtl/SharedObject.h index 5493872f..d4b1cb61 100644 --- a/libjitd/SharedObject.h +++ b/libsrtl/SharedObject.h @@ -15,6 +15,8 @@ * along with this program. If not, see . */ +#pragma once + #include #include @@ -33,7 +35,7 @@ class SharedObject { } ~SharedObject() { dlclose(Handle); } - void *getAddressFor(const std::string &Name) { + void *getAddressFor(const std::string &Name) const { auto Ptr = dlsym(Handle, Name.c_str()); if (!Ptr) { CREATE_ERROR(dlerror()); diff --git a/libsrtl/Utils.cpp b/libsrtl/Utils.cpp index 057873e0..62559067 100644 --- a/libsrtl/Utils.cpp +++ b/libsrtl/Utils.cpp @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -62,6 +63,9 @@ boost::optional vNameValue(const Json::Value &Vs, namespace ScillaVM { +namespace bf = boost::filesystem; +namespace bp = boost::process; + std::string readFile(const std::string &Filename) { std::ifstream IfsFile(Filename); std::string FileStr((std::istreambuf_iterator(IfsFile)), @@ -91,6 +95,25 @@ std::string serializeJSON(const Json::Value &J) { return Oss.str(); } +CompileToSO::CompileToSO(const std::string &Filename) + : SOFile(bf::temp_directory_path() / bf::unique_path()), + InputFile(Filename) {} + +std::string CompileToSO::compile() const { + try { + auto ExecP = bp::search_path("clang"); + if (bp::system(ExecP, "-fPIC", "-shared", InputFile, "-o", + SOFile.native())) { + CREATE_ERROR("Compilation of " + InputFile + " failed."); + } + } catch (std::system_error &E) { + CREATE_ERROR(E.what()); + } + return SOFile.native(); +} + +CompileToSO::~CompileToSO() { boost::filesystem::remove(SOFile); } + boost::optional mapDepthOfTypeString(const std::string &TypeStr) { typedef std::pair FieldTypePair; diff --git a/runners/CMakeLists.txt b/runners/CMakeLists.txt index 769a0ebf..30714362 100644 --- a/runners/CMakeLists.txt +++ b/runners/CMakeLists.txt @@ -4,7 +4,7 @@ target_compile_definitions(${TARGET_SCILLA_RUNNER} PUBLIC ${LLVM_DEFINITIONS}) target_include_directories(${TARGET_SCILLA_RUNNER} PUBLIC ${PROJECT_SOURCE_DIR}/include) # We include LLVM includes as system includes to avoid warnings from there. target_include_directories(${TARGET_SCILLA_RUNNER} SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) -target_link_libraries (${TARGET_SCILLA_RUNNER} PUBLIC ScillaRTL ScillaJITD ${Boost_LIBRARIES}) +target_link_libraries (${TARGET_SCILLA_RUNNER} PUBLIC ScillaRTL pthread ${llvm_libs} ${Boost_LIBRARIES}) set(TARGET_EXPR_RUNNER expr-runner) add_executable(${TARGET_EXPR_RUNNER} expr-runner.cpp) @@ -12,4 +12,4 @@ target_compile_definitions(${TARGET_EXPR_RUNNER} PUBLIC ${LLVM_DEFINITIONS}) target_include_directories(${TARGET_EXPR_RUNNER} PUBLIC ${PROJECT_SOURCE_DIR}/include) # We include LLVM includes as system includes to avoid warnings from there. target_include_directories(${TARGET_EXPR_RUNNER} SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) -target_link_libraries (${TARGET_EXPR_RUNNER} PUBLIC ScillaRTL ScillaJITD ${Boost_LIBRARIES}) \ No newline at end of file +target_link_libraries (${TARGET_EXPR_RUNNER} PUBLIC ScillaRTL pthread ${llvm_libs} ${Boost_LIBRARIES}) \ No newline at end of file diff --git a/runners/expr-runner.cpp b/runners/expr-runner.cpp index b4aa6ab8..cdd080a2 100644 --- a/runners/expr-runner.cpp +++ b/runners/expr-runner.cpp @@ -21,8 +21,8 @@ #include "ScillaVM/Debug.h" #include "ScillaVM/Errors.h" -#include "ScillaVM/JITD.h" -#include "ScillaVM/SRTL.h" +#include "ScillaVM/ScillaExec.h" +#include "ScillaVM/Utils.h" using namespace ScillaVM; @@ -108,23 +108,15 @@ int main(int argc, char *argv[]) { } } - ScillaJIT::init(); - - ScillaStdout.clear(); + std::string ScillaOutput; try { auto InputFilename = VM["input-file"].as(); - auto GasLimit = VM["gaslimit"].as(); - auto SJ = ScillaJIT::create(ScillaParams(), InputFilename); - auto ScillaMainAddr = SJ->getAddressFor("scilla_main"); - auto ScillaMain = reinterpret_cast(ScillaMainAddr); + // Tool to compile the LLVM-IR to a binary shared object. + CompileToSO CSO(InputFilename); - // Set gas available in the JIT'ed code and then initialize libraries. - SJ->initGasAndLibs(GasLimit); - - // Execute ... - ScillaMain(); - // Collect and print the remaining gas. - ScillaStdout += "Gas remaining: " + std::to_string(SJ->getGasRem()) + "\n"; + auto GasLimit = VM["gaslimit"].as(); + ScillaExprExec SJ(ScillaParams(), CSO.compile()); + ScillaOutput = SJ.exec(GasLimit); } catch (const ScillaError &e) { std::cerr << e.toString() << "\n"; return EXIT_FAILURE; @@ -137,14 +129,14 @@ int main(int argc, char *argv[]) { std::cerr << "Error opening output file " << OutputFilename << "\n"; return EXIT_FAILURE; } else { - OFile << ScillaStdout; + OFile << ScillaOutput; if (OFile.bad()) { std::cerr << "Error writing to output file " << OutputFilename << "\n"; return EXIT_FAILURE; } } } else { - std::cout << ScillaStdout; + std::cout << ScillaOutput; } return EXIT_SUCCESS; diff --git a/runners/scilla-runner.cpp b/runners/scilla-runner.cpp index 3bc5f06c..326a4a73 100644 --- a/runners/scilla-runner.cpp +++ b/runners/scilla-runner.cpp @@ -21,8 +21,7 @@ #include "ScillaVM/Debug.h" #include "ScillaVM/Errors.h" -#include "ScillaVM/JITD.h" -#include "ScillaVM/SRTL.h" +#include "ScillaVM/ScillaExec.h" #include "ScillaVM/Utils.h" using namespace ScillaVM; @@ -115,14 +114,16 @@ int main(int argc, char *argv[]) { std::bind(&MemStateServer::updateStateValue, &State, ph::_1, ph::_2); ScillaParams SP(fetchStateValue, fetchRemoteStateValue, updateStateValue); - ScillaJIT::init(); - - ScillaStdout.clear(); + std::string OutputS; try { // Prepare all inputs. auto InputFilename = VM["input-contract"].as(); auto InitFilename = VM["init"].as(); auto GasLimit = VM["gaslimit"].as(); + + // Tool to compile the LLVM-IR to a binary shared object. + CompileToSO CSO(InputFilename); + // Parse the init JSON. auto IJ = parseJSONFile(InitFilename); // If there's a contract-info provided, use its field name / type info. @@ -142,17 +143,17 @@ int main(int argc, char *argv[]) { } // Create JIT engine. - auto JE = ScillaJIT::create(SP, InputFilename); + ScillaContrExec JE(SP, CSO.compile()); Json::Value OutJ; if (VM.count("message")) { // Transition execution auto MessageFilename = VM["message"].as(); auto MJ = parseJSONFile(MessageFilename); // Execute message - OutJ = JE->execMsg(Balance, GasLimit, IJ, MJ); + OutJ = JE.execMsg(Balance, GasLimit, IJ, MJ); } else { // Deployment - OutJ = JE->deploy(IJ, GasLimit); + OutJ = JE.deploy(IJ, GasLimit); } auto OSJ = State.dumpToJSON(); @@ -161,7 +162,7 @@ int main(int argc, char *argv[]) { OutJ["states"].append(S); // Append output to the Scilla output object for printing later. - ScillaStdout += OutJ.toStyledString(); + OutputS += OutJ.toStyledString(); } catch (const ScillaError &e) { std::cerr << e.toString() << "\n"; return EXIT_FAILURE; @@ -174,14 +175,14 @@ int main(int argc, char *argv[]) { std::cerr << "Error opening output file " << OutputFilename << "\n"; return EXIT_FAILURE; } else { - OFile << ScillaStdout; + OFile << OutputS; if (OFile.bad()) { std::cerr << "Error writing to output file " << OutputFilename << "\n"; return EXIT_FAILURE; } } } else { - std::cout << ScillaStdout; + std::cout << OutputS; } return EXIT_SUCCESS; diff --git a/testsuite/CMakeLists.txt b/testsuite/CMakeLists.txt index b6dcaaaf..bcb6190f 100644 --- a/testsuite/CMakeLists.txt +++ b/testsuite/CMakeLists.txt @@ -12,7 +12,7 @@ add_executable(${TARGET_SCILLA_TESTS} target_include_directories(${TARGET_SCILLA_TESTS} PUBLIC ${PROJECT_SOURCE_DIR}/include) target_include_directories(${TARGET_SCILLA_TESTS} PUBLIC ${BOOST_INCLUDE_TARGETS}) -target_link_libraries (${TARGET_SCILLA_TESTS} PUBLIC ScillaRTL ScillaJITD ${Boost_LIBRARIES}) +target_link_libraries (${TARGET_SCILLA_TESTS} PUBLIC ScillaRTL pthread ${llvm_libs} ${Boost_LIBRARIES}) # Add a custom target to run the testsuite as `make runtests` # Note: We don't use `make test` becaus `test` is a reserved target. diff --git a/testsuite/ContrTests.cpp b/testsuite/ContrTests.cpp index 5296ff55..02dab4da 100644 --- a/testsuite/ContrTests.cpp +++ b/testsuite/ContrTests.cpp @@ -21,7 +21,7 @@ using boost::test_tools::output_test_stream; #include -#include +#include #include #include "StateJsonUtils.h" @@ -32,11 +32,6 @@ using namespace ScillaTestsuite; namespace { -const std::string CacheDir((boost::filesystem::temp_directory_path() /= - "scilla_testsuite_cache") - .native()); -ScillaCacheManager OCache(CacheDir); - struct ContractTest { struct Input { // ID is for diagnostic purposes, an ID / name for this input. @@ -75,17 +70,17 @@ void testMessagesHelper(const ContractTest &CT, bool CommonJIT) { ScillaParams SP(fetchStateValue, fetchRemoteStateValue, updateStateValue); std::string PathPrefix = Config::TestsuiteSrc + "/contr/"; + // Tool to compile the LLVM-IR to a binary shared object. + CompileToSO CSO(PathPrefix + CT.ContrFilename); - ScillaJIT_Safe::init(); - - std::unique_ptr JE; + std::unique_ptr JE; if (CommonJIT) { BOOST_TEST_CHECKPOINT("Creating common JIT for " + CT.ContrFilename); // Create a JIT engine and execute the message. // TODO: Due to the below mentioned bug, this can't be in a try-catch block. { - ScopeTimer CreateTimer(CT.ContrFilename + ": ScillaJIT::create"); - JE = ScillaJIT_Safe::create(SP, PathPrefix + CT.ContrFilename, &OCache); + ScopeTimer CreateTimer(CT.ContrFilename + ": ScillaExec::create"); + JE = std::make_unique(SP, CSO.compile()); } } @@ -96,8 +91,8 @@ void testMessagesHelper(const ContractTest &CT, bool CommonJIT) { // TODO: Due to the below mentioned bug, this can't be in a try-catch // block. { - ScopeTimer CreateTimer(CT.ContrFilename + ": ScillaJIT::create"); - JE = ScillaJIT_Safe::create(SP, PathPrefix + CT.ContrFilename, &OCache); + ScopeTimer CreateTimer(CT.ContrFilename + ": ScillaExec::create"); + JE = std::make_unique(SP, CSO.compile()); } } BOOST_TEST_MESSAGE("Testing " + CT.ContrFilename + " with input " + @@ -124,7 +119,7 @@ void testMessagesHelper(const ContractTest &CT, bool CommonJIT) { // Let's execute. Json::Value OJ; { - ScopeTimer ExecMsgTimer(CT.ContrFilename + ": ScillaJIT::execMsg"); + ScopeTimer ExecMsgTimer(CT.ContrFilename + ": ScillaExec::execMsg"); if (Input.MessageFilename.empty()) { OJ = JE->deploy(InitJSON, Config::GasLimit); } else { @@ -213,8 +208,8 @@ void testMessageFail(const std::string &ContrFilename, ScillaParams SP(fetchStateValue, fetchRemoteStateValue, updateStateValue); std::string PathPrefix = Config::TestsuiteSrc + "/contr/"; - - ScillaJIT_Safe::init(); + // Tool to compile the LLVM-IR to a binary shared object. + CompileToSO CSO(PathPrefix + ContrFilename); Json::Value MessageJSON, InitJSON; std::string Balance = "0"; @@ -238,16 +233,16 @@ void testMessageFail(const std::string &ContrFilename, BOOST_FAIL(E.toString()); } - std::unique_ptr JE; + std::unique_ptr JE; bool CaughtException = false; try { // Create a JIT engine { - ScopeTimer CreateTimer(ContrFilename + ": ScillaJIT::create"); - JE = ScillaJIT_Safe::create(SP, PathPrefix + ContrFilename, &OCache); + ScopeTimer CreateTimer(ContrFilename + ": ScillaExec::create"); + JE = std::make_unique(SP, CSO.compile()); } { - ScopeTimer ExecMsgTimer(ContrFilename + ": ScillaJIT::execMsg"); + ScopeTimer ExecMsgTimer(ContrFilename + ": ScillaExec::execMsg"); if (MessageFilename.empty()) { JE->deploy(InitJSON, Config::GasLimit); } else { @@ -631,7 +626,7 @@ BOOST_AUTO_TEST_CASE(map_corners_test_exec_unique_jits) { // Run a large number of these tests with a common JIT. // This test is disabled as it hogs up CI time. To see it work, -// comment out the call to ObjManager::deleteAll() in ScillaJIT::execMsg(). +// comment out the call to ObjManager::deleteAll() in ScillaExec::execMsg(). // Check peak memory usage: https://stackoverflow.com/a/774601/2128804 int MCT_NumRepeats = 500; BOOST_AUTO_TEST_CASE(map_corners_test_stress, diff --git a/testsuite/ExprExecTests.cpp b/testsuite/ExprExecTests.cpp index 27ba5ebe..f386982d 100644 --- a/testsuite/ExprExecTests.cpp +++ b/testsuite/ExprExecTests.cpp @@ -20,8 +20,8 @@ using boost::test_tools::output_test_stream; #include -#include -#include +#include +#include #include "Testsuite.h" @@ -33,26 +33,14 @@ using namespace ScillaTestsuite; void testExecExprHelper(const std::string &Filename, const std::string &ResultFilename) { - ScillaJIT::init(); - // TODO: Pushing ScillaJIT::create into the try-catch below - // causes a segfault later. Likely related to the exception - // bug (and workaround) linked to right below. - // Linking to an LLVM build with LLVM_ENABLE_EH=On doesn't solve. - auto SJ = ScillaJIT::create(ScillaVM::ScillaParams(), Filename); + std::string ScillaOutput; try { - auto ScillaMainAddr = SJ->getAddressFor("scilla_main"); - BOOST_TEST_CHECKPOINT(Filename + ": JIT compilation succeeded"); - auto ScillaMain = reinterpret_cast(ScillaMainAddr); - ScillaStdout.clear(); - // Set the remaining gas inside the LLVM-IR for the expression. - auto GasRemPtr = reinterpret_cast(SJ->getAddressFor("_gasrem")); - *GasRemPtr = Config::GasLimit; - - // Execute expression. - ScillaMain(); - - // Collect and print the remaining gas. - ScillaStdout += "Gas remaining: " + std::to_string(*GasRemPtr) + "\n"; + // Tool to compile the LLVM-IR to a binary shared object. + CompileToSO CSO(Filename); + // Setup a Scilla expression execution object. + ScillaExprExec SJ(ScillaVM::ScillaParams(), CSO.compile()); + BOOST_TEST_CHECKPOINT(Filename + ": Loaded compiled shared object."); + ScillaOutput = SJ.exec(Config::GasLimit); } catch (const ScillaError &E) { BOOST_FAIL(E.toString()); } @@ -60,16 +48,9 @@ void testExecExprHelper(const std::string &Filename, BOOST_TEST_CHECKPOINT(Filename + ": Execution succeeded"); output_test_stream Output(ResultFilename, !Config::UpdateResults); - Output << ScillaStdout; + Output << ScillaOutput; BOOST_TEST(Output.match_pattern()); BOOST_TEST_CHECKPOINT(Filename + ": Output matched"); - - // https://github.com/boostorg/boost/issues/379 - try { - throw std::exception(); - } catch (std::exception &) { - ; - } } // Calls testExecExprHelper for both non-debug and debug LLVM-IR inputs. @@ -87,28 +68,15 @@ void testExecFailExpr(const std::string &Testname) { auto Filename = Config::TestsuiteSrc + "/expr/" + Testname + ".ll"; - ScillaJIT::init(); - // TODO: Pushing ScillaJIT::create into the try-catch below - // causes a segfault later. Likely related to the exception - // bug (and workaround) linked to right below. - // Linking to an LLVM build with LLVM_ENABLE_EH=On doesn't solve. - auto SJ = ScillaJIT::create(ScillaVM::ScillaParams(), Filename); - bool CaughtException = false; + std::string ScillaOutput; try { - auto ScillaMainAddr = SJ->getAddressFor("scilla_main"); - BOOST_TEST_CHECKPOINT(Filename + ": JIT compilation succeeded"); - auto ScillaMain = reinterpret_cast(ScillaMainAddr); - ScillaStdout.clear(); - // Set the remaining gas inside the LLVM-IR for the expression. - auto GasRemPtr = reinterpret_cast(SJ->getAddressFor("_gasrem")); - *GasRemPtr = Config::GasLimit; - - // Execute expression. - ScillaMain(); - - // Collect and print the remaining gas. - ScillaStdout += "Gas remaining: " + std::to_string(*GasRemPtr) + "\n"; + // Tool to compile the LLVM-IR to a binary shared object. + CompileToSO CSO(Filename); + // Setup a Scilla expression execution object. + ScillaExprExec SJ(ScillaVM::ScillaParams(), CSO.compile()); + BOOST_TEST_CHECKPOINT(Filename + ": Loaded compiled shared object."); + ScillaOutput = SJ.exec(Config::GasLimit); } catch (const ScillaError &E) { output_test_stream Output(Filename + ".result", !Config::UpdateResults); Output << E.toString(); diff --git a/testsuite/StateJsonTests.cpp b/testsuite/StateJsonTests.cpp index 75c85db5..3ffde4bf 100644 --- a/testsuite/StateJsonTests.cpp +++ b/testsuite/StateJsonTests.cpp @@ -18,10 +18,11 @@ #include #include -#include #include +#include "../libsrtl/ObjManager.h" #include "../libsrtl/ScillaValue.h" + #include "StateJsonUtils.h" #include "Testsuite.h" #include "TypeDescrs.h" From 3420f7e1adae3e8d28b9b3ad3c635e8b19ea8347 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Sun, 13 Jun 2021 11:21:55 +0530 Subject: [PATCH 2/6] Minor header improvements --- include/ScillaVM/Debug.h | 2 ++ libsrtl/ScillaTypes.cpp | 1 + libsrtl/ScillaTypes.h | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/ScillaVM/Debug.h b/include/ScillaVM/Debug.h index 7ed3b3a6..1e2e6878 100644 --- a/include/ScillaVM/Debug.h +++ b/include/ScillaVM/Debug.h @@ -24,6 +24,8 @@ // in debug builds. For the former to work, DEBUG_TYPE must be // defined. SVM_DEBUG is equal to SVM_DEBUG_TYPE(DEBUG_TYPE, ...). +#pragma once + #include #include diff --git a/libsrtl/ScillaTypes.cpp b/libsrtl/ScillaTypes.cpp index 9c975a3c..97632c58 100644 --- a/libsrtl/ScillaTypes.cpp +++ b/libsrtl/ScillaTypes.cpp @@ -20,6 +20,7 @@ #include "ScillaTypes.h" #include "ScillaVM/Errors.h" +#include "SRTL.h" namespace ScillaVM { diff --git a/libsrtl/ScillaTypes.h b/libsrtl/ScillaTypes.h index e30ac6a2..d2e7e2bb 100644 --- a/libsrtl/ScillaTypes.h +++ b/libsrtl/ScillaTypes.h @@ -20,8 +20,7 @@ #include #include #include - -#include "SRTL.h" +#include namespace ScillaVM { From b9e02b0dd70a1765a8570d734039f61e346cb4d2 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Sun, 13 Jun 2021 12:36:13 +0530 Subject: [PATCH 3/6] Rename ScillaVM to ScillaRTL and reorg --- CMakeLists.txt | 4 +- README.md | 53 ++-- include/{ScillaVM => ScillaRTL}/Debug.h | 8 +- include/{ScillaVM => ScillaRTL}/Errors.h | 6 +- include/{ScillaVM => ScillaRTL}/ScillaExec.h | 4 +- include/{ScillaVM => ScillaRTL}/Utils.h | 4 +- {libsrtl => libScillaRTL}/CMakeLists.txt | 0 {libsrtl => libScillaRTL}/Debug.cpp | 6 +- {libsrtl => libScillaRTL}/ObjManager.h | 4 +- {libsrtl => libScillaRTL}/SRTL.cpp | 8 +- {libsrtl => libScillaRTL}/SRTL.h | 4 +- {libsrtl => libScillaRTL}/SafeInt.cpp | 6 +- {libsrtl => libScillaRTL}/SafeInt.h | 4 +- {libsrtl => libScillaRTL}/ScillaBuiltins.cpp | 14 +- libScillaRTL/ScillaBuiltins.h | 276 +++++++++++++++++++ {libsrtl => libScillaRTL}/ScillaExecImpl.cpp | 10 +- {libsrtl => libScillaRTL}/ScillaExecImpl.h | 6 +- {libsrtl => libScillaRTL}/ScillaTypes.cpp | 10 +- {libsrtl => libScillaRTL}/ScillaTypes.h | 4 +- {libsrtl => libScillaRTL}/ScillaValue.cpp | 8 +- {libsrtl => libScillaRTL}/ScillaValue.h | 4 +- {libsrtl => libScillaRTL}/SharedObject.h | 6 +- {libsrtl => libScillaRTL}/Utils.cpp | 10 +- libsrtl/ScillaBuiltins.h | 276 ------------------- runners/expr-runner.cpp | 14 +- runners/scilla-runner.cpp | 14 +- testsuite/ContrTests.cpp | 18 +- testsuite/ExprExecTests.cpp | 12 +- testsuite/StateJsonTests.cpp | 14 +- testsuite/Testsuite.cpp | 6 +- testsuite/TypeDescrs.cpp | 2 +- testsuite/TypeDescrs.h | 4 +- testsuite/TypeTests.cpp | 32 +-- 33 files changed, 418 insertions(+), 433 deletions(-) rename include/{ScillaVM => ScillaRTL}/Debug.h (92%) rename include/{ScillaVM => ScillaRTL}/Errors.h (97%) rename include/{ScillaVM => ScillaRTL}/ScillaExec.h (98%) rename include/{ScillaVM => ScillaRTL}/Utils.h (98%) rename {libsrtl => libScillaRTL}/CMakeLists.txt (100%) rename {libsrtl => libScillaRTL}/Debug.cpp (93%) rename {libsrtl => libScillaRTL}/ObjManager.h (98%) rename {libsrtl => libScillaRTL}/SRTL.cpp (98%) rename {libsrtl => libScillaRTL}/SRTL.h (97%) rename {libsrtl => libScillaRTL}/SafeInt.cpp (98%) rename {libsrtl => libScillaRTL}/SafeInt.h (98%) rename {libsrtl => libScillaRTL}/ScillaBuiltins.cpp (99%) create mode 100644 libScillaRTL/ScillaBuiltins.h rename {libsrtl => libScillaRTL}/ScillaExecImpl.cpp (98%) rename {libsrtl => libScillaRTL}/ScillaExecImpl.h (97%) rename {libsrtl => libScillaRTL}/ScillaTypes.cpp (99%) rename {libsrtl => libScillaRTL}/ScillaTypes.h (99%) rename {libsrtl => libScillaRTL}/ScillaValue.cpp (99%) rename {libsrtl => libScillaRTL}/ScillaValue.h (98%) rename {libsrtl => libScillaRTL}/SharedObject.h (93%) rename {libsrtl => libScillaRTL}/Utils.cpp (99%) delete mode 100644 libsrtl/ScillaBuiltins.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dc364629..5345514c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5.1) -project(ScillaVM) +project(ScillaRTL) # detect operating system message(STATUS "We are on a ${CMAKE_SYSTEM_NAME} system") @@ -53,7 +53,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # C++ standard set(CMAKE_CXX_STANDARD 14) -add_subdirectory(libsrtl) +add_subdirectory(libScillaRTL) add_subdirectory(runners) add_subdirectory(testsuite) add_subdirectory(deps/cryptoutils EXCLUDE_FROM_ALL) diff --git a/README.md b/README.md index 56102320..3154249e 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,29 @@ -# Scilla Virtual Machine +# Scilla Runtime Library [![Build Status](https://travis-ci.com/Zilliqa/scilla-vm.svg?branch=master)](https://travis-ci.com/Zilliqa/scilla-vm) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://github.com/Zilliqa/scilla/blob/master/LICENSE) -A compiled execution backend for Scilla. +The Scilla Runtime Library provides two main functionalities -The compiled execution backend is divided into two parts: - 1. The JIT driver (JITD): JIT compiles Scilla contracts translated to - LLVM-IR (see [scilla-compiler](https://github.com/Zilliqa/scilla-compiler)), - links it with the run-time library and executes transitions. - compiling it to machine code, and finally executing it. - 2. Scilla run-time library (SRTL), which the contract code interacts - with for performing pre-compiled operations, such as interacting with - the blockchain, executing builtins etc. - -Design docs for the [VM architecture](https://github.com/Zilliqa/scilla-backend/wiki/Scilla-Backend-Design) -and the planned [interaction with the blockchain](https://github.com/Zilliqa/scilla-backend/wiki/Interaction-of-State-Variables-with-Blockchain) -are available. + 1. An entry point to execute Scilla contracts. The contract to be executed + must be compiled by the [Scilla LLVM compiler](https://github.com/Zilliqa/scilla-compiler), + and linked into a shared library object. + 2. A collection of functions that implement various common (i.e., not specific to a contract) + Scilla operations and enable the compiled binary to interact with the blockchain during + execution. ## Build and install -Add Ubuntu repository for LLVM-10. Below command line is for Ubuntu 18.04, change -suitably for your OS (see the LLVM [apt page](https://apt.llvm.org/https://apt.llvm.org/)) - - ``` - sudo add-apt-repository 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main' -y - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - -``` - Install these Ubuntu packages - - `sudo apt-get install build-essential cmake llvm-10-dev libboost-dev libboost-test-dev libjsoncpp-dev libboost-filesystem-dev libboost-program-options-dev libsecp256k1-dev` + - `sudo apt-get install build-essential cmake libboost-dev libboost-test-dev libjsoncpp-dev libboost-filesystem-dev libboost-program-options-dev libsecp256k1-dev` -We suggest building ScillaVM in a directory that is *not* the source directory. +We suggest building ScillaRTL in a directory that is *not* the source directory. * `$git clone --recurse-submodules https://github.com/Zilliqa/scilla-vm.git` * `$cd scilla-vm; mkdir build; cd build` * `$cmake ..` configures the project. Additional (optional) flags: - `-DCMAKE_INSTALL_PREFIX=/where/to/install/scilla-vm`: To specify an install directory other than the default. The default installation path typically requires root permissions. - - `-DLLVM_DIR=/path/to/llvm/install/lib/cmake/llvm`: - If your LLVM is not installed in a default (system) directory, - provide this [flag](https://llvm.org/docs/CMake.html#embedding-llvm-in-your-project) - to enable `CMake` to find LLVM. Note: LLVM must be built with [RTTI support](https://llvm.org/docs/CMake.html). - `-DCMAKE_BUILD_TYPE=[Debug|Release|RelWithDebInfo|MinSizeRel]`: The default build is `Debug`. * `$make` builds the entire project. You can find the built files in `bin/` and `lib/`. * `$make install` installs the project. @@ -50,8 +32,8 @@ We suggest building ScillaVM in a directory that is *not* the source directory. directory. ## Run -While Scilla VM is intended to be primarily used as a library from the Zilliqa blockchain, -we provide two wrapper executables for development, debugging and simply trying out the VM. +While ScillaRTL is intended to be primarily used as a library from the Zilliqa blockchain, +we provide two wrapper executables for development, debugging and simply trying it out. `expr-runner` takes as input, a compiled pure Scilla expression and executes it, by calling a wrapper function `scilla_main` generated by the compiler. If the expression is printable, the compiler also generates a call to print it. @@ -61,9 +43,9 @@ With these inputs, the transition specified in the message JSON is executed. The is printed. ``` -$build/bin/expr-runner testsuite/expr/lit-pair-list-int.ll +$build/bin/expr-runner -g 1000 testsuite/expr/lit-pair-list-int.ll -$build/bin/scilla-runner --input-contract testsuite/contr/simple-map.ll --message testsuite/contr/simple-map.message_Increment.json --contract-info testsuite/contr/simple-map.contrinfo.json --state testsuite/contr/simple-map.state_00.json --init testsuite/contr/empty_init.json +$build/bin/scilla-runner -g 10000 --input-contract testsuite/contr/simple-map.ll --message testsuite/contr/simple-map.message_Increment.json --contract-info testsuite/contr/simple-map.contrinfo.json --state testsuite/contr/simple-map.state_00.json --init testsuite/contr/empty_init.json ``` ## Developer Notes @@ -142,5 +124,8 @@ We maintain the following conventions: #### Contract execution tests The directory `testsuite/contr` contains text LLVM-IR files, all generated by `scilla-compiler`. -The directory also contains the supporting JSONs required for executing transitions in these -compiled contracts. +The directory also contains the supporting JSONs required for executing transitions in these compiled contracts. Each LLVM-IR file `foo.ll` also has `foo.dbg.ll` that is +a compiled version of the same contract with `debuginfo`. These LLVM-IR files can be +updated from the Scilla LLVM compiler using the `scripts/update_contrs.sh`. This +script updates both the debug and non-debug LLVM-IR modules and also the contract info +for that contract. diff --git a/include/ScillaVM/Debug.h b/include/ScillaRTL/Debug.h similarity index 92% rename from include/ScillaVM/Debug.h rename to include/ScillaRTL/Debug.h index 1e2e6878..77adacea 100644 --- a/include/ScillaVM/Debug.h +++ b/include/ScillaRTL/Debug.h @@ -29,24 +29,24 @@ #include #include -namespace ScillaVM { +namespace ScillaRTL { bool isInCurrentDebugTypes(std::string TYPE); void addToCurrentDebugTypes(std::string TYPE); void enableAllDebugTypes(); -} // namespace ScillaVM +} // namespace ScillaRTL #ifndef NDEBUG #define SVM_DEBUG_TYPE(TYPE, X) \ do { \ - if (ScillaVM::isInCurrentDebugTypes(TYPE)) { \ + if (ScillaRTL::isInCurrentDebugTypes(TYPE)) { \ X; \ } \ } while (false) #define SVM_DEBUG(X) SVM_DEBUG_TYPE(DEBUG_TYPE, X) -namespace ScillaVM { +namespace ScillaRTL { std::ostream &dbgs(); } #else diff --git a/include/ScillaVM/Errors.h b/include/ScillaRTL/Errors.h similarity index 97% rename from include/ScillaVM/Errors.h rename to include/ScillaRTL/Errors.h index 9498fa07..242b7b85 100644 --- a/include/ScillaVM/Errors.h +++ b/include/ScillaRTL/Errors.h @@ -19,7 +19,7 @@ #include -namespace ScillaVM { +namespace ScillaRTL { struct SourceLoc { std::string File; @@ -38,7 +38,7 @@ struct SourceLoc { struct ScillaError { // Error message std::string Msg; - // Where in ScillaVM was this error thrown from. + // Where in ScillaRTL was this error thrown from. SourceLoc ThrowLoc; // Where in the Scilla source were we when the error occurred. SourceLoc ScillaSrcLoc; @@ -56,7 +56,7 @@ struct ScillaError { } }; -} // namespace ScillaVM +} // namespace ScillaRTL // Throws a ScillaError object, attaching the location of error // Uses a default (empty) Scilla source location. diff --git a/include/ScillaVM/ScillaExec.h b/include/ScillaRTL/ScillaExec.h similarity index 98% rename from include/ScillaVM/ScillaExec.h rename to include/ScillaRTL/ScillaExec.h index ab4da8c9..1c80a57c 100644 --- a/include/ScillaVM/ScillaExec.h +++ b/include/ScillaRTL/ScillaExec.h @@ -26,7 +26,7 @@ #include // Forward declarations. -namespace ScillaVM { +namespace ScillaRTL { // Information that Scilla will need to execute contracts. struct ScillaParams { @@ -120,4 +120,4 @@ class ScillaExprExec { uint64_t getGasRem() const; }; -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/include/ScillaVM/Utils.h b/include/ScillaRTL/Utils.h similarity index 98% rename from include/ScillaVM/Utils.h rename to include/ScillaRTL/Utils.h index 7dfaeee5..08f5800a 100644 --- a/include/ScillaVM/Utils.h +++ b/include/ScillaRTL/Utils.h @@ -37,7 +37,7 @@ template bool has_type(const boost::any *a) { } } // namespace boost -namespace ScillaVM { +namespace ScillaRTL { std::string readFile(const std::string &Filename); Json::Value parseJSONString(const std::string &JS); @@ -106,4 +106,4 @@ class MemStateServer { Json::Value dumpToJSON(); }; -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/CMakeLists.txt b/libScillaRTL/CMakeLists.txt similarity index 100% rename from libsrtl/CMakeLists.txt rename to libScillaRTL/CMakeLists.txt diff --git a/libsrtl/Debug.cpp b/libScillaRTL/Debug.cpp similarity index 93% rename from libsrtl/Debug.cpp rename to libScillaRTL/Debug.cpp index 540a4f74..186c2fdc 100644 --- a/libsrtl/Debug.cpp +++ b/libScillaRTL/Debug.cpp @@ -17,9 +17,9 @@ #include -#include +#include -namespace ScillaVM { +namespace ScillaRTL { bool EnableAllDebugTypes; std::set EnabledDebugTypes; @@ -39,4 +39,4 @@ std::ostream &dbgs() { return std::cout; } -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/ObjManager.h b/libScillaRTL/ObjManager.h similarity index 98% rename from libsrtl/ObjManager.h rename to libScillaRTL/ObjManager.h index 3476fd24..cc40e455 100644 --- a/libsrtl/ObjManager.h +++ b/libScillaRTL/ObjManager.h @@ -21,7 +21,7 @@ #include -namespace ScillaVM { +namespace ScillaRTL { // Allocates, constructs, owns and destructs objects. // Objects of any type can be managed. It works similar to how @@ -82,4 +82,4 @@ class ObjManager { ~ObjManager() { deleteAll(); }; }; -} // namespace ScillaVM \ No newline at end of file +} // namespace ScillaRTL \ No newline at end of file diff --git a/libsrtl/SRTL.cpp b/libScillaRTL/SRTL.cpp similarity index 98% rename from libsrtl/SRTL.cpp rename to libScillaRTL/SRTL.cpp index 261835be..020c7e98 100644 --- a/libsrtl/SRTL.cpp +++ b/libScillaRTL/SRTL.cpp @@ -17,8 +17,8 @@ #include -#include "ScillaVM/Errors.h" -#include "ScillaVM/Utils.h" +#include "ScillaRTL/Errors.h" +#include "ScillaRTL/Utils.h" #include "SRTL.h" #include "SafeInt.h" @@ -40,7 +40,7 @@ void unquoteString(std::string &Input) { } } // namespace -namespace ScillaVM { +namespace ScillaRTL { std::string ScillaStdout = ""; @@ -196,4 +196,4 @@ bool dynamicTypecheck(const ScillaExecImpl *SJ, const ScillaTypes::Typ *TargetT, return recurser(TargetT, Val); } -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/SRTL.h b/libScillaRTL/SRTL.h similarity index 97% rename from libsrtl/SRTL.h rename to libScillaRTL/SRTL.h index 8e5d53c5..b1dca65e 100644 --- a/libsrtl/SRTL.h +++ b/libScillaRTL/SRTL.h @@ -24,7 +24,7 @@ #include -namespace ScillaVM { +namespace ScillaRTL { class ScillaExecImpl; namespace ScillaTypes { @@ -61,4 +61,4 @@ bool isUserAddr(const ScillaExecImpl *SJ, const std::string &Addr); bool dynamicTypecheck(const ScillaExecImpl *SJ, const ScillaTypes::Typ *Target, const ScillaTypes::Typ *ParsedT, void *Val); -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/SafeInt.cpp b/libScillaRTL/SafeInt.cpp similarity index 98% rename from libsrtl/SafeInt.cpp rename to libScillaRTL/SafeInt.cpp index 01c0b700..06e8b807 100644 --- a/libsrtl/SafeInt.cpp +++ b/libScillaRTL/SafeInt.cpp @@ -19,13 +19,13 @@ #include #include "SafeInt.h" -#include +#include #if BOOST_ENDIAN_BIG_BYTE #error "Big endian architecture not supported." #endif -namespace ScillaVM { +namespace ScillaRTL { using namespace ScillaTypes; @@ -127,4 +127,4 @@ template class SafeInt<64, SafeIntKind::Unsigned>; template class SafeInt<128, SafeIntKind::Unsigned>; template class SafeInt<256, SafeIntKind::Unsigned>; -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/SafeInt.h b/libScillaRTL/SafeInt.h similarity index 98% rename from libsrtl/SafeInt.h rename to libScillaRTL/SafeInt.h index 82d8c739..69d60a17 100644 --- a/libsrtl/SafeInt.h +++ b/libScillaRTL/SafeInt.h @@ -23,7 +23,7 @@ #include "ScillaTypes.h" -namespace ScillaVM { +namespace ScillaRTL { // A class for safe arithmetic operations. // Creates an error on overflows or underflows in any operation. @@ -82,4 +82,4 @@ typedef SafeInt<64, SafeIntKind::Unsigned> SafeUint64; typedef SafeInt<128, SafeIntKind::Unsigned> SafeUint128; typedef SafeInt<256, SafeIntKind::Unsigned> SafeUint256; -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/ScillaBuiltins.cpp b/libScillaRTL/ScillaBuiltins.cpp similarity index 99% rename from libsrtl/ScillaBuiltins.cpp rename to libScillaRTL/ScillaBuiltins.cpp index 9c3d1613..0ed2151d 100644 --- a/libsrtl/ScillaBuiltins.cpp +++ b/libScillaRTL/ScillaBuiltins.cpp @@ -29,11 +29,11 @@ #include "ScillaBuiltins.h" #include "ScillaExecImpl.h" #include "ScillaTypes.h" -#include "ScillaVM/Errors.h" -#include "ScillaVM/Utils.h" +#include "ScillaRTL/Errors.h" +#include "ScillaRTL/Utils.h" #include "ScillaValue.h" -namespace ScillaVM { +namespace ScillaRTL { void TransitionState::processMessage(std::string OutType, Json::Value &M) { if (OutJ.empty()) { @@ -101,9 +101,9 @@ Json::Value TransitionState::finalize(void) { return OutJ; } -} // namespace ScillaVM +} // namespace ScillaRTL -using namespace ScillaVM; +using namespace ScillaRTL; namespace { @@ -396,8 +396,8 @@ void *_fetch_remote_field(ScillaExecImpl *SJ, return fetchFieldHelper(SJ, Addr, Name, T, NumIdx, Indices, FetchVal); } -void _update_field(ScillaVM::ScillaExecImpl *SJ, const char *Name, - const ScillaVM::ScillaTypes::Typ *T, int32_t NumIdx, +void _update_field(ScillaRTL::ScillaExecImpl *SJ, const char *Name, + const ScillaRTL::ScillaTypes::Typ *T, int32_t NumIdx, const uint8_t *Indices, void *Val) { std::vector KeyTypes; diff --git a/libScillaRTL/ScillaBuiltins.h b/libScillaRTL/ScillaBuiltins.h new file mode 100644 index 00000000..8036dbc9 --- /dev/null +++ b/libScillaRTL/ScillaBuiltins.h @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2020 Zilliqa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +/* This file declares functions that are callable from an executing + * Scilla contract. It is not intended to be called from other C++ + * code, and is therefore not a public header. */ + +#include "ScillaRTL/ScillaExec.h" + +#include "SafeInt.h" +#include "ScillaTypes.h" +#include "ScillaValue.h" + +namespace ScillaRTL { + +// Values that begin with a transition and change as it executes. +class TransitionState { + SafeUint128 Balance; + SafeUint128 InAmount; + uint64_t *GasRemPtr; + bool Accepted; + // Contains the output messages of executing a transition. + Json::Value OutJ; + + void processMessage(std::string OutType, Json::Value &M); + +public: + TransitionState(std::string Balance_P, std::string InAmount_P, + uint64_t *GasRemPtr_P) + : Balance(Balance_P), InAmount(InAmount_P), GasRemPtr(GasRemPtr_P), + Accepted(false), OutJ(Json::objectValue){}; + + void processSend(Json::Value &M); + void processEvent(Json::Value &M); + void processAccept(); + + // Returns the output of the transition execution. Destroys *this*. + Json::Value finalize(); +}; + +} // end of namespace ScillaRTL + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" + +extern "C" { + +// Print Scilla value @V whose type is described by @T to ScillaStdout . +void _print_scilla_val(const ScillaRTL::ScillaTypes::Typ *T, void *V); + +// Allocate memory for JIT code owned by @SJ +void *_salloc(ScillaRTL::ScillaExecImpl *SJ, size_t size); + +// Handler for out-of-gas during execution +void _out_of_gas(); + +// Fetch field @Name whose type is @T. For map accesses, FetchVal can be false, +// to indicate that the return value is a Scilla `Bool`, indicating found or +// not. +void *_fetch_field(ScillaRTL::ScillaExecImpl *SJ, const char *Name, + const ScillaRTL::ScillaTypes::Typ *T, int32_t NumIdx, + const uint8_t *Indices, int32_t FetchVal); + +// Same as _fetch_field, but with an address parameter. +void * +_fetch_remote_field(ScillaRTL::ScillaExecImpl *SJ, + const uint8_t Addr[ScillaRTL::ScillaTypes::AddrByStr_Len], + const char *Name, const ScillaRTL::ScillaTypes::Typ *T, + int32_t NumIdx, const uint8_t *Indices, int32_t FetchVal); + +// Update field @Name whose type is @T with value @Val. If Val is nullptr, +// then this is a map update and the keys must be deleted. +void _update_field(ScillaRTL::ScillaExecImpl *SJ, const char *Name, + const ScillaRTL::ScillaTypes::Typ *, int32_t NumIdx, + const uint8_t *Indices, void *Val); + +// Integer addition builtins +ScillaRTL::ScillaTypes::Int32 _add_Int32(ScillaRTL::ScillaTypes::Int32, + ScillaRTL::ScillaTypes::Int32); +ScillaRTL::ScillaTypes::Int64 _add_Int64(ScillaRTL::ScillaTypes::Int64, + ScillaRTL::ScillaTypes::Int64); +ScillaRTL::ScillaTypes::Int128 _add_Int128(ScillaRTL::ScillaTypes::Int128, + ScillaRTL::ScillaTypes::Int128); +ScillaRTL::ScillaTypes::Int256 *_add_Int256(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Int256 *Lhs, + ScillaRTL::ScillaTypes::Int256 *Rhs); + +ScillaRTL::ScillaTypes::Uint32 _add_Uint32(ScillaRTL::ScillaTypes::Uint32, + ScillaRTL::ScillaTypes::Uint32); +ScillaRTL::ScillaTypes::Uint64 _add_Uint64(ScillaRTL::ScillaTypes::Uint64, + ScillaRTL::ScillaTypes::Uint64); +ScillaRTL::ScillaTypes::Uint128 _add_Uint128(ScillaRTL::ScillaTypes::Uint128, + ScillaRTL::ScillaTypes::Uint128); +ScillaRTL::ScillaTypes::Uint256 * +_add_Uint256(ScillaRTL::ScillaExecImpl *SJ, ScillaRTL::ScillaTypes::Uint256 *Lhs, + ScillaRTL::ScillaTypes::Uint256 *Rhs); + +uint8_t *_eq_Int32(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Int32 Lhs, + ScillaRTL::ScillaTypes::Int32 Rhs); + +uint8_t *_eq_Int64(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Int64 Lhs, + ScillaRTL::ScillaTypes::Int64 Rhs); + +uint8_t *_eq_Int128(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Int128 Lhs, + ScillaRTL::ScillaTypes::Int128 Rhs); + +uint8_t *_eq_Int256(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Int256 *Lhs, + ScillaRTL::ScillaTypes::Int256 *Rhs); + +uint8_t *_eq_Uint32(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint32 Lhs, + ScillaRTL::ScillaTypes::Uint32 Rhs); + +uint8_t *_eq_Uint64(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint64 Lhs, + ScillaRTL::ScillaTypes::Uint64 Rhs); + +uint8_t *_eq_Uint128(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint128 Lhs, + ScillaRTL::ScillaTypes::Uint128 Rhs); + +uint8_t *_eq_Uint256(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint256 *Lhs, + ScillaRTL::ScillaTypes::Uint256 *Rhs); + +void *_to_nat(ScillaRTL::ScillaExecImpl *SJ, ScillaRTL::ScillaTypes::Uint32 UI); + +void _send(ScillaRTL::ScillaExecImpl *SJ, const ScillaRTL::ScillaTypes::Typ *T, + const void *V); + +void _event(ScillaRTL::ScillaExecImpl *SJ, const ScillaRTL::ScillaTypes::Typ *T, + const void *V); + +void _throw(ScillaRTL::ScillaExecImpl *SJ, const ScillaRTL::ScillaTypes::Typ *T, + const void *V); + +uint8_t *_eq_String(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Lhs, + ScillaRTL::ScillaTypes::String Rhs); + +uint8_t *_eq_ByStr(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Lhs, + ScillaRTL::ScillaTypes::String Rhs); + +uint8_t *_eq_ByStrX(ScillaRTL::ScillaExecImpl *SJ, int X, uint8_t *Lhs, + uint8_t *Rhs); + +ScillaRTL::ScillaTypes::String _to_bystr(ScillaRTL::ScillaExecImpl *SJ, int X, + uint8_t *Buf); + +ScillaRTL::ScillaTypes::String _to_string(ScillaRTL::ScillaExecImpl *SJ, + const ScillaRTL::ScillaTypes::Typ *T, + const void *V); + +ScillaRTL::ScillaTypes::String _to_ascii(ScillaRTL::ScillaExecImpl *SJ, + const uint8_t *S, int L); + +void *_bystr_to_bystrx(ScillaRTL::ScillaExecImpl *SJ, int X, + ScillaRTL::ScillaTypes::String Str); + +uint8_t *_bech32_to_bystr20(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Prefix, + ScillaRTL::ScillaTypes::String Addr); +void *_bystr20_to_bech32(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Prefix, uint8_t *Addr20); + +void *_uint32_to_bystrx(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint32 I); + +void *_uint64_to_bystrx(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint64 I); + +void *_uint128_to_bystrx(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint128 I); + +void *_uint256_to_bystrx(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::Uint256 *I); + +ScillaRTL::ScillaTypes::Uint32 _bystrx_to_uint32(ScillaRTL::ScillaExecImpl *, + int X, void *BS); +ScillaRTL::ScillaTypes::Uint64 _bystrx_to_uint64(ScillaRTL::ScillaExecImpl *, + int X, void *BS); +ScillaRTL::ScillaTypes::Uint128 _bystrx_to_uint128(ScillaRTL::ScillaExecImpl *, + int X, void *BS); +ScillaRTL::ScillaTypes::Uint256 *_bystrx_to_uint256(ScillaRTL::ScillaExecImpl *SJ, + int X, void *BS); + +void *_sha256hash(ScillaRTL::ScillaExecImpl *SJ, + const ScillaRTL::ScillaTypes::Typ *T, void *V); + +void *_keccak256hash(ScillaRTL::ScillaExecImpl *SJ, + const ScillaRTL::ScillaTypes::Typ *T, void *V); + +void *_ripemd160hash(ScillaRTL::ScillaExecImpl *SJ, + const ScillaRTL::ScillaTypes::Typ *T, void *V); + +uint8_t *_schnorr_verify(ScillaRTL::ScillaExecImpl *SJ, uint8_t *PubK, + ScillaRTL::ScillaTypes::String Msg, uint8_t *Sign); + +uint8_t *_schnorr_get_address(ScillaRTL::ScillaExecImpl *SJ, uint8_t *PubK); + +uint8_t *_ecdsa_verify(ScillaRTL::ScillaExecImpl *SJ, uint8_t *PubK, + ScillaRTL::ScillaTypes::String Msg, uint8_t *Sign); + +uint8_t *_ecdsa_recover_pk(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Msg, uint8_t *Sign, + ScillaRTL::ScillaTypes::Uint32 RecID); + +ScillaRTL::ScillaTypes::String _concat_String(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Lhs, + ScillaRTL::ScillaTypes::String Rhs); + +ScillaRTL::ScillaTypes::String _concat_ByStr(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Lhs, + ScillaRTL::ScillaTypes::String Rhs); + +void *_concat_ByStrX(ScillaRTL::ScillaExecImpl *SJ, int X1, uint8_t *Lhs, int X2, + uint8_t *Rhs); + +ScillaRTL::ScillaTypes::String _substr_String(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Str, + ScillaRTL::ScillaTypes::Uint32 Pos, + ScillaRTL::ScillaTypes::Uint32 Len); + +ScillaRTL::ScillaTypes::String _substr_ByStr(ScillaRTL::ScillaExecImpl *SJ, + ScillaRTL::ScillaTypes::String Str, + ScillaRTL::ScillaTypes::Uint32 Pos, + ScillaRTL::ScillaTypes::Uint32 Len); + +ScillaRTL::ScillaTypes::Uint32 _strlen_String(ScillaRTL::ScillaTypes::String Str); +ScillaRTL::ScillaTypes::Uint32 _strlen_ByStr(ScillaRTL::ScillaTypes::String Str); + +void _accept(ScillaRTL::ScillaExecImpl *SJ); + +ScillaRTL::ScillaParams::MapValueT *_new_empty_map(ScillaRTL::ScillaExecImpl *SJ); +ScillaRTL::ScillaParams::MapValueT *_put(ScillaRTL::ScillaExecImpl *SJ, + const ScillaRTL::ScillaTypes::Typ *T, + ScillaRTL::ScillaParams::MapValueT *M, + void *K, void *V); +void *_get(ScillaRTL::ScillaExecImpl *SJ, const ScillaRTL::ScillaTypes::Typ *T, + const ScillaRTL::ScillaParams::MapValueT *M, const void *K); +void *_contains(ScillaRTL::ScillaExecImpl *SJ, + const ScillaRTL::ScillaTypes::Typ *T, + const ScillaRTL::ScillaParams::MapValueT *M, const void *K); + +void *_remove(ScillaRTL::ScillaExecImpl *SJ, const ScillaRTL::ScillaTypes::Typ *T, + const ScillaRTL::ScillaParams::MapValueT *M, const void *K); + +// Scilla builtin _size : The size of a map. +ScillaRTL::ScillaTypes::Uint32 _size(const ScillaRTL::ScillaParams::MapValueT *M); + +uint64_t _literal_cost(const ScillaRTL::ScillaTypes::Typ *T, const void *V); +uint64_t _mapsortcost(const ScillaRTL::ScillaParams::MapValueT *M); + +} // extern "C" +#pragma clang diagnostic pop diff --git a/libsrtl/ScillaExecImpl.cpp b/libScillaRTL/ScillaExecImpl.cpp similarity index 98% rename from libsrtl/ScillaExecImpl.cpp rename to libScillaRTL/ScillaExecImpl.cpp index 9a4dfbe6..480ee9af 100644 --- a/libsrtl/ScillaExecImpl.cpp +++ b/libScillaRTL/ScillaExecImpl.cpp @@ -19,9 +19,9 @@ #include #include -#include "ScillaVM/Debug.h" -#include "ScillaVM/Errors.h" -#include "ScillaVM/ScillaExec.h" +#include "ScillaRTL/Debug.h" +#include "ScillaRTL/Errors.h" +#include "ScillaRTL/ScillaExec.h" #include "ObjManager.h" #include "SRTL.h" @@ -30,7 +30,7 @@ #include "ScillaTypes.h" #include "SharedObject.h" -namespace ScillaVM { +namespace ScillaRTL { ScillaContrExec::~ScillaContrExec() = default; @@ -356,4 +356,4 @@ Json::Value ScillaExecImpl::execMsg(const std::string &Balance, return Result; } -} // namespace ScillaVM \ No newline at end of file +} // namespace ScillaRTL \ No newline at end of file diff --git a/libsrtl/ScillaExecImpl.h b/libScillaRTL/ScillaExecImpl.h similarity index 97% rename from libsrtl/ScillaExecImpl.h rename to libScillaRTL/ScillaExecImpl.h index 52d76433..39644c8c 100644 --- a/libsrtl/ScillaExecImpl.h +++ b/libScillaRTL/ScillaExecImpl.h @@ -19,9 +19,9 @@ #include #include "ObjManager.h" -#include "ScillaVM/ScillaExec.h" +#include "ScillaRTL/ScillaExec.h" -namespace ScillaVM { +namespace ScillaRTL { class SharedObject; class TransitionState; @@ -66,4 +66,4 @@ class ScillaExecImpl { std::unique_ptr TS; }; -} // namespace ScillaVM \ No newline at end of file +} // namespace ScillaRTL \ No newline at end of file diff --git a/libsrtl/ScillaTypes.cpp b/libScillaRTL/ScillaTypes.cpp similarity index 99% rename from libsrtl/ScillaTypes.cpp rename to libScillaRTL/ScillaTypes.cpp index 97632c58..fd1f3acf 100644 --- a/libsrtl/ScillaTypes.cpp +++ b/libScillaRTL/ScillaTypes.cpp @@ -19,10 +19,10 @@ #include #include "ScillaTypes.h" -#include "ScillaVM/Errors.h" +#include "ScillaRTL/Errors.h" #include "SRTL.h" -namespace ScillaVM { +namespace ScillaRTL { namespace ScillaTypes { @@ -363,13 +363,13 @@ bool Typ::areAddressFieldsSorted(const Typ *T) { } } // namespace ScillaTypes -} // namespace ScillaVM +} // namespace ScillaRTL #include #include #include -namespace ScillaVM { +namespace ScillaRTL { namespace ScillaTypes { const Typ *Typ::fromString(TypParserPartialCache *TPPC, const Typ *Ts[], int NT, @@ -661,4 +661,4 @@ const Typ *Typ::fromString(TypParserPartialCache *TPPC, const Typ *Ts[], int NT, } } // namespace ScillaTypes -} // namespace ScillaVM \ No newline at end of file +} // namespace ScillaRTL \ No newline at end of file diff --git a/libsrtl/ScillaTypes.h b/libScillaRTL/ScillaTypes.h similarity index 99% rename from libsrtl/ScillaTypes.h rename to libScillaRTL/ScillaTypes.h index d2e7e2bb..2feaa4f2 100644 --- a/libsrtl/ScillaTypes.h +++ b/libScillaRTL/ScillaTypes.h @@ -22,7 +22,7 @@ #include #include -namespace ScillaVM { +namespace ScillaRTL { // Type descriptor definitions, whose values are generated by the compiler. // Any changes to the definitions here must be synchronized with the compiler. @@ -234,4 +234,4 @@ struct Typ { } // namespace ScillaTypes -} // end of namespace ScillaVM +} // end of namespace ScillaRTL diff --git a/libsrtl/ScillaValue.cpp b/libScillaRTL/ScillaValue.cpp similarity index 99% rename from libsrtl/ScillaValue.cpp rename to libScillaRTL/ScillaValue.cpp index 36c09f89..8a059760 100644 --- a/libsrtl/ScillaValue.cpp +++ b/libScillaRTL/ScillaValue.cpp @@ -17,14 +17,14 @@ #include -#include "ScillaVM/Errors.h" -#include "ScillaVM/Utils.h" +#include "ScillaRTL/Errors.h" +#include "ScillaRTL/Utils.h" #include "SafeInt.h" #include "ScillaExecImpl.h" #include "ScillaValue.h" -namespace ScillaVM { +namespace ScillaRTL { namespace { constexpr char Hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', @@ -851,4 +851,4 @@ uint64_t literalCost(const ScillaTypes::Typ *T, const void *V) { } } // namespace ScillaValues -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/ScillaValue.h b/libScillaRTL/ScillaValue.h similarity index 98% rename from libsrtl/ScillaValue.h rename to libScillaRTL/ScillaValue.h index a0afbfeb..3ea6024b 100644 --- a/libsrtl/ScillaValue.h +++ b/libScillaRTL/ScillaValue.h @@ -25,7 +25,7 @@ #include "SRTL.h" #include "ScillaTypes.h" -namespace ScillaVM { +namespace ScillaRTL { class ObjManager; @@ -68,4 +68,4 @@ void serializeForHashing(ByteVec &Ret, const ScillaTypes::Typ *T, uint64_t literalCost(const ScillaTypes::Typ *T, const void *V); } // namespace ScillaValues -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/SharedObject.h b/libScillaRTL/SharedObject.h similarity index 93% rename from libsrtl/SharedObject.h rename to libScillaRTL/SharedObject.h index d4b1cb61..f188c0ad 100644 --- a/libsrtl/SharedObject.h +++ b/libScillaRTL/SharedObject.h @@ -19,9 +19,9 @@ #include -#include +#include -namespace ScillaVM { +namespace ScillaRTL { class SharedObject { void *Handle; @@ -43,4 +43,4 @@ class SharedObject { return Ptr; } }; -} // namespace ScillaVM \ No newline at end of file +} // namespace ScillaRTL \ No newline at end of file diff --git a/libsrtl/Utils.cpp b/libScillaRTL/Utils.cpp similarity index 99% rename from libsrtl/Utils.cpp rename to libScillaRTL/Utils.cpp index 62559067..b4360668 100644 --- a/libsrtl/Utils.cpp +++ b/libScillaRTL/Utils.cpp @@ -26,8 +26,8 @@ #include #include "ScillaTypes.h" -#include "ScillaVM/Errors.h" -#include "ScillaVM/Utils.h" +#include "ScillaRTL/Errors.h" +#include "ScillaRTL/Utils.h" namespace { @@ -61,7 +61,7 @@ boost::optional vNameValue(const Json::Value &Vs, } // namespace -namespace ScillaVM { +namespace ScillaRTL { namespace bf = boost::filesystem; namespace bp = boost::process; @@ -523,7 +523,7 @@ std::string MemStateServer::initState(const Json::Value &InitJ, return recurser(ThisAddress, StateJ); -} // namespace ScillaVM +} // namespace ScillaRTL Json::Value MemStateServer::dumpToJSON() { Json::Value RetVal(Json::arrayValue); @@ -564,4 +564,4 @@ Json::Value MemStateServer::dumpToJSON() { return RetVal; } -} // namespace ScillaVM +} // namespace ScillaRTL diff --git a/libsrtl/ScillaBuiltins.h b/libsrtl/ScillaBuiltins.h deleted file mode 100644 index d9251bc8..00000000 --- a/libsrtl/ScillaBuiltins.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2020 Zilliqa - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -/* This file declares functions that are callable from an executing - * Scilla contract. It is not intended to be called from other C++ - * code, and is therefore not a public header. */ - -#include "ScillaVM/ScillaExec.h" - -#include "SafeInt.h" -#include "ScillaTypes.h" -#include "ScillaValue.h" - -namespace ScillaVM { - -// Values that begin with a transition and change as it executes. -class TransitionState { - SafeUint128 Balance; - SafeUint128 InAmount; - uint64_t *GasRemPtr; - bool Accepted; - // Contains the output messages of executing a transition. - Json::Value OutJ; - - void processMessage(std::string OutType, Json::Value &M); - -public: - TransitionState(std::string Balance_P, std::string InAmount_P, - uint64_t *GasRemPtr_P) - : Balance(Balance_P), InAmount(InAmount_P), GasRemPtr(GasRemPtr_P), - Accepted(false), OutJ(Json::objectValue){}; - - void processSend(Json::Value &M); - void processEvent(Json::Value &M); - void processAccept(); - - // Returns the output of the transition execution. Destroys *this*. - Json::Value finalize(); -}; - -} // end of namespace ScillaVM - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" - -extern "C" { - -// Print Scilla value @V whose type is described by @T to ScillaStdout . -void _print_scilla_val(const ScillaVM::ScillaTypes::Typ *T, void *V); - -// Allocate memory for JIT code owned by @SJ -void *_salloc(ScillaVM::ScillaExecImpl *SJ, size_t size); - -// Handler for out-of-gas during execution -void _out_of_gas(); - -// Fetch field @Name whose type is @T. For map accesses, FetchVal can be false, -// to indicate that the return value is a Scilla `Bool`, indicating found or -// not. -void *_fetch_field(ScillaVM::ScillaExecImpl *SJ, const char *Name, - const ScillaVM::ScillaTypes::Typ *T, int32_t NumIdx, - const uint8_t *Indices, int32_t FetchVal); - -// Same as _fetch_field, but with an address parameter. -void * -_fetch_remote_field(ScillaVM::ScillaExecImpl *SJ, - const uint8_t Addr[ScillaVM::ScillaTypes::AddrByStr_Len], - const char *Name, const ScillaVM::ScillaTypes::Typ *T, - int32_t NumIdx, const uint8_t *Indices, int32_t FetchVal); - -// Update field @Name whose type is @T with value @Val. If Val is nullptr, -// then this is a map update and the keys must be deleted. -void _update_field(ScillaVM::ScillaExecImpl *SJ, const char *Name, - const ScillaVM::ScillaTypes::Typ *, int32_t NumIdx, - const uint8_t *Indices, void *Val); - -// Integer addition builtins -ScillaVM::ScillaTypes::Int32 _add_Int32(ScillaVM::ScillaTypes::Int32, - ScillaVM::ScillaTypes::Int32); -ScillaVM::ScillaTypes::Int64 _add_Int64(ScillaVM::ScillaTypes::Int64, - ScillaVM::ScillaTypes::Int64); -ScillaVM::ScillaTypes::Int128 _add_Int128(ScillaVM::ScillaTypes::Int128, - ScillaVM::ScillaTypes::Int128); -ScillaVM::ScillaTypes::Int256 *_add_Int256(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Int256 *Lhs, - ScillaVM::ScillaTypes::Int256 *Rhs); - -ScillaVM::ScillaTypes::Uint32 _add_Uint32(ScillaVM::ScillaTypes::Uint32, - ScillaVM::ScillaTypes::Uint32); -ScillaVM::ScillaTypes::Uint64 _add_Uint64(ScillaVM::ScillaTypes::Uint64, - ScillaVM::ScillaTypes::Uint64); -ScillaVM::ScillaTypes::Uint128 _add_Uint128(ScillaVM::ScillaTypes::Uint128, - ScillaVM::ScillaTypes::Uint128); -ScillaVM::ScillaTypes::Uint256 * -_add_Uint256(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint256 *Lhs, - ScillaVM::ScillaTypes::Uint256 *Rhs); - -uint8_t *_eq_Int32(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Int32 Lhs, - ScillaVM::ScillaTypes::Int32 Rhs); - -uint8_t *_eq_Int64(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Int64 Lhs, - ScillaVM::ScillaTypes::Int64 Rhs); - -uint8_t *_eq_Int128(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Int128 Lhs, - ScillaVM::ScillaTypes::Int128 Rhs); - -uint8_t *_eq_Int256(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Int256 *Lhs, - ScillaVM::ScillaTypes::Int256 *Rhs); - -uint8_t *_eq_Uint32(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint32 Lhs, - ScillaVM::ScillaTypes::Uint32 Rhs); - -uint8_t *_eq_Uint64(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint64 Lhs, - ScillaVM::ScillaTypes::Uint64 Rhs); - -uint8_t *_eq_Uint128(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint128 Lhs, - ScillaVM::ScillaTypes::Uint128 Rhs); - -uint8_t *_eq_Uint256(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint256 *Lhs, - ScillaVM::ScillaTypes::Uint256 *Rhs); - -void *_to_nat(ScillaVM::ScillaExecImpl *SJ, ScillaVM::ScillaTypes::Uint32 UI); - -void _send(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, - const void *V); - -void _event(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, - const void *V); - -void _throw(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, - const void *V); - -uint8_t *_eq_String(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Lhs, - ScillaVM::ScillaTypes::String Rhs); - -uint8_t *_eq_ByStr(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Lhs, - ScillaVM::ScillaTypes::String Rhs); - -uint8_t *_eq_ByStrX(ScillaVM::ScillaExecImpl *SJ, int X, uint8_t *Lhs, - uint8_t *Rhs); - -ScillaVM::ScillaTypes::String _to_bystr(ScillaVM::ScillaExecImpl *SJ, int X, - uint8_t *Buf); - -ScillaVM::ScillaTypes::String _to_string(ScillaVM::ScillaExecImpl *SJ, - const ScillaVM::ScillaTypes::Typ *T, - const void *V); - -ScillaVM::ScillaTypes::String _to_ascii(ScillaVM::ScillaExecImpl *SJ, - const uint8_t *S, int L); - -void *_bystr_to_bystrx(ScillaVM::ScillaExecImpl *SJ, int X, - ScillaVM::ScillaTypes::String Str); - -uint8_t *_bech32_to_bystr20(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Prefix, - ScillaVM::ScillaTypes::String Addr); -void *_bystr20_to_bech32(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Prefix, uint8_t *Addr20); - -void *_uint32_to_bystrx(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint32 I); - -void *_uint64_to_bystrx(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint64 I); - -void *_uint128_to_bystrx(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint128 I); - -void *_uint256_to_bystrx(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::Uint256 *I); - -ScillaVM::ScillaTypes::Uint32 _bystrx_to_uint32(ScillaVM::ScillaExecImpl *, - int X, void *BS); -ScillaVM::ScillaTypes::Uint64 _bystrx_to_uint64(ScillaVM::ScillaExecImpl *, - int X, void *BS); -ScillaVM::ScillaTypes::Uint128 _bystrx_to_uint128(ScillaVM::ScillaExecImpl *, - int X, void *BS); -ScillaVM::ScillaTypes::Uint256 *_bystrx_to_uint256(ScillaVM::ScillaExecImpl *SJ, - int X, void *BS); - -void *_sha256hash(ScillaVM::ScillaExecImpl *SJ, - const ScillaVM::ScillaTypes::Typ *T, void *V); - -void *_keccak256hash(ScillaVM::ScillaExecImpl *SJ, - const ScillaVM::ScillaTypes::Typ *T, void *V); - -void *_ripemd160hash(ScillaVM::ScillaExecImpl *SJ, - const ScillaVM::ScillaTypes::Typ *T, void *V); - -uint8_t *_schnorr_verify(ScillaVM::ScillaExecImpl *SJ, uint8_t *PubK, - ScillaVM::ScillaTypes::String Msg, uint8_t *Sign); - -uint8_t *_schnorr_get_address(ScillaVM::ScillaExecImpl *SJ, uint8_t *PubK); - -uint8_t *_ecdsa_verify(ScillaVM::ScillaExecImpl *SJ, uint8_t *PubK, - ScillaVM::ScillaTypes::String Msg, uint8_t *Sign); - -uint8_t *_ecdsa_recover_pk(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Msg, uint8_t *Sign, - ScillaVM::ScillaTypes::Uint32 RecID); - -ScillaVM::ScillaTypes::String _concat_String(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Lhs, - ScillaVM::ScillaTypes::String Rhs); - -ScillaVM::ScillaTypes::String _concat_ByStr(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Lhs, - ScillaVM::ScillaTypes::String Rhs); - -void *_concat_ByStrX(ScillaVM::ScillaExecImpl *SJ, int X1, uint8_t *Lhs, int X2, - uint8_t *Rhs); - -ScillaVM::ScillaTypes::String _substr_String(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Str, - ScillaVM::ScillaTypes::Uint32 Pos, - ScillaVM::ScillaTypes::Uint32 Len); - -ScillaVM::ScillaTypes::String _substr_ByStr(ScillaVM::ScillaExecImpl *SJ, - ScillaVM::ScillaTypes::String Str, - ScillaVM::ScillaTypes::Uint32 Pos, - ScillaVM::ScillaTypes::Uint32 Len); - -ScillaVM::ScillaTypes::Uint32 _strlen_String(ScillaVM::ScillaTypes::String Str); -ScillaVM::ScillaTypes::Uint32 _strlen_ByStr(ScillaVM::ScillaTypes::String Str); - -void _accept(ScillaVM::ScillaExecImpl *SJ); - -ScillaVM::ScillaParams::MapValueT *_new_empty_map(ScillaVM::ScillaExecImpl *SJ); -ScillaVM::ScillaParams::MapValueT *_put(ScillaVM::ScillaExecImpl *SJ, - const ScillaVM::ScillaTypes::Typ *T, - ScillaVM::ScillaParams::MapValueT *M, - void *K, void *V); -void *_get(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, - const ScillaVM::ScillaParams::MapValueT *M, const void *K); -void *_contains(ScillaVM::ScillaExecImpl *SJ, - const ScillaVM::ScillaTypes::Typ *T, - const ScillaVM::ScillaParams::MapValueT *M, const void *K); - -void *_remove(ScillaVM::ScillaExecImpl *SJ, const ScillaVM::ScillaTypes::Typ *T, - const ScillaVM::ScillaParams::MapValueT *M, const void *K); - -// Scilla builtin _size : The size of a map. -ScillaVM::ScillaTypes::Uint32 _size(const ScillaVM::ScillaParams::MapValueT *M); - -uint64_t _literal_cost(const ScillaVM::ScillaTypes::Typ *T, const void *V); -uint64_t _mapsortcost(const ScillaVM::ScillaParams::MapValueT *M); - -} // extern "C" -#pragma clang diagnostic pop diff --git a/runners/expr-runner.cpp b/runners/expr-runner.cpp index cdd080a2..c540d6d7 100644 --- a/runners/expr-runner.cpp +++ b/runners/expr-runner.cpp @@ -19,12 +19,12 @@ #include #include -#include "ScillaVM/Debug.h" -#include "ScillaVM/Errors.h" -#include "ScillaVM/ScillaExec.h" -#include "ScillaVM/Utils.h" +#include "ScillaRTL/Debug.h" +#include "ScillaRTL/Errors.h" +#include "ScillaRTL/ScillaExec.h" +#include "ScillaRTL/Utils.h" -using namespace ScillaVM; +using namespace ScillaRTL; namespace { @@ -100,11 +100,11 @@ int main(int argc, char *argv[]) { parseCLIArgs(argc, argv, VM); if (VM.count("debug")) { - ScillaVM::enableAllDebugTypes(); + ScillaRTL::enableAllDebugTypes(); } else if (VM.count("debug-only")) { auto &DTs = VM["debug-only"].as>(); for (auto &DT : DTs) { - ScillaVM::addToCurrentDebugTypes(DT); + ScillaRTL::addToCurrentDebugTypes(DT); } } diff --git a/runners/scilla-runner.cpp b/runners/scilla-runner.cpp index 326a4a73..36c58792 100644 --- a/runners/scilla-runner.cpp +++ b/runners/scilla-runner.cpp @@ -19,12 +19,12 @@ #include #include -#include "ScillaVM/Debug.h" -#include "ScillaVM/Errors.h" -#include "ScillaVM/ScillaExec.h" -#include "ScillaVM/Utils.h" +#include "ScillaRTL/Debug.h" +#include "ScillaRTL/Errors.h" +#include "ScillaRTL/ScillaExec.h" +#include "ScillaRTL/Utils.h" -using namespace ScillaVM; +using namespace ScillaRTL; namespace { @@ -95,11 +95,11 @@ int main(int argc, char *argv[]) { parseCLIArgs(argc, argv, VM); if (VM.count("debug")) { - ScillaVM::enableAllDebugTypes(); + ScillaRTL::enableAllDebugTypes(); } else if (VM.count("debug-only")) { auto &DTs = VM["debug-only"].as>(); for (auto &DT : DTs) { - ScillaVM::addToCurrentDebugTypes(DT); + ScillaRTL::addToCurrentDebugTypes(DT); } } diff --git a/testsuite/ContrTests.cpp b/testsuite/ContrTests.cpp index 02dab4da..c2938864 100644 --- a/testsuite/ContrTests.cpp +++ b/testsuite/ContrTests.cpp @@ -20,14 +20,14 @@ #include using boost::test_tools::output_test_stream; -#include -#include -#include +#include +#include +#include #include "StateJsonUtils.h" #include "Testsuite.h" -using namespace ScillaVM; +using namespace ScillaRTL; using namespace ScillaTestsuite; namespace { @@ -73,14 +73,14 @@ void testMessagesHelper(const ContractTest &CT, bool CommonJIT) { // Tool to compile the LLVM-IR to a binary shared object. CompileToSO CSO(PathPrefix + CT.ContrFilename); - std::unique_ptr JE; + std::unique_ptr JE; if (CommonJIT) { BOOST_TEST_CHECKPOINT("Creating common JIT for " + CT.ContrFilename); // Create a JIT engine and execute the message. // TODO: Due to the below mentioned bug, this can't be in a try-catch block. { ScopeTimer CreateTimer(CT.ContrFilename + ": ScillaExec::create"); - JE = std::make_unique(SP, CSO.compile()); + JE = std::make_unique(SP, CSO.compile()); } } @@ -92,7 +92,7 @@ void testMessagesHelper(const ContractTest &CT, bool CommonJIT) { // block. { ScopeTimer CreateTimer(CT.ContrFilename + ": ScillaExec::create"); - JE = std::make_unique(SP, CSO.compile()); + JE = std::make_unique(SP, CSO.compile()); } } BOOST_TEST_MESSAGE("Testing " + CT.ContrFilename + " with input " + @@ -233,13 +233,13 @@ void testMessageFail(const std::string &ContrFilename, BOOST_FAIL(E.toString()); } - std::unique_ptr JE; + std::unique_ptr JE; bool CaughtException = false; try { // Create a JIT engine { ScopeTimer CreateTimer(ContrFilename + ": ScillaExec::create"); - JE = std::make_unique(SP, CSO.compile()); + JE = std::make_unique(SP, CSO.compile()); } { ScopeTimer ExecMsgTimer(ContrFilename + ": ScillaExec::execMsg"); diff --git a/testsuite/ExprExecTests.cpp b/testsuite/ExprExecTests.cpp index f386982d..113139d1 100644 --- a/testsuite/ExprExecTests.cpp +++ b/testsuite/ExprExecTests.cpp @@ -19,15 +19,15 @@ #include using boost::test_tools::output_test_stream; -#include -#include -#include +#include +#include +#include #include "Testsuite.h" namespace { -using namespace ScillaVM; +using namespace ScillaRTL; using namespace ScillaTestsuite; void testExecExprHelper(const std::string &Filename, @@ -38,7 +38,7 @@ void testExecExprHelper(const std::string &Filename, // Tool to compile the LLVM-IR to a binary shared object. CompileToSO CSO(Filename); // Setup a Scilla expression execution object. - ScillaExprExec SJ(ScillaVM::ScillaParams(), CSO.compile()); + ScillaExprExec SJ(ScillaRTL::ScillaParams(), CSO.compile()); BOOST_TEST_CHECKPOINT(Filename + ": Loaded compiled shared object."); ScillaOutput = SJ.exec(Config::GasLimit); } catch (const ScillaError &E) { @@ -74,7 +74,7 @@ void testExecFailExpr(const std::string &Testname) { // Tool to compile the LLVM-IR to a binary shared object. CompileToSO CSO(Filename); // Setup a Scilla expression execution object. - ScillaExprExec SJ(ScillaVM::ScillaParams(), CSO.compile()); + ScillaExprExec SJ(ScillaRTL::ScillaParams(), CSO.compile()); BOOST_TEST_CHECKPOINT(Filename + ": Loaded compiled shared object."); ScillaOutput = SJ.exec(Config::GasLimit); } catch (const ScillaError &E) { diff --git a/testsuite/StateJsonTests.cpp b/testsuite/StateJsonTests.cpp index 3ffde4bf..47e921b4 100644 --- a/testsuite/StateJsonTests.cpp +++ b/testsuite/StateJsonTests.cpp @@ -17,11 +17,11 @@ #include -#include -#include +#include +#include -#include "../libsrtl/ObjManager.h" -#include "../libsrtl/ScillaValue.h" +#include "../libScillaRTL/ObjManager.h" +#include "../libScillaRTL/ScillaValue.h" #include "StateJsonUtils.h" #include "Testsuite.h" @@ -29,11 +29,11 @@ namespace { // Type parser partial cache for faster run across tests. -ScillaVM::ScillaTypes::TypParserPartialCache TPPC; +ScillaRTL::ScillaTypes::TypParserPartialCache TPPC; // Parse a state JSON, Re-serialize back to JSON and compare. void testStateJson(const std::string &Testname, bool ExpectError = false) { - using namespace ScillaVM; + using namespace ScillaRTL; using namespace ScillaTestsuite; auto Filename = Config::TestsuiteSrc + "/state_jsons/" + Testname + ".json"; @@ -71,7 +71,7 @@ void testStateJson(const std::string &Testname, bool ExpectError = false) { BOOST_TEST_CHECKPOINT(Filename + ": " + VName.asString() + " comparison successful"); } - } catch (const ScillaVM::ScillaError &e) { + } catch (const ScillaRTL::ScillaError &e) { if (!ExpectError) BOOST_FAIL(e.toString()); else diff --git a/testsuite/Testsuite.cpp b/testsuite/Testsuite.cpp index 82a48d7d..433338e6 100644 --- a/testsuite/Testsuite.cpp +++ b/testsuite/Testsuite.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include namespace { namespace po = boost::program_options; @@ -104,11 +104,11 @@ struct CommandLineInit { BOOST_TEST_REQUIRE(boost::filesystem::is_directory(Dir)); Config::TestsuiteSrc = Dir; if (VM.count("debug")) { - ScillaVM::enableAllDebugTypes(); + ScillaRTL::enableAllDebugTypes(); } else if (VM.count("debug-only")) { auto &DTs = VM["debug-only"].as>(); for (auto &DT : DTs) { - ScillaVM::addToCurrentDebugTypes(DT); + ScillaRTL::addToCurrentDebugTypes(DT); } } if (VM.count("update-result")) { diff --git a/testsuite/TypeDescrs.cpp b/testsuite/TypeDescrs.cpp index d13c2a39..9ba655cf 100644 --- a/testsuite/TypeDescrs.cpp +++ b/testsuite/TypeDescrs.cpp @@ -21,7 +21,7 @@ namespace TypeDescrs { -using namespace ScillaVM::ScillaTypes; +using namespace ScillaRTL::ScillaTypes; // IntX types PrimTyp Int32_primtyp = {PrimTyp::Int_typ, {PrimTyp::Bits32}}; diff --git a/testsuite/TypeDescrs.h b/testsuite/TypeDescrs.h index 896ff45b..bff52056 100644 --- a/testsuite/TypeDescrs.h +++ b/testsuite/TypeDescrs.h @@ -15,11 +15,11 @@ * along with this program. If not, see . */ -#include "../libsrtl/ScillaTypes.h" +#include "../libScillaRTL/ScillaTypes.h" namespace TypeDescrs { -using namespace ScillaVM::ScillaTypes; +using namespace ScillaRTL::ScillaTypes; // IntX types extern Typ Int32_typ; diff --git a/testsuite/TypeTests.cpp b/testsuite/TypeTests.cpp index 40912c4b..471c17cc 100644 --- a/testsuite/TypeTests.cpp +++ b/testsuite/TypeTests.cpp @@ -19,19 +19,19 @@ #include -#include "../libsrtl/ScillaTypes.h" +#include "../libScillaRTL/ScillaTypes.h" #include "TypeDescrs.h" -#include -#include +#include +#include namespace { // Type parser partial cache for faster run across tests. -ScillaVM::ScillaTypes::TypParserPartialCache TPPC; +ScillaRTL::ScillaTypes::TypParserPartialCache TPPC; } // namespace BOOST_AUTO_TEST_SUITE(types) -using namespace ScillaVM::ScillaTypes; +using namespace ScillaRTL::ScillaTypes; // This tests the testsuite type descriptors. BOOST_AUTO_TEST_CASE(tydescrs_sanity) { @@ -74,14 +74,14 @@ const Typ *parseTypeString(const std::string TS) { using namespace TypeDescrs; try { return Typ::fromString(&TPPC, AllTyDescrs, NTyDescrs, TS); - } catch (const ScillaVM::ScillaError &E) { + } catch (const ScillaRTL::ScillaError &E) { BOOST_FAIL(E.toString()); } BOOST_UNREACHABLE_RETURN(); } void testMapDepthOfTypeString(const std::string TypeStr, int ExpectedDepth) { - auto DepthFromString = ScillaVM::mapDepthOfTypeString(TypeStr); + auto DepthFromString = ScillaRTL::mapDepthOfTypeString(TypeStr); BOOST_REQUIRE_MESSAGE(DepthFromString, "Map depth parser failed " << TypeStr); BOOST_REQUIRE_MESSAGE(ExpectedDepth == *DepthFromString, "Mismatch in map depth for " @@ -97,7 +97,7 @@ void parserTestSuccess(const std::string &Input, const std::string &ExpectedO) { << Typ::toString(T)); auto DepthFromType = Typ::getMapDepth(T); testMapDepthOfTypeString(Input, DepthFromType); - } catch (const ScillaVM::ScillaError &E) { + } catch (const ScillaRTL::ScillaError &E) { BOOST_FAIL(E.toString()); } } @@ -107,7 +107,7 @@ void parserTestFail(const std::string &Input) { bool CaughtError = false; try { Typ::fromString(&TPPC, AllTyDescrs, NTyDescrs, Input); - } catch (const ScillaVM::ScillaError &E) { + } catch (const ScillaRTL::ScillaError &E) { CaughtError = true; BOOST_TEST_MESSAGE("\tCaught expected exception: " << E.toString()); } @@ -438,13 +438,13 @@ BOOST_AUTO_TEST_CASE(map_depth_from_type_str_tests) { } BOOST_AUTO_TEST_CASE(map_depth_from_type_str_tests_fail) { - BOOST_REQUIRE(!ScillaVM::mapDepthOfTypeString("Map")); - BOOST_REQUIRE(!ScillaVM::mapDepthOfTypeString("List Map")); - BOOST_REQUIRE(!ScillaVM::mapDepthOfTypeString("Map Map")); - BOOST_REQUIRE(!ScillaVM::mapDepthOfTypeString("Map Map Map")); - BOOST_REQUIRE(!ScillaVM::mapDepthOfTypeString("Map (Map) Map")); - BOOST_REQUIRE(!ScillaVM::mapDepthOfTypeString("Map Uint32 Map")); - BOOST_REQUIRE(!ScillaVM::mapDepthOfTypeString("Map Uint32 (List Map)")); + BOOST_REQUIRE(!ScillaRTL::mapDepthOfTypeString("Map")); + BOOST_REQUIRE(!ScillaRTL::mapDepthOfTypeString("List Map")); + BOOST_REQUIRE(!ScillaRTL::mapDepthOfTypeString("Map Map")); + BOOST_REQUIRE(!ScillaRTL::mapDepthOfTypeString("Map Map Map")); + BOOST_REQUIRE(!ScillaRTL::mapDepthOfTypeString("Map (Map) Map")); + BOOST_REQUIRE(!ScillaRTL::mapDepthOfTypeString("Map Uint32 Map")); + BOOST_REQUIRE(!ScillaRTL::mapDepthOfTypeString("Map Uint32 (List Map)")); } BOOST_AUTO_TEST_SUITE_END() From df6b197b9b95395a9c934aa04fe3291487a6b04f Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Sun, 13 Jun 2021 14:16:12 +0530 Subject: [PATCH 4/6] Rename DEBUG/dbgs logging to DLog/dlog --- include/ScillaRTL/{Debug.h => DLog.h} | 33 +++++++++++++++------------ libScillaRTL/CMakeLists.txt | 2 +- libScillaRTL/{Debug.cpp => DLog.cpp} | 20 ++++++++-------- libScillaRTL/ScillaExecImpl.cpp | 1 - runners/expr-runner.cpp | 18 +++++++-------- runners/scilla-runner.cpp | 18 +++++++-------- testsuite/Testsuite.cpp | 18 +++++++-------- 7 files changed, 55 insertions(+), 55 deletions(-) rename include/ScillaRTL/{Debug.h => DLog.h} (62%) rename libScillaRTL/{Debug.cpp => DLog.cpp} (63%) diff --git a/include/ScillaRTL/Debug.h b/include/ScillaRTL/DLog.h similarity index 62% rename from include/ScillaRTL/Debug.h rename to include/ScillaRTL/DLog.h index 77adacea..2f860699 100644 --- a/include/ScillaRTL/Debug.h +++ b/include/ScillaRTL/DLog.h @@ -15,14 +15,14 @@ * along with this program. If not, see . */ -// This debug log infrastructure is inspired by: +// This DLOG log infrastructure is inspired by: // https://llvm.org/docs/ProgrammersManual.html#fine-grained-debug-info-with-debug-type-and-the-debug-only-option // Provide -// SVM_DEBUG(dbgs() << "debug message") and -// SVM_DEBUG_TYPE("foo", dbgs() << "debug message") -// in debug builds. For the former to work, DEBUG_TYPE must be -// defined. SVM_DEBUG is equal to SVM_DEBUG_TYPE(DEBUG_TYPE, ...). +// SRTL_DLOG(dlog() << "debug log message") and +// SRTL_DLOG_TYPE("foo", dlog() << "debug log message") +// in DLog builds. For the former to work, DLOG_TYPE must be +// defined. SRTL_DLOG is equal to SRTL_DLOG_TYPE(DLOG_TYPE, ...). #pragma once @@ -30,26 +30,29 @@ #include namespace ScillaRTL { -bool isInCurrentDebugTypes(std::string TYPE); -void addToCurrentDebugTypes(std::string TYPE); -void enableAllDebugTypes(); +bool isInCurrentDLogTypes(std::string TYPE); +void addToCurrentDLogTypes(std::string TYPE); +void enableAllDLogTypes(); } // namespace ScillaRTL #ifndef NDEBUG -#define SVM_DEBUG_TYPE(TYPE, X) \ +#define SRTL_DLOG_TYPE(TYPE, X) \ do { \ - if (ScillaRTL::isInCurrentDebugTypes(TYPE)) { \ + if (ScillaRTL::isInCurrentDLogTypes(TYPE)) { \ X; \ } \ } while (false) -#define SVM_DEBUG(X) SVM_DEBUG_TYPE(DEBUG_TYPE, X) +#define SRTL_DLOG(X) SRTL_DLOG_TYPE(DLOG_TYPE, X) namespace ScillaRTL { -std::ostream &dbgs(); +std::ostream &dlogImpl(const std::string &File, int Line); } + +#define dlog() dlogImpl(__FILE__, __LINE__) + #else -#define SVM_DEBUG_TYPE(TYPE, X) -#define SVM_DEBUG(X) -#endif +#define SRTL_DLOG_TYPE(TYPE, X) +#define SRTL_DLOG(X) +#endif // NDEBUG diff --git a/libScillaRTL/CMakeLists.txt b/libScillaRTL/CMakeLists.txt index dd9c1f26..84f1585d 100644 --- a/libScillaRTL/CMakeLists.txt +++ b/libScillaRTL/CMakeLists.txt @@ -7,7 +7,7 @@ add_library(${TARGET} SHARED ScillaValue.cpp SafeInt.cpp Utils.cpp - Debug.cpp + DLog.cpp ) target_compile_definitions(${TARGET} PUBLIC ${LLVM_DEFINITIONS}) diff --git a/libScillaRTL/Debug.cpp b/libScillaRTL/DLog.cpp similarity index 63% rename from libScillaRTL/Debug.cpp rename to libScillaRTL/DLog.cpp index 186c2fdc..c6a5387b 100644 --- a/libScillaRTL/Debug.cpp +++ b/libScillaRTL/DLog.cpp @@ -17,25 +17,23 @@ #include -#include +#include namespace ScillaRTL { -bool EnableAllDebugTypes; -std::set EnabledDebugTypes; +bool EnableAllDLogTypes; +std::set EnabledDLogTypes; -bool isInCurrentDebugTypes(std::string TYPE) { - return EnableAllDebugTypes || EnabledDebugTypes.count(TYPE); +bool isInCurrentDLogTypes(std::string TYPE) { + return EnableAllDLogTypes || EnabledDLogTypes.count(TYPE); } -void addToCurrentDebugTypes(std::string TYPE) { - EnabledDebugTypes.insert(TYPE); -} +void addToCurrentDLogTypes(std::string TYPE) { EnabledDLogTypes.insert(TYPE); } -void enableAllDebugTypes() { EnableAllDebugTypes = true; } +void enableAllDLogTypes() { EnableAllDLogTypes = true; } -std::ostream &dbgs() { - std::cout << "dbgs@" << __FILE__ << ":" << __LINE__ << ": "; +std::ostream &dlogImpl(const std::string &File, int Line) { + std::cout << "dlog@" << File << ":" << Line << ": "; return std::cout; } diff --git a/libScillaRTL/ScillaExecImpl.cpp b/libScillaRTL/ScillaExecImpl.cpp index 480ee9af..16360ed6 100644 --- a/libScillaRTL/ScillaExecImpl.cpp +++ b/libScillaRTL/ScillaExecImpl.cpp @@ -19,7 +19,6 @@ #include #include -#include "ScillaRTL/Debug.h" #include "ScillaRTL/Errors.h" #include "ScillaRTL/ScillaExec.h" diff --git a/runners/expr-runner.cpp b/runners/expr-runner.cpp index c540d6d7..088f7814 100644 --- a/runners/expr-runner.cpp +++ b/runners/expr-runner.cpp @@ -19,7 +19,7 @@ #include #include -#include "ScillaRTL/Debug.h" +#include "ScillaRTL/DLog.h" #include "ScillaRTL/Errors.h" #include "ScillaRTL/ScillaExec.h" #include "ScillaRTL/Utils.h" @@ -41,10 +41,10 @@ void parseCLIArgs(int argc, char *argv[], po::variables_map &VM) { ("output-file,o", po::value(), "Specify output filename") ("gaslimit,g", po::value(), "Gas limit") ("help,h", "Print help message") - ("debug", "Enable full logging (debug builds only)") - ("debug-only", + ("dlog", "Enable full logging (debug builds only)") + ("dlog-only", po::value >(), - "DEBUG_TYPE to activate for logging (debug builds only") + "SRTL_DLOG_TYPE to activate for logging (debug builds only") ("version,v", "Print version") ; @@ -99,12 +99,12 @@ int main(int argc, char *argv[]) { po::variables_map VM; parseCLIArgs(argc, argv, VM); - if (VM.count("debug")) { - ScillaRTL::enableAllDebugTypes(); - } else if (VM.count("debug-only")) { - auto &DTs = VM["debug-only"].as>(); + if (VM.count("dlog")) { + ScillaRTL::enableAllDLogTypes(); + } else if (VM.count("dlog-only")) { + auto &DTs = VM["dlog-only"].as>(); for (auto &DT : DTs) { - ScillaRTL::addToCurrentDebugTypes(DT); + ScillaRTL::addToCurrentDLogTypes(DT); } } diff --git a/runners/scilla-runner.cpp b/runners/scilla-runner.cpp index 36c58792..0bd6096e 100644 --- a/runners/scilla-runner.cpp +++ b/runners/scilla-runner.cpp @@ -19,7 +19,7 @@ #include #include -#include "ScillaRTL/Debug.h" +#include "ScillaRTL/DLog.h" #include "ScillaRTL/Errors.h" #include "ScillaRTL/ScillaExec.h" #include "ScillaRTL/Utils.h" @@ -47,10 +47,10 @@ void parseCLIArgs(int argc, char *argv[], po::variables_map &VM) { ("gaslimit,g", po::value(), "Gas limit") ("contract-info,c", po::value(), "Specify the contract info JSON from checker") ("output-file,o", po::value(), "Specify output filename") - ("debug", "Enable full logging (debug builds only)") - ("debug-only", + ("dlog", "Enable full logging (debug builds only)") + ("dlog-only", po::value >(), - "DEBUG_TYPE to activate for logging (debug builds only") + "SRTL_DLOG_TYPE to activate for logging (debug builds only") ("help,h", "Print help message") ("version,v", "Print version") ; @@ -94,12 +94,12 @@ int main(int argc, char *argv[]) { po::variables_map VM; parseCLIArgs(argc, argv, VM); - if (VM.count("debug")) { - ScillaRTL::enableAllDebugTypes(); - } else if (VM.count("debug-only")) { - auto &DTs = VM["debug-only"].as>(); + if (VM.count("dlog")) { + ScillaRTL::enableAllDLogTypes(); + } else if (VM.count("dlog-only")) { + auto &DTs = VM["dlog-only"].as>(); for (auto &DT : DTs) { - ScillaRTL::addToCurrentDebugTypes(DT); + ScillaRTL::addToCurrentDLogTypes(DT); } } diff --git a/testsuite/Testsuite.cpp b/testsuite/Testsuite.cpp index 433338e6..2a7cbbe5 100644 --- a/testsuite/Testsuite.cpp +++ b/testsuite/Testsuite.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include namespace { namespace po = boost::program_options; @@ -36,10 +36,10 @@ void parseCLIArgs(int argc, char *argv[], po::variables_map &VM) { // clang-format off Desc.add_options() ("help,h", "Print help message") - ("debug", "Enable full logging (debug builds only)") - ("debug-only", + ("dlog", "Enable full logging (debug builds only)") + ("dlog-only", po::value >(), - "DEBUG_TYPE to activate for logging (debug builds only") + "SRTL_DLOG_TYPE to activate for logging (debug builds only") ("update-result", "Update expected results of all executed tests") ; @@ -103,12 +103,12 @@ struct CommandLineInit { auto Dir = VM["testsuite-dir"].as(); BOOST_TEST_REQUIRE(boost::filesystem::is_directory(Dir)); Config::TestsuiteSrc = Dir; - if (VM.count("debug")) { - ScillaRTL::enableAllDebugTypes(); - } else if (VM.count("debug-only")) { - auto &DTs = VM["debug-only"].as>(); + if (VM.count("dlog")) { + ScillaRTL::enableAllDLogTypes(); + } else if (VM.count("dlog-only")) { + auto &DTs = VM["dlog-only"].as>(); for (auto &DT : DTs) { - ScillaRTL::addToCurrentDebugTypes(DT); + ScillaRTL::addToCurrentDLogTypes(DT); } } if (VM.count("update-result")) { From b12452d566023b1c9863689147611ed7fbe9b7d5 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Sun, 13 Jun 2021 14:42:01 +0530 Subject: [PATCH 5/6] Use clang-10 explicitly when compiling to shared lib --- README.md | 4 +++- libScillaRTL/Utils.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3154249e..3008c11c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,9 @@ The Scilla Runtime Library provides two main functionalities ## Build and install Install these Ubuntu packages - - `sudo apt-get install build-essential cmake libboost-dev libboost-test-dev libjsoncpp-dev libboost-filesystem-dev libboost-program-options-dev libsecp256k1-dev` + - `sudo apt-get install build-essential clang-10 cmake libboost-dev libboost-test-dev libjsoncpp-dev libboost-filesystem-dev libboost-program-options-dev libsecp256k1-dev` + +Use the LLVM apt repository if clang-10 is not in your OS repository. We suggest building ScillaRTL in a directory that is *not* the source directory. * `$git clone --recurse-submodules https://github.com/Zilliqa/scilla-vm.git` diff --git a/libScillaRTL/Utils.cpp b/libScillaRTL/Utils.cpp index b4360668..65ae2a08 100644 --- a/libScillaRTL/Utils.cpp +++ b/libScillaRTL/Utils.cpp @@ -101,7 +101,7 @@ CompileToSO::CompileToSO(const std::string &Filename) std::string CompileToSO::compile() const { try { - auto ExecP = bp::search_path("clang"); + auto ExecP = bp::search_path("clang-10"); if (bp::system(ExecP, "-fPIC", "-shared", InputFile, "-o", SOFile.native())) { CREATE_ERROR("Compilation of " + InputFile + " failed."); From f051988660d3fd3347cd3c0cd468447c2c4640c9 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Sun, 13 Jun 2021 14:51:20 +0530 Subject: [PATCH 6/6] Use clang-10 package in CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6b51e466..88c64757 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ addons: - libjsoncpp-dev - libsecp256k1-dev - llvm-10-dev + - clang-10 cache: directories: - $HOME/openssl