From 8e270c26e980bbaabe4a2c074052196028f8a013 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Fri, 24 Jan 2020 10:43:03 -0500 Subject: [PATCH 1/2] remove old WAVM Platform files and WAVM intrinsics --- libraries/wasm-jit/CMakeLists.txt | 1 - .../wasm-jit/Include/Platform/Platform.h | 176 +------- .../wasm-jit/Source/Logging/CMakeLists.txt | 1 - libraries/wasm-jit/Source/Logging/Logging.cpp | 4 - .../wasm-jit/Source/Platform/CMakeLists.txt | 20 - libraries/wasm-jit/Source/Platform/POSIX.cpp | 422 ------------------ .../wasm-jit/Source/Platform/Windows.cpp | 368 --------------- .../wasm-jit/Source/Runtime/CMakeLists.txt | 3 +- .../wasm-jit/Source/Runtime/Intrinsics.cpp | 7 +- .../wasm-jit/Source/Runtime/RuntimePrivate.h | 14 - .../Source/Runtime/WAVMIntrinsics.cpp | 222 --------- 11 files changed, 14 insertions(+), 1224 deletions(-) delete mode 100644 libraries/wasm-jit/Source/Platform/CMakeLists.txt delete mode 100644 libraries/wasm-jit/Source/Platform/POSIX.cpp delete mode 100644 libraries/wasm-jit/Source/Platform/Windows.cpp delete mode 100644 libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp diff --git a/libraries/wasm-jit/CMakeLists.txt b/libraries/wasm-jit/CMakeLists.txt index 7697f6ee59f..a62632b2623 100644 --- a/libraries/wasm-jit/CMakeLists.txt +++ b/libraries/wasm-jit/CMakeLists.txt @@ -69,7 +69,6 @@ add_subdirectory(Include/Inline) add_subdirectory(Source/IR) add_subdirectory(Source/Logging) -add_subdirectory(Source/Platform) add_subdirectory(Source/Runtime) add_subdirectory(Source/WASM) add_subdirectory(Source/WAST) diff --git a/libraries/wasm-jit/Include/Platform/Platform.h b/libraries/wasm-jit/Include/Platform/Platform.h index edaeef071d8..8c964d8487b 100644 --- a/libraries/wasm-jit/Include/Platform/Platform.h +++ b/libraries/wasm-jit/Include/Platform/Platform.h @@ -6,23 +6,13 @@ #include "Inline/BasicTypes.h" #include "Inline/Errors.h" -#ifdef _WIN32 - #define THREAD_LOCAL thread_local - #define DLL_EXPORT __declspec(dllexport) - #define DLL_IMPORT __declspec(dllimport) - #define FORCEINLINE __forceinline - #define SUPPRESS_UNUSED(variable) (void)(variable); - #include - #define PACKED_STRUCT(definition) __pragma(pack(push, 1)) definition; __pragma(pack(pop)) -#else - // Use __thread instead of the C++11 thread_local because Apple's clang doesn't support thread_local yet. - #define THREAD_LOCAL __thread - #define DLL_EXPORT - #define DLL_IMPORT - #define FORCEINLINE inline __attribute__((always_inline)) - #define SUPPRESS_UNUSED(variable) (void)(variable); - #define PACKED_STRUCT(definition) definition __attribute__((packed)); -#endif +// Use __thread instead of the C++11 thread_local because Apple's clang doesn't support thread_local yet. +#define THREAD_LOCAL __thread +#define DLL_EXPORT +#define DLL_IMPORT +#define FORCEINLINE inline __attribute__((always_inline)) +#define SUPPRESS_UNUSED(variable) (void)(variable); +#define PACKED_STRUCT(definition) definition __attribute__((packed)); #ifndef PLATFORM_API #define PLATFORM_API DLL_IMPORT @@ -31,155 +21,13 @@ namespace Platform { // countLeadingZeroes/countTrailingZeroes returns the number of leading/trailing zeroes, or the bit width of the input if no bits are set. - #ifdef _WIN32 - // BitScanReverse/BitScanForward return 0 if the input is 0. - inline U32 countLeadingZeroes(U32 value) { unsigned long result; return _BitScanReverse(&result,value) ? (31 - result) : 32; } - inline U32 countTrailingZeroes(U32 value) { unsigned long result; return _BitScanForward(&result,value) ? result : 32; } - - #ifdef _WIN64 - inline U64 countLeadingZeroes(U64 value) { unsigned long result; return _BitScanReverse64(&result,value) ? (63 - result) : 64; } - inline U64 countTrailingZeroes(U64 value) { unsigned long result; return _BitScanForward64(&result,value) ? result : 64; } - #else - inline U64 countLeadingZeroes(U64 value) { throw; } - inline U64 countTrailingZeroes(U64 value) { throw; } - #endif - #else - // __builtin_clz/__builtin_ctz are undefined if the input is 0. - inline U64 countLeadingZeroes(U64 value) { return value == 0 ? 64 : __builtin_clzll(value); } - inline U32 countLeadingZeroes(U32 value) { return value == 0 ? 32 : __builtin_clz(value); } - inline U64 countTrailingZeroes(U64 value) { return value == 0 ? 64 : __builtin_ctzll(value); } - inline U32 countTrailingZeroes(U32 value) { return value == 0 ? 32 : __builtin_ctz(value); } - #endif + // __builtin_clz/__builtin_ctz are undefined if the input is 0. + inline U64 countLeadingZeroes(U64 value) { return value == 0 ? 64 : __builtin_clzll(value); } + inline U32 countLeadingZeroes(U32 value) { return value == 0 ? 32 : __builtin_clz(value); } + inline U64 countTrailingZeroes(U64 value) { return value == 0 ? 64 : __builtin_ctzll(value); } + inline U32 countTrailingZeroes(U32 value) { return value == 0 ? 32 : __builtin_ctz(value); } inline U64 floorLogTwo(U64 value) { return value <= 1 ? 0 : 63 - countLeadingZeroes(value); } inline U32 floorLogTwo(U32 value) { return value <= 1 ? 0 : 31 - countLeadingZeroes(value); } inline U64 ceilLogTwo(U64 value) { return floorLogTwo(value * 2 - 1); } inline U32 ceilLogTwo(U32 value) { return floorLogTwo(value * 2 - 1); } - - // - // Memory - // - - // Describes allowed memory accesses. - enum class MemoryAccess - { - None, - ReadOnly, - ReadWrite, - Execute, - ReadWriteExecute - }; - - // Returns the base 2 logarithm of the smallest virtual page size. - PLATFORM_API Uptr getPageSizeLog2(); - - // Allocates virtual addresses without commiting physical pages to them. - // Returns the base virtual address of the allocated addresses, or nullptr if the virtual address space has been exhausted. - PLATFORM_API U8* allocateVirtualPages(Uptr numPages); - - // Commits physical memory to the specified virtual pages. - // baseVirtualAddress must be a multiple of the preferred page size. - // Return true if successful, or false if physical memory has been exhausted. - PLATFORM_API bool commitVirtualPages(U8* baseVirtualAddress,Uptr numPages,MemoryAccess access = MemoryAccess::ReadWrite); - - // Changes the allowed access to the specified virtual pages. - // baseVirtualAddress must be a multiple of the preferred page size. - // Return true if successful, or false if the access-level could not be set. - PLATFORM_API bool setVirtualPageAccess(U8* baseVirtualAddress,Uptr numPages,MemoryAccess access); - - // Decommits the physical memory that was committed to the specified virtual pages. - // baseVirtualAddress must be a multiple of the preferred page size. - PLATFORM_API void decommitVirtualPages(U8* baseVirtualAddress,Uptr numPages); - - // Frees virtual addresses. Any physical memory committed to the addresses must have already been decommitted. - // baseVirtualAddress must be a multiple of the preferred page size. - PLATFORM_API void freeVirtualPages(U8* baseVirtualAddress,Uptr numPages); - - // - // Call stack and exceptions - // - - // Describes a call stack. - struct CallStack - { - struct Frame - { - Uptr ip; - }; - std::vector stackFrames; - }; - - // Captures the execution context of the caller. - PLATFORM_API CallStack captureCallStack(Uptr numOmittedFramesFromTop = 0); - - // Describes an instruction pointer. - PLATFORM_API bool describeInstructionPointer(Uptr ip,std::string& outDescription); - - #ifdef _WIN64 - // Registers/deregisters the data used by Windows SEH to unwind stack frames. - PLATFORM_API void registerSEHUnwindInfo(Uptr imageLoadAddress,Uptr pdataAddress,Uptr pdataNumBytes); - PLATFORM_API void deregisterSEHUnwindInfo(Uptr pdataAddress); - #endif - - // Calls a thunk, and if it causes any of some specific hardware traps, returns true. - // If a trap was caught, the outCause, outContext, and outOperand parameters are set to describe the trap. - enum HardwareTrapType - { - none, - accessViolation, - stackOverflow, - intDivideByZeroOrOverflow - }; - PLATFORM_API HardwareTrapType catchHardwareTraps( - CallStack& outTrapCallStack, - Uptr& outTrapOperand, - const std::function& thunk - ); - PLATFORM_API [[noreturn]] void immediately_exit(std::exception_ptr except); - - // - // Threading - // - - // Returns the current value of a clock that may be used as an absolute time for wait timeouts. - // The resolution is microseconds, and the origin is arbitrary. - PLATFORM_API U64 getMonotonicClock(); - - // Platform-independent mutexes. - struct Mutex; - PLATFORM_API Mutex* createMutex(); - PLATFORM_API void destroyMutex(Mutex* mutex); - PLATFORM_API void lockMutex(Mutex* mutex); - PLATFORM_API void unlockMutex(Mutex* mutex); - - // RAII-style lock for Mutex. - struct Lock - { - Lock(Mutex* inMutex) : mutex(inMutex) { lockMutex(mutex); } - ~Lock() { unlockMutex(mutex); } - - void release() - { - if(mutex) - { - unlockMutex(mutex); - } - mutex = nullptr; - } - - void detach() - { - WAVM_ASSERT_THROW(mutex); - mutex = nullptr; - } - - private: - Mutex* mutex; - }; - - // Platform-independent events. - struct Event; - PLATFORM_API Event* createEvent(); - PLATFORM_API void destroyEvent(Event* event); - PLATFORM_API bool waitForEvent(Event* event,U64 untilClock); - PLATFORM_API void signalEvent(Event* event); } diff --git a/libraries/wasm-jit/Source/Logging/CMakeLists.txt b/libraries/wasm-jit/Source/Logging/CMakeLists.txt index 7ca6fff5842..659dd7c9ba5 100644 --- a/libraries/wasm-jit/Source/Logging/CMakeLists.txt +++ b/libraries/wasm-jit/Source/Logging/CMakeLists.txt @@ -7,7 +7,6 @@ include_directories(${WAVM_INCLUDE_DIR}/Logging) add_definitions(-DLOGGING_API=DLL_EXPORT) add_library(Logging STATIC ${Sources} ${PublicHeaders}) -target_link_libraries(Logging Platform) # Link with dl on Linux for dladdr. if(CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/libraries/wasm-jit/Source/Logging/Logging.cpp b/libraries/wasm-jit/Source/Logging/Logging.cpp index a18f6225348..7fae383da9a 100644 --- a/libraries/wasm-jit/Source/Logging/Logging.cpp +++ b/libraries/wasm-jit/Source/Logging/Logging.cpp @@ -7,7 +7,6 @@ namespace Log { - static Platform::Mutex* categoryEnabledMutex = Platform::createMutex(); static bool categoryEnabled[(Uptr)Category::num] = { true, // error @@ -20,19 +19,16 @@ namespace Log }; void setCategoryEnabled(Category category,bool enable) { - Platform::Lock lock(categoryEnabledMutex); WAVM_ASSERT_THROW(category < Category::num); categoryEnabled[(Uptr)category] = enable; } bool isCategoryEnabled(Category category) { - Platform::Lock lock(categoryEnabledMutex); WAVM_ASSERT_THROW(category < Category::num); return categoryEnabled[(Uptr)category]; } void printf(Category category,const char* format,...) { - Platform::Lock lock(categoryEnabledMutex); if(categoryEnabled[(Uptr)category]) { va_list varArgs; diff --git a/libraries/wasm-jit/Source/Platform/CMakeLists.txt b/libraries/wasm-jit/Source/Platform/CMakeLists.txt deleted file mode 100644 index d77fe151391..00000000000 --- a/libraries/wasm-jit/Source/Platform/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(Sources - POSIX.cpp - Windows.cpp) -set(PublicHeaders - ${WAVM_INCLUDE_DIR}/Platform/Platform.h) -include_directories(${WAVM_INCLUDE_DIR}/Platform) - -add_definitions(-DPLATFORM_API=DLL_EXPORT) - -add_library(Platform STATIC ${Sources} ${PublicHeaders}) - -# Link with dl on Linux for dladdr. -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries(Platform dl pthread rt) -endif() - -install(TARGETS Platform - LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) - diff --git a/libraries/wasm-jit/Source/Platform/POSIX.cpp b/libraries/wasm-jit/Source/Platform/POSIX.cpp deleted file mode 100644 index b6810e97480..00000000000 --- a/libraries/wasm-jit/Source/Platform/POSIX.cpp +++ /dev/null @@ -1,422 +0,0 @@ -#ifndef _WIN32 - -#include "Inline/BasicTypes.h" -#include "Inline/Errors.h" -#include "Platform/Platform.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define __STDC_FORMAT_MACROS -#include - -#ifdef __APPLE__ - #define MAP_ANONYMOUS MAP_ANON -#endif - -#ifdef __linux__ - #include - #include -#endif -#ifdef __FreeBSD__ - #include - #include - #include - #include -#endif - -namespace Platform -{ - static Uptr internalGetPreferredVirtualPageSizeLog2() - { - U32 preferredVirtualPageSize = sysconf(_SC_PAGESIZE); - // Verify our assumption that the virtual page size is a power of two. - WAVM_ASSERT_THROW(!(preferredVirtualPageSize & (preferredVirtualPageSize - 1))); - return floorLogTwo(preferredVirtualPageSize); - } - Uptr getPageSizeLog2() - { - static Uptr preferredVirtualPageSizeLog2 = internalGetPreferredVirtualPageSizeLog2(); - return preferredVirtualPageSizeLog2; - } - - U32 memoryAccessAsPOSIXFlag(MemoryAccess access) - { - switch(access) - { - default: - case MemoryAccess::None: return PROT_NONE; - case MemoryAccess::ReadOnly: return PROT_READ; - case MemoryAccess::ReadWrite: return PROT_READ | PROT_WRITE; - case MemoryAccess::Execute: return PROT_EXEC; - case MemoryAccess::ReadWriteExecute: return PROT_EXEC | PROT_READ | PROT_WRITE; - } - } - - bool isPageAligned(U8* address) - { - const Uptr addressBits = reinterpret_cast(address); - return (addressBits & ((1ull << getPageSizeLog2()) - 1)) == 0; - } - - U8* allocateVirtualPages(Uptr numPages) - { - Uptr numBytes = numPages << getPageSizeLog2(); - auto result = mmap(nullptr,numBytes,PROT_NONE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0); - if(result == MAP_FAILED) - { - return nullptr; - } - return (U8*)result; - } - - bool commitVirtualPages(U8* baseVirtualAddress,Uptr numPages,MemoryAccess access) - { - errorUnless(isPageAligned(baseVirtualAddress)); - return mprotect(baseVirtualAddress,numPages << getPageSizeLog2(),memoryAccessAsPOSIXFlag(access)) == 0; - } - - bool setVirtualPageAccess(U8* baseVirtualAddress,Uptr numPages,MemoryAccess access) - { - errorUnless(isPageAligned(baseVirtualAddress)); - return mprotect(baseVirtualAddress,numPages << getPageSizeLog2(),memoryAccessAsPOSIXFlag(access)) == 0; - } - - void decommitVirtualPages(U8* baseVirtualAddress,Uptr numPages) - { - errorUnless(isPageAligned(baseVirtualAddress)); - auto numBytes = numPages << getPageSizeLog2(); - if(madvise(baseVirtualAddress,numBytes,MADV_DONTNEED)) { Errors::fatal("madvise failed"); } - if(mprotect(baseVirtualAddress,numBytes,PROT_NONE)) { Errors::fatal("mprotect failed"); } - } - - void freeVirtualPages(U8* baseVirtualAddress,Uptr numPages) - { - errorUnless(isPageAligned(baseVirtualAddress)); - if(munmap(baseVirtualAddress,numPages << getPageSizeLog2())) { Errors::fatal("munmap failed"); } - } - - bool describeInstructionPointer(Uptr ip,std::string& outDescription) - { - #if defined __linux__ || defined __FreeBSD__ - // Look up static symbol information for the address. - Dl_info symbolInfo; - if(dladdr((void*)ip,&symbolInfo) && symbolInfo.dli_sname) - { - outDescription = symbolInfo.dli_sname; - return true; - } - #endif - return false; - } - - enum { signalStackNumBytes = 65536 }; - THREAD_LOCAL U8* signalStack = nullptr; - THREAD_LOCAL U8* stackMinAddr = nullptr; - THREAD_LOCAL U8* stackMaxAddr = nullptr; - - void initThread() - { - if(!signalStack) - { - // Allocate a stack to use when handling signals, so stack overflow can be handled safely. - signalStack = new U8[signalStackNumBytes]; - stack_t signalStackInfo; - signalStackInfo.ss_size = signalStackNumBytes; - signalStackInfo.ss_sp = signalStack; - signalStackInfo.ss_flags = 0; - if(sigaltstack(&signalStackInfo,nullptr) < 0) - { - Errors::fatal("sigaltstack failed"); - } - - // Get the stack address from pthreads, but use getrlimit to find the maximum size of the stack instead of the current. - struct rlimit stackLimit; - getrlimit(RLIMIT_STACK,&stackLimit); - #if defined __linux__ || defined __FreeBSD__ - // Linux uses pthread_getattr_np/pthread_attr_getstack, and returns a pointer to the minimum address of the stack. - pthread_attr_t threadAttributes; - pthread_attr_init(&threadAttributes); - #ifdef __linux__ - pthread_getattr_np(pthread_self(),&threadAttributes); - #else - pthread_attr_get_np(pthread_self(), &threadAttributes); - #endif - Uptr stackSize; - pthread_attr_getstack(&threadAttributes,(void**)&stackMinAddr,&stackSize); - pthread_attr_destroy(&threadAttributes); - stackMaxAddr = stackMinAddr + stackSize; - stackMinAddr = stackMaxAddr - stackLimit.rlim_cur; - #else - // MacOS uses pthread_getstackaddr_np, and returns a pointer to the maximum address of the stack. - stackMaxAddr = (U8*)pthread_get_stackaddr_np(pthread_self()); - stackMinAddr = stackMaxAddr - stackLimit.rlim_cur; - #endif - - // Include an extra page below the stack's usable address range to distinguish stack overflows from general SIGSEGV. - const Uptr pageSize = sysconf(_SC_PAGESIZE); - stackMinAddr -= pageSize; - } - } - - THREAD_LOCAL sigjmp_buf signalReturnEnv; - THREAD_LOCAL HardwareTrapType signalType = HardwareTrapType::none; - THREAD_LOCAL CallStack* signalCallStack = nullptr; - THREAD_LOCAL Uptr* signalOperand = nullptr; - THREAD_LOCAL bool isReentrantSignal = false; - THREAD_LOCAL bool isCatchingSignals = false; - thread_local std::exception_ptr thrown_exception; - - void signalHandler(int signalNumber,siginfo_t* signalInfo,void*) - { - if(isReentrantSignal) { Errors::fatal("reentrant signal handler"); } - isReentrantSignal = true; - - // Derive the exception cause the from signal that was received. - switch(signalNumber) - { - case SIGFPE: - if(signalInfo->si_code != FPE_INTDIV && signalInfo->si_code != FPE_INTOVF) { Errors::fatal("unknown SIGFPE code"); } - signalType = HardwareTrapType::intDivideByZeroOrOverflow; - break; - case SIGSEGV: - case SIGBUS: - signalType = signalInfo->si_addr >= stackMinAddr && signalInfo->si_addr < stackMaxAddr - ? HardwareTrapType::stackOverflow - : HardwareTrapType::accessViolation; - *signalOperand = reinterpret_cast(signalInfo->si_addr); - break; - default: - Errors::fatalf("unknown signal number: %i",signalNumber); - break; - }; - - // Capture the execution context, omitting this function and the function that called it, - // so the top of the callstack is the function that triggered the signal. - *signalCallStack = captureCallStack(2); - - // If the signal occurred outside of a catchHardwareTraps call, just treat it as a fatal error. - if(!isCatchingSignals) - { - switch(signalNumber) - { - case SIGFPE: Errors::fatalf("unhandled SIGFPE\n"); - case SIGSEGV: Errors::fatalf("unhandled SIGSEGV\n"); - case SIGBUS: Errors::fatalf("unhandled SIGBUS\n"); - default: Errors::unreachable(); - }; - } - - // Jump back to the setjmp in catchHardwareTraps. - siglongjmp(signalReturnEnv,1); - } - - THREAD_LOCAL bool hasInitializedSignalHandlers = false; - - void initSignals() - { - if(!hasInitializedSignalHandlers) - { - hasInitializedSignalHandlers = true; - - // Set a signal handler for the signals we want to intercept. - struct sigaction signalAction; - signalAction.sa_sigaction = signalHandler; - sigemptyset(&signalAction.sa_mask); - signalAction.sa_flags = SA_SIGINFO | SA_ONSTACK; - sigaction(SIGSEGV,&signalAction,nullptr); - sigaction(SIGBUS,&signalAction,nullptr); - sigaction(SIGFPE,&signalAction,nullptr); - } - } - - HardwareTrapType catchHardwareTraps( - CallStack& outTrapCallStack, - Uptr& outTrapOperand, - const std::function& thunk - ) - { - initThread(); - initSignals(); - - jmp_buf oldSignalReturnEnv; - memcpy(&oldSignalReturnEnv,&signalReturnEnv,sizeof(jmp_buf)); - const bool oldIsCatchingSignals = isCatchingSignals; - thrown_exception = nullptr; - - // Use setjmp to allow signals to jump back to this point. - bool isReturningFromSignalHandler = sigsetjmp(signalReturnEnv,1); - if(!isReturningFromSignalHandler) - { - signalType = HardwareTrapType::none; - signalCallStack = &outTrapCallStack; - signalOperand = &outTrapOperand; - isCatchingSignals = true; - - // Call the thunk. - thunk(); - } - - // Reset the signal state. - memcpy(&signalReturnEnv,&oldSignalReturnEnv,sizeof(jmp_buf)); - isCatchingSignals = oldIsCatchingSignals; - isReentrantSignal = false; - signalCallStack = nullptr; - signalOperand = nullptr; - - if(thrown_exception) - std::rethrow_exception(thrown_exception); - - return signalType; - } - - void immediately_exit(std::exception_ptr except) { - thrown_exception = except; - siglongjmp(signalReturnEnv,1); - } - - CallStack captureCallStack(Uptr numOmittedFramesFromTop) - { - #if 0 - // Unwind the callstack. - enum { maxCallStackSize = signalStackNumBytes / sizeof(void*) / 8 }; - void* callstackAddresses[maxCallStackSize]; - auto numCallStackEntries = backtrace(callstackAddresses,maxCallStackSize); - - // Copy the return pointers into the stack frames of the resulting ExecutionContext. - // Skip the first numOmittedFramesFromTop+1 frames, which correspond to this function - // and others that the caller would like to omit. - CallStack result; - for(Iptr index = numOmittedFramesFromTop + 1;index < numCallStackEntries;++index) - { - result.stackFrames.push_back({(Uptr)callstackAddresses[index]}); - } - return result; - #else - return CallStack(); - #endif - } - - U64 getMonotonicClock() - { - #ifdef __APPLE__ - timeval timeVal; - gettimeofday(&timeVal, nullptr); - return U64(timeVal.tv_sec) * 1000000 + U64(timeVal.tv_usec); - #else - timespec monotonicClock; - clock_gettime(CLOCK_MONOTONIC,&monotonicClock); - return U64(monotonicClock.tv_sec) * 1000000 + U64(monotonicClock.tv_nsec) / 1000; - #endif - } - - struct Mutex - { - pthread_mutex_t pthreadMutex; - }; - - Mutex* createMutex() - { - auto mutex = new Mutex(); - errorUnless(!pthread_mutex_init(&mutex->pthreadMutex,nullptr)); - return mutex; - } - - void destroyMutex(Mutex* mutex) - { - errorUnless(!pthread_mutex_destroy(&mutex->pthreadMutex)); - delete mutex; - } - - void lockMutex(Mutex* mutex) - { - errorUnless(!pthread_mutex_lock(&mutex->pthreadMutex)); - } - - void unlockMutex(Mutex* mutex) - { - errorUnless(!pthread_mutex_unlock(&mutex->pthreadMutex)); - } - - struct Event - { - pthread_cond_t conditionVariable; - pthread_mutex_t mutex; - }; - - Event* createEvent() - { - auto event = new Event(); - - pthread_condattr_t conditionVariableAttr; - errorUnless(!pthread_condattr_init(&conditionVariableAttr)); - - // Set the condition variable to use the monotonic clock for wait timeouts. - #ifndef __APPLE__ - errorUnless(!pthread_condattr_setclock(&conditionVariableAttr,CLOCK_MONOTONIC)); - #endif - - errorUnless(!pthread_cond_init(&event->conditionVariable,nullptr)); - errorUnless(!pthread_mutex_init(&event->mutex,nullptr)); - - errorUnless(!pthread_condattr_destroy(&conditionVariableAttr)); - - return event; - } - - void destroyEvent(Event* event) - { - pthread_cond_destroy(&event->conditionVariable); - errorUnless(!pthread_mutex_destroy(&event->mutex)); - delete event; - } - - bool waitForEvent(Event* event,U64 untilTime) - { - errorUnless(!pthread_mutex_lock(&event->mutex)); - - int result; - if(untilTime == UINT64_MAX) - { - result = pthread_cond_wait(&event->conditionVariable,&event->mutex); - } - else - { - timespec untilTimeSpec; - untilTimeSpec.tv_sec = untilTime / 1000000; - untilTimeSpec.tv_nsec = (untilTime % 1000000) * 1000; - - result = pthread_cond_timedwait(&event->conditionVariable,&event->mutex,&untilTimeSpec); - } - - errorUnless(!pthread_mutex_unlock(&event->mutex)); - - if(result == ETIMEDOUT) - { - return false; - } - else - { - errorUnless(!result); - return true; - } - } - - void signalEvent(Event* event) - { - errorUnless(!pthread_cond_signal(&event->conditionVariable)); - } -} - -#endif diff --git a/libraries/wasm-jit/Source/Platform/Windows.cpp b/libraries/wasm-jit/Source/Platform/Windows.cpp deleted file mode 100644 index 2c34c613b64..00000000000 --- a/libraries/wasm-jit/Source/Platform/Windows.cpp +++ /dev/null @@ -1,368 +0,0 @@ -#if _WIN32 - -#include "Inline/BasicTypes.h" -#include "Inline/Errors.h" -#include "Platform.h" - -#include -#include -#include -#include - -#undef min - -namespace Platform -{ - static Uptr internalGetPreferredVirtualPageSizeLog2() - { - SYSTEM_INFO systemInfo; - GetSystemInfo(&systemInfo); - Uptr preferredVirtualPageSize = systemInfo.dwPageSize; - // Verify our assumption that the virtual page size is a power of two. - errorUnless(!(preferredVirtualPageSize & (preferredVirtualPageSize - 1))); - return floorLogTwo(preferredVirtualPageSize); - } - Uptr getPageSizeLog2() - { - static Uptr preferredVirtualPageSizeLog2 = internalGetPreferredVirtualPageSizeLog2(); - return preferredVirtualPageSizeLog2; - } - - U32 memoryAccessAsWin32Flag(MemoryAccess access) - { - switch(access) - { - default: - case MemoryAccess::None: return PAGE_NOACCESS; - case MemoryAccess::ReadOnly: return PAGE_READONLY; - case MemoryAccess::ReadWrite: return PAGE_READWRITE; - case MemoryAccess::Execute: return PAGE_EXECUTE_READ; - case MemoryAccess::ReadWriteExecute: return PAGE_EXECUTE_READWRITE; - } - } - - static bool isPageAligned(U8* address) - { - const Uptr addressBits = reinterpret_cast(address); - return (addressBits & ((1ull << getPageSizeLog2()) - 1)) == 0; - } - - U8* allocateVirtualPages(Uptr numPages) - { - Uptr numBytes = numPages << getPageSizeLog2(); - auto result = VirtualAlloc(nullptr,numBytes,MEM_RESERVE,PAGE_NOACCESS); - if(result == NULL) - { - return nullptr; - } - return (U8*)result; - } - - bool commitVirtualPages(U8* baseVirtualAddress,Uptr numPages,MemoryAccess access) - { - errorUnless(isPageAligned(baseVirtualAddress)); - return baseVirtualAddress == VirtualAlloc(baseVirtualAddress,numPages << getPageSizeLog2(),MEM_COMMIT,memoryAccessAsWin32Flag(access)); - } - - bool setVirtualPageAccess(U8* baseVirtualAddress,Uptr numPages,MemoryAccess access) - { - errorUnless(isPageAligned(baseVirtualAddress)); - DWORD oldProtection = 0; - return VirtualProtect(baseVirtualAddress,numPages << getPageSizeLog2(),memoryAccessAsWin32Flag(access),&oldProtection) != 0; - } - - void decommitVirtualPages(U8* baseVirtualAddress,Uptr numPages) - { - errorUnless(isPageAligned(baseVirtualAddress)); - auto result = VirtualFree(baseVirtualAddress,numPages << getPageSizeLog2(),MEM_DECOMMIT); - if(baseVirtualAddress && !result) { Errors::fatal("VirtualFree(MEM_DECOMMIT) failed"); } - } - - void freeVirtualPages(U8* baseVirtualAddress,Uptr numPages) - { - errorUnless(isPageAligned(baseVirtualAddress)); - auto result = VirtualFree(baseVirtualAddress,0/*numPages << getPageSizeLog2()*/,MEM_RELEASE); - if(baseVirtualAddress && !result) { Errors::fatal("VirtualFree(MEM_RELEASE) failed"); } - } - - // The interface to the DbgHelp DLL - struct DbgHelp - { - typedef BOOL (WINAPI* SymFromAddr)(HANDLE,U64,U64*,SYMBOL_INFO*); - SymFromAddr symFromAddr; - DbgHelp() - { - HMODULE dbgHelpModule = ::LoadLibraryA("Dbghelp.dll"); - if(dbgHelpModule) - { - symFromAddr = (SymFromAddr)::GetProcAddress(dbgHelpModule,"SymFromAddr"); - - // Initialize the debug symbol lookup. - typedef BOOL (WINAPI* SymInitialize)(HANDLE,PCTSTR,BOOL); - SymInitialize symInitialize = (SymInitialize)::GetProcAddress(dbgHelpModule,"SymInitialize"); - if(symInitialize) - { - symInitialize(GetCurrentProcess(),nullptr,TRUE); - } - } - } - }; - DbgHelp* dbgHelp = nullptr; - - bool describeInstructionPointer(Uptr ip,std::string& outDescription) - { - // Initialize DbgHelp. - if(!dbgHelp) { dbgHelp = new DbgHelp(); } - - // Allocate up a SYMBOL_INFO struct to receive information about the symbol for this instruction pointer. - const Uptr maxSymbolNameChars = 256; - const Uptr symbolAllocationSize = sizeof(SYMBOL_INFO) + sizeof(TCHAR) * (maxSymbolNameChars - 1); - SYMBOL_INFO* symbolInfo = (SYMBOL_INFO*)alloca(symbolAllocationSize); - ZeroMemory(symbolInfo,symbolAllocationSize); - symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO); - symbolInfo->MaxNameLen = maxSymbolNameChars; - - // Call DbgHelp::SymFromAddr to try to find any debug symbol containing this address. - if(!dbgHelp->symFromAddr(GetCurrentProcess(),ip,nullptr,symbolInfo)) { return false; } - else - { - outDescription = symbolInfo->Name; - return true; - } - } - - #if defined(_WIN32) && defined(_AMD64_) - void registerSEHUnwindInfo(Uptr imageLoadAddress,Uptr pdataAddress,Uptr pdataNumBytes) - { - const U32 numFunctions = (U32)(pdataNumBytes / sizeof(RUNTIME_FUNCTION)); - - // Register our manually fixed up copy of the function table. - if(!RtlAddFunctionTable(reinterpret_cast(pdataAddress),numFunctions,imageLoadAddress)) - { - Errors::fatal("RtlAddFunctionTable failed"); - } - } - void deregisterSEHUnwindInfo(Uptr pdataAddress) - { - auto functionTable = reinterpret_cast(pdataAddress); - RtlDeleteFunctionTable(functionTable); - delete [] functionTable; - } - #endif - - CallStack unwindStack(const CONTEXT& immutableContext) - { - // Make a mutable copy of the context. - CONTEXT context; - memcpy(&context,&immutableContext,sizeof(CONTEXT)); - - // Unwind the stack until there isn't a valid instruction pointer, which signals we've reached the base. - CallStack callStack; - #ifdef _WIN64 - while(context.Rip) - { - callStack.stackFrames.push_back({context.Rip}); - - // Look up the SEH unwind information for this function. - U64 imageBase; - auto runtimeFunction = RtlLookupFunctionEntry(context.Rip,&imageBase,nullptr); - if(!runtimeFunction) - { - // Leaf functions that don't touch Rsp may not have unwind information. - context.Rip = *(U64*)context.Rsp; - context.Rsp += 8; - } - else - { - // Use the SEH information to unwind to the next stack frame. - void* handlerData; - U64 establisherFrame; - RtlVirtualUnwind( - UNW_FLAG_NHANDLER, - imageBase, - context.Rip, - runtimeFunction, - &context, - &handlerData, - &establisherFrame, - nullptr - ); - } - } - #endif - - return callStack; - } - - CallStack captureCallStack(Uptr numOmittedFramesFromTop) - { - // Capture the current processor state. - CONTEXT context; - RtlCaptureContext(&context); - - // Unwind the stack. - auto result = unwindStack(context); - - // Remote the requested number of omitted frames, +1 for this function. - const Uptr numOmittedFrames = std::min(result.stackFrames.size(),numOmittedFramesFromTop + 1); - result.stackFrames.erase(result.stackFrames.begin(),result.stackFrames.begin() + numOmittedFrames); - - return result; - } - - THREAD_LOCAL bool isReentrantException = false; - LONG CALLBACK sehFilterFunction(EXCEPTION_POINTERS* exceptionPointers,HardwareTrapType& outType,Uptr& outTrapOperand,CallStack& outCallStack) - { - if(isReentrantException) { Errors::fatal("reentrant exception"); } - else - { - // Decide how to handle this exception code. - switch(exceptionPointers->ExceptionRecord->ExceptionCode) - { - case EXCEPTION_ACCESS_VIOLATION: - outType = HardwareTrapType::accessViolation; - outTrapOperand = exceptionPointers->ExceptionRecord->ExceptionInformation[1]; - break; - case EXCEPTION_STACK_OVERFLOW: outType = HardwareTrapType::stackOverflow; break; - case STATUS_INTEGER_DIVIDE_BY_ZERO: outType = HardwareTrapType::intDivideByZeroOrOverflow; break; - case STATUS_INTEGER_OVERFLOW: outType = HardwareTrapType::intDivideByZeroOrOverflow; break; - default: return EXCEPTION_CONTINUE_SEARCH; - } - isReentrantException = true; - - // Unwind the stack frames from the context of the exception. - outCallStack = unwindStack(*exceptionPointers->ContextRecord); - - return EXCEPTION_EXECUTE_HANDLER; - } - } - - THREAD_LOCAL bool isThreadInitialized = false; - void initThread() - { - if(!isThreadInitialized) - { - isThreadInitialized = true; - - // Ensure that there's enough space left on the stack in the case of a stack overflow to prepare the stack trace. - ULONG stackOverflowReserveBytes = 32768; - SetThreadStackGuarantee(&stackOverflowReserveBytes); - } - } - - HardwareTrapType catchHardwareTraps( - CallStack& outTrapCallStack, - Uptr& outTrapOperand, - const std::function& thunk - ) - { - initThread(); - - HardwareTrapType result = HardwareTrapType::none; - __try - { - thunk(); - } - __except(sehFilterFunction(GetExceptionInformation(),result,outTrapOperand,outTrapCallStack)) - { - isReentrantException = false; - - // After a stack overflow, the stack will be left in a damaged state. Let the CRT repair it. - if(result == HardwareTrapType::stackOverflow) { _resetstkoflw(); } - } - return result; - } - - U64 getMonotonicClock() - { - LARGE_INTEGER performanceCounter; - LARGE_INTEGER performanceCounterFrequency; - QueryPerformanceCounter(&performanceCounter); - QueryPerformanceFrequency(&performanceCounterFrequency); - - const U64 wavmFrequency = 1000000; - - return performanceCounterFrequency.QuadPart > wavmFrequency - ? performanceCounter.QuadPart / (performanceCounterFrequency.QuadPart / wavmFrequency) - : performanceCounter.QuadPart * (wavmFrequency / performanceCounterFrequency.QuadPart); - } - - struct Mutex - { - CRITICAL_SECTION criticalSection; - }; - - Mutex* createMutex() - { - auto mutex = new Mutex(); - InitializeCriticalSection(&mutex->criticalSection); - return mutex; - } - - void destroyMutex(Mutex* mutex) - { - DeleteCriticalSection(&mutex->criticalSection); - delete mutex; - } - - void lockMutex(Mutex* mutex) - { - EnterCriticalSection(&mutex->criticalSection); - } - - void unlockMutex(Mutex* mutex) - { - LeaveCriticalSection(&mutex->criticalSection); - } - - Event* createEvent() - { - return reinterpret_cast(CreateEvent(nullptr,FALSE,FALSE,nullptr)); - } - - void destroyEvent(Event* event) - { - CloseHandle(reinterpret_cast(event)); - } - - bool waitForEvent(Event* event,U64 untilTime) - { - U64 currentTime = getMonotonicClock(); - const U64 startProcessTime = currentTime; - while(true) - { - const U64 timeoutMicroseconds = currentTime > untilTime ? 0 : (untilTime - currentTime); - const U64 timeoutMilliseconds64 = timeoutMicroseconds / 1000; - const U32 timeoutMilliseconds32 = - timeoutMilliseconds64 > UINT32_MAX - ? (UINT32_MAX - 1) - : U32(timeoutMilliseconds64); - - const U32 waitResult = WaitForSingleObject(reinterpret_cast(event),timeoutMilliseconds32); - if(waitResult != WAIT_TIMEOUT) - { - errorUnless(waitResult == WAIT_OBJECT_0); - return true; - } - else - { - currentTime = getMonotonicClock(); - if(currentTime >= untilTime) - { - return false; - } - } - }; - } - - void signalEvent(Event* event) - { - errorUnless(SetEvent(reinterpret_cast(event))); - } - - void immediately_exit(std::exception_ptr except) { - std::rethrow_exception(except); - } -} - -#endif diff --git a/libraries/wasm-jit/Source/Runtime/CMakeLists.txt b/libraries/wasm-jit/Source/Runtime/CMakeLists.txt index 907dbf37871..4fb6d2e234e 100644 --- a/libraries/wasm-jit/Source/Runtime/CMakeLists.txt +++ b/libraries/wasm-jit/Source/Runtime/CMakeLists.txt @@ -4,7 +4,6 @@ set(Sources LLVMJIT.h ObjectGC.cpp RuntimePrivate.h - WAVMIntrinsics.cpp ) set(PublicHeaders @@ -21,7 +20,7 @@ add_definitions(-DRUNTIME_API=DLL_EXPORT) target_include_directories( Runtime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../chain/include ) # Link against the LLVM libraries -target_link_libraries(Runtime Platform Logging IR) +target_link_libraries(Runtime Logging IR) install(TARGETS Runtime LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} diff --git a/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp b/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp index 11f5dc3a3f1..32cd1f7e940 100644 --- a/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp +++ b/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp @@ -11,9 +11,8 @@ namespace Intrinsics struct Singleton { std::map functionMap; - Platform::Mutex* mutex; - Singleton(): mutex(Platform::createMutex()) {} + Singleton() {} Singleton(const Singleton&) = delete; static Singleton& get() @@ -35,14 +34,12 @@ namespace Intrinsics : name(inName) { function = new Runtime::FunctionInstance(nullptr,type,nativeFunction); - Platform::Lock lock(Singleton::get().mutex); Singleton::get().functionMap[getDecoratedName(inName,type)] = this; } Function::~Function() { { - Platform::Lock Lock(Singleton::get().mutex); Singleton::get().functionMap.erase(Singleton::get().functionMap.find(getDecoratedName(name,function->type))); } delete function; @@ -51,7 +48,6 @@ namespace Intrinsics Runtime::ObjectInstance* find(const std::string& name,const IR::ObjectType& type) { std::string decoratedName = getDecoratedName(name,type); - Platform::Lock Lock(Singleton::get().mutex); Runtime::ObjectInstance* result = nullptr; switch(type.kind) { @@ -84,7 +80,6 @@ namespace Intrinsics std::vector getAllIntrinsicObjects() { - Platform::Lock lock(Singleton::get().mutex); std::vector result; for(auto mapIt : Singleton::get().functionMap) { result.push_back(mapIt.second->function); } return result; diff --git a/libraries/wasm-jit/Source/Runtime/RuntimePrivate.h b/libraries/wasm-jit/Source/Runtime/RuntimePrivate.h index c180b31330f..590a6f65aab 100644 --- a/libraries/wasm-jit/Source/Runtime/RuntimePrivate.h +++ b/libraries/wasm-jit/Source/Runtime/RuntimePrivate.h @@ -142,20 +142,6 @@ namespace Runtime ~ModuleInstance() override; }; - // Initializes global state used by the WAVM intrinsics. - void initWAVMIntrinsics(); - - // Checks whether an address is owned by a table or memory. - bool isAddressOwnedByTable(U8* address); - bool isAddressOwnedByMemory(U8* address); - - // Allocates virtual pages with alignBytes of padding, and returns an aligned base address. - // The unaligned allocation address and size are written to outUnalignedBaseAddress and outUnalignedNumPlatformPages. - U8* allocateVirtualPagesAligned(Uptr numBytes,Uptr alignmentBytes,U8*& outUnalignedBaseAddress,Uptr& outUnalignedNumPlatformPages); - - // Turns a hardware trap that occurred in WASM code into a runtime exception or fatal error. - [[noreturn]] void handleHardwareTrap(Platform::HardwareTrapType trapType,Platform::CallStack&& trapCallStack,Uptr trapOperand); - // Adds GC roots from WASM threads to the provided array. void getThreadGCRoots(std::vector& outGCRoots); } diff --git a/libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp b/libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp deleted file mode 100644 index 9e38eeebea0..00000000000 --- a/libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include "Inline/BasicTypes.h" -#include "Inline/Floats.h" -#include "Logging/Logging.h" -#include "Intrinsics.h" -#include "RuntimePrivate.h" - -#include - -namespace Runtime -{ - static void causeIntrensicException(Exception::Cause cause) { - try { - Platform::immediately_exit(std::make_exception_ptr(Exception{cause, std::vector()})); - } - catch (...) { - Platform::immediately_exit(std::current_exception()); - } - __builtin_unreachable(); - } - - template - Float quietNaN(Float value) - { - Floats::FloatComponents components; - components.value = value; - components.bits.significand |= typename Floats::FloatComponents::Bits(1) << (Floats::FloatComponents::numSignificandBits - 1); - return components.value; - } - - template - Float floatMin(Float left,Float right) - { - // If either operand is a NaN, convert it to a quiet NaN and return it. - if(left != left) { return quietNaN(left); } - else if(right != right) { return quietNaN(right); } - // If either operand is less than the other, return it. - else if(left < right) { return left; } - else if(right < left) { return right; } - else - { - // Finally, if the operands are apparently equal, compare their integer values to distinguish -0.0 from +0.0 - Floats::FloatComponents leftComponents; - leftComponents.value = left; - Floats::FloatComponents rightComponents; - rightComponents.value = right; - return leftComponents.bitcastInt < rightComponents.bitcastInt ? right : left; - } - } - - template - Float floatMax(Float left,Float right) - { - // If either operand is a NaN, convert it to a quiet NaN and return it. - if(left != left) { return quietNaN(left); } - else if(right != right) { return quietNaN(right); } - // If either operand is less than the other, return it. - else if(left > right) { return left; } - else if(right > left) { return right; } - else - { - // Finally, if the operands are apparently equal, compare their integer values to distinguish -0.0 from +0.0 - Floats::FloatComponents leftComponents; - leftComponents.value = left; - Floats::FloatComponents rightComponents; - rightComponents.value = right; - return leftComponents.bitcastInt > rightComponents.bitcastInt ? right : left; - } - } - - template - Float floatCeil(Float value) - { - if(value != value) { return quietNaN(value); } - else { return ceil(value); } - } - - template - Float floatFloor(Float value) - { - if(value != value) { return quietNaN(value); } - else { return floor(value); } - } - - template - Float floatTrunc(Float value) - { - if(value != value) { return quietNaN(value); } - else { return trunc(value); } - } - - template - Float floatNearest(Float value) - { - if(value != value) { return quietNaN(value); } - else { return nearbyint(value); } - } - - DEFINE_INTRINSIC_FUNCTION2(wavmIntrinsics,floatMin,floatMin,f32,f32,left,f32,right) { return floatMin(left,right); } - DEFINE_INTRINSIC_FUNCTION2(wavmIntrinsics,floatMin,floatMin,f64,f64,left,f64,right) { return floatMin(left,right); } - DEFINE_INTRINSIC_FUNCTION2(wavmIntrinsics,floatMax,floatMax,f32,f32,left,f32,right) { return floatMax(left,right); } - DEFINE_INTRINSIC_FUNCTION2(wavmIntrinsics,floatMax,floatMax,f64,f64,left,f64,right) { return floatMax(left,right); } - - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatCeil,floatCeil,f32,f32,value) { return floatCeil(value); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatCeil,floatCeil,f64,f64,value) { return floatCeil(value); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatFloor,floatFloor,f32,f32,value) { return floatFloor(value); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatFloor,floatFloor,f64,f64,value) { return floatFloor(value); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatTrunc,floatTrunc,f32,f32,value) { return floatTrunc(value); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatTrunc,floatTrunc,f64,f64,value) { return floatTrunc(value); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatNearest,floatNearest,f32,f32,value) { return floatNearest(value); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatNearest,floatNearest,f64,f64,value) { return floatNearest(value); } - - template - Dest floatToInt(Source sourceValue,Source minValue,Source maxValue) - { - if(sourceValue != sourceValue) - { - causeIntrensicException(Exception::Cause::invalidFloatOperation); - } - else if(sourceValue >= maxValue || (isMinInclusive ? sourceValue <= minValue : sourceValue < minValue)) - { - causeIntrensicException(Exception::Cause::integerDivideByZeroOrIntegerOverflow); - } - return (Dest)sourceValue; - } - - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToSignedInt,floatToSignedInt,i32,f32,source) { return floatToInt(source,(F32)INT32_MIN,-(F32)INT32_MIN); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToSignedInt,floatToSignedInt,i32,f64,source) { return floatToInt(source,(F64)INT32_MIN,-(F64)INT32_MIN); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToSignedInt,floatToSignedInt,i64,f32,source) { return floatToInt(source,(F32)INT64_MIN,-(F32)INT64_MIN); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToSignedInt,floatToSignedInt,i64,f64,source) { return floatToInt(source,(F64)INT64_MIN,-(F64)INT64_MIN); } - - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToUnsignedInt,floatToUnsignedInt,i32,f32,source) { return floatToInt(source,-1.0f,-2.0f * INT32_MIN); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToUnsignedInt,floatToUnsignedInt,i32,f64,source) { return floatToInt(source,-1.0,-2.0 * INT32_MIN); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToUnsignedInt,floatToUnsignedInt,i64,f32,source) { return floatToInt(source,-1.0f,-2.0f * INT64_MIN); } - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,floatToUnsignedInt,floatToUnsignedInt,i64,f64,source) { return floatToInt(source,-1.0,-2.0 * INT64_MIN); } - - DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,divideByZeroOrIntegerOverflowTrap,divideByZeroOrIntegerOverflowTrap,none) - { - causeIntrensicException(Exception::Cause::integerDivideByZeroOrIntegerOverflow); - } - - DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,unreachableTrap,unreachableTrap,none) - { - causeIntrensicException(Exception::Cause::reachedUnreachable); - } - - DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,accessViolationTrap,accessViolationTrap,none) - { - causeIntrensicException(Exception::Cause::accessViolation); - } - - DEFINE_INTRINSIC_FUNCTION3(wavmIntrinsics,indirectCallSignatureMismatch,indirectCallSignatureMismatch,none,i32,index,i64,expectedSignatureBits,i64,tableBits) - { - try { - TableInstance* table = reinterpret_cast(tableBits); - void* elementValue = table->baseAddress[index].value; - const FunctionType* actualSignature = table->baseAddress[index].type; - const FunctionType* expectedSignature = reinterpret_cast((Uptr)expectedSignatureBits); - std::string ipDescription = ""; - LLVMJIT::describeInstructionPointer(reinterpret_cast(elementValue),ipDescription); - Log::printf(Log::Category::debug,"call_indirect signature mismatch: expected %s at index %u but got %s (%s)\n", - asString(expectedSignature).c_str(), - index, - actualSignature ? asString(actualSignature).c_str() : "nullptr", - ipDescription.c_str() - ); - causeIntrensicException(elementValue == nullptr ? Exception::Cause::undefinedTableElement : Exception::Cause::indirectCallSignatureMismatch); - } - catch (...) { - Platform::immediately_exit(std::current_exception()); - } - } - - DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,indirectCallIndexOutOfBounds,indirectCallIndexOutOfBounds,none) - { - causeIntrensicException(Exception::Cause::undefinedTableElement); - } - - DEFINE_INTRINSIC_FUNCTION2(wavmIntrinsics,_growMemory,growMemory,i32,i32,deltaPages,i64,memoryBits) - { - MemoryInstance* memory = reinterpret_cast(memoryBits); - if(!memory) - causeIntrensicException(Exception::Cause::outOfMemory); - const Iptr numPreviousMemoryPages = growMemory(memory,(Uptr)deltaPages); - if(numPreviousMemoryPages + (Uptr)deltaPages > IR::maxMemoryPages) { return -1; } - else { return (I32)numPreviousMemoryPages; } - } - - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,_currentMemory,currentMemory,i32,i64,memoryBits) - { - MemoryInstance* memory = reinterpret_cast(memoryBits); - if(!memory) - causeIntrensicException(Exception::Cause::outOfMemory); - Uptr numMemoryPages = getMemoryNumPages(memory); - if(numMemoryPages > UINT32_MAX) { numMemoryPages = UINT32_MAX; } - return (U32)numMemoryPages; - } - - THREAD_LOCAL Uptr indentLevel = 0; - - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,debugEnterFunction,debugEnterFunction,none,i64,functionInstanceBits) - { - FunctionInstance* function = reinterpret_cast(functionInstanceBits); - Log::printf(Log::Category::debug,"ENTER: %s\n",function->debugName.c_str()); - ++indentLevel; - } - - DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,debugExitFunction,debugExitFunction,none,i64,functionInstanceBits) - { - FunctionInstance* function = reinterpret_cast(functionInstanceBits); - --indentLevel; - Log::printf(Log::Category::debug,"EXIT: %s\n",function->debugName.c_str()); - } - - DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,debugBreak,debugBreak,none) - { - Log::printf(Log::Category::debug,"================== wavmIntrinsics.debugBreak\n"); - } - - void initWAVMIntrinsics() - { - } -} From 9a04e87de40dcad6c73737f8f27a89ec125bcdaa Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Fri, 24 Jan 2020 18:17:55 -0500 Subject: [PATCH 2/2] need to remove Platform lib from cmake modules --- CMakeModules/EosioTester.cmake.in | 2 -- CMakeModules/EosioTesterBuild.cmake.in | 2 -- 2 files changed, 4 deletions(-) diff --git a/CMakeModules/EosioTester.cmake.in b/CMakeModules/EosioTester.cmake.in index 988fd241095..31e90b52e79 100644 --- a/CMakeModules/EosioTester.cmake.in +++ b/CMakeModules/EosioTester.cmake.in @@ -61,7 +61,6 @@ find_library(libwasm WASM @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/li find_library(libwast WAST @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(libwabt wabt @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(libir IR @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) -find_library(libplatform Platform @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(liblogging Logging @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(libruntime Runtime @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(libsoftfloat softfloat @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) @@ -93,7 +92,6 @@ macro(add_eosio_test_executable test_name) ${libwasm} ${libwabt} ${libruntime} - ${libplatform} ${libir} ${libsoftfloat} ${liboscrypto} diff --git a/CMakeModules/EosioTesterBuild.cmake.in b/CMakeModules/EosioTesterBuild.cmake.in index 62704dcf78d..3dfcd23c30e 100644 --- a/CMakeModules/EosioTesterBuild.cmake.in +++ b/CMakeModules/EosioTesterBuild.cmake.in @@ -60,7 +60,6 @@ find_library(libwasm WASM @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WASM NO_D find_library(libwast WAST @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WAST NO_DEFAULT_PATH) find_library(libir IR @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/IR NO_DEFAULT_PATH) find_library(libwabt wabt @CMAKE_BINARY_DIR@/libraries/wabt NO_DEFAULT_PATH) -find_library(libplatform Platform @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/Platform NO_DEFAULT_PATH) find_library(liblogging Logging @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/Logging NO_DEFAULT_PATH) find_library(libruntime Runtime @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/Runtime NO_DEFAULT_PATH) find_library(libsoftfloat softfloat @CMAKE_BINARY_DIR@/libraries/softfloat NO_DEFAULT_PATH) @@ -92,7 +91,6 @@ macro(add_eosio_test_executable test_name) ${libwasm} ${libwabt} ${libruntime} - ${libplatform} ${libir} ${libsoftfloat} ${liboscrypto}