diff --git a/.github/workflows/es-actions.yml b/.github/workflows/es-actions.yml index fea4f80e7..c80d7293c 100644 --- a/.github/workflows/es-actions.yml +++ b/.github/workflows/es-actions.yml @@ -102,11 +102,6 @@ jobs: run: | sudo apt-get update sudo apt-get install -y ninja-build gcc-multilib g++-multilib libicu-dev - - name: Patch WABT - working-directory: ./third_party/wasm/wabt - run: | - cp ../../../tools/test/wasm-js/wabt_patch . - patch -p0 < wabt_patch - name: Build x86 env: BUILD_OPTIONS: -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DESCARGOT_MODE=debug -DESCARGOT_WASM=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_OUTPUT=shell -GNinja @@ -540,11 +535,6 @@ jobs: run: | sudo apt-get update sudo apt-get install -y ninja-build gcc-multilib g++-multilib - - name: Patch WABT - working-directory: ./third_party/wasm/wabt - run: | - cp ../../../tools/test/wasm-js/wabt_patch . - patch -p0 < wabt_patch - name: Build x86 env: BUILD_OPTIONS: -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DESCARGOT_MODE=debug -DESCARGOT_WASM=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_OUTPUT=shell -GNinja diff --git a/.gitignore b/.gitignore index 32a19873a..378a2e23c 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,3 @@ cmake_install.cmake #etc .vscode EscargotInfo.h -third_party/wasm/config.h diff --git a/.gitmodules b/.gitmodules index 26dc208ea..23d5acd38 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,7 +22,7 @@ path = third_party/googletest url = https://github.com/google/googletest.git ignore = untracked -[submodule "third_party/wasm/wabt"] - path = third_party/wasm/wabt - url = https://github.com/WebAssembly/wabt - ignore = untracked +[submodule "third_party/walrus"] + path = third_party/walrus + url = https://github.com/Samsung/walrus.git + ignore = untracked diff --git a/build/escargot.cmake b/build/escargot.cmake index a7e6830d5..c2b1ff348 100644 --- a/build/escargot.cmake +++ b/build/escargot.cmake @@ -135,20 +135,24 @@ IF (ESCARGOT_LIBICU_SUPPORT_WITH_DLOPEN) SET (ESCARGOT_LIBRARIES ${ESCARGOT_LIBRARIES} runtime-icu-binder-static) ENDIF() -# WebAssembly (wabt) +# WebAssembly (walrus) IF (ESCARGOT_WASM) - SET (WASM_CXX_FLAGS + SET (WALRUS_CXXFLAGS ${ESCARGOT_THIRDPARTY_CFLAGS} # we can share flags with gcutil - ) + -g3) SET (WASM_ARCH ${ESCARGOT_ARCH}) + SET (WALRUS_HOST ${ESCARGOT_HOST}) + SET (WALRUS_ARCH ${ESCARGOT_ARCH}) + SET (WALRUS_MODE ${ESCARGOT_MODE}) + SET (WALRUS_OUTPUT "shared_lib") IF (${ESCARGOT_MODE} STREQUAL "release") - SET (WASM_CXX_FLAGS ${WASM_CXX_FLAGS} ${ESCARGOT_CXXFLAGS_RELEASE}) + SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} ${ESCARGOT_CXXFLAGS_RELEASE}) ENDIF() - ADD_SUBDIRECTORY (third_party/wasm) + ADD_SUBDIRECTORY (third_party/walrus) - SET (ESCARGOT_LIBRARIES ${ESCARGOT_LIBRARIES} wasm) + SET (ESCARGOT_LIBRARIES ${ESCARGOT_LIBRARIES} walrus) ENDIF() # BUILD diff --git a/src/api/EscargotPublic.cpp b/src/api/EscargotPublic.cpp index 1d2a58f0b..00232b0d0 100644 --- a/src/api/EscargotPublic.cpp +++ b/src/api/EscargotPublic.cpp @@ -4578,11 +4578,6 @@ ObjectRef* WASMOperationsRef::instantiatePromiseOfModuleWithImportObject(Executi { return toRef(WASMOperations::instantiatePromiseOfModuleWithImportObject(*toImpl(state), toImpl(promiseOfModule), toImpl(importObj))); } - -void WASMOperationsRef::collectHeap() -{ - WASMOperations::collectHeap(); -} #else ValueRef* WASMOperationsRef::copyStableBufferBytes(ExecutionStateRef* state, ValueRef* source) { @@ -4604,12 +4599,6 @@ ObjectRef* WASMOperationsRef::instantiatePromiseOfModuleWithImportObject(Executi RELEASE_ASSERT_NOT_REACHED(); return nullptr; } - -void WASMOperationsRef::collectHeap() -{ - ESCARGOT_LOG_ERROR("If you want to use this function, you should enable WASM"); - RELEASE_ASSERT_NOT_REACHED(); -} #endif } // namespace Escargot diff --git a/src/api/EscargotPublic.h b/src/api/EscargotPublic.h index 6b7b81224..241708622 100644 --- a/src/api/EscargotPublic.h +++ b/src/api/EscargotPublic.h @@ -2197,7 +2197,6 @@ class ESCARGOT_EXPORT WASMOperationsRef { static ValueRef* copyStableBufferBytes(ExecutionStateRef* state, ValueRef* source); static ObjectRef* asyncCompileModule(ExecutionStateRef* state, ValueRef* source); static ObjectRef* instantiatePromiseOfModuleWithImportObject(ExecutionStateRef* state, PromiseObjectRef* promiseOfModule, ValueRef* importObj); - static void collectHeap(); }; } // namespace Escargot diff --git a/src/runtime/ThreadLocal.cpp b/src/runtime/ThreadLocal.cpp index 31f9892de..486fdf246 100644 --- a/src/runtime/ThreadLocal.cpp +++ b/src/runtime/ThreadLocal.cpp @@ -207,13 +207,4 @@ void ThreadLocal::finalize() inited = false; } -#if defined(ENABLE_WASM) -void ThreadLocal::wasmGC(uint64_t lastCheckTime) -{ - ASSERT(inited && !!g_wasmContext.store); - wasm_store_gc(g_wasmContext.store); - g_wasmContext.lastGCCheckTime = lastCheckTime; -} -#endif - } // namespace Escargot diff --git a/src/runtime/ThreadLocal.h b/src/runtime/ThreadLocal.h index 566a0e14a..d9a0d466c 100644 --- a/src/runtime/ThreadLocal.h +++ b/src/runtime/ThreadLocal.h @@ -123,19 +123,11 @@ class ThreadLocal { } #if defined(ENABLE_WASM) - static void wasmGC(uint64_t lastCheckTime); - static wasm_store_t* wasmStore() { ASSERT(inited && !!g_wasmContext.store); return g_wasmContext.store; } - - static uint64_t wasmLastGCCheckTime() - { - ASSERT(inited && !!g_wasmContext.store); - return g_wasmContext.lastGCCheckTime; - } #endif static GCEventListenerSet& gcEventListenerSet() diff --git a/src/runtime/VMInstance.cpp b/src/runtime/VMInstance.cpp index 7ee4435f3..7df1d667b 100644 --- a/src/runtime/VMInstance.cpp +++ b/src/runtime/VMInstance.cpp @@ -56,12 +56,6 @@ NT_TIB* getTIB() namespace Escargot { -#if defined(ENABLE_WASM) -#ifndef ESCARGOT_WASM_GC_CHECK_INTERVAL -#define ESCARGOT_WASM_GC_CHECK_INTERVAL 10000 -#endif -#endif - Value VMInstance::functionPrototypeNativeGetter(ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) { ASSERT(self->isFunctionObject()); @@ -245,11 +239,6 @@ void vmReclaimEndCallback(void* data) self->m_lastCompressibleStringsTestTime = currentTick; } #endif -#if defined(ENABLE_WASM) - if (currentTick - ThreadLocal::wasmLastGCCheckTime() > ESCARGOT_WASM_GC_CHECK_INTERVAL) { - ThreadLocal::wasmGC(currentTick); - } -#endif #endif auto& currentCodeSizeTotal = self->compiledByteCodeSize(); diff --git a/src/wasm/BuiltinWASM.cpp b/src/wasm/BuiltinWASM.cpp index 7bdb1cf77..610b36eb8 100644 --- a/src/wasm/BuiltinWASM.cpp +++ b/src/wasm/BuiltinWASM.cpp @@ -347,7 +347,7 @@ static Value builtinWASMInstanceConstructor(ExecutionState& state, Value thisVal // Instantiate the core of a WebAssembly module module with imports, and let instance be the result. own wasm_trap_t* trap = nullptr; - own wasm_instance_t* instance = wasm_instance_new(ThreadLocal::wasmStore(), module, imports.data, &trap); + own wasm_instance_t* instance = wasm_instance_new(ThreadLocal::wasmStore(), module, &imports, &trap); wasm_extern_vec_delete(&imports); if (!instance) { diff --git a/src/wasm/ExportedFunctionObject.cpp b/src/wasm/ExportedFunctionObject.cpp index e7b881797..e320842ca 100644 --- a/src/wasm/ExportedFunctionObject.cpp +++ b/src/wasm/ExportedFunctionObject.cpp @@ -94,7 +94,7 @@ static Value callExportedFunction(ExecutionState& state, Value thisValue, size_t wasm_functype_delete(functype); // Let (store, ret) be the result of func_invoke(store, funcaddr, args). - own wasm_trap_t* trap = wasm_func_call(funcaddr, args.data, ret.data); + own wasm_trap_t* trap = wasm_func_call(funcaddr, &args, &ret); // If ret is error, throw an exception. This exception should be a WebAssembly RuntimeError exception, unless otherwise indicated by the WebAssembly error mapping. if (trap) { diff --git a/src/wasm/WASMOperations.cpp b/src/wasm/WASMOperations.cpp index c15cfff7c..986284626 100644 --- a/src/wasm/WASMOperations.cpp +++ b/src/wasm/WASMOperations.cpp @@ -40,7 +40,7 @@ namespace Escargot { -static own wasm_trap_t* callbackHostFunction(void* env, const wasm_val_t args[], wasm_val_t results[]) +static own wasm_trap_t* callbackHostFunction(void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results) { WASMHostFunctionEnvironment* funcEnv = (WASMHostFunctionEnvironment*)env; @@ -63,11 +63,37 @@ static own wasm_trap_t* callbackHostFunction(void* env, const wasm_val_t args[], // For each arg of arguments, for (size_t i = 0; i < argSize; i++) { // Append ! ToJSValue(arg) to jsArguments. - jsArguments[i] = WASMValueConverter::wasmToJSValue(state, args[i]); + jsArguments[i] = WASMValueConverter::wasmToJSValue(state, args->data[i]); } // Let ret be ? Call(func, undefined, jsArguments). - Value ret = Object::call(state, func, Value(), argSize, jsArguments); + SandBox sb(funcEnv->realm); + + struct CallBackData { + Object* func; + size_t argSize; + Value* arguments; + } callBackData; + callBackData.func = func; + callBackData.argSize = argSize; + callBackData.arguments = jsArguments; + + auto result = sb.run([](ExecutionState& state, void* data) -> Value { + CallBackData* callBackData = (CallBackData*)data; + return Object::call(state, callBackData->func, Value(), callBackData->argSize, callBackData->arguments); + }, + &callBackData); + + // Assert: result.[[Type]] is throw or normal. + // If result.[[Type]] is throw, then trigger a WebAssembly trap, and propagate result.[[Value]] to the enclosing JavaScript. + // Otherwise, return result.[[Value]]. + if (UNLIKELY(!result.error.isEmpty())) { + std::string errMessage = result.error.toStringWithoutException(state)->toNonGCUTF8StringData(); + // throw a WASM exception + wasm_trap_trigger(errMessage.data(), errMessage.length()); + ASSERT_NOT_REACHED(); + return nullptr; + } // Let resultsSize be results?s size. size_t resultsSize = res->size; @@ -76,9 +102,10 @@ static own wasm_trap_t* callbackHostFunction(void* env, const wasm_val_t args[], return nullptr; } + Value ret = result.result; if (resultsSize == 1) { // Otherwise, if resultsSize is 1, return << ToWebAssemblyValue(ret, results[0]) >> - results[0] = WASMValueConverter::wasmToWebAssemblyValue(state, ret, wasm_valtype_kind(res->data[0])); + results->data[0] = WASMValueConverter::wasmToWebAssemblyValue(state, ret, wasm_valtype_kind(res->data[0])); } else { // Otherwise, // Let method be ? GetMethod(ret, @@iterator). @@ -98,15 +125,10 @@ static own wasm_trap_t* callbackHostFunction(void* env, const wasm_val_t args[], // For each value and resultType in values and results, paired linearly, // Append ToWebAssemblyValue(value, resultType) to wasmValues. for (size_t i = 0; i < resultsSize; i++) { - results[i] = WASMValueConverter::wasmToWebAssemblyValue(state, values[i], wasm_valtype_kind(res->data[i])); + results->data[i] = WASMValueConverter::wasmToWebAssemblyValue(state, values[i], wasm_valtype_kind(res->data[i])); } } - // TODO - // Assert: result.[[Type]] is throw or normal. - // If result.[[Type]] is throw, then trigger a WebAssembly trap, and propagate result.[[Value]] to the enclosing JavaScript. - // Otherwise, return result.[[Value]]. - return nullptr; } @@ -146,7 +168,7 @@ static Value wasmInstantiateModule(ExecutionState& state, Value thisValue, size_ // Instantiate the core of a WebAssembly module module with imports, and let instance be the result. own wasm_trap_t* trap = nullptr; - own wasm_instance_t* instance = wasm_instance_new(ThreadLocal::wasmStore(), module, imports.data, &trap); + own wasm_instance_t* instance = wasm_instance_new(ThreadLocal::wasmStore(), module, &imports, &trap); wasm_extern_vec_delete(&imports); if (!instance) { @@ -526,7 +548,7 @@ Value WASMOperations::instantiateCoreModule(ExecutionState& state, Value thisVal // Instantiate the core of a WebAssembly module module with imports, and let instance be the result. own wasm_trap_t* trap = nullptr; - own wasm_instance_t* instance = wasm_instance_new(ThreadLocal::wasmStore(), module, imports.data, &trap); + own wasm_instance_t* instance = wasm_instance_new(ThreadLocal::wasmStore(), module, &imports, &trap); wasm_extern_vec_delete(&imports); if (!instance) { @@ -558,12 +580,6 @@ Object* WASMOperations::instantiatePromiseOfModuleWithImportObject(ExecutionStat return promiseOfModule->then(state, moduleInstantiator); } -void WASMOperations::collectHeap() -{ - // collect (GC) WASM Objects allocated inside WASM heap - wasm_store_gc(ThreadLocal::wasmStore()); -} - } // namespace Escargot #endif // ENABLE_WASM diff --git a/src/wasm/WASMOperations.h b/src/wasm/WASMOperations.h index db3d51aeb..4022ee309 100644 --- a/src/wasm/WASMOperations.h +++ b/src/wasm/WASMOperations.h @@ -38,8 +38,6 @@ class WASMOperations { static void readImportsOfModule(ExecutionState& state, wasm_module_t* module, const Value& importObj, wasm_extern_vec_t* imports); static Value instantiateCoreModule(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget); static Object* instantiatePromiseOfModuleWithImportObject(ExecutionState& state, PromiseObject* promiseOfModule, Value importObj); - - static void collectHeap(); }; } // namespace Escargot diff --git a/src/wasm/WASMValueConverter.cpp b/src/wasm/WASMValueConverter.cpp index 8f030ca9e..948b4dc0d 100644 --- a/src/wasm/WASMValueConverter.cpp +++ b/src/wasm/WASMValueConverter.cpp @@ -28,31 +28,6 @@ namespace Escargot { -#define WASM_I32_VAL(result, i) \ - result.kind = WASM_I32; \ - result.of.i32 = i; - -#define WASM_I64_VAL(result, i) \ - result.kind = WASM_I64; \ - result.of.i64 = i - -#define WASM_F32_VAL(result, z) \ - result.kind = WASM_F32; \ - result.of.f32 = z; - -#define WASM_F64_VAL(result, z) \ - result.kind = WASM_F64; \ - result.of.f64 = z - -#define WASM_REF_VAL(result, r) \ - result.kind = WASM_ANYREF; \ - result.of.ref = r - -#define WASM_INIT_VAL(result) \ - wasm_val_t result{}; \ - result.kind = WASM_ANYREF; \ - result.of.ref = NULL; - Value WASMValueConverter::wasmToJSValue(ExecutionState& state, const wasm_val_t& value) { Value result; @@ -84,27 +59,27 @@ Value WASMValueConverter::wasmToJSValue(ExecutionState& state, const wasm_val_t& wasm_val_t WASMValueConverter::wasmToWebAssemblyValue(ExecutionState& state, const Value& value, wasm_valkind_t type) { - WASM_INIT_VAL(result); + wasm_val_t result = WASM_INIT_VAL; switch (type) { case WASM_I32: { int32_t val = value.toInt32(state); - WASM_I32_VAL(result, val); + result = WASM_I32_VAL(val); break; } case WASM_F32: { // FIXME Let f32 be ? ToNumber(v) rounded to the nearest representable value using IEEE 754-2019 round to nearest, ties to even mode. float32_t val = value.toNumber(state); - WASM_F32_VAL(result, val); + result = WASM_F32_VAL(val); break; } case WASM_F64: { float64_t val = value.toNumber(state); - WASM_F64_VAL(result, val); + result = WASM_F64_VAL(val); break; } case WASM_I64: { int64_t val = value.toBigInt(state)->toInt64(); - WASM_I64_VAL(result, val); + result = WASM_I64_VAL(val); break; } default: { @@ -118,22 +93,22 @@ wasm_val_t WASMValueConverter::wasmToWebAssemblyValue(ExecutionState& state, con wasm_val_t WASMValueConverter::wasmDefaultValue(wasm_valkind_t type) { - WASM_INIT_VAL(result); + wasm_val_t result = WASM_INIT_VAL; switch (type) { case WASM_I32: { - WASM_I32_VAL(result, 0); + result = WASM_I32_VAL(0); break; } case WASM_I64: { - WASM_I64_VAL(result, 0); + result = WASM_I64_VAL(0); break; } case WASM_F32: { - WASM_F32_VAL(result, 0); + result = WASM_F32_VAL(0); break; } case WASM_F64: { - WASM_F64_VAL(result, 0); + result = WASM_F64_VAL(0); break; } default: { diff --git a/third_party/walrus b/third_party/walrus new file mode 160000 index 000000000..8f4e6e98f --- /dev/null +++ b/third_party/walrus @@ -0,0 +1 @@ +Subproject commit 8f4e6e98f735054be70aee1feef6422a88b1c009 diff --git a/third_party/wasm/CMakeLists.txt b/third_party/wasm/CMakeLists.txt deleted file mode 100644 index 5209b9ddc..000000000 --- a/third_party/wasm/CMakeLists.txt +++ /dev/null @@ -1,192 +0,0 @@ -PROJECT(WASM) -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -if (NOT "${CMAKE_PROJECT_VERSION}") - set(CMAKE_PROJECT_VERSION "1.0.29") -endif () - -if (MSVC) - set(COMPILER_IS_CLANG 0) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 1) -elseif (CMAKE_C_COMPILER_ID MATCHES "Clang") - set(COMPILER_IS_CLANG 1) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 0) -elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") - set(COMPILER_IS_CLANG 0) - set(COMPILER_IS_GNU 1) - set(COMPILER_IS_MSVC 0) -elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten") - set(COMPILER_IS_CLANG 1) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 0) -else () - set(COMPILER_IS_CLANG 0) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 0) -endif () - -include(CheckIncludeFile) -include(CheckSymbolExists) -check_include_file("alloca.h" HAVE_ALLOCA_H) -check_include_file("unistd.h" HAVE_UNISTD_H) -check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) -check_symbol_exists(strcasecmp "strings.h" HAVE_STRCASECMP) - -include(CheckTypeSize) -check_type_size(ssize_t SSIZE_T) -#check_type_size(size_t SIZEOF_SIZE_T) - -# Escargot specific option (for the case of compilation to 32bit from 64bit) -if (ESCARGOT_BUILD_32BIT) - set(SIZEOF_SIZE_T 4) -else () - set(SIZEOF_SIZE_T 8) -endif () - -set(WABT_ROOT ${PROJECT_SOURCE_DIR}/wabt) -configure_file(${WABT_ROOT}/src/config.h.in ${PROJECT_SOURCE_DIR}/config.h) - -include_directories(${WABT_ROOT} ${PROJECT_SOURCE_DIR}) - -set(WABT_SRC - ${PROJECT_SOURCE_DIR}/config.h - - wabt/src/apply-names.h - wabt/src/apply-names.cc - wabt/src/binary.h - wabt/src/binary.cc - wabt/src/binary-reader.h - wabt/src/binary-reader.cc - wabt/src/binary-reader-ir.h - wabt/src/binary-reader-ir.cc - wabt/src/binary-reader-logging.h - wabt/src/binary-reader-logging.cc - wabt/src/binary-writer.h - wabt/src/binary-writer.cc - wabt/src/binary-writer-spec.h - wabt/src/binary-writer-spec.cc - wabt/src/binding-hash.h - wabt/src/binding-hash.cc - wabt/src/color.h - wabt/src/color.cc - wabt/src/common.h - wabt/src/common.cc - wabt/src/config.cc - wabt/src/decompiler.h - wabt/src/decompiler-ast.h - wabt/src/decompiler-ls.h - wabt/src/decompiler-naming.h - wabt/src/decompiler.cc - wabt/src/error-formatter.h - wabt/src/error-formatter.cc - wabt/src/expr-visitor.h - wabt/src/expr-visitor.cc - wabt/src/feature.h - wabt/src/feature.cc - wabt/src/filenames.h - wabt/src/filenames.cc - wabt/src/generate-names.h - wabt/src/generate-names.cc - wabt/src/ir.h - wabt/src/ir.cc - wabt/src/ir-util.h - wabt/src/ir-util.cc - wabt/src/leb128.h - wabt/src/leb128.cc - wabt/src/lexer-source.h - wabt/src/lexer-source.cc - wabt/src/lexer-source-line-finder.h - wabt/src/lexer-source-line-finder.cc - wabt/src/literal.h - wabt/src/literal.cc - wabt/src/opcode.h - wabt/src/opcode.cc - wabt/src/opcode-code-table.h - wabt/src/opcode-code-table.c - wabt/src/option-parser.h - wabt/src/option-parser.cc - wabt/src/resolve-names.h - wabt/src/resolve-names.cc - wabt/src/shared-validator.h - wabt/src/shared-validator.cc - wabt/src/stream.h - wabt/src/stream.cc - wabt/src/string-util.h - wabt/src/token.h - wabt/src/token.cc - wabt/src/tracing.h - wabt/src/tracing.cc - wabt/src/type.h - wabt/src/type-checker.h - wabt/src/type-checker.cc - wabt/src/utf8.h - wabt/src/utf8.cc - wabt/src/validator.h - wabt/src/validator.cc - wabt/src/wast-lexer.h - wabt/src/wast-lexer.cc - wabt/src/wast-parser.h - wabt/src/wast-parser.cc - wabt/src/wat-writer.h - wabt/src/wat-writer.cc - - # TODO(binji): Move this into its own library? - wabt/src/interp/binary-reader-interp.h - wabt/src/interp/binary-reader-interp.cc - wabt/src/interp/interp.h - wabt/src/interp/interp.cc - wabt/src/interp/interp-inl.h - wabt/src/interp/interp-math.h - wabt/src/interp/interp-util.h - wabt/src/interp/interp-util.cc - wabt/src/interp/istream.h - wabt/src/interp/istream.cc -) - -# disable -Wpointer-arith: this is a GCC extension, and doesn't work in MSVC. -set(WASM_CXX_FLAGS_INTERNAL - -Wall -Wextra -Werror -Wno-unused-parameter -Wpointer-arith - -Wuninitialized -fPIC -fdata-sections -ffunction-sections -) - -# set c++ flags -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast") - -# Need to define __STDC_*_MACROS because C99 specifies that C++ shouldn't -# define format (e.g. PRIu64) or limit (e.g. UINT32_MAX) macros without the -# definition, and some libcs (e.g. glibc2.17 and earlier) follow that. -set(WASM_CXX_FLAGS_INTERNAL ${WASM_CXX_FLAGS_INTERNAL} -D__STDC_LIMIT_MACROS=1 -D__STDC_FORMAT_MACROS=1 -DNDEBUG) - -if (COMPILER_IS_GNU) -# disable -Wclobbered: it seems to be guessing incorrectly about a local -# variable being clobbered by longjmp. - set(WASM_CXX_FLAGS_INTERNAL ${WASM_CXX_FLAGS_INTERNAL} -Wno-clobbered) -endif () - -if (WASM_ARCH STREQUAL "x86") -# wasm doesn't allow for x87 floating point math - set(WASM_CXX_FLAGS_INTERNAL ${WASM_CXX_FLAGS_INTERNAL} -msse2 -mfpmath=sse) -endif () - -add_compile_options(${WASM_CXX_FLAGS_INTERNAL}) -add_compile_options(${WASM_CXX_FLAGS}) - -set(WASM_CFLAGS_FROM_ENV $ENV{CFLAGS}) -separate_arguments(WASM_CFLAGS_FROM_ENV) -add_compile_options(${WASM_CFLAGS_FROM_ENV}) - -# build wabt lib -add_library(wabt STATIC ${WABT_SRC}) - -# build wasm lib -add_library(wasm SHARED wabt/src/interp/interp-wasm-c-api.cc) -target_link_libraries(wasm wabt -Wl,--gc-sections ${WASM_CXX_FLAGS}) -target_include_directories(wasm PUBLIC ${PROJECT_SOURCE_DIR}/include) -target_compile_options(wasm PRIVATE $<$:-Wno-old-style-cast>) -target_compile_definitions(wasm PRIVATE "WASM_API_EXTERN=__attribute__((visibility(\"default\")))") -set_target_properties(wasm PROPERTIES CXX_VISIBILITY_PRESET hidden) diff --git a/third_party/wasm/include/LICENSE b/third_party/wasm/include/LICENSE deleted file mode 100644 index 8f71f43fe..000000000 --- a/third_party/wasm/include/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/third_party/wasm/include/README.md b/third_party/wasm/include/README.md deleted file mode 100644 index 1dbcbda97..000000000 --- a/third_party/wasm/include/README.md +++ /dev/null @@ -1,112 +0,0 @@ -# WebAssembly C and C++ API - -Work in progress! No docs yet. - - -### Design Goals - -* Provide a "black box" API for embedding a Wasm engine in other C/C++ applications. - - * Be completely agnostic to VM specifics. - - * Non-goal: "white box" interoperability with embedder (such as combined GC instead of mere finalisation) -- *much* more difficult to achieve. - -* Allow creation of bindings for other languages through typical C foreign function interfaces. - - * Support a plain C API. - - * Stick to mostly manual memory management of interface objects. - -* Avoid language features that raise barrier to use. - - * E.g., no exceptions or post-C++11 features in C++ API. - - * E.g., no passing of structs by-value or post-C99 features in C API. - -* Achieve link-time compatibility between different implementations. - - * All implementation-dependent API classes are abstract and can be instantiated through factory methods only. - - -### Interfaces - -* C++ API: - - * See `include/wasm.hh` for interface. - - * See `example/*.cc` for example usages. - -* C API: - - * See `include/wasm.h` for interface. - - * See `example/*.c` for example usages. - -Some random explanations: - -* The VM must be initialised by creating an instance of an *engine* (`wasm::Engine`/`wasm_engine_t`) and is shut down by deleting it. Such an instance may only be created once per process. - -* All runtime objects are tied to a specific *store* (`wasm::Store`/`wasm_store_t`). Multiple stores can be created, but their objects cannot interact. Every store and its objects must only be accessed in a single thread. - -* To exchange module objects between threads, create a *shared* module (`wasm::Shared`/`wasm_shared_module_t`). Other objects cannot be shared in current Wasm. - -* *Vector* structures (`wasm::vec`/`wasm_x_vec_t`) are lightweight abstractions of a pair of a plain array and its length. The C++ API does not use `std::vector` because that does not support adopting pre-existing arrays. - -* *References* point to runtime objects, but may involve internal indirections, which may or may not be cached. Thus, pointer equality on `Ref*` or subclasses cannot be used to compare identity of the underlying objects (`Ref::eq` may be added later). However, `nullptr`/`NULL` uniquely represents null references. - -* The API already encompasses current proposals like [multiple return values](https://github.com/WebAssembly/multi-value/blob/master/proposals/multi-value/Overview.md) and [reference types](https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md), but not yet [threads](https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md). - - -### Prototype Implementation - -* This repo contains a prototype implementation based on V8 is in `src`. - - * Note that this requires adding a module to V8, so it patches V8's build file. - -* The C API is implemented on top of the C++ API. - -* See `Makefile` for build recipe. Canonical steps to run examples: - - 1. `make v8-checkout` - 2. `make v8` - 3. `make all` - - -#### Limitations - -V8 implementation: - -* Currently requires patching V8 by adding a module. - -* Host functions (`Func::make`) create a JavaScript function internally, since V8 cannot handle raw C imports yet. - -* As a consequence, does not support multiple results in external calls or host functions. - -* Host functions and host globals are created through auxiliary modules constructed on the fly, to work around limitations in JS API. - -* `Shared` is currently implemented via serialisation, since V8 does not currently have direct support for cross-isolate sharing. - - -### Other Implementations - -Currently, known implementations of this API are included in - -* V8 natively (both C and C++) -* Wabt (only C?) -* Wasmtime (only C?) -* [Wasmer](https://github.com/wasmerio/wasmer/tree/master/lib/c-api) (only C, C++ coming soon) - - -### TODO - -Possible API tweaks: - - * Add `Ref::eq` (or better, a subclass `EqRef::eq`) for reference equality? - - * Add a way to return error messages from `Module::make` and `Module::validate`. - - * Use `restrict` in C API? - - * Find a way to perform C callbacks through C++ without extra wrapper? - - * Add iterators to `vec` class? diff --git a/third_party/wasm/include/wasm.h b/third_party/wasm/include/wasm.h deleted file mode 100644 index e367e0852..000000000 --- a/third_party/wasm/include/wasm.h +++ /dev/null @@ -1,710 +0,0 @@ -// WebAssembly C API - -#ifndef WASM_H -#define WASM_H - -#include -#include -#include -#include -#include - -#ifndef WASM_API_EXTERN -#ifdef _WIN32 -#define WASM_API_EXTERN __declspec(dllimport) -#else -#define WASM_API_EXTERN -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/////////////////////////////////////////////////////////////////////////////// -// Auxiliaries - -// Machine types - -inline void assertions() { - static_assert(sizeof(float) == sizeof(uint32_t), "incompatible float type"); - static_assert(sizeof(double) == sizeof(uint64_t), "incompatible double type"); - static_assert(sizeof(intptr_t) == sizeof(uint32_t) || - sizeof(intptr_t) == sizeof(uint64_t), - "incompatible pointer type"); -} - -typedef char byte_t; -typedef float float32_t; -typedef double float64_t; - - -// Ownership - -#define own - -// The qualifier `own` is used to indicate ownership of data in this API. -// It is intended to be interpreted similar to a `const` qualifier: -// -// - `own wasm_xxx_t*` owns the pointed-to data -// - `own wasm_xxx_t` distributes to all fields of a struct or union `xxx` -// - `own wasm_xxx_vec_t` owns the vector as well as its elements(!) -// - an `own` function parameter passes ownership from caller to callee -// - an `own` function result passes ownership from callee to caller -// - an exception are `own` pointer parameters named `out`, which are copy-back -// output parameters passing back ownership from callee to caller -// -// Own data is created by `wasm_xxx_new` functions and some others. -// It must be released with the corresponding `wasm_xxx_delete` function. -// -// Deleting a reference does not necessarily delete the underlying object, -// it merely indicates that this owner no longer uses it. -// -// For vectors, `const wasm_xxx_vec_t` is used informally to indicate that -// neither the vector nor its elements should be modified. -// TODO: introduce proper `wasm_xxx_const_vec_t`? - - -#define WASM_DECLARE_OWN(name) \ - typedef struct wasm_##name##_t wasm_##name##_t; \ - \ - WASM_API_EXTERN void wasm_##name##_delete(own wasm_##name##_t*); - - -// Vectors - -#define WASM_DECLARE_VEC(name, ptr_or_none) \ - typedef struct wasm_##name##_vec_t { \ - size_t size; \ - wasm_##name##_t ptr_or_none* data; \ - } wasm_##name##_vec_t; \ - \ - WASM_API_EXTERN void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \ - WASM_API_EXTERN void wasm_##name##_vec_new_uninitialized( \ - own wasm_##name##_vec_t* out, size_t); \ - WASM_API_EXTERN void wasm_##name##_vec_new( \ - own wasm_##name##_vec_t* out, \ - size_t, own wasm_##name##_t ptr_or_none const[]); \ - WASM_API_EXTERN void wasm_##name##_vec_copy( \ - own wasm_##name##_vec_t* out, const wasm_##name##_vec_t*); \ - WASM_API_EXTERN void wasm_##name##_vec_delete(own wasm_##name##_vec_t*); \ - WASM_API_EXTERN void wasm_##name##_vec_delete_with_size( \ - own wasm_##name##_vec_t*, size_t); - - -// Byte vectors - -typedef byte_t wasm_byte_t; -WASM_DECLARE_VEC(byte, ) - -typedef wasm_byte_vec_t wasm_name_t; - -#define wasm_name wasm_byte_vec -#define wasm_name_new wasm_byte_vec_new -#define wasm_name_new_empty wasm_byte_vec_new_empty -#define wasm_name_new_new_uninitialized wasm_byte_vec_new_uninitialized -#define wasm_name_copy wasm_byte_vec_copy -#define wasm_name_delete wasm_byte_vec_delete - -static inline void wasm_name_new_from_string( - own wasm_name_t* out, const char* s -) { - wasm_name_new(out, strlen(s) + 1, s); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Runtime Environment - -// Configuration - -WASM_DECLARE_OWN(config) - -WASM_API_EXTERN own wasm_config_t* wasm_config_new(); - -// Embedders may provide custom functions for manipulating configs. - - -// Engine - -WASM_DECLARE_OWN(engine) - -WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(); -WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*); - - -// Store - -WASM_DECLARE_OWN(store) - -WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*); - -WASM_API_EXTERN void wasm_store_gc(wasm_store_t*); - - -/////////////////////////////////////////////////////////////////////////////// -// Type Representations - -// Type attributes - -typedef uint8_t wasm_mutability_t; -enum wasm_mutability_enum { - WASM_CONST, - WASM_VAR, -}; - -typedef struct wasm_limits_t { - uint32_t min; - uint32_t max; -} wasm_limits_t; - -static const uint32_t wasm_limits_max_default = 0xffffffff; - - -// Generic - -#define WASM_DECLARE_TYPE(name) \ - WASM_DECLARE_OWN(name) \ - WASM_DECLARE_VEC(name, *) \ - \ - WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t*); - - -// Value Types - -WASM_DECLARE_TYPE(valtype) - -typedef uint8_t wasm_valkind_t; -enum wasm_valkind_enum { - WASM_I32, - WASM_I64, - WASM_F32, - WASM_F64, - WASM_ANYREF = 128, - WASM_FUNCREF, -}; - -WASM_API_EXTERN own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t); - -WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*); - -static inline bool wasm_valkind_is_num(wasm_valkind_t k) { - return k < WASM_ANYREF; -} -static inline bool wasm_valkind_is_ref(wasm_valkind_t k) { - return k >= WASM_ANYREF; -} - -static inline bool wasm_valtype_is_num(const wasm_valtype_t* t) { - return wasm_valkind_is_num(wasm_valtype_kind(t)); -} -static inline bool wasm_valtype_is_ref(const wasm_valtype_t* t) { - return wasm_valkind_is_ref(wasm_valtype_kind(t)); -} - - -// Function Types - -WASM_DECLARE_TYPE(functype) - -WASM_API_EXTERN own wasm_functype_t* wasm_functype_new( - own wasm_valtype_vec_t* params, own wasm_valtype_vec_t* results); - -WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t*); -WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t*); - - -// Global Types - -WASM_DECLARE_TYPE(globaltype) - -WASM_API_EXTERN own wasm_globaltype_t* wasm_globaltype_new( - own wasm_valtype_t*, wasm_mutability_t); - -WASM_API_EXTERN const wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t*); -WASM_API_EXTERN wasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t*); - - -// Table Types - -WASM_DECLARE_TYPE(tabletype) - -WASM_API_EXTERN own wasm_tabletype_t* wasm_tabletype_new( - own wasm_valtype_t*, const wasm_limits_t*); - -WASM_API_EXTERN const wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t*); -WASM_API_EXTERN const wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t*); - - -// Memory Types - -WASM_DECLARE_TYPE(memorytype) - -WASM_API_EXTERN own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*); - -WASM_API_EXTERN const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t*); - - -// Extern Types - -WASM_DECLARE_TYPE(externtype) - -typedef uint8_t wasm_externkind_t; -enum wasm_externkind_enum { - WASM_EXTERN_FUNC, - WASM_EXTERN_GLOBAL, - WASM_EXTERN_TABLE, - WASM_EXTERN_MEMORY, -}; - -WASM_API_EXTERN wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t*); - -WASM_API_EXTERN wasm_externtype_t* wasm_functype_as_externtype(wasm_functype_t*); -WASM_API_EXTERN wasm_externtype_t* wasm_globaltype_as_externtype(wasm_globaltype_t*); -WASM_API_EXTERN wasm_externtype_t* wasm_tabletype_as_externtype(wasm_tabletype_t*); -WASM_API_EXTERN wasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t*); - -WASM_API_EXTERN wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t*); -WASM_API_EXTERN wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t*); -WASM_API_EXTERN wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t*); -WASM_API_EXTERN wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t*); - -WASM_API_EXTERN const wasm_externtype_t* wasm_functype_as_externtype_const(const wasm_functype_t*); -WASM_API_EXTERN const wasm_externtype_t* wasm_globaltype_as_externtype_const(const wasm_globaltype_t*); -WASM_API_EXTERN const wasm_externtype_t* wasm_tabletype_as_externtype_const(const wasm_tabletype_t*); -WASM_API_EXTERN const wasm_externtype_t* wasm_memorytype_as_externtype_const(const wasm_memorytype_t*); - -WASM_API_EXTERN const wasm_functype_t* wasm_externtype_as_functype_const(const wasm_externtype_t*); -WASM_API_EXTERN const wasm_globaltype_t* wasm_externtype_as_globaltype_const(const wasm_externtype_t*); -WASM_API_EXTERN const wasm_tabletype_t* wasm_externtype_as_tabletype_const(const wasm_externtype_t*); -WASM_API_EXTERN const wasm_memorytype_t* wasm_externtype_as_memorytype_const(const wasm_externtype_t*); - - -// Import Types - -WASM_DECLARE_TYPE(importtype) - -WASM_API_EXTERN own wasm_importtype_t* wasm_importtype_new( - own wasm_name_t* module, own wasm_name_t* name, own wasm_externtype_t*); - -WASM_API_EXTERN const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*); -WASM_API_EXTERN const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*); -WASM_API_EXTERN const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*); - - -// Export Types - -WASM_DECLARE_TYPE(exporttype) - -WASM_API_EXTERN own wasm_exporttype_t* wasm_exporttype_new( - own wasm_name_t*, own wasm_externtype_t*); - -WASM_API_EXTERN const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t*); -WASM_API_EXTERN const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t*); - - -/////////////////////////////////////////////////////////////////////////////// -// Runtime Objects - -// Values - -struct wasm_ref_t; - -typedef struct wasm_val_t { - wasm_valkind_t kind; - union { - int32_t i32; - int64_t i64; - float32_t f32; - float64_t f64; - struct wasm_ref_t* ref; - } of; -} wasm_val_t; - -WASM_API_EXTERN void wasm_val_delete(own wasm_val_t* v); -WASM_API_EXTERN void wasm_val_copy(own wasm_val_t* out, const wasm_val_t*); - -WASM_DECLARE_VEC(val, ) - - -// References - -#define WASM_DECLARE_REF_BASE(name) \ - WASM_DECLARE_OWN(name) \ - \ - WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \ - WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \ - \ - WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \ - WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \ - WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \ - wasm_##name##_t*, void*, void (*)(void*)); - -#define WASM_DECLARE_REF(name) \ - WASM_DECLARE_REF_BASE(name) \ - \ - WASM_API_EXTERN wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \ - WASM_API_EXTERN wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \ - WASM_API_EXTERN const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \ - WASM_API_EXTERN const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*); - -#define WASM_DECLARE_SHARABLE_REF(name) \ - WASM_DECLARE_REF(name) \ - WASM_DECLARE_OWN(shared_##name) \ - \ - WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \ - WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*); - - -WASM_DECLARE_REF_BASE(ref) - - -// Frames - -WASM_DECLARE_OWN(frame) -WASM_DECLARE_VEC(frame, *) -WASM_API_EXTERN own wasm_frame_t* wasm_frame_copy(const wasm_frame_t*); - -WASM_API_EXTERN struct wasm_instance_t* wasm_frame_instance(const wasm_frame_t*); -WASM_API_EXTERN uint32_t wasm_frame_func_index(const wasm_frame_t*); -WASM_API_EXTERN size_t wasm_frame_func_offset(const wasm_frame_t*); -WASM_API_EXTERN size_t wasm_frame_module_offset(const wasm_frame_t*); - - -// Traps - -typedef wasm_name_t wasm_message_t; // null terminated - -WASM_DECLARE_REF(trap) - -WASM_API_EXTERN own wasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t*); - -WASM_API_EXTERN void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out); -WASM_API_EXTERN own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*); -WASM_API_EXTERN void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out); - - -// Foreign Objects - -WASM_DECLARE_REF(foreign) - -WASM_API_EXTERN own wasm_foreign_t* wasm_foreign_new(wasm_store_t*); - - -// Modules - -WASM_DECLARE_SHARABLE_REF(module) - -WASM_API_EXTERN own wasm_module_t* wasm_module_new( - wasm_store_t*, const wasm_byte_vec_t* binary); - -WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary); - -WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out); -WASM_API_EXTERN void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_vec_t* out); - -WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out); -WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*); - - -// Function Instances - -WASM_DECLARE_REF(func) - -typedef own wasm_trap_t* (*wasm_func_callback_t)( - const wasm_val_t args[], wasm_val_t results[]); -typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)( - void* env, const wasm_val_t args[], wasm_val_t results[]); - -WASM_API_EXTERN own wasm_func_t* wasm_func_new( - wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t); -WASM_API_EXTERN own wasm_func_t* wasm_func_new_with_env( - wasm_store_t*, const wasm_functype_t* type, wasm_func_callback_with_env_t, - void* env, void (*finalizer)(void*)); - -WASM_API_EXTERN own wasm_functype_t* wasm_func_type(const wasm_func_t*); -WASM_API_EXTERN size_t wasm_func_param_arity(const wasm_func_t*); -WASM_API_EXTERN size_t wasm_func_result_arity(const wasm_func_t*); - -WASM_API_EXTERN own wasm_trap_t* wasm_func_call( - const wasm_func_t*, const wasm_val_t args[], wasm_val_t results[]); - - -// Global Instances - -WASM_DECLARE_REF(global) - -WASM_API_EXTERN own wasm_global_t* wasm_global_new( - wasm_store_t*, const wasm_globaltype_t*, const wasm_val_t*); - -WASM_API_EXTERN own wasm_globaltype_t* wasm_global_type(const wasm_global_t*); - -WASM_API_EXTERN void wasm_global_get(const wasm_global_t*, own wasm_val_t* out); -WASM_API_EXTERN void wasm_global_set(wasm_global_t*, const wasm_val_t*); - - -// Table Instances - -WASM_DECLARE_REF(table) - -typedef uint32_t wasm_table_size_t; - -WASM_API_EXTERN own wasm_table_t* wasm_table_new( - wasm_store_t*, const wasm_tabletype_t*, wasm_ref_t* init); - -WASM_API_EXTERN own wasm_tabletype_t* wasm_table_type(const wasm_table_t*); - -WASM_API_EXTERN own wasm_ref_t* wasm_table_get(const wasm_table_t*, wasm_table_size_t index); -WASM_API_EXTERN bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*); - -WASM_API_EXTERN wasm_table_size_t wasm_table_size(const wasm_table_t*); -WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init); - - -// Memory Instances - -WASM_DECLARE_REF(memory) - -typedef uint32_t wasm_memory_pages_t; - -static const size_t MEMORY_PAGE_SIZE = 0x10000; - -WASM_API_EXTERN own wasm_memory_t* wasm_memory_new(wasm_store_t*, const wasm_memorytype_t*); - -WASM_API_EXTERN own wasm_memorytype_t* wasm_memory_type(const wasm_memory_t*); - -WASM_API_EXTERN byte_t* wasm_memory_data(wasm_memory_t*); -WASM_API_EXTERN size_t wasm_memory_data_size(const wasm_memory_t*); - -WASM_API_EXTERN wasm_memory_pages_t wasm_memory_size(const wasm_memory_t*); -WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta); - - -// Externals - -WASM_DECLARE_REF(extern) -WASM_DECLARE_VEC(extern, *) - -WASM_API_EXTERN wasm_externkind_t wasm_extern_kind(const wasm_extern_t*); -WASM_API_EXTERN own wasm_externtype_t* wasm_extern_type(const wasm_extern_t*); - -WASM_API_EXTERN wasm_extern_t* wasm_func_as_extern(wasm_func_t*); -WASM_API_EXTERN wasm_extern_t* wasm_global_as_extern(wasm_global_t*); -WASM_API_EXTERN wasm_extern_t* wasm_table_as_extern(wasm_table_t*); -WASM_API_EXTERN wasm_extern_t* wasm_memory_as_extern(wasm_memory_t*); - -WASM_API_EXTERN wasm_func_t* wasm_extern_as_func(wasm_extern_t*); -WASM_API_EXTERN wasm_global_t* wasm_extern_as_global(wasm_extern_t*); -WASM_API_EXTERN wasm_table_t* wasm_extern_as_table(wasm_extern_t*); -WASM_API_EXTERN wasm_memory_t* wasm_extern_as_memory(wasm_extern_t*); - -WASM_API_EXTERN const wasm_extern_t* wasm_func_as_extern_const(const wasm_func_t*); -WASM_API_EXTERN const wasm_extern_t* wasm_global_as_extern_const(const wasm_global_t*); -WASM_API_EXTERN const wasm_extern_t* wasm_table_as_extern_const(const wasm_table_t*); -WASM_API_EXTERN const wasm_extern_t* wasm_memory_as_extern_const(const wasm_memory_t*); - -WASM_API_EXTERN const wasm_func_t* wasm_extern_as_func_const(const wasm_extern_t*); -WASM_API_EXTERN const wasm_global_t* wasm_extern_as_global_const(const wasm_extern_t*); -WASM_API_EXTERN const wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t*); -WASM_API_EXTERN const wasm_memory_t* wasm_extern_as_memory_const(const wasm_extern_t*); - - -// Module Instances - -WASM_DECLARE_REF(instance) - -WASM_API_EXTERN own wasm_instance_t* wasm_instance_new( - wasm_store_t*, const wasm_module_t*, const wasm_extern_t* const imports[], - own wasm_trap_t** -); - -WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out); - -WASM_API_EXTERN uint32_t wasm_instance_func_index(const wasm_instance_t*, const wasm_func_t*); - - -/////////////////////////////////////////////////////////////////////////////// -// Convenience - -// Value Type construction short-hands - -static inline own wasm_valtype_t* wasm_valtype_new_i32() { - return wasm_valtype_new(WASM_I32); -} -static inline own wasm_valtype_t* wasm_valtype_new_i64() { - return wasm_valtype_new(WASM_I64); -} -static inline own wasm_valtype_t* wasm_valtype_new_f32() { - return wasm_valtype_new(WASM_F32); -} -static inline own wasm_valtype_t* wasm_valtype_new_f64() { - return wasm_valtype_new(WASM_F64); -} - -static inline own wasm_valtype_t* wasm_valtype_new_anyref() { - return wasm_valtype_new(WASM_ANYREF); -} -static inline own wasm_valtype_t* wasm_valtype_new_funcref() { - return wasm_valtype_new(WASM_FUNCREF); -} - - -// Function Types construction short-hands - -static inline own wasm_functype_t* wasm_functype_new_0_0() { - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new_empty(¶ms); - wasm_valtype_vec_new_empty(&results); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_1_0( - own wasm_valtype_t* p -) { - wasm_valtype_t* ps[1] = {p}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 1, ps); - wasm_valtype_vec_new_empty(&results); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_2_0( - own wasm_valtype_t* p1, own wasm_valtype_t* p2 -) { - wasm_valtype_t* ps[2] = {p1, p2}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 2, ps); - wasm_valtype_vec_new_empty(&results); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_3_0( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3 -) { - wasm_valtype_t* ps[3] = {p1, p2, p3}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 3, ps); - wasm_valtype_vec_new_empty(&results); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_0_1( - own wasm_valtype_t* r -) { - wasm_valtype_t* rs[1] = {r}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new_empty(¶ms); - wasm_valtype_vec_new(&results, 1, rs); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_1_1( - own wasm_valtype_t* p, own wasm_valtype_t* r -) { - wasm_valtype_t* ps[1] = {p}; - wasm_valtype_t* rs[1] = {r}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 1, ps); - wasm_valtype_vec_new(&results, 1, rs); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_2_1( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* r -) { - wasm_valtype_t* ps[2] = {p1, p2}; - wasm_valtype_t* rs[1] = {r}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 2, ps); - wasm_valtype_vec_new(&results, 1, rs); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_3_1( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3, - own wasm_valtype_t* r -) { - wasm_valtype_t* ps[3] = {p1, p2, p3}; - wasm_valtype_t* rs[1] = {r}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 3, ps); - wasm_valtype_vec_new(&results, 1, rs); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_0_2( - own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { - wasm_valtype_t* rs[2] = {r1, r2}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new_empty(¶ms); - wasm_valtype_vec_new(&results, 2, rs); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_1_2( - own wasm_valtype_t* p, own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { - wasm_valtype_t* ps[1] = {p}; - wasm_valtype_t* rs[2] = {r1, r2}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 1, ps); - wasm_valtype_vec_new(&results, 2, rs); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_2_2( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, - own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { - wasm_valtype_t* ps[2] = {p1, p2}; - wasm_valtype_t* rs[2] = {r1, r2}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 2, ps); - wasm_valtype_vec_new(&results, 2, rs); - return wasm_functype_new(¶ms, &results); -} - -static inline own wasm_functype_t* wasm_functype_new_3_2( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3, - own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { - wasm_valtype_t* ps[3] = {p1, p2, p3}; - wasm_valtype_t* rs[2] = {r1, r2}; - wasm_valtype_vec_t params, results; - wasm_valtype_vec_new(¶ms, 3, ps); - wasm_valtype_vec_new(&results, 2, rs); - return wasm_functype_new(¶ms, &results); -} - - -// Value construction short-hands - -static inline void wasm_val_init_ptr(own wasm_val_t* out, void* p) { -#if UINTPTR_MAX == UINT32_MAX - out->kind = WASM_I32; - out->of.i32 = (intptr_t)p; -#elif UINTPTR_MAX == UINT64_MAX - out->kind = WASM_I64; - out->of.i64 = (intptr_t)p; -#endif -} - -static inline void* wasm_val_ptr(const wasm_val_t* val) { -#if UINTPTR_MAX == UINT32_MAX - return (void*)(intptr_t)val->of.i32; -#elif UINTPTR_MAX == UINT64_MAX - return (void*)(intptr_t)val->of.i64; -#endif -} - - -/////////////////////////////////////////////////////////////////////////////// - -#undef own - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // #ifdef WASM_H diff --git a/third_party/wasm/wabt b/third_party/wasm/wabt deleted file mode 160000 index c32fa5972..000000000 --- a/third_party/wasm/wabt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c32fa597218dbe2c25b43a9837a8475b493ddb71 diff --git a/tools/test/wasm-js/wabt_patch b/tools/test/wasm-js/wabt_patch deleted file mode 100644 index 1f936bf85..000000000 --- a/tools/test/wasm-js/wabt_patch +++ /dev/null @@ -1,54 +0,0 @@ -diff --git src/interp/interp-wasm-c-api.cc src/interp/interp-wasm-c-api.cc -index 4df66b89..2edc17d9 100644 ---- src/interp/interp-wasm-c-api.cc -+++ src/interp/interp-wasm-c-api.cc -@@ -626,6 +626,11 @@ own wasm_store_t* wasm_store_new(wasm_engine_t* engine) { - return new wasm_store_t(s_features); - } - -+void wasm_store_gc(wasm_store_t* store) { -+ assert(store); -+ store->I.Collect(); -+} -+ - // wasm_module - - own wasm_module_t* wasm_module_new(wasm_store_t* store, -@@ -760,6 +765,20 @@ void wasm_instance_exports(const wasm_instance_t* instance, - } - } - -+uint32_t wasm_instance_func_index(const wasm_instance_t* instance, -+ const wasm_func_t* func) { -+ auto&& funcs = instance->As()->funcs(); -+ -+ assert(funcs.size() < wasm_limits_max_default); -+ for (size_t i = 0; i < funcs.size(); ++i) { -+ if (funcs[i] == func->I.ref()) { -+ return i; -+ } -+ } -+ -+ return wasm_limits_max_default; -+} -+ - // wasm_functype - - own wasm_functype_t* wasm_functype_new(own wasm_valtype_vec_t* params, -@@ -1170,6 +1189,16 @@ void wasm_val_vec_delete(own wasm_val_vec_t* vec) { - } \ - delete[] vec->data; \ - vec->size = 0; \ -+ } \ -+ void wasm_##name##_vec_delete_with_size(wasm_##name##_vec_t* vec, \ -+ size_t size) { \ -+ assert(size <= vec->size); \ -+ TRACE0(); \ -+ for (size_t i = 0; i < size; ++i) { \ -+ delete vec->data[i]; \ -+ } \ -+ delete[] vec->data; \ -+ vec->size = 0; \ - } - - WASM_IMPL_VEC_OWN(frame);