mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-05 09:46:53 +00:00
Wasmi 1.0.4 local patch
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
"requires": [
|
||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1756234269.497",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1756234289.683",
|
||||
"wasmi/0.42.1#2a96357d4e6bf40dfe201106d849c24f%1764802092.014",
|
||||
"wasmi/1.0.4#9cc7fac2db8eea07368fd0328a53648a%1766110559.972459",
|
||||
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1756234266.869",
|
||||
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1756234262.318",
|
||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1756234314.246",
|
||||
|
||||
@@ -35,7 +35,7 @@ class Xrpl(ConanFile):
|
||||
"openssl/3.5.4",
|
||||
"secp256k1/0.7.0",
|
||||
"soci/4.0.3",
|
||||
"wasmi/0.42.1",
|
||||
"wasmi/1.0.4",
|
||||
"zlib/1.3.1",
|
||||
]
|
||||
|
||||
@@ -126,6 +126,7 @@ class Xrpl(ConanFile):
|
||||
transitive_headers_opt = (
|
||||
{"transitive_headers": True} if conan_version.split(".")[0] == "2" else {}
|
||||
)
|
||||
|
||||
self.requires("boost/1.88.0", force=True, **transitive_headers_opt)
|
||||
self.requires("date/3.0.4", **transitive_headers_opt)
|
||||
self.requires("lz4/1.10.0", force=True)
|
||||
|
||||
18
external/wasmi/conandata.yml
vendored
Normal file
18
external/wasmi/conandata.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Do not update. Maintained by programmability team.
|
||||
|
||||
sources:
|
||||
"1.0.4":
|
||||
url: https://github.com/wasmi-labs/wasmi/archive/refs/tags/v1.0.4.tar.gz
|
||||
sha256: 90bfdd6d43930958c0f3eabe82e90800a7df4204b673c22f6966f94c6a5452e0
|
||||
"0.42.1":
|
||||
url: https://github.com/wasmi-labs/wasmi/archive/refs/tags/v0.42.1.tar.gz
|
||||
sha256: 2a5697be33c7afce8f671af4a5a3621d9e93ce55d253d31bd8201458e465fbb8
|
||||
patches:
|
||||
"1.0.4":
|
||||
- patch_file: "patches/0002-xrplf-1.0.4.patch"
|
||||
patch_description: Integrate wasmi lib into smart-escrow.
|
||||
patch_type: conan
|
||||
"0.42.1":
|
||||
- patch_file: "patches/0001-xrplf-0.42.1.patch"
|
||||
patch_description: Integrate wasmi lib into smart-escrow.
|
||||
patch_type: conan
|
||||
42
external/wasmi/conanfile.py
vendored
Normal file
42
external/wasmi/conanfile.py
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
from conan import ConanFile, tools
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||
from conan.tools.files import apply_conandata_patches, export_conandata_patches, get
|
||||
import os
|
||||
|
||||
required_conan_version = ">=2.0.0"
|
||||
|
||||
class WasmiConan(ConanFile):
|
||||
name = "wasmi"
|
||||
license = "Apache License v2.0"
|
||||
url = "https://github.com/wasmi-labs/wasmi.git"
|
||||
description = "WebAssembly (Wasm) interpreter"
|
||||
package_type = "library"
|
||||
settings = "os", "arch", "compiler", "build_type"
|
||||
options = {"shared": [False]}
|
||||
default_options = {"shared": False}
|
||||
|
||||
def export_sources(self):
|
||||
export_conandata_patches(self)
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self, src_folder="src")
|
||||
|
||||
def source(self):
|
||||
get(self, **self.conan_data["sources"][self.version], strip_root=True)
|
||||
apply_conandata_patches(self)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure(build_script_folder=os.path.join(self.source_folder, "crates", "c_api"))
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
cmake = CMake(self)
|
||||
cmake.install()
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libs = ["wasmi"]
|
||||
665
external/wasmi/patches/0002-xrplf-1.0.4.patch
vendored
Normal file
665
external/wasmi/patches/0002-xrplf-1.0.4.patch
vendored
Normal file
@@ -0,0 +1,665 @@
|
||||
diff --git a/crates/c_api/CMakeLists.txt b/crates/c_api/CMakeLists.txt
|
||||
index b15c787..54eaed2 100644
|
||||
--- a/crates/c_api/CMakeLists.txt
|
||||
+++ b/crates/c_api/CMakeLists.txt
|
||||
@@ -6,6 +6,8 @@ option(BUILD_SHARED_LIBS "Build using shared libraries" OFF)
|
||||
option(WASMI_ALWAYS_BUILD "If cmake should always invoke cargo to build Wasmi" ON)
|
||||
set(WASMI_TARGET "" CACHE STRING "Rust target to build for")
|
||||
|
||||
+add_compile_definitions(COMPILING_WASM_RUNTIME_API=1)
|
||||
+
|
||||
if(NOT WASMI_TARGET)
|
||||
execute_process(
|
||||
COMMAND rustc -vV
|
||||
@@ -43,6 +45,10 @@ endif()
|
||||
list(TRANSFORM WASMI_SHARED_FILES PREPEND ${WASMI_TARGET_DIR}/)
|
||||
list(TRANSFORM WASMI_STATIC_FILES PREPEND ${WASMI_TARGET_DIR}/)
|
||||
|
||||
+if(NOT BUILD_SHARED_LIBS)
|
||||
+ set(WASMI_SHARED_FILES)
|
||||
+endif()
|
||||
+
|
||||
# Instructions on how to build and install the Wasmi Rust crate.
|
||||
find_program(WASMI_CARGO_BINARY cargo REQUIRED)
|
||||
include(ExternalProject)
|
||||
@@ -79,7 +85,6 @@ else()
|
||||
target_link_libraries(wasmi INTERFACE ${WASMI_STATIC_FILES})
|
||||
|
||||
if(WASMI_TARGET MATCHES "windows")
|
||||
- target_compile_options(wasmi INTERFACE -DWASM_API_EXTERN= -DWASI_API_EXTERN=)
|
||||
target_link_libraries(wasmi INTERFACE ws2_32 advapi32 userenv ntdll shell32 ole32 bcrypt)
|
||||
elseif(NOT WASMI_TARGET MATCHES "darwin")
|
||||
target_link_libraries(wasmi INTERFACE pthread dl m)
|
||||
@@ -112,6 +117,7 @@ install(
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
+if(BUILD_SHARED_LIBS)
|
||||
if(WASMI_TARGET MATCHES "darwin")
|
||||
set(INSTALLED_LIB "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libwasmi.dylib")
|
||||
install(
|
||||
@@ -131,6 +137,7 @@ if(WASMI_TARGET MATCHES "darwin")
|
||||
install(CODE "execute_process(COMMAND ${install_name_tool_cmd})")
|
||||
endif()
|
||||
endif()
|
||||
+endif()
|
||||
|
||||
# Documentation Generation via Doxygen:
|
||||
set(DOXYGEN_CONF_IN ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.conf.in)
|
||||
@@ -141,19 +148,3 @@ add_custom_target(doc
|
||||
DEPENDS ${WASMI_GENERATED_CONF_H} ${DOXYGEN_CONF_OUT}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
-
|
||||
-# C-Header Formatting via clang-format:
|
||||
-find_program(CLANG_FORMAT clang-format REQUIRED)
|
||||
-file(GLOB_RECURSE HEADER_FILES
|
||||
- ${CMAKE_CURRENT_SOURCE_DIR}/include/wasmi.h
|
||||
- ${CMAKE_CURRENT_SOURCE_DIR}/include/wasmi/*.h
|
||||
- ${CMAKE_CURRENT_SOURCE_DIR}/include/wasmi/*.hh
|
||||
-)
|
||||
-add_custom_target(check-format
|
||||
- COMMAND ${CLANG_FORMAT} -style=llvm -Werror --dry-run ${HEADER_FILES}
|
||||
- COMMENT "clang-format: Check formatting for Wasmi C-API header files"
|
||||
-)
|
||||
-add_custom_target(format
|
||||
- COMMAND ${CLANG_FORMAT} -style=llvm -i ${HEADER_FILES}
|
||||
- COMMENT "clang-format: Apply formatting rules for Wasmi C-API header files"
|
||||
-)
|
||||
diff --git a/crates/c_api/include/wasm.h b/crates/c_api/include/wasm.h
|
||||
index 5ee617f..a76f10e 100644
|
||||
--- a/crates/c_api/include/wasm.h
|
||||
+++ b/crates/c_api/include/wasm.h
|
||||
@@ -13,11 +13,17 @@
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef WASM_API_EXTERN
|
||||
-#if defined(_WIN32) && !defined(__MINGW32__) && !defined(LIBWASM_STATIC)
|
||||
+#if defined(_MSC_BUILD)
|
||||
+#if defined(COMPILING_WASM_RUNTIME_API)
|
||||
+#define WASM_API_EXTERN __declspec(dllexport)
|
||||
+#elif defined(_DLL)
|
||||
#define WASM_API_EXTERN __declspec(dllimport)
|
||||
#else
|
||||
#define WASM_API_EXTERN
|
||||
#endif
|
||||
+#else
|
||||
+#define WASM_API_EXTERN
|
||||
+#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -145,7 +151,13 @@ WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t
|
||||
WASM_DECLARE_OWN(store)
|
||||
|
||||
WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*);
|
||||
+WASM_API_EXTERN own wasm_store_t* wasm_store_new_with_memory_max_pages(wasm_engine_t*, uint32_t max_pages);
|
||||
+
|
||||
+// Store fuel functions (forward declarations)
|
||||
+struct wasmi_error;
|
||||
|
||||
+WASM_API_EXTERN struct wasmi_error* wasm_store_get_fuel(const wasm_store_t*, uint64_t* fuel);
|
||||
+WASM_API_EXTERN struct wasmi_error* wasm_store_set_fuel(wasm_store_t*, uint64_t fuel);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Type Representations
|
||||
diff --git a/crates/c_api/include/wasmi.h b/crates/c_api/include/wasmi.h
|
||||
index 2caffa3..8f0f0ed 100644
|
||||
--- a/crates/c_api/include/wasmi.h
|
||||
+++ b/crates/c_api/include/wasmi.h
|
||||
@@ -10,18 +10,18 @@
|
||||
/**
|
||||
* \brief Wasmi version string.
|
||||
*/
|
||||
-#define WASMI_VERSION "0.35.0"
|
||||
+#define WASMI_VERSION "1.0.4"
|
||||
/**
|
||||
* \brief Wasmi major version number.
|
||||
*/
|
||||
-#define WASMI_VERSION_MAJOR 0
|
||||
+#define WASMI_VERSION_MAJOR 1
|
||||
/**
|
||||
* \brief Wasmi minor version number.
|
||||
*/
|
||||
-#define WASMI_VERSION_MINOR 35
|
||||
+#define WASMI_VERSION_MINOR 0
|
||||
/**
|
||||
* \brief Wasmi patch version number.
|
||||
*/
|
||||
-#define WASMI_VERSION_PATCH 0
|
||||
+#define WASMI_VERSION_PATCH 4
|
||||
|
||||
#endif // WASMI_H
|
||||
diff --git a/crates/c_api/include/wasmi/config.h b/crates/c_api/include/wasmi/config.h
|
||||
index 67baa75..491a1cc 100644
|
||||
--- a/crates/c_api/include/wasmi/config.h
|
||||
+++ b/crates/c_api/include/wasmi/config.h
|
||||
@@ -35,6 +35,40 @@ WASMI_CONFIG_PROP(void, consume_fuel, bool)
|
||||
*/
|
||||
WASMI_CONFIG_PROP(void, ignore_custom_sections, bool)
|
||||
|
||||
+/**
|
||||
+ * \brief Sets the maximum recursion depth of the engine's stack during execution.
|
||||
+ *
|
||||
+ * An execution traps if it exceeds this limit.
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, set_max_recursion_depth, size_t)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Sets the minimum (or initial) height of the engine's value stack in bytes.
|
||||
+ *
|
||||
+ * Lower initial heights may improve memory consumption.
|
||||
+ * Higher initial heights may improve cold start times.
|
||||
+ *
|
||||
+ * Note: Panics if value is greater than the current maximum height of the value stack.
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, set_min_stack_height, size_t)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Sets the maximum height of the engine's value stack in bytes.
|
||||
+ *
|
||||
+ * An execution traps if it exceeds this limit.
|
||||
+ *
|
||||
+ * Note: Panics if value is less than the current minimum height of the value stack.
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, set_max_stack_height, size_t)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Sets the maximum number of cached stacks for reuse.
|
||||
+ *
|
||||
+ * A higher value may improve execution performance.
|
||||
+ * A lower value may improve memory consumption.
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, set_max_cached_stacks, size_t)
|
||||
+
|
||||
/**
|
||||
* \brief Whether or not to Wasm mutable-globals proposal is enabled.
|
||||
*
|
||||
@@ -92,6 +126,52 @@ WASMI_CONFIG_PROP(void, wasm_tail_call, bool)
|
||||
*/
|
||||
WASMI_CONFIG_PROP(void, wasm_extended_const, bool)
|
||||
|
||||
+/**
|
||||
+ * \brief Whether or not to Wasm multi-memory proposal is enabled.
|
||||
+ *
|
||||
+ * Default value: `true`
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, wasm_multi_memory, bool)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Whether or not to Wasm custom-page-sizes proposal is enabled.
|
||||
+ *
|
||||
+ * Default value: `false`
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, wasm_custom_page_sizes, bool)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Whether or not to Wasm memory64 proposal is enabled.
|
||||
+ *
|
||||
+ * Default value: `true`
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, wasm_memory64, bool)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Whether or not to Wasm wide-arithmetic proposal is enabled.
|
||||
+ *
|
||||
+ * Default value: `false`
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, wasm_wide_arithmetic, bool)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Whether or not to Wasm simd proposal is enabled.
|
||||
+ *
|
||||
+ * Only available when compiled with the `simd` feature.
|
||||
+ *
|
||||
+ * Default value: `true` (when feature enabled)
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, wasm_simd, bool)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Whether or not to Wasm relaxed-simd proposal is enabled.
|
||||
+ *
|
||||
+ * Only available when compiled with the `simd` feature.
|
||||
+ *
|
||||
+ * Default value: `true` (when feature enabled)
|
||||
+ */
|
||||
+WASMI_CONFIG_PROP(void, wasm_relaxed_simd, bool)
|
||||
+
|
||||
/**
|
||||
* \brief Whether or not to floating Wasm point types and operations are
|
||||
* enabled.
|
||||
@@ -125,6 +205,58 @@ WASMI_CONFIG_PROP(void, compilation_mode, enum wasmi_compilation_mode_enum)
|
||||
|
||||
#undef WASMI_CONFIG_PROP
|
||||
|
||||
+/**
|
||||
+ * \brief Enforced limits for Wasm module parsing and compilation.
|
||||
+ *
|
||||
+ * Opaque type representing limits that can be enforced on Wasm modules.
|
||||
+ */
|
||||
+typedef struct wasmi_enforced_limits_t wasmi_enforced_limits_t;
|
||||
+
|
||||
+/**
|
||||
+ * \brief Creates a new enforced limits object with strict preset values.
|
||||
+ *
|
||||
+ * This set of strict enforced rules can be used to safeguard against
|
||||
+ * malicious actors trying to attack the Wasmi compilation procedures.
|
||||
+ *
|
||||
+ * The strict limits are:
|
||||
+ * - max_globals: 1000
|
||||
+ * - max_functions: 10,000
|
||||
+ * - max_tables: 100
|
||||
+ * - max_element_segments: 1000
|
||||
+ * - max_memories: 1
|
||||
+ * - max_data_segments: 1000
|
||||
+ * - max_params: 32
|
||||
+ * - max_results: 32
|
||||
+ * - min_avg_bytes_per_function: 40 (enforced at 1000+ total bytes)
|
||||
+ *
|
||||
+ * The returned object must be freed using wasmi_enforced_limits_delete().
|
||||
+ *
|
||||
+ * \return A new enforced limits object with strict preset values
|
||||
+ */
|
||||
+WASM_API_EXTERN wasmi_enforced_limits_t* wasmi_enforced_limits_strict();
|
||||
+
|
||||
+/**
|
||||
+ * \brief Deletes an enforced limits object.
|
||||
+ *
|
||||
+ * \param limits The enforced limits object to delete
|
||||
+ */
|
||||
+WASM_API_EXTERN void wasmi_enforced_limits_delete(wasmi_enforced_limits_t* limits);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Sets the enforced limits for the configuration.
|
||||
+ *
|
||||
+ * By default no limits are enforced. Use this function to apply a set of
|
||||
+ * enforced limits (such as those created by wasmi_enforced_limits_strict())
|
||||
+ * to the configuration.
|
||||
+ *
|
||||
+ * \param config The configuration to modify
|
||||
+ * \param limits The enforced limits to apply
|
||||
+ */
|
||||
+WASM_API_EXTERN void wasmi_config_enforced_limits_set(
|
||||
+ wasm_config_t* config,
|
||||
+ const wasmi_enforced_limits_t* limits
|
||||
+);
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
diff --git a/crates/c_api/src/config.rs b/crates/c_api/src/config.rs
|
||||
index 6a1c1aa..cc69342 100644
|
||||
--- a/crates/c_api/src/config.rs
|
||||
+++ b/crates/c_api/src/config.rs
|
||||
@@ -1,5 +1,5 @@
|
||||
use alloc::boxed::Box;
|
||||
-use wasmi::{CompilationMode, Config};
|
||||
+use wasmi::{CompilationMode, Config, EnforcedLimits};
|
||||
|
||||
/// The Wasm configuration.
|
||||
///
|
||||
@@ -111,6 +111,68 @@ pub extern "C" fn wasmi_config_wasm_extended_const_set(c: &mut wasm_config_t, en
|
||||
c.inner.wasm_extended_const(enable);
|
||||
}
|
||||
|
||||
+/// Enables or disables support for the Wasm [`multi-memory`] proposal.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::wasm_multi_memory`]
|
||||
+///
|
||||
+/// [`multi-memory`]: <https://github.com/WebAssembly/multi-memory>
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_wasm_multi_memory_set(c: &mut wasm_config_t, enable: bool) {
|
||||
+ c.inner.wasm_multi_memory(enable);
|
||||
+}
|
||||
+
|
||||
+/// Enables or disables support for the Wasm [`custom-page-sizes`] proposal.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::wasm_custom_page_sizes`]
|
||||
+///
|
||||
+/// [`custom-page-sizes`]: <https://github.com/WebAssembly/custom-page-sizes>
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_wasm_custom_page_sizes_set(c: &mut wasm_config_t, enable: bool) {
|
||||
+ c.inner.wasm_custom_page_sizes(enable);
|
||||
+}
|
||||
+
|
||||
+/// Enables or disables support for the Wasm [`memory64`] proposal.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::wasm_memory64`]
|
||||
+///
|
||||
+/// [`memory64`]: <https://github.com/WebAssembly/memory64>
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_wasm_memory64_set(c: &mut wasm_config_t, enable: bool) {
|
||||
+ c.inner.wasm_memory64(enable);
|
||||
+}
|
||||
+
|
||||
+/// Enables or disables support for the Wasm [`wide-arithmetic`] proposal.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::wasm_wide_arithmetic`]
|
||||
+///
|
||||
+/// [`wide-arithmetic`]: <https://github.com/WebAssembly/wide-arithmetic>
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_wasm_wide_arithmetic_set(c: &mut wasm_config_t, enable: bool) {
|
||||
+ c.inner.wasm_wide_arithmetic(enable);
|
||||
+}
|
||||
+
|
||||
+/// Enables or disables support for the Wasm [`simd`] proposal.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::wasm_simd`]
|
||||
+///
|
||||
+/// [`simd`]: <https://github.com/WebAssembly/simd>
|
||||
+#[cfg(feature = "simd")]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_wasm_simd_set(c: &mut wasm_config_t, enable: bool) {
|
||||
+ c.inner.wasm_simd(enable);
|
||||
+}
|
||||
+
|
||||
+/// Enables or disables support for the Wasm [`relaxed-simd`] proposal.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::wasm_relaxed_simd`]
|
||||
+///
|
||||
+/// [`relaxed-simd`]: <https://github.com/WebAssembly/relaxed-simd>
|
||||
+#[cfg(feature = "simd")]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_wasm_relaxed_simd_set(c: &mut wasm_config_t, enable: bool) {
|
||||
+ c.inner.wasm_relaxed_simd(enable);
|
||||
+}
|
||||
+
|
||||
/// Enables or disables support for floating point numbers for the config.
|
||||
///
|
||||
/// Wraps [`wasmi::Config::floats`]
|
||||
@@ -164,3 +226,111 @@ pub extern "C" fn wasmi_config_ignore_custom_sections_set(
|
||||
) {
|
||||
config.inner.ignore_custom_sections(enable);
|
||||
}
|
||||
+
|
||||
+/// Sets the maximum recursion depth of the engine's stack during execution.
|
||||
+///
|
||||
+/// An execution traps if it exceeds this limit.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::set_max_recursion_depth`]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_set_max_recursion_depth(
|
||||
+ config: &mut wasm_config_t,
|
||||
+ value: usize,
|
||||
+) {
|
||||
+ config.inner.set_max_recursion_depth(value);
|
||||
+}
|
||||
+
|
||||
+/// Sets the minimum (or initial) height of the engine's value stack in bytes.
|
||||
+///
|
||||
+/// # Note
|
||||
+///
|
||||
+/// - Lower initial heights may improve memory consumption.
|
||||
+/// - Higher initial heights may improve cold start times.
|
||||
+///
|
||||
+/// # Panics
|
||||
+///
|
||||
+/// If `value` is greater than the current maximum height of the value stack.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::set_min_stack_height`]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_set_min_stack_height(config: &mut wasm_config_t, value: usize) {
|
||||
+ config.inner.set_min_stack_height(value);
|
||||
+}
|
||||
+
|
||||
+/// Sets the maximum height of the engine's value stack in bytes.
|
||||
+///
|
||||
+/// An execution traps if it exceeds this limit.
|
||||
+///
|
||||
+/// # Panics
|
||||
+///
|
||||
+/// If `value` is less than the current minimum height of the value stack.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::set_max_stack_height`]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_set_max_stack_height(config: &mut wasm_config_t, value: usize) {
|
||||
+ config.inner.set_max_stack_height(value);
|
||||
+}
|
||||
+
|
||||
+/// Sets the maximum number of cached stacks for reuse.
|
||||
+///
|
||||
+/// # Note
|
||||
+///
|
||||
+/// - A higher value may improve execution performance.
|
||||
+/// - A lower value may improve memory consumption.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::set_max_cached_stacks`]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_set_max_cached_stacks(config: &mut wasm_config_t, value: usize) {
|
||||
+ config.inner.set_max_cached_stacks(value);
|
||||
+}
|
||||
+
|
||||
+/// Enforced limits for Wasm module parsing and compilation.
|
||||
+///
|
||||
+/// Wraps [`wasmi::EnforcedLimits`]
|
||||
+#[repr(C)]
|
||||
+#[derive(Clone)]
|
||||
+pub struct wasmi_enforced_limits_t {
|
||||
+ pub(crate) inner: EnforcedLimits,
|
||||
+}
|
||||
+
|
||||
+wasmi_c_api_macros::declare_own!(wasmi_enforced_limits_t);
|
||||
+
|
||||
+/// Creates a new [`wasmi_enforced_limits_t`] with strict limits.
|
||||
+///
|
||||
+/// This set of strict enforced rules can be used to safeguard against
|
||||
+/// malicious actors trying to attack the Wasmi compilation procedures.
|
||||
+///
|
||||
+/// The strict limits are:
|
||||
+/// - max_globals: 1000
|
||||
+/// - max_functions: 10,000
|
||||
+/// - max_tables: 100
|
||||
+/// - max_element_segments: 1000
|
||||
+/// - max_memories: 1
|
||||
+/// - max_data_segments: 1000
|
||||
+/// - max_params: 32
|
||||
+/// - max_results: 32
|
||||
+/// - min_avg_bytes_per_function: 40 (enforced at 1000+ total bytes)
|
||||
+///
|
||||
+/// The returned [`wasmi_enforced_limits_t`] must be freed using
|
||||
+/// [`wasmi_enforced_limits_delete`] or consumed by [`wasmi_config_enforced_limits_set`].
|
||||
+///
|
||||
+/// Wraps [`wasmi::EnforcedLimits::strict`]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_enforced_limits_strict() -> Box<wasmi_enforced_limits_t> {
|
||||
+ Box::new(wasmi_enforced_limits_t {
|
||||
+ inner: EnforcedLimits::strict(),
|
||||
+ })
|
||||
+}
|
||||
+
|
||||
+/// Sets the enforced limits for the config.
|
||||
+///
|
||||
+/// By default no limits are enforced.
|
||||
+///
|
||||
+/// Wraps [`wasmi::Config::enforced_limits`]
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasmi_config_enforced_limits_set(
|
||||
+ config: &mut wasm_config_t,
|
||||
+ limits: &wasmi_enforced_limits_t,
|
||||
+) {
|
||||
+ config.inner.enforced_limits(limits.inner);
|
||||
+}
|
||||
diff --git a/crates/c_api/src/error.rs b/crates/c_api/src/error.rs
|
||||
index f51aff8..dc85727 100644
|
||||
--- a/crates/c_api/src/error.rs
|
||||
+++ b/crates/c_api/src/error.rs
|
||||
@@ -1,4 +1,5 @@
|
||||
-use alloc::{boxed::Box, string::String};
|
||||
+use crate::wasm_name_t;
|
||||
+use alloc::{boxed::Box, string::String, vec::Vec};
|
||||
use core::ffi;
|
||||
use wasmi::Error;
|
||||
|
||||
@@ -50,3 +51,16 @@ pub(crate) fn handle_result<T>(
|
||||
Err(error) => Some(Box::new(wasmi_error_t::from(error))),
|
||||
}
|
||||
}
|
||||
+
|
||||
+/// Returns the error message of the [`wasmi_error_t`].
|
||||
+///
|
||||
+/// Stores the returned error message in `out`.
|
||||
+#[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
|
||||
+#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
|
||||
+pub extern "C" fn wasmi_error_message(error: &wasmi_error_t, out: &mut wasm_name_t) {
|
||||
+ let mut buffer = Vec::new();
|
||||
+ buffer.extend_from_slice(format!("{:?}", error.inner).as_bytes());
|
||||
+ buffer.reserve_exact(1);
|
||||
+ buffer.push(0);
|
||||
+ out.set_buffer(buffer.into());
|
||||
+}
|
||||
diff --git a/crates/c_api/src/store.rs b/crates/c_api/src/store.rs
|
||||
index 56d4898..9abda8e 100644
|
||||
--- a/crates/c_api/src/store.rs
|
||||
+++ b/crates/c_api/src/store.rs
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{wasm_engine_t, wasmi_error_t, ForeignData};
|
||||
use alloc::{boxed::Box, sync::Arc};
|
||||
use core::{cell::UnsafeCell, ffi};
|
||||
-use wasmi::{AsContext, AsContextMut, Store, StoreContext, StoreContextMut};
|
||||
+use wasmi::{AsContext, AsContextMut, Store, StoreContext, StoreContextMut, StoreLimits, StoreLimitsBuilder};
|
||||
|
||||
/// This representation of a `Store` is used to implement the `wasm.h` API (and
|
||||
/// *not* the `wasmi.h` API!)
|
||||
@@ -16,7 +16,7 @@ use wasmi::{AsContext, AsContextMut, Store, StoreContext, StoreContextMut};
|
||||
/// least Wasmi's implementation).
|
||||
#[derive(Clone)]
|
||||
pub struct WasmStoreRef {
|
||||
- inner: Arc<UnsafeCell<Store<()>>>,
|
||||
+ inner: Arc<UnsafeCell<Store<StoreLimits>>>,
|
||||
}
|
||||
|
||||
impl WasmStoreRef {
|
||||
@@ -27,7 +27,7 @@ impl WasmStoreRef {
|
||||
/// # Safety
|
||||
///
|
||||
/// It is the callers responsibility to provide a valid `self`.
|
||||
- pub unsafe fn context(&self) -> StoreContext<'_, ()> {
|
||||
+ pub unsafe fn context(&self) -> StoreContext<'_, StoreLimits> {
|
||||
(*self.inner.get()).as_context()
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ impl WasmStoreRef {
|
||||
/// # Safety
|
||||
///
|
||||
/// It is the callers responsibility to provide a valid `self`.
|
||||
- pub unsafe fn context_mut(&mut self) -> StoreContextMut<'_, ()> {
|
||||
+ pub unsafe fn context_mut(&mut self) -> StoreContextMut<'_, StoreLimits> {
|
||||
(*self.inner.get()).as_context_mut()
|
||||
}
|
||||
}
|
||||
@@ -56,17 +56,71 @@ pub struct wasm_store_t {
|
||||
|
||||
wasmi_c_api_macros::declare_own!(wasm_store_t);
|
||||
|
||||
-/// Creates a new [`Store<()>`](wasmi::Store) for the given `engine`.
|
||||
+/// Creates a new [`Store<StoreLimits>`](wasmi::Store) for the given `engine`.
|
||||
+///
|
||||
+/// The store is created with no resource limits (original behavior).
|
||||
+/// For memory-limited stores, use [`wasm_store_new_with_memory_max_pages`].
|
||||
///
|
||||
/// The returned [`wasm_store_t`] must be freed using [`wasm_store_delete`].
|
||||
///
|
||||
-/// Wraps [`<wasmi::Store<()>>::new`](wasmi::Store::new).
|
||||
+/// Wraps [`<wasmi::Store<StoreLimits>>::new`](wasmi::Store::new).
|
||||
#[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
|
||||
pub extern "C" fn wasm_store_new(engine: &wasm_engine_t) -> Box<wasm_store_t> {
|
||||
let engine = &engine.inner;
|
||||
- let store = Store::new(engine, ());
|
||||
+
|
||||
+ // Create store with no resource limits (original behavior)
|
||||
+ let limits = StoreLimitsBuilder::new().build();
|
||||
+ let store = Store::new(engine, limits);
|
||||
+
|
||||
+ Box::new(wasm_store_t {
|
||||
+ inner: WasmStoreRef {
|
||||
+ inner: Arc::new(UnsafeCell::new(store)),
|
||||
+ },
|
||||
+ })
|
||||
+}
|
||||
+
|
||||
+/// Creates a new [`Store<StoreLimits>`](wasmi::Store) for the given `engine` with memory limits.
|
||||
+///
|
||||
+/// This function creates a store with resource limits suitable for blockchain smart contracts.
|
||||
+/// The memory limit is enforced during WebAssembly execution.
|
||||
+///
|
||||
+/// If `max_pages` exceeds 1024 (64MB), this function will panic.
|
||||
+///
|
||||
+/// The returned [`wasm_store_t`] must be freed using [`wasm_store_delete`].
|
||||
+///
|
||||
+/// Wraps [`<wasmi::Store<StoreLimits>>::new`](wasmi::Store::new).
|
||||
+#[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
|
||||
+#[allow(clippy::arc_with_non_send_sync)]
|
||||
+#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
|
||||
+pub extern "C" fn wasm_store_new_with_memory_max_pages(
|
||||
+ engine: &wasm_engine_t,
|
||||
+ max_pages: u32,
|
||||
+) -> Box<wasm_store_t> {
|
||||
+ // Validate max_pages limit (64MB = 1024 pages)
|
||||
+ if max_pages > 1024 {
|
||||
+ panic!("max_pages ({}) exceeds maximum allowed value of 1024 pages (64MB)", max_pages);
|
||||
+ }
|
||||
+
|
||||
+ // Convert pages to bytes (each page is 64KB)
|
||||
+ let max_memory_bytes = (max_pages as usize) * (64 * 1024);
|
||||
+
|
||||
+ // Create store limits with blockchain-suitable defaults
|
||||
+ let limits = StoreLimitsBuilder::new()
|
||||
+ .memory_size(max_memory_bytes) // User-specified memory limit
|
||||
+ .instances(1) // Single instance for blockchain
|
||||
+ .tables(1) // Single table for blockchain
|
||||
+ .memories(1) // Single memory for blockchain
|
||||
+ .table_elements(64) // Limited table elements for blockchain
|
||||
+ .trap_on_grow_failure(false) // Return -1 on growth failure instead of trapping
|
||||
+ .build();
|
||||
+
|
||||
+ let mut store = Store::new(&engine.inner, limits);
|
||||
+
|
||||
+ // Install the resource limiter
|
||||
+ store.limiter(|limits| limits);
|
||||
+
|
||||
Box::new(wasm_store_t {
|
||||
inner: WasmStoreRef {
|
||||
inner: Arc::new(UnsafeCell::new(store)),
|
||||
@@ -175,3 +229,40 @@ pub extern "C" fn wasmi_context_set_fuel(
|
||||
) -> Option<Box<wasmi_error_t>> {
|
||||
crate::handle_result(store.set_fuel(fuel), |()| {})
|
||||
}
|
||||
+
|
||||
+////////////////////////////////////////////////////////////////////////////////////////
|
||||
+////////////////////////////////////////////////////////////////////////////////////////
|
||||
+
|
||||
+/// Returns the current fuel of the wasm store context in `fuel`.
|
||||
+///
|
||||
+/// Wraps [`Store::get_fuel`].
|
||||
+///
|
||||
+/// # Errors
|
||||
+///
|
||||
+/// If [`Store::get_fuel`] errors.
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasm_store_get_fuel(
|
||||
+ store: &wasm_store_t,
|
||||
+ fuel: &mut u64,
|
||||
+) -> Option<Box<wasmi_error_t>> {
|
||||
+ let context = unsafe { store.inner.context() };
|
||||
+ crate::handle_result(context.get_fuel(), |amt| {
|
||||
+ *fuel = amt;
|
||||
+ })
|
||||
+}
|
||||
+
|
||||
+/// Sets the current fuel of the wasm store context to `fuel`.
|
||||
+///
|
||||
+/// Wraps [`Store::set_fuel`].
|
||||
+///
|
||||
+/// # Errors
|
||||
+///
|
||||
+/// If [`Store::set_fuel`] errors.
|
||||
+#[no_mangle]
|
||||
+pub extern "C" fn wasm_store_set_fuel(
|
||||
+ store: &mut wasm_store_t,
|
||||
+ fuel: u64,
|
||||
+) -> Option<Box<wasmi_error_t>> {
|
||||
+ let mut context = unsafe { store.inner.context_mut() };
|
||||
+ crate::handle_result(context.set_fuel(fuel), |()| {})
|
||||
+}
|
||||
Reference in New Issue
Block a user