From 6eaf779a2d17452d8c7c51bb45709676f7ce6baf Mon Sep 17 00:00:00 2001 From: Callum Macmillan Date: Thu, 1 Dec 2022 02:39:14 +0000 Subject: [PATCH 1/5] Install patched LLDB on vscode extension activation (#1637) Download and install the WAMR patched LLDB binary on vscode extension activation. This allows the user to download the packaged .vsix file, where the activation script should handle determining what LLDB binary they should use, and install it in the correct location. --- .../wamr-ide/VSCode-Extension/package.json | 8 +- .../debug/{osx => darwin}/.placeholder | 0 .../src/decorationProvider.ts | 6 +- .../VSCode-Extension/src/extension.ts | 36 ++++++-- .../src/utilities/directoryUtilities.ts | 83 +++++++++++++++++-- .../src/utilities/lldbUtilities.ts | 83 +++++++++++++++++++ .../src/view/NewProjectPanel.ts | 14 ++-- 7 files changed, 202 insertions(+), 28 deletions(-) rename test-tools/wamr-ide/VSCode-Extension/resource/debug/{osx => darwin}/.placeholder (100%) create mode 100644 test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts diff --git a/test-tools/wamr-ide/VSCode-Extension/package.json b/test-tools/wamr-ide/VSCode-Extension/package.json index 4550452373..61d1387cce 100644 --- a/test-tools/wamr-ide/VSCode-Extension/package.json +++ b/test-tools/wamr-ide/VSCode-Extension/package.json @@ -129,7 +129,7 @@ "program": "./resource/debug/windows/bin/lldb-vscode.exe" }, "osx": { - "program": "./resource/debug/osx/bin/lldb-vscode" + "program": "./resource/debug/darwin/bin/lldb-vscode" }, "linux": { "program": "./resource/debug/linux/bin/lldb-vscode" @@ -237,7 +237,9 @@ "@types/glob": "^7.1.3", "@types/mocha": "^8.2.2", "@types/node": "14.x", + "@types/request": "^2.48.8", "@types/vscode": "^1.54.0", + "@types/yauzl": "^2.10.0", "@typescript-eslint/eslint-plugin": "^4.26.0", "@typescript-eslint/parser": "^4.26.0", "eslint": "^7.32.0", @@ -248,6 +250,8 @@ "vscode-test": "^1.5.2" }, "dependencies": { - "@vscode/webview-ui-toolkit": "^0.8.4" + "@vscode/webview-ui-toolkit": "^0.8.4", + "request": "^2.88.2", + "yauzl": "^2.10.0" } } diff --git a/test-tools/wamr-ide/VSCode-Extension/resource/debug/osx/.placeholder b/test-tools/wamr-ide/VSCode-Extension/resource/debug/darwin/.placeholder similarity index 100% rename from test-tools/wamr-ide/VSCode-Extension/resource/debug/osx/.placeholder rename to test-tools/wamr-ide/VSCode-Extension/resource/debug/darwin/.placeholder diff --git a/test-tools/wamr-ide/VSCode-Extension/src/decorationProvider.ts b/test-tools/wamr-ide/VSCode-Extension/src/decorationProvider.ts index db636913e0..e9687f6902 100644 --- a/test-tools/wamr-ide/VSCode-Extension/src/decorationProvider.ts +++ b/test-tools/wamr-ide/VSCode-Extension/src/decorationProvider.ts @@ -4,7 +4,7 @@ */ import * as vscode from 'vscode'; -import { ReadFromFile } from './utilities/directoryUtilities'; +import { readFromFile } from './utilities/directoryUtilities'; import * as path from 'path'; import * as os from 'os'; @@ -63,8 +63,8 @@ export class DecorationProvider implements vscode.FileDecorationProvider { prjConfigDir = path.join(currentPrjDir, '.wamr'); configFilePath = path.join(prjConfigDir, 'compilation_config.json'); - if (ReadFromFile(configFilePath) !== '') { - configData = JSON.parse(ReadFromFile(configFilePath)); + if (readFromFile(configFilePath) !== '') { + configData = JSON.parse(readFromFile(configFilePath)); includePathArr = configData['include_paths']; excludeFileArr = configData['exclude_files']; diff --git a/test-tools/wamr-ide/VSCode-Extension/src/extension.ts b/test-tools/wamr-ide/VSCode-Extension/src/extension.ts index 57f2aa09bd..7eb8b34a65 100644 --- a/test-tools/wamr-ide/VSCode-Extension/src/extension.ts +++ b/test-tools/wamr-ide/VSCode-Extension/src/extension.ts @@ -12,12 +12,13 @@ import { WasmTaskProvider } from './taskProvider'; import { TargetConfigPanel } from './view/TargetConfigPanel'; import { NewProjectPanel } from './view/NewProjectPanel'; import { - CheckIfDirectoryExist, - WriteIntoFile, - ReadFromFile, + checkIfDirectoryExists, + writeIntoFile, + readFromFile, } from './utilities/directoryUtilities'; import { decorationProvider } from './decorationProvider'; import { WasmDebugConfigurationProvider } from './debugConfigurationProvider'; +import { isLLDBInstalled, promptInstallLLDB } from './utilities/lldbUtilities'; let wasmTaskProvider: WasmTaskProvider; let wasmDebugConfigProvider: WasmDebugConfigurationProvider; @@ -213,7 +214,7 @@ export async function activate(context: vscode.ExtensionContext) { return; } }); - } else if (!CheckIfDirectoryExist(curWorkspace as string)) { + } else if (!checkIfDirectoryExists(curWorkspace as string)) { vscode.window .showWarningMessage( 'Invalid workspace:', @@ -369,7 +370,7 @@ export async function activate(context: vscode.ExtensionContext) { let disposableDebug = vscode.commands.registerCommand( 'wamride.debug', - () => { + async () => { if (!isWasmProject) { vscode.window.showErrorMessage('debug failed', { modal: true, @@ -378,6 +379,15 @@ export async function activate(context: vscode.ExtensionContext) { return; } + /* we should check again whether the user installed lldb, as this can be skipped during activation */ + try { + if (!isLLDBInstalled(context)) { + await promptInstallLLDB(context); + } + } catch (e) { + vscode.window.showWarningMessage((e as Error).message); + } + /* refuse to debug if build process failed */ if (!checkIfBuildSuccess()) { vscode.window.showErrorMessage('Debug failed', { @@ -582,7 +592,7 @@ export async function activate(context: vscode.ExtensionContext) { return; } }); - } else if (!CheckIfDirectoryExist(curWorkspace as string)) { + } else if (!checkIfDirectoryExists(curWorkspace as string)) { vscode.window .showWarningMessage( 'Invalid workspace:', @@ -686,6 +696,14 @@ export async function activate(context: vscode.ExtensionContext) { disposableToggleExcludeFile, disposableDebug ); + + try { + if (!isLLDBInstalled(context)) { + await promptInstallLLDB(context); + } + } catch (e) { + vscode.window.showWarningMessage((e as Error).message); + } } function openWindoWithSituation(uri: vscode.Uri) { @@ -736,13 +754,13 @@ export function writeIntoConfigFile( let prjConfigDir = path.join(currentPrjDir, '.wamr'); let configFilePath = path.join(prjConfigDir, 'compilation_config.json'); - WriteIntoFile(configFilePath, jsonStr); + writeIntoFile(configFilePath, jsonStr); } export function readFromConfigFile(): string { let prjConfigDir = path.join(currentPrjDir, '.wamr'); let configFilePath = path.join(prjConfigDir, 'compilation_config.json'); - return ReadFromFile(configFilePath); + return readFromFile(configFilePath); } /** @@ -854,7 +872,7 @@ function generateCMakeFile( .concat('\n', strSrcList) .concat('\n', strIncludeList); - WriteIntoFile(cmakeFilePath, fullStr); + writeIntoFile(cmakeFilePath, fullStr); } function getAllSrcFiles(_path: string) { diff --git a/test-tools/wamr-ide/VSCode-Extension/src/utilities/directoryUtilities.ts b/test-tools/wamr-ide/VSCode-Extension/src/utilities/directoryUtilities.ts index cff54c7f02..348e5730a7 100644 --- a/test-tools/wamr-ide/VSCode-Extension/src/utilities/directoryUtilities.ts +++ b/test-tools/wamr-ide/VSCode-Extension/src/utilities/directoryUtilities.ts @@ -7,12 +7,14 @@ import fileSystem = require('fs'); import vscode = require('vscode'); import path = require('path'); import os = require('os'); +import request = require('request'); +import yauzl = require('yauzl'); /** * * @param path destination path */ -export function CreateDirectory( +export function createDirectory( dest: string, mode: string | number | null | undefined = undefined ): boolean { @@ -30,7 +32,7 @@ export function CreateDirectory( } let parent = path.dirname(dest); - if (!CreateDirectory(parent, mode)) { + if (!createDirectory(parent, mode)) { return false; } @@ -42,7 +44,7 @@ export function CreateDirectory( } } -export function CopyFiles(src: string, dest: string, flags?: number): boolean { +export function copyFiles(src: string, dest: string, flags?: number): boolean { try { fileSystem.copyFileSync(src, dest); return true; @@ -52,7 +54,7 @@ export function CopyFiles(src: string, dest: string, flags?: number): boolean { } } -export function WriteIntoFile(path: string, data: string): void { +export function writeIntoFile(path: string, data: string): void { try { fileSystem.writeFileSync(path, data, null); } catch (err) { @@ -60,7 +62,7 @@ export function WriteIntoFile(path: string, data: string): void { } } -export function ReadFromFile(path: string): string { +export function readFromFile(path: string): string { try { let data = fileSystem.readFileSync(path, { encoding: 'utf-8' }); return data as string; @@ -70,7 +72,7 @@ export function ReadFromFile(path: string): string { } } -export function WriteIntoFileAsync( +export function writeIntoFileAsync( path: string, data: string, callback: fileSystem.NoParamCallback @@ -83,7 +85,7 @@ export function WriteIntoFileAsync( } } -export function CheckIfDirectoryExist(path: string): boolean { +export function checkIfPathExists(path: string): boolean { try { if (fileSystem.existsSync(path)) { return true; @@ -96,6 +98,22 @@ export function CheckIfDirectoryExist(path: string): boolean { } } +export function checkIfDirectoryExists(path: string): boolean { + const doesPathExist = checkIfPathExists(path); + if (doesPathExist) { + return fileSystem.lstatSync(path).isDirectory(); + } + return false; +} + +export function checkIfFileExists(path: string): boolean { + const doesPathExist = checkIfPathExists(path); + if (doesPathExist) { + return fileSystem.lstatSync(path).isFile(); + } + return false; +} + export function checkFolderName(folderName: string) { let invalidCharacterArr: string[] = []; var valid = true; @@ -118,3 +136,54 @@ export function checkFolderName(folderName: string) { return valid; } + +export function downloadFile(url: string, destinationPath: string): Promise { + return new Promise((resolve, reject) => { + const file = fileSystem.createWriteStream(destinationPath); + const stream = request(url, undefined, (error, response, body) => { + if (response.statusCode !== 200) { + reject(new Error(`Download from ${url} failed with ${response.statusMessage}`)); + } + }).pipe(file); + stream.on("close", resolve); + stream.on("error", reject); + }); +} + +export function unzipFile(sourcePath: string, getDestinationFileName: (entryName: string) => string): Promise { + return new Promise((resolve, reject) => { + const unzippedFilePaths: string[] = []; + yauzl.open(sourcePath, { lazyEntries: true }, function(error, zipfile) { + if (error) { + reject(error); + return; + } + zipfile.readEntry(); + zipfile.on("entry", function(entry) { + // This entry is a directory so skip it + if (/\/$/.test(entry.fileName)) { + zipfile.readEntry(); + return; + } + + zipfile.openReadStream(entry, function(error, readStream) { + if (error) { + reject(error); + return; + } + readStream.on("end", () => zipfile.readEntry()); + const destinationFileName = getDestinationFileName(entry.fileName); + fileSystem.mkdirSync(path.dirname(destinationFileName), { recursive: true }); + + const file = fileSystem.createWriteStream(destinationFileName); + readStream.pipe(file).on("error", reject); + unzippedFilePaths.push(destinationFileName); + }); + }); + zipfile.on("end", function() { + zipfile.close(); + resolve(unzippedFilePaths); + }); + }); + }); +} \ No newline at end of file diff --git a/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts b/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts new file mode 100644 index 0000000000..50d468b94a --- /dev/null +++ b/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import * as vscode from 'vscode'; +import * as os from 'os'; +import * as path from 'path'; +import * as fs from 'fs'; +import { checkIfFileExists, downloadFile, unzipFile } from './directoryUtilities'; + +const LLDB_RESOURCE_DIR = "resource/debug"; +const LLDB_OS_DOWNLOAD_URL_SUFFIX_MAP: Partial> = { + "linux": "x86_64-ubuntu-22.04", + "darwin": "universal-macos-latest" +}; + +const WAMR_LLDB_NOT_SUPPORTED_ERROR = new Error("WAMR LLDB is not supported on this platform"); + +function getLLDBUnzipFilePath(destinationFolder: string, filename: string) { + const dirs = filename.split("/"); + if (dirs[0] === "inst") { + dirs.shift(); + } + + return path.join(destinationFolder, ...dirs); +} + +function getLLDBDownloadUrl(context: vscode.ExtensionContext): string { + const wamrVersion = require(path.join(context.extensionPath, "package.json")).version; + const lldbOsUrlSuffix = LLDB_OS_DOWNLOAD_URL_SUFFIX_MAP[os.platform()]; + + if (!lldbOsUrlSuffix) { + throw WAMR_LLDB_NOT_SUPPORTED_ERROR; + } + + return `https://github.com/bytecodealliance/wasm-micro-runtime/releases/download/WAMR-${wamrVersion}/wamr-lldb-${wamrVersion}-${lldbOsUrlSuffix}.zip`; +} + +export function isLLDBInstalled(context: vscode.ExtensionContext): boolean { + const extensionPath = context.extensionPath; + const lldbOSDir = os.platform(); + const lldbBinaryPath = path.join(extensionPath, LLDB_RESOURCE_DIR, lldbOSDir, "bin", "lldb"); + return checkIfFileExists(lldbBinaryPath); +} + +export async function promptInstallLLDB(context: vscode.ExtensionContext) { + const extensionPath = context.extensionPath; + const setupPrompt = "setup"; + const skipPrompt = "skip"; + const response = await vscode.window.showWarningMessage('No LLDB instance found. Setup now?', setupPrompt, skipPrompt); + + if (response === skipPrompt) { + return; + } + + const downloadUrl = getLLDBDownloadUrl(context); + const destinationDir = os.platform(); + + if (!downloadUrl) { + throw WAMR_LLDB_NOT_SUPPORTED_ERROR; + } + + const lldbDestinationFolder = path.join(extensionPath, LLDB_RESOURCE_DIR, destinationDir); + const lldbZipPath = path.join(lldbDestinationFolder, "bundle.zip"); + + vscode.window.showInformationMessage(`Downloading LLDB...`); + + await downloadFile(downloadUrl, lldbZipPath); + + vscode.window.showInformationMessage(`LLDB downloaded to ${lldbZipPath}. Installing...`); + + const lldbFiles = await unzipFile(lldbZipPath, filename => getLLDBUnzipFilePath(lldbDestinationFolder, filename)); + // Allow execution of lldb + lldbFiles.forEach(file => fs.chmodSync(file, "0775")); + + vscode.window.showInformationMessage(`LLDB installed at ${lldbDestinationFolder}`); + + // Remove the bundle.zip + fs.unlink(lldbZipPath, () => {}); +} + + diff --git a/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts b/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts index a7536564fc..29f1e05475 100644 --- a/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts +++ b/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts @@ -8,8 +8,8 @@ import * as path from 'path'; import * as fs from 'fs'; import * as os from 'os'; import { - CreateDirectory, - CopyFiles, + createDirectory, + copyFiles, checkFolderName, } from '../utilities/directoryUtilities'; import { getUri } from '../utilities/getUri'; @@ -84,16 +84,16 @@ export class NewProjectPanel { } } - CreateDirectory(path.join(ROOT_PATH, '.wamr')); - CreateDirectory(path.join(ROOT_PATH, 'include')); - CreateDirectory(path.join(ROOT_PATH, 'src')); + createDirectory(path.join(ROOT_PATH, '.wamr')); + createDirectory(path.join(ROOT_PATH, 'include')); + createDirectory(path.join(ROOT_PATH, 'src')); - CopyFiles( + copyFiles( path.join(EXT_PATH, 'resource/scripts/CMakeLists.txt'), path.join(ROOT_PATH, '.wamr/CMakeLists.txt') ); - CopyFiles( + copyFiles( path.join(EXT_PATH, 'resource/scripts/project.cmake'), path.join(ROOT_PATH, '.wamr/project.cmake') ); From 1652f22a7761b55bdc7187398fae1a8f159073d2 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Thu, 1 Dec 2022 19:24:13 +0800 Subject: [PATCH 2/5] Fix issues reported by Coverity (#1775) Fix some issues reported by Coverity and fix windows exception check with guard page issue --- core/iwasm/common/wasm_runtime_common.c | 61 +++++++++++-------- core/iwasm/compilation/aot_emit_control.c | 1 + core/iwasm/interpreter/wasm_mini_loader.c | 3 +- .../sandboxed-system-primitives/src/posix.c | 9 +-- samples/file/src/main.c | 6 +- 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 17cf9da31b..8ddf4af437 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -143,9 +143,9 @@ runtime_signal_handler(void *sig_addr) WASMJmpBuf *jmpbuf_node; uint8 *mapped_mem_start_addr = NULL; uint8 *mapped_mem_end_addr = NULL; + uint32 page_size = os_getpagesize(); #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 uint8 *stack_min_addr; - uint32 page_size; uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT; #endif @@ -163,7 +163,6 @@ runtime_signal_handler(void *sig_addr) #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 /* Get stack info of current thread */ - page_size = os_getpagesize(); stack_min_addr = os_thread_get_stack_boundary(); #endif @@ -216,29 +215,41 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info) mapped_mem_start_addr = memory_inst->memory_data; mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB; - if (mapped_mem_start_addr <= (uint8 *)sig_addr - && (uint8 *)sig_addr < mapped_mem_end_addr) { - /* The address which causes segmentation fault is inside - the memory instance's guard regions. - Set exception and let the wasm func continue to run, when - the wasm func returns, the caller will check whether the - exception is thrown and return to runtime. */ - wasm_set_exception(module_inst, - "out of bounds memory access"); - if (module_inst->module_type == Wasm_Module_Bytecode) { - /* Continue to search next exception handler for - interpreter mode as it can be caught by - `__try { .. } __except { .. }` sentences in - wasm_runtime.c */ - return EXCEPTION_CONTINUE_SEARCH; - } - else { - /* Skip current instruction and continue to run for - AOT mode. TODO: implement unwind support for AOT - code in Windows platform */ - exce_info->ContextRecord->Rip++; - return EXCEPTION_CONTINUE_EXECUTION; - } + } + + if (memory_inst && mapped_mem_start_addr <= (uint8 *)sig_addr + && (uint8 *)sig_addr < mapped_mem_end_addr) { + /* The address which causes segmentation fault is inside + the memory instance's guard regions. + Set exception and let the wasm func continue to run, when + the wasm func returns, the caller will check whether the + exception is thrown and return to runtime. */ + wasm_set_exception(module_inst, "out of bounds memory access"); + if (module_inst->module_type == Wasm_Module_Bytecode) { + /* Continue to search next exception handler for + interpreter mode as it can be caught by + `__try { .. } __except { .. }` sentences in + wasm_runtime.c */ + return EXCEPTION_CONTINUE_SEARCH; + } + else { + /* Skip current instruction and continue to run for + AOT mode. TODO: implement unwind support for AOT + code in Windows platform */ + exce_info->ContextRecord->Rip++; + return EXCEPTION_CONTINUE_EXECUTION; + } + } + else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr + && (uint8 *)sig_addr + < exec_env_tls->exce_check_guard_page + page_size) { + bh_assert(wasm_get_exception(module_inst)); + if (module_inst->module_type == Wasm_Module_Bytecode) { + return EXCEPTION_CONTINUE_SEARCH; + } + else { + exce_info->ContextRecord->Rip++; + return EXCEPTION_CONTINUE_EXECUTION; } } } diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 6d452b04f0..68c286f43c 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -462,6 +462,7 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, false, NULL, NULL))) { goto fail; } + aot_block_destroy(block); return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip); } diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index f009ca875c..af116a8234 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -5125,10 +5125,11 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block, /* Free the emit data */ wasm_runtime_free(emit_data); - return true; fail: + /* Free the emit data */ + wasm_runtime_free(emit_data); return false; } #endif diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index a1e3e37388..0d44ae7da1 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -3081,14 +3081,15 @@ wasi_ssp_sock_addr_resolve( size_t _max_info_size; size_t actual_info_size; - if (!ns_lookup_list_search(ns_lookup_list, host)) { - return __WASI_EACCES; - } - if (!wamr_addr_info) { return __WASI_ENOMEM; } + if (!ns_lookup_list_search(ns_lookup_list, host)) { + wasm_runtime_free(wamr_addr_info); + return __WASI_EACCES; + } + int ret = os_socket_addr_resolve( host, service, hints->hints_enabled ? &hints_is_tcp : NULL, hints->hints_enabled ? &hints_is_ipv4 : NULL, wamr_addr_info, diff --git a/samples/file/src/main.c b/samples/file/src/main.c index de5eb29184..2fb99e2555 100644 --- a/samples/file/src/main.c +++ b/samples/file/src/main.c @@ -26,7 +26,6 @@ main(int argc, char *argv_main[]) wasm_module_inst_t module_inst = NULL; wasm_exec_env_t exec_env = NULL; uint32 buf_size, stack_size = 8092, heap_size = 8092; - uint32_t wasm_buffer = 0; RuntimeInitArgs init_args; memset(&init_args, 0, sizeof(RuntimeInitArgs)); @@ -103,11 +102,8 @@ main(int argc, char *argv_main[]) fail: if (exec_env) wasm_runtime_destroy_exec_env(exec_env); - if (module_inst) { - if (wasm_buffer) - wasm_runtime_module_free(module_inst, wasm_buffer); + if (module_inst) wasm_runtime_deinstantiate(module_inst); - } if (module) wasm_runtime_unload(module); if (buffer) From fc8f70cfa42919070c6ccc7be0998f70506d2b9e Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Thu, 1 Dec 2022 22:03:09 +0800 Subject: [PATCH 3/5] Fix issues detected by Coverity (#1776) - wasm_func_call always return trap if failed - in Debug, always run LEAK_TEST in samples/wasm-c-api --- core/iwasm/common/wasm_c_api.c | 1 + samples/wasm-c-api/CMakeLists.txt | 13 ++++--- samples/wasm-c-api/src/callback.c | 8 +++-- samples/wasm-c-api/src/clone.c | 8 +++-- samples/wasm-c-api/src/empty_imports.c | 14 +++++--- samples/wasm-c-api/src/global.c | 40 ++++++++++++++------- samples/wasm-c-api/src/globalexportimport.c | 29 ++++++++++----- samples/wasm-c-api/src/hello.c | 8 +++-- samples/wasm-c-api/src/hostref.c | 40 +++++++++++++-------- samples/wasm-c-api/src/memory.c | 21 +++++++---- samples/wasm-c-api/src/multi.c | 8 +++-- samples/wasm-c-api/src/serialize.c | 4 ++- samples/wasm-c-api/src/table.c | 13 +++++-- samples/wasm-c-api/src/threads.c | 4 ++- 14 files changed, 144 insertions(+), 67 deletions(-) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 212a778019..6908fbf449 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -2112,6 +2112,7 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out) memset(&module_name, 0, sizeof(wasm_val_vec_t)); memset(&name, 0, sizeof(wasm_val_vec_t)); extern_type = NULL; + import_type = NULL; if (i < import_func_count) { wasm_functype_t *type = NULL; diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index 2b3a02db49..3fce87c017 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -199,11 +199,16 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") if(VALGRIND) foreach(EX ${EXAMPLES}) - add_custom_target(${EX}_LEAK_TEST - COMMAND ${VALGRIND} --tool=memcheck --leak-check=yes ./${EX} + add_custom_command( + OUTPUT ${EX}_leak_check.report DEPENDS ${EX} ${EX}_WASM - VERBATIM - COMMENT "run a leak check on ${EX}" + COMMAND ${VALGRIND} --tool=memcheck --leak-check=summary -- ./${EX} > ${EX}_leak_check.report 2>&1 + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + add_custom_target(${EX}_LEAK_TEST ALL + DEPENDS ${EX}_leak_check.report + COMMAND grep "All heap blocks were freed -- no leaks are possible" ${EX}_leak_check.report + COMMENT "Please read ${EX}_leak_check.report when meeting Error" ) endforeach() endif (VALGRIND) diff --git a/samples/wasm-c-api/src/callback.c b/samples/wasm-c-api/src/callback.c index b1294670d3..ccb9ec0675 100644 --- a/samples/wasm-c-api/src/callback.c +++ b/samples/wasm-c-api/src/callback.c @@ -169,9 +169,11 @@ int main(int argc, const char* argv[]) { wasm_val_t rs[1] = { WASM_INIT_VAL }; wasm_val_vec_t args = WASM_ARRAY_VEC(as); wasm_val_vec_t results = WASM_ARRAY_VEC(rs); - if (wasm_func_call(run_func, &args, &results)) { - printf("> Error calling function!\n"); - return 1; + wasm_trap_t *trap = wasm_func_call(run_func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + return 1; } wasm_extern_vec_delete(&exports); diff --git a/samples/wasm-c-api/src/clone.c b/samples/wasm-c-api/src/clone.c index bfe621758e..ce8ebd8bdb 100644 --- a/samples/wasm-c-api/src/clone.c +++ b/samples/wasm-c-api/src/clone.c @@ -231,10 +231,13 @@ vm_function_set_byte(const wasm_vm_t *vm, uint32_t offset, uint8_t byte) wasm_val_vec_t args = WASM_ARRAY_VEC(a_v); wasm_val_vec_t results = WASM_EMPTY_VEC; wasm_trap_t *trap = wasm_func_call(vm->function_list[0], &args, &results); - if (trap) + if (trap) { printf("call wasm_set_byte failed"); + wasm_trap_delete(trap); + return false; + } - return trap != NULL; + return true; } bool @@ -247,6 +250,7 @@ vm_function_get_byte(const wasm_vm_t *vm, uint32_t offset, uint8_t *byte) wasm_trap_t *trap = wasm_func_call(vm->function_list[1], &args, &results); if (trap) { printf("call wasm_get_byte failed"); + wasm_trap_delete(trap); return false; } diff --git a/samples/wasm-c-api/src/empty_imports.c b/samples/wasm-c-api/src/empty_imports.c index 5858ed6b54..c8788b51ac 100644 --- a/samples/wasm-c-api/src/empty_imports.c +++ b/samples/wasm-c-api/src/empty_imports.c @@ -97,10 +97,16 @@ int main(int argc, const char* argv[]) { wasm_val_t results[1] = { WASM_INIT_VAL }; wasm_val_vec_t results_vec = WASM_ARRAY_VEC(results); - if (wasm_func_call(add_func, &args_vec, &results_vec) - || results_vec.data[0].of.i32 != 7) { - printf("> Error calling function!\n"); - return 1; + wasm_trap_t *trap = wasm_func_call(add_func, &args_vec, &results_vec); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + return 1; + } + + if (results_vec.data[0].of.i32 != 7) { + printf("> Error calling function!\n"); + return 1; } wasm_extern_vec_delete(&exports); diff --git a/samples/wasm-c-api/src/global.c b/samples/wasm-c-api/src/global.c index bc4671d239..91c8cb654d 100644 --- a/samples/wasm-c-api/src/global.c +++ b/samples/wasm-c-api/src/global.c @@ -37,15 +37,22 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { check(val, type, expected); \ } -#define check_call(func, type, expected) \ - { \ - wasm_val_t vs[1]; \ - wasm_val_vec_t args = WASM_EMPTY_VEC; \ - wasm_val_vec_t results = WASM_ARRAY_VEC(vs); \ - wasm_func_call(func, &args, &results); \ - check(vs[0], type, expected); \ - } - +#define check_trap(trap) \ + if (trap) { \ + printf("> Error calling function\n"); \ + wasm_trap_delete(trap); \ + exit(1); \ + } + +#define check_call(func, type, expected) \ + { \ + wasm_val_t vs[1]; \ + wasm_val_vec_t args = WASM_EMPTY_VEC; \ + wasm_val_vec_t results = WASM_ARRAY_VEC(vs); \ + wasm_trap_t *trap = wasm_func_call(func, &args, &results); \ + check_trap(trap); \ + check(vs[0], type, expected); \ + } int main(int argc, const char* argv[]) { // Initialize. @@ -225,16 +232,23 @@ int main(int argc, const char* argv[]) { wasm_val_vec_t res = WASM_EMPTY_VEC; wasm_val_t vs73[] = { WASM_F32_VAL(73) }; wasm_val_vec_t args73 = WASM_ARRAY_VEC(vs73); - wasm_func_call(set_var_f32_import, &args73, &res); + wasm_trap_t *trap = wasm_func_call(set_var_f32_import, &args73, &res); + check_trap(trap); + wasm_val_t vs74[] = { WASM_I64_VAL(74) }; wasm_val_vec_t args74 = WASM_ARRAY_VEC(vs74); - wasm_func_call(set_var_i64_import, &args74, &res); + trap = wasm_func_call(set_var_i64_import, &args74, &res); + check_trap(trap); + wasm_val_t vs77[] = { WASM_F32_VAL(77) }; wasm_val_vec_t args77 = WASM_ARRAY_VEC(vs77); - wasm_func_call(set_var_f32_export, &args77, &res); + trap = wasm_func_call(set_var_f32_export, &args77, &res); + check_trap(trap); + wasm_val_t vs78[] = { WASM_I64_VAL(78) }; wasm_val_vec_t args78 = WASM_ARRAY_VEC(vs78); - wasm_func_call(set_var_i64_export, &args78, &res); + trap = wasm_func_call(set_var_i64_export, &args78, &res); + check_trap(trap); check_global(var_f32_import, f32, 73); check_global(var_i64_import, i64, 74); diff --git a/samples/wasm-c-api/src/globalexportimport.c b/samples/wasm-c-api/src/globalexportimport.c index 92420a1b9f..1c1715f2e5 100644 --- a/samples/wasm-c-api/src/globalexportimport.c +++ b/samples/wasm-c-api/src/globalexportimport.c @@ -50,13 +50,21 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { check(val, type, expected); \ } -#define check_call(func, type, expected) \ - { \ - wasm_val_vec_t results; \ - wasm_val_vec_new_uninitialized(&results, 1); \ - wasm_func_call(func, NULL, &results); \ - check(results.data[0], type, expected); \ - } +#define check_trap(trap) \ + if (trap) { \ + printf("> Error calling function\n"); \ + wasm_trap_delete(trap); \ + exit(1); \ + } + +#define check_call(func, type, expected) \ + { \ + wasm_val_vec_t results; \ + wasm_val_vec_new_uninitialized(&results, 1); \ + wasm_trap_t *trap = wasm_func_call(func, NULL, &results); \ + check_trap(trap); \ + check(results.data[0], type, expected); \ + } wasm_module_t * create_module_from_file(wasm_store_t* store, const char * filename) { @@ -149,7 +157,9 @@ int main(int argc, const char* argv[]) { printf("Modify the variable to 77.0...\n"); wasm_val_vec_t args77; wasm_val_vec_new(&args77, 1, (wasm_val_t []){ {.kind = WASM_F32, .of = {.f32 = 77.0}} }); - wasm_func_call(set_var_f32_export, &args77, NULL); //Call to module export + wasm_trap_t *trap = wasm_func_call(set_var_f32_export, &args77, + NULL); // Call to module export + check_trap(trap); check_call(get_var_f32_export, f32, 77.0); //Call to module export check_global(var_f32_export, f32, 77.0); //Failed here, still 37 check_call(get_var_f32_import, f32, 77.0); //Call to module import Failed here, still 37 @@ -158,7 +168,8 @@ int main(int argc, const char* argv[]) { printf("Modify the variable to 78.0...\n"); wasm_val_vec_t args78; wasm_val_vec_new(&args78, 1, (wasm_val_t []){ {.kind = WASM_F32, .of = {.f32 = 78.0}} }); - wasm_func_call(set_var_f32_import, &args78, NULL); + trap = wasm_func_call(set_var_f32_import, &args78, NULL); + check_trap(trap); check_global(var_f32_export, f32, 78.0); check_call(get_var_f32_export, f32, 78.0); //Call to module export Failed here, still 77 check_call(get_var_f32_import, f32, 78.0); //Call to module import diff --git a/samples/wasm-c-api/src/hello.c b/samples/wasm-c-api/src/hello.c index 5a2b9843e7..3ebea87b08 100644 --- a/samples/wasm-c-api/src/hello.c +++ b/samples/wasm-c-api/src/hello.c @@ -118,9 +118,11 @@ int main(int argc, const char* argv[]) { printf("Calling export...\n"); wasm_val_vec_t args = WASM_EMPTY_VEC; wasm_val_vec_t results = WASM_EMPTY_VEC; - if (wasm_func_call(run_func, &args, &results)) { - printf("> Error calling function!\n"); - return 1; + wasm_trap_t *trap = wasm_func_call(run_func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + return 1; } wasm_extern_vec_delete(&exports); diff --git a/samples/wasm-c-api/src/hostref.c b/samples/wasm-c-api/src/hostref.c index a411ddd9f4..219c862d68 100644 --- a/samples/wasm-c-api/src/hostref.c +++ b/samples/wasm-c-api/src/hostref.c @@ -50,9 +50,11 @@ own wasm_ref_t* call_v_r(const wasm_func_t* func) { wasm_val_t rs[] = { WASM_INIT_VAL }; wasm_val_vec_t args = WASM_EMPTY_VEC; wasm_val_vec_t results = WASM_ARRAY_VEC(rs); - if (wasm_func_call(func, &args, &results)) { - printf("> Error calling function!\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + exit(1); } printf("okay\n"); return rs[0].of.ref; @@ -63,9 +65,11 @@ void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) { wasm_val_t vs[1] = { WASM_REF_VAL(ref) }; wasm_val_vec_t args = WASM_ARRAY_VEC(vs); wasm_val_vec_t results = WASM_EMPTY_VEC; - if (wasm_func_call(func, &args, &results)) { - printf("> Error calling function!\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + exit(1); } printf("okay\n"); } @@ -76,9 +80,11 @@ own wasm_ref_t* call_r_r(const wasm_func_t* func, wasm_ref_t* ref) { wasm_val_t rs[1] = { WASM_INIT_VAL }; wasm_val_vec_t args = WASM_ARRAY_VEC(vs); wasm_val_vec_t results = WASM_ARRAY_VEC(rs); - if (wasm_func_call(func, &args, &results)) { - printf("> Error calling function!\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + exit(1); } printf("okay\n"); return rs[0].of.ref; @@ -89,9 +95,11 @@ void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) { wasm_val_t vs[2] = { WASM_I32_VAL(i), WASM_REF_VAL(ref) }; wasm_val_vec_t args = WASM_ARRAY_VEC(vs); wasm_val_vec_t results = WASM_EMPTY_VEC; - if (wasm_func_call(func, &args, &results)) { - printf("> Error calling function!\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + exit(1); } printf("okay\n"); } @@ -102,9 +110,11 @@ own wasm_ref_t* call_i_r(const wasm_func_t* func, int32_t i) { wasm_val_t rs[1] = { WASM_INIT_VAL }; wasm_val_vec_t args = WASM_ARRAY_VEC(vs); wasm_val_vec_t results = WASM_ARRAY_VEC(rs); - if (wasm_func_call(func, &args, &results)) { - printf("> Error calling function!\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + exit(1); } printf("okay\n"); return rs[0].of.ref; diff --git a/samples/wasm-c-api/src/memory.c b/samples/wasm-c-api/src/memory.c index 64d1c07778..737dd8501d 100644 --- a/samples/wasm-c-api/src/memory.c +++ b/samples/wasm-c-api/src/memory.c @@ -36,9 +36,16 @@ void check_call(wasm_func_t* func, int i, wasm_val_t args[], int32_t expected) { wasm_val_t r[] = {WASM_INIT_VAL}; wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL}; wasm_val_vec_t results = WASM_ARRAY_VEC(r); - if (wasm_func_call(func, &args_, &results) || r[0].of.i32 != expected) { - printf("> Error on result\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args_, &results); + if (trap) { + printf("> Error on result\n"); + wasm_trap_delete(trap); + exit(1); + } + + if (r[0].of.i32 != expected) { + printf("> Error on result\n"); + exit(1); } } @@ -59,9 +66,11 @@ void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected void check_ok(wasm_func_t* func, int i, wasm_val_t args[]) { wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL}; wasm_val_vec_t results = WASM_EMPTY_VEC; - if (wasm_func_call(func, &args_, &results)) { - printf("> Error on result, expected empty\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args_, &results); + if (trap) { + printf("> Error on result, expected empty\n"); + wasm_trap_delete(trap); + exit(1); } } diff --git a/samples/wasm-c-api/src/multi.c b/samples/wasm-c-api/src/multi.c index 92ef0eea77..a1c8fa9fc9 100644 --- a/samples/wasm-c-api/src/multi.c +++ b/samples/wasm-c-api/src/multi.c @@ -133,9 +133,11 @@ int main(int argc, const char* argv[]) { }; wasm_val_vec_t args = WASM_ARRAY_VEC(vals); wasm_val_vec_t results = WASM_ARRAY_VEC(res); - if (wasm_func_call(run_func, &args, &results)) { - printf("> Error calling function!\n"); - return 1; + wasm_trap_t *trap = wasm_func_call(run_func, &args, &results); + if (trap) { + printf("> Error calling function!\n"); + wasm_trap_delete(trap); + return 1; } wasm_extern_vec_delete(&exports); diff --git a/samples/wasm-c-api/src/serialize.c b/samples/wasm-c-api/src/serialize.c index d65706916c..83436817f2 100644 --- a/samples/wasm-c-api/src/serialize.c +++ b/samples/wasm-c-api/src/serialize.c @@ -111,8 +111,10 @@ main(int argc, const char *argv[]) // Call. printf("Calling export...\n"); wasm_val_vec_t empty = WASM_EMPTY_VEC; - if (wasm_func_call(run_func, &empty, &empty)) { + wasm_trap_t *trap = wasm_func_call(run_func, &empty, &empty); + if (trap) { printf("> Error calling function!\n"); + wasm_trap_delete(trap); return 1; } diff --git a/samples/wasm-c-api/src/table.c b/samples/wasm-c-api/src/table.c index 0bf68e05a7..c4a7da8bcf 100644 --- a/samples/wasm-c-api/src/table.c +++ b/samples/wasm-c-api/src/table.c @@ -53,9 +53,16 @@ void check_call(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) wasm_val_t r[1] = { WASM_INIT_VAL }; wasm_val_vec_t args = WASM_ARRAY_VEC(vs); wasm_val_vec_t results = WASM_ARRAY_VEC(r); - if (wasm_func_call(func, &args, &results) || r[0].of.i32 != expected) { - printf("> Error on result\n"); - exit(1); + wasm_trap_t *trap = wasm_func_call(func, &args, &results); + if (trap) { + printf("> Error on calling\n"); + wasm_trap_delete(trap); + exit(1); + } + + if (r[0].of.i32 != expected) { + printf("> Error on result\n"); + exit(1); } } diff --git a/samples/wasm-c-api/src/threads.c b/samples/wasm-c-api/src/threads.c index d7ae48939c..cbe4aaf444 100644 --- a/samples/wasm-c-api/src/threads.c +++ b/samples/wasm-c-api/src/threads.c @@ -85,8 +85,10 @@ run(void *args_abs) // Call. wasm_val_vec_t empty = WASM_EMPTY_VEC; - if (wasm_func_call(run_func, &empty, &empty)) { + wasm_trap_t *trap = wasm_func_call(run_func, &empty, &empty); + if (trap) { printf("> Error calling function!\n"); + wasm_trap_delete(trap); return NULL; } From 191e4a8663243d66d0142e9234578e4837a8b666 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 2 Dec 2022 02:18:20 +0000 Subject: [PATCH 4/5] Add ARM aeabi memcpy/memmove/memset symbols for AOT bulk memory ops (#1777) --- core/iwasm/aot/arch/aot_reloc_arm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/iwasm/aot/arch/aot_reloc_arm.c b/core/iwasm/aot/arch/aot_reloc_arm.c index 1389bfb25a..fbf9be13c8 100644 --- a/core/iwasm/aot/arch/aot_reloc_arm.c +++ b/core/iwasm/aot/arch/aot_reloc_arm.c @@ -37,6 +37,9 @@ void __aeabi_idivmod(); void __aeabi_l2d(); void __aeabi_l2f(); void __aeabi_ldivmod(); +void __aeabi_memcpy(); +void __aeabi_memmove(); +void __aeabi_memset(); void __aeabi_uidiv(); void __aeabi_uidivmod(); void __aeabi_ul2d(); @@ -120,6 +123,9 @@ static SymbolMap target_sym_map[] = { REG_SYM(__aeabi_l2d), REG_SYM(__aeabi_l2f), REG_SYM(__aeabi_ldivmod), + REG_SYM(__aeabi_memcpy), + REG_SYM(__aeabi_memmove), + REG_SYM(__aeabi_memset), REG_SYM(__aeabi_uidiv), REG_SYM(__aeabi_uidivmod), REG_SYM(__aeabi_ul2d), From 822a8a5e663da43de81bdfdbfff8424d1ce009aa Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 2 Dec 2022 12:41:40 +0900 Subject: [PATCH 5/5] wasm_native.c: Fix build with certain combinations of options (#1778) Fix a regression in https://github.com/bytecodealliance/wasm-micro-runtime/pull/1756 --- core/iwasm/common/wasm_native.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/core/iwasm/common/wasm_native.c b/core/iwasm/common/wasm_native.c index c7be95fcf0..0fa5962771 100644 --- a/core/iwasm/common/wasm_native.c +++ b/core/iwasm/common/wasm_native.c @@ -379,10 +379,11 @@ wasm_native_unregister_natives(const char *module_name, bool wasm_native_init() { -#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \ - || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \ - || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \ - || WASM_ENABLE_APP_FRAMEWORK != 0 +#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \ + || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \ + || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \ + || WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \ + || WASM_ENABLE_LIB_PTHREAD != 0 NativeSymbol *native_symbols; uint32 n_native_symbols; #endif @@ -461,10 +462,11 @@ wasm_native_init() #endif return true; -#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \ - || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \ - || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \ - || WASM_ENABLE_APP_FRAMEWORK != 0 +#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \ + || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \ + || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \ + || WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \ + || WASM_ENABLE_LIB_PTHREAD != 0 fail: wasm_native_destroy(); return false;