From 81cbeb2fd7b11bc05e6acdbaf0173b291eb1e6fb Mon Sep 17 00:00:00 2001 From: Mihai Dimoiu Date: Wed, 25 Mar 2026 14:53:51 +0200 Subject: [PATCH] Add Component Model binary parser + validation --- .clang-tidy | 10 + .gitignore | 1 + CMakeLists.txt | 5 + build-scripts/config_common.cmake | 8 +- build-scripts/runtime_lib.cmake | 5 + code_analysis.sh | 60 + core/config.h | 4 + core/iwasm/aot/aot_runtime.c | 6 +- .../component-model/iwasm_component.cmake | 12 + .../common/component-model/wasm_component.c | 486 ++++ .../common/component-model/wasm_component.h | 1726 +++++++++++++ .../wasm_component_alias_section.c | 183 ++ .../wasm_component_canons_section.c | 850 +++++++ .../wasm_component_component_section.c | 51 + .../wasm_component_core_custom_section.c | 100 + .../wasm_component_core_instance_section.c | 286 +++ .../wasm_component_core_module_section.c | 102 + .../wasm_component_core_type_section.c | 822 +++++++ .../component-model/wasm_component_export.c | 17 + .../component-model/wasm_component_export.h | 14 + .../wasm_component_exports_section.c | 182 ++ .../component-model/wasm_component_helpers.c | 1126 +++++++++ .../wasm_component_imports_section.c | 133 + .../wasm_component_instances_section.c | 273 ++ .../wasm_component_start_section.c | 94 + .../wasm_component_types_section.c | 1947 +++++++++++++++ .../component-model/wasm_component_validate.c | 2186 +++++++++++++++++ .../component-model/wasm_component_validate.h | 56 + .../wasm_component_values_section.c | 446 ++++ core/iwasm/common/wasm_application.c | 49 +- core/iwasm/common/wasm_ieee754.h | 60 + core/iwasm/common/wasm_runtime_common.c | 105 + core/iwasm/include/wasm_export.h | 71 + core/iwasm/interpreter/wasm.h | 2 + core/iwasm/interpreter/wasm_loader.c | 17 +- core/iwasm/interpreter/wasm_runtime.c | 62 +- core/iwasm/interpreter/wasm_runtime.h | 19 +- .../libraries/libc-wasi/libc_wasi_wrapper.c | 1 - doc/build_wamr.md | 11 + product-mini/platforms/linux/CMakeLists.txt | 5 + tests/unit/CMakeLists.txt | 44 +- .../aot-stack-frame/wasm-apps/CMakeLists.txt | 7 +- tests/unit/common/test_helper.h | 4 +- tests/unit/component/CMakeLists.txt | 64 + tests/unit/component/helpers.cc | 215 ++ tests/unit/component/helpers.h | 57 + tests/unit/component/test_binary_parser.cc | 144 ++ tests/unit/component/wasm-apps/add.wasm | Bin 0 -> 53310 bytes tests/unit/component/wasm-apps/complex.wasm | Bin 0 -> 172678 bytes .../wasm-apps/complex_with_host.wasm | Bin 0 -> 173280 bytes .../wasm-apps/logging-service.component.wasm | Bin 0 -> 167736 bytes .../processor-service.component.wasm | Bin 0 -> 161835 bytes ...processor_and_logging_merged_wac_plug.wasm | Bin 0 -> 333023 bytes .../unit/component/wasm-apps/sampletypes.wasm | Bin 0 -> 191847 bytes tests/unit/linear-memory-aot/build_aot.sh | 2 +- tests/unit/runtime-common/build_aot.sh | 3 +- .../interpreter/interpreter_test_enhance.cc | 10 +- .../spec-test-script/collect_coverage.sh | 12 +- tests/wamr-test-suites/test_wamr.sh | 164 +- 59 files changed, 12190 insertions(+), 129 deletions(-) create mode 100755 code_analysis.sh create mode 100644 core/iwasm/common/component-model/iwasm_component.cmake create mode 100644 core/iwasm/common/component-model/wasm_component.c create mode 100644 core/iwasm/common/component-model/wasm_component.h create mode 100644 core/iwasm/common/component-model/wasm_component_alias_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_canons_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_component_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_core_custom_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_core_instance_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_core_module_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_core_type_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_export.c create mode 100644 core/iwasm/common/component-model/wasm_component_export.h create mode 100644 core/iwasm/common/component-model/wasm_component_exports_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_helpers.c create mode 100644 core/iwasm/common/component-model/wasm_component_imports_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_instances_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_start_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_types_section.c create mode 100644 core/iwasm/common/component-model/wasm_component_validate.c create mode 100644 core/iwasm/common/component-model/wasm_component_validate.h create mode 100644 core/iwasm/common/component-model/wasm_component_values_section.c create mode 100644 core/iwasm/common/wasm_ieee754.h create mode 100644 tests/unit/component/CMakeLists.txt create mode 100644 tests/unit/component/helpers.cc create mode 100644 tests/unit/component/helpers.h create mode 100644 tests/unit/component/test_binary_parser.cc create mode 100644 tests/unit/component/wasm-apps/add.wasm create mode 100644 tests/unit/component/wasm-apps/complex.wasm create mode 100644 tests/unit/component/wasm-apps/complex_with_host.wasm create mode 100644 tests/unit/component/wasm-apps/logging-service.component.wasm create mode 100644 tests/unit/component/wasm-apps/processor-service.component.wasm create mode 100644 tests/unit/component/wasm-apps/processor_and_logging_merged_wac_plug.wasm create mode 100644 tests/unit/component/wasm-apps/sampletypes.wasm diff --git a/.clang-tidy b/.clang-tidy index b5f3da69d..8000d24f8 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,6 +4,12 @@ # Here is an explanation for why some of the checks are disabled: # +# -misc-include-cleaner: too noisy with platform abstraction headers +# -bugprone-easily-swappable-parameters: most C APIs have consecutive same-type params +# -bugprone-macro-parentheses: WAMR macros intentionally use unparenthesized args +# -misc-no-recursion: interpreter/validator use intentional recursion +# -readability-magic-numbers: wasm spec constants (opcodes, limits) are ubiquitous +# Checks: > -*, @@ -11,6 +17,9 @@ Checks: > cert-*, clang-analyzer-*, concurrency-*, + cppcoreguidelines-init-variables, + cppcoreguidelines-narrowing-conversions, + cppcoreguidelines-pro-type-cstyle-cast, misc-*, modernize-*, performance-*, @@ -18,6 +27,7 @@ Checks: > readability-*, -bugprone-easily-swappable-parameters, -bugprone-macro-parentheses, + -misc-include-cleaner, -misc-no-recursion, -misc-unused-parameters, -readability-braces-around-statements, diff --git a/.gitignore b/.gitignore index 1d14dff9a..ef5bec323 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ *.so .clangd .DS_Store +code_analysis_report.log *.o .aider* diff --git a/CMakeLists.txt b/CMakeLists.txt index 3872b2c9c..76e446417 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,11 @@ if (NOT DEFINED WAMR_BUILD_LIBC_WASI) set (WAMR_BUILD_LIBC_WASI 1) endif () +if (NOT DEFINED WAMR_BUILD_COMPONENT_MODEL) + # Enable Component Model by default + set (WAMR_BUILD_COMPONENT_MODEL 1) +endif () + if (NOT DEFINED WAMR_BUILD_FAST_INTERP) # Enable fast interpreter set (WAMR_BUILD_FAST_INTERP 1) diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index cd6b08d5c..cc93487e4 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -779,7 +779,13 @@ if (WAMR_BUILD_BRANCH_HINTS EQUAL 1) message (" Branch hints enabled") add_definitions(-DWASM_ENABLE_BRANCH_HINTS=1) endif () - +if (WAMR_BUILD_COMPONENT_MODEL EQUAL 1) + message (" Component Model enabled") + add_definitions(-DWASM_ENABLE_COMPONENT_MODEL=1) +else() + message (" Component Model disabled") + add_definitions(-DWASM_ENABLE_COMPONENT_MODEL=0) +endif () ######################################## # Show Phase4 Wasm proposals status. ######################################## diff --git a/build-scripts/runtime_lib.cmake b/build-scripts/runtime_lib.cmake index bac81c4f2..d74cd7d0d 100644 --- a/build-scripts/runtime_lib.cmake +++ b/build-scripts/runtime_lib.cmake @@ -87,6 +87,10 @@ if (WAMR_BUILD_GC EQUAL 1) set (WAMR_BUILD_REF_TYPES 1) endif () +if (WAMR_BUILD_COMPONENT_MODEL EQUAL 1) + include (${IWASM_DIR}/common/component-model/iwasm_component.cmake) +endif () + if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1) include (${IWASM_DIR}/libraries/libc-builtin/libc_builtin.cmake) endif () @@ -219,6 +223,7 @@ set (source_all ${IWASM_COMPL_SOURCE} ${IWASM_FAST_JIT_SOURCE} ${IWASM_GC_SOURCE} + ${IWASM_COMPONENT_SOURCE} ${LIB_WASI_THREADS_SOURCE} ${LIB_PTHREAD_SOURCE} ${THREAD_MGR_SOURCE} diff --git a/code_analysis.sh b/code_analysis.sh new file mode 100755 index 000000000..63fea9e10 --- /dev/null +++ b/code_analysis.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# Prerequisites: clang-tidy and cppcheck (First time install: sudo apt-get update && sudo apt-get install -y clang-tidy cppcheck) +# Prerequisite for clang-tidy: CMAKE_EXPORT_COMPILE_COMMANDS=ON +rm -rf product-mini/platforms/linux/build && mkdir -p product-mini/platforms/linux/build +cd product-mini/platforms/linux/build +cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON && make -j8 +cd ../../../../ + +# Define the target folders +TARGET_DIRS="core/iwasm/interpreter \ + core/iwasm/common/component-model \ + tests/unit/component*" + +# Define the log report file +REPORT_FILE="code_analysis_report.log" +echo "--- Running code analysis for: $TARGET_DIRS" +echo "--- The analysis report will be written into $REPORT_FILE" + +: > "$REPORT_FILE" +exec > "$REPORT_FILE" 2>&1 + +echo "--- Running Cppcheck ---" +cppcheck -q --force --enable=warning,performance,style,portability $TARGET_DIRS + +echo "--- Running Clang-Tidy ---" +FILES=$(find $TARGET_DIRS -name "*.c") +HEADERS=$(find $TARGET_DIRS -name "*.h") +$(command -v /opt/wasi-sdk/bin/clang-tidy || echo clang-tidy) -p product-mini/platforms/linux/build --quiet $HEADERS $FILES + +TOTAL=$(grep -c ': error:' "$REPORT_FILE" 2>/dev/null || echo 0) +printf "Total errors: $TOTAL" + +for CHECK in \ + bugprone-narrowing-conversions \ + bugprone-multi-level-implicit-pointer-conversion \ + bugprone-null-dereference \ + bugprone-use-after-move \ + bugprone-sizeof-expression \ + clang-analyzer-core \ + clang-analyzer-security \ + clang-analyzer-deadcode \ + cppcoreguidelines-init-variables \ + cppcoreguidelines-narrowing-conversions \ + performance-no-int-to-ptr \ + readability-math-missing-parentheses \ + concurrency-mt-unsafe \ + cert-msc30-c \ + cert-err34-c \ + readability-redundant-casting; do + COUNT=$(grep -c "$CHECK" "$REPORT_FILE" 2>/dev/null || echo 0) + if [ "$COUNT" -gt 0 ]; then + printf ' %-56s %d\n' "$CHECK:" "$COUNT" | tee -a "$REPORT_FILE" + fi +done + +echo "--- Analysis complete. Check $REPORT_FILE ---" diff --git a/core/config.h b/core/config.h index 31404deb9..d4944ced0 100644 --- a/core/config.h +++ b/core/config.h @@ -137,6 +137,10 @@ #define WASM_ENABLE_WAMR_COMPILER 0 #endif +#ifndef WASM_ENABLE_COMPONENT_MODEL +#define WASM_ENABLE_COMPONENT_MODEL 0 +#endif + #ifndef WASM_ENABLE_LIBC_BUILTIN #define WASM_ENABLE_LIBC_BUILTIN 0 #endif diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 7f57b1adf..4c6ba63be 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -51,7 +51,11 @@ bh_static_assert(offsetof(AOTModuleInstance, cur_exception) bh_static_assert(offsetof(AOTModuleInstance, c_api_func_imports) == 13 * sizeof(uint64) + 128 + 7 * sizeof(uint64)); bh_static_assert(offsetof(AOTModuleInstance, global_table_data) - == 13 * sizeof(uint64) + 128 + 14 * sizeof(uint64)); + == 13 * sizeof(uint64) + 128 + 14 * sizeof(uint64) +#if WASM_ENABLE_COMPONENT_MODEL != 0 + + sizeof(void *) + sizeof(uint64) +#endif + ); bh_static_assert(sizeof(AOTMemoryInstance) == 120); bh_static_assert(offsetof(AOTTableInstance, elems) == 24); diff --git a/core/iwasm/common/component-model/iwasm_component.cmake b/core/iwasm/common/component-model/iwasm_component.cmake new file mode 100644 index 000000000..6e095a174 --- /dev/null +++ b/core/iwasm/common/component-model/iwasm_component.cmake @@ -0,0 +1,12 @@ +# Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set (IWASM_COMPONENT_DIR ${CMAKE_CURRENT_LIST_DIR}) + +add_definitions (-DWASM_ENABLE_COMPONENT_MODEL=1) + +include_directories (${IWASM_COMPONENT_DIR}) + +file (GLOB source_all ${IWASM_COMPONENT_DIR}/*.c) + +set (IWASM_COMPONENT_SOURCE ${source_all}) diff --git a/core/iwasm/common/component-model/wasm_component.c b/core/iwasm/common/component-model/wasm_component.c new file mode 100644 index 000000000..db53fad3c --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component.c @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include "../interpreter/wasm.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Parse all sections in a WASM component binary +// Each section is dispatched to its own parser and stored in the output structure +bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMComponent *out_component, LoadArgs *args, unsigned int depth) { + if (!buf || size < 8 || !out_component) { + return false; + } + + // Decode the header first + if (!wasm_decode_header(buf, size, &out_component->header)) { + return false; + } + + // const uint8_t *begin = buf; + const uint8_t *p = buf + 8; + const uint8_t *end = buf + size; + uint32_t section_capacity = 8; + + WASMComponentSection *sections = wasm_runtime_malloc(section_capacity * sizeof(WASMComponentSection)); + if (!sections) { + return false; + } + + uint32_t section_count = 0; + while (p < end) { + // Read section id (1 byte) and payload length (LEB128) + uint8_t section_id = *p++; + char error_buf[128] = { 0 }; + + // Read payload length + uint64 payload_len = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &payload_len, + error_buf, sizeof(error_buf))) { + wasm_runtime_free(sections); + return false; // Error handling + } + + if ((uint32_t)(end - p) < payload_len) { + wasm_runtime_free(sections); + return false; + } + + // Store section info + if (section_count == section_capacity) { + section_capacity *= 2; + WASMComponentSection *new_sections = wasm_runtime_realloc(sections, section_capacity * sizeof(WASMComponentSection)); + if (!new_sections) { + wasm_runtime_free(sections); + return false; + } + sections = new_sections; + } + + const uint8_t *payload_start = p; + uint32_t current_section_index = section_count; + sections[current_section_index].payload = payload_start; + sections[current_section_index].payload_len = (uint32_t)payload_len; + sections[current_section_index].id = section_id; + sections[current_section_index].parsed.any = NULL; // Initialize parsed union to NULL + section_count++; + + uint32_t consumed_len = 0; + bool parse_success = false; + + // LOG_DEBUG("Parsing section: %d | Section size: %d | payload_start: %d\n", section_id, payload_len, payload_start-begin); + switch (section_id) { + // Section 0: custom section + case WASM_COMP_SECTION_CORE_CUSTOM: { + // Parse custom section (name + data) + WASMComponentCoreCustomSection *custom = wasm_runtime_malloc(sizeof(WASMComponentCoreCustomSection)); + if (custom) memset(custom, 0, sizeof(WASMComponentCoreCustomSection)); + + parse_success = wasm_component_parse_core_custom_section(&p, (uint32_t)payload_len, custom, error_buf, sizeof(error_buf), &consumed_len); + if (!parse_success || consumed_len != payload_len) { + if (custom) { + wasm_runtime_free(custom); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing custom section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Custom section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } else { + sections[current_section_index].parsed.core_custom = custom; + } + break; + } + // Section 1: module section + case WASM_COMP_SECTION_CORE_MODULE: { + // Parse and load the embedded core wasm module + WASMComponentCoreModuleWrapper *module = wasm_runtime_malloc(sizeof(WASMComponentCoreModuleWrapper)); + if (module) memset(module, 0, sizeof(WASMComponentCoreModuleWrapper)); + parse_success = wasm_component_parse_core_module_section(&payload_start, (uint32_t)payload_len, module, args, error_buf, sizeof(error_buf),&consumed_len); + if (!parse_success || consumed_len != payload_len) { + if (module) { + wasm_runtime_free(module); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing module section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Module section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } else { + sections[current_section_index].parsed.core_module = module; + } + break; + } + // Section 2: instance section + case WASM_COMP_SECTION_CORE_INSTANCE: { + WASMComponentCoreInstSection *core_instance_section = wasm_runtime_malloc(sizeof(WASMComponentCoreInstSection)); + if (core_instance_section) memset(core_instance_section, 0, sizeof(WASMComponentCoreInstSection)); + parse_success = wasm_component_parse_core_instance_section(&payload_start, (uint32_t)payload_len, core_instance_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.core_instance_section = core_instance_section; + } else { + if (core_instance_section) { + wasm_runtime_free(core_instance_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing core instances section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Core Instances section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 3: core types section + case WASM_COMP_SECTION_CORE_TYPE: { + WASMComponentCoreTypeSection *core_type_section = wasm_runtime_malloc(sizeof(WASMComponentCoreTypeSection)); + if (core_type_section) memset(core_type_section, 0, sizeof(WASMComponentCoreTypeSection)); + parse_success = wasm_component_parse_core_type_section(&payload_start, (uint32_t)payload_len, core_type_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.core_type_section = core_type_section; + } else { + if (core_type_section) { + wasm_runtime_free(core_type_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing core types section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Core types section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 4: component section + case WASM_COMP_SECTION_COMPONENT: { + // Parse and load the embedded component + WASMComponent *component = wasm_runtime_malloc(sizeof(WASMComponent)); + if (!component) { + LOG_DEBUG("Failed to allocate memory for nested component\n"); + wasm_runtime_free(sections); + return false; + } + // Initialize the component structure to avoid garbage data + memset(component, 0, sizeof(WASMComponent)); + + // Parse the nested component sections directly from the payload + parse_success = wasm_component_parse_sections(payload_start, (uint32_t)payload_len, component, args, depth + 1); + consumed_len = payload_len; // The entire payload is consumed + + if (!parse_success) { + LOG_DEBUG(" Failed to parse nested component, freeing component at %p\n", component); + wasm_runtime_free(component); + LOG_DEBUG("Error parsing sub component section\n"); + wasm_runtime_free(sections); + return false; + } else { + LOG_DEBUG(" Successfully parsed nested component at %p\n", component); + sections[current_section_index].parsed.component = component; + } + break; + } + // Section 5: instances section + case WASM_COMP_SECTION_INSTANCES: { + WASMComponentInstSection *instance_section = wasm_runtime_malloc(sizeof(WASMComponentInstSection)); + if (instance_section) memset(instance_section, 0, sizeof(WASMComponentInstSection)); + parse_success = wasm_component_parse_instances_section(&payload_start, (uint32_t)payload_len, instance_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.instance_section = instance_section; + } else { + if (instance_section) { + wasm_runtime_free(instance_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing instances section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Instances section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 6: aliases section for imports/exports + case WASM_COMP_SECTION_ALIASES: { + // Parse alias definitions for imports/exports + WASMComponentAliasSection *alias_section = wasm_runtime_malloc(sizeof(WASMComponentAliasSection)); + if (alias_section) memset(alias_section, 0, sizeof(WASMComponentAliasSection)); + parse_success = wasm_component_parse_alias_section(&payload_start, (uint32_t)payload_len, alias_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.alias_section = alias_section; + } else { + if (alias_section) { + wasm_runtime_free(alias_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing alias section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Alias section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 7: types section + case WASM_COMP_SECTION_TYPE: { + WASMComponentTypeSection *type_section = wasm_runtime_malloc(sizeof(WASMComponentTypeSection)); + if (type_section) memset(type_section, 0, sizeof(WASMComponentTypeSection)); + parse_success = wasm_component_parse_types_section(&payload_start, (uint32_t)payload_len, type_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.type_section = type_section; + } else { + if (type_section) { + wasm_runtime_free(type_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing types section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Types section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 8: canons section + case WASM_COMP_SECTION_CANONS: { + WASMComponentCanonSection *canon_section = wasm_runtime_malloc(sizeof(WASMComponentCanonSection)); + if (canon_section) memset(canon_section, 0, sizeof(WASMComponentCanonSection)); + parse_success = wasm_component_parse_canons_section(&payload_start, (uint32_t)payload_len, canon_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.canon_section = canon_section; + } else { + if (canon_section) { + wasm_runtime_free(canon_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing canons section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Canons section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 9: start section + case WASM_COMP_SECTION_START: { + WASMComponentStartSection *start_section = wasm_runtime_malloc(sizeof(WASMComponentStartSection)); + if (start_section) memset(start_section, 0, sizeof(WASMComponentStartSection)); + parse_success = wasm_component_parse_start_section(&payload_start, (uint32_t)payload_len, start_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.start_section = start_section; + } else { + if (start_section) { + wasm_runtime_free(start_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing start section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Start section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 10: imports section (component model imports) + case WASM_COMP_SECTION_IMPORTS: { + // Parse all imports: name (simple/versioned) and externdesc (all 6 types) + WASMComponentImportSection *import_section = wasm_runtime_malloc(sizeof(WASMComponentImportSection)); + if (import_section) memset(import_section, 0, sizeof(WASMComponentImportSection)); + parse_success = wasm_component_parse_imports_section(&payload_start, (uint32_t)payload_len, import_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.import_section = import_section; + } else { + if (import_section) { + wasm_runtime_free(import_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing imports section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Imports section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 11: exports section + case WASM_COMP_SECTION_EXPORTS: { + WASMComponentExportSection *export_section = wasm_runtime_malloc(sizeof(WASMComponentExportSection)); + if (export_section) memset(export_section, 0, sizeof(WASMComponentExportSection)); + parse_success = wasm_component_parse_exports_section(&payload_start, (uint32_t)payload_len, export_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.export_section = export_section; + } else { + if (export_section) { + wasm_runtime_free(export_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing export section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Exports section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + // Section 12: values section + case WASM_COMP_SECTION_VALUES: { + WASMComponentValueSection *value_section = wasm_runtime_malloc(sizeof(WASMComponentValueSection)); + if (value_section) memset(value_section, 0, sizeof(WASMComponentValueSection)); + parse_success = wasm_component_parse_values_section(&payload_start, (uint32_t)payload_len, value_section, error_buf, sizeof(error_buf), &consumed_len); + if (parse_success && consumed_len == payload_len) { + sections[current_section_index].parsed.value_section = value_section; + } else { + if (value_section) { + wasm_runtime_free(value_section); + } + if (error_buf[0]) { + LOG_DEBUG("Error parsing values section: %s\n", error_buf); + } + if (consumed_len != payload_len) { + LOG_DEBUG("FATAL ERROR: Values section consumed %u bytes but expected %lu\n", consumed_len, payload_len); + wasm_runtime_free(sections); + return false; + } + } + break; + } + default: + // Unknown/unsupported section id + LOG_DEBUG("FATAL ERROR: Unknown/unsupported section (id=%u, size=%lu)\n", section_id, payload_len); + wasm_runtime_free(sections); + return false; + } + + + // Advance the main parser by the consumed amount + p = payload_start + consumed_len; + + // Safety check to ensure we don't go past the end + if (p > end) { + wasm_runtime_free(sections); + return false; + } + } + + out_component->sections = sections; + out_component->section_count = section_count; + return true; +} + +// Check if Header is Component +bool is_wasm_component(WASMHeader header) { + if (header.magic != WASM_MAGIC_NUMBER || + header.version != WASM_COMPONENT_VERSION || + header.layer != WASM_COMPONENT_LAYER) { + return false; + } + + return true; +} + +// Main component free function +void wasm_component_free(WASMComponent *component) { + if (!component || !component->sections) return; + + for (uint32_t i = 0; i < component->section_count; ++i) { + WASMComponentSection *sec = &component->sections[i]; + + switch (sec->id) { + case WASM_COMP_SECTION_CORE_CUSTOM: // Section 0 + wasm_component_free_core_custom_section(sec); + break; + + case WASM_COMP_SECTION_CORE_MODULE: // Section 1 + wasm_component_free_core_module_section(sec); + break; + + case WASM_COMP_SECTION_CORE_INSTANCE: // Section 2 + wasm_component_free_core_instance_section(sec); + break; + + case WASM_COMP_SECTION_CORE_TYPE: // Section 3 + wasm_component_free_core_type_section(sec); + break; + + case WASM_COMP_SECTION_COMPONENT: // Section 4 + wasm_component_free_component_section(sec); + break; + + case WASM_COMP_SECTION_INSTANCES: // Section 5 + wasm_component_free_instances_section(sec); + break; + + case WASM_COMP_SECTION_ALIASES: // Section 6 + wasm_component_free_alias_section(sec); + break; + + case WASM_COMP_SECTION_TYPE: // Section 7 + wasm_component_free_types_section(sec); + break; + + case WASM_COMP_SECTION_CANONS: // Section 8 + wasm_component_free_canons_section(sec); + break; + + case WASM_COMP_SECTION_START: // Section 9 + wasm_component_free_start_section(sec); + break; + + case WASM_COMP_SECTION_IMPORTS: // Section 10 + wasm_component_free_imports_section(sec); + break; + + case WASM_COMP_SECTION_EXPORTS: // Section 11 + wasm_component_free_exports_section(sec); + break; + + case WASM_COMP_SECTION_VALUES: // Section 12 + wasm_component_free_values_section(sec); + break; + + default: + // For other sections that don't have parsed data or are stubs + // Just free the any pointer if it exists + if (sec->parsed.any) { + wasm_runtime_free(sec->parsed.any); + sec->parsed.any = NULL; + } + break; + } + } + + wasm_runtime_free(component->sections); + component->sections = NULL; + component->section_count = 0; +} \ No newline at end of file diff --git a/core/iwasm/common/component-model/wasm_component.h b/core/iwasm/common/component-model/wasm_component.h new file mode 100644 index 000000000..1891ac696 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component.h @@ -0,0 +1,1726 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef WASM_COMPONENT_H +#define WASM_COMPONENT_H + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- +#include "wasm_export.h" +#include "../interpreter/wasm.h" +#include +#include + +// ----------------------------------------------------------------------------- +// Forward Declarations for Reusing Existing WASM Structures +// ----------------------------------------------------------------------------- +struct WASMFuncType; // From wasm.h - for core function types +struct WASMRefTypeMap; // From wasm.h - for reference type mapping +struct WASMStructType; // From wasm.h - for struct types +struct WASMArrayType; // From wasm.h - for array types +struct WASMStructFieldType; // From wasm.h - for struct field types + +// ----------------------------------------------------------------------------- +// Forward Declarations for Component-Specific Structures +// ----------------------------------------------------------------------------- +struct WASMComponentCoreName; +struct WASMComponentSort; +struct WASMComponentSortIdx; +struct WASMComponentValueType; +struct WASMComponentValueBound; +struct WASMComponentTypeBound; +struct WASMComponentExternDesc; +struct WASMComponentImportName; +struct WASMComponentExportName; +struct WASMComponentImportExportName; +struct WASMComponentAliasDefinition; +struct WASMComponentLabelValType; +struct WASMComponentCaseValType; +struct WASMComponentDefValType; +struct WASMComponentFuncType; +struct WASMComponentResourceType; +struct WASMComponentComponentType; +struct WASMComponentInstType; +struct WASMComponentTypes; +struct WASMComponentSection; +struct WASMComponent; +struct WASMComponentInstArg; +struct WASMComponentInlineExport; + +// ----------------------------------------------------------------------------- +// Constants and Macros +// ----------------------------------------------------------------------------- +#define INVALID_VALUE (uint8_t)0xFF +#define MAX_DEPTH_RECURSION 100 + +// ----------------------------------------------------------------------------- +// Enums +// ----------------------------------------------------------------------------- +// Core Sort Values +// ----------------------------------------------------------------------------- +typedef enum WASMComponentCoreSort { + WASM_COMP_CORE_SORT_FUNC = 0x00, // func + WASM_COMP_CORE_SORT_TABLE = 0x01, // table + WASM_COMP_CORE_SORT_MEMORY = 0x02, // memory + WASM_COMP_CORE_SORT_GLOBAL = 0x03, // global + WASM_COMP_CORE_SORT_TYPE = 0x10, // type + WASM_COMP_CORE_SORT_MODULE = 0x11, // module + WASM_COMP_CORE_SORT_INSTANCE = 0x12 // instance +} WASMComponentCoreSort; + +// Component Sort Values +// ----------------------------------------------------------------------------- +typedef enum WASMComponentSortValues { + WASM_COMP_SORT_CORE_SORT = 0x00, // core func + WASM_COMP_SORT_FUNC = 0x01, // func + WASM_COMP_SORT_VALUE = 0x02, // value + WASM_COMP_SORT_TYPE = 0x03, // type + WASM_COMP_SORT_COMPONENT = 0x04, // component + WASM_COMP_SORT_INSTANCE = 0x05 // instance +} WASMComponentSortValues; + +// Component Model Primitive Value Types - Those are different from Core WebAssembly +// ----------------------------------------------------------------------------- +typedef enum WASMComponentPrimValType { + WASM_COMP_PRIMVAL_BOOL = 0x7f, // 0x7f => bool + WASM_COMP_PRIMVAL_S8 = 0x7e, // 0x7e => s8 + WASM_COMP_PRIMVAL_U8 = 0x7d, // 0x7d => u8 + WASM_COMP_PRIMVAL_S16 = 0x7c, // 0x7c => s16 + WASM_COMP_PRIMVAL_U16 = 0x7b, // 0x7b => u16 + WASM_COMP_PRIMVAL_S32 = 0x7a, // 0x7a => s32 + WASM_COMP_PRIMVAL_U32 = 0x79, // 0x79 => u32 + WASM_COMP_PRIMVAL_S64 = 0x78, // 0x78 => s64 + WASM_COMP_PRIMVAL_U64 = 0x77, // 0x77 => u64 + WASM_COMP_PRIMVAL_F32 = 0x76, // 0x76 => f32 + WASM_COMP_PRIMVAL_F64 = 0x75, // 0x75 => f64 + WASM_COMP_PRIMVAL_CHAR = 0x74, // 0x74 => char + WASM_COMP_PRIMVAL_STRING = 0x73, // 0x73 => string + WASM_COMP_PRIMVAL_ERROR_CONTEXT = 0x64 // 0x64 => error-context +} WASMComponentPrimValType; + +// ----------------------------------------------------------------------------- +// Section IDs for WASM Component Model +// ----------------------------------------------------------------------------- +typedef enum WASMComponentSectionType { + WASM_COMP_SECTION_CORE_CUSTOM = 0x00, // section_0() + WASM_COMP_SECTION_CORE_MODULE = 0x01, // section_1() + WASM_COMP_SECTION_CORE_INSTANCE = 0x02, // section_2(vec()) + WASM_COMP_SECTION_CORE_TYPE = 0x03, // section_3(vec()) + WASM_COMP_SECTION_COMPONENT = 0x04, // section_4() + WASM_COMP_SECTION_INSTANCES = 0x05, // section_5(vec()) + WASM_COMP_SECTION_ALIASES = 0x06, // section_6(vec()) + WASM_COMP_SECTION_TYPE = 0x07, // section_7(vec()) + WASM_COMP_SECTION_CANONS = 0x08, // section_8(vec()) + WASM_COMP_SECTION_START = 0x09, // section_9() + WASM_COMP_SECTION_IMPORTS = 0x0A, // section_10(vec()) + WASM_COMP_SECTION_EXPORTS = 0x0B, // section_11(vec()) + WASM_COMP_SECTION_VALUES = 0x0C // section_12(vec()) +} WASMComponentSectionType; + +// ----------------------------------------------------------------------------- +// Import/Export Name Tag - Distinguishes simple vs versioned names +// importname' ::= 0x00 len: in: => in +// | 0x01 len: in: vs: => in vs +// ----------------------------------------------------------------------------- +typedef enum WASMComponentImportExportTypeTag { + WASM_COMP_IMPORTNAME_SIMPLE = 0x00, // 0x00 (simple name) + WASM_COMP_IMPORTNAME_VERSIONED = 0x01 // 0x01 (versioned name) +} WASMComponentImportExportTypeTag; + +// ----------------------------------------------------------------------------- +// WASMComponentValueTypeTag Tag - Distinguishes primitive value vs type index +// valtype ::= i: => i +// | pvt: => pvt +// ----------------------------------------------------------------------------- +typedef enum WASMComponentValueTypeTag { + WASM_COMP_VAL_TYPE_IDX = 0x00, // 0x00 (type index) + WASM_COMP_VAL_TYPE_PRIMVAL = 0x01 // 0x01 (primitive value) +} WASMComponentValueTypeTag; + +// ----------------------------------------------------------------------------- +// External Descriptor Type - Identifies the kind of import/export +// externdesc ::= 0x00 0x11 i: => (core module (type i)) +// | 0x01 i: => (func (type i)) +// | 0x02 b: => (value b) +// | 0x03 b: => (type b) +// | 0x04 i: => (component (type i)) +// | 0x05 i: => (instance (type i)) +// ----------------------------------------------------------------------------- +typedef enum WASMComponentExternDescType { + WASM_COMP_EXTERN_CORE_MODULE = 0x00, // 0x00 0x11 (core module) + WASM_COMP_EXTERN_FUNC = 0x01, // 0x01 (func) + WASM_COMP_EXTERN_VALUE = 0x02, // 0x02 (value) + WASM_COMP_EXTERN_TYPE = 0x03, // 0x03 (type) + WASM_COMP_EXTERN_COMPONENT = 0x04, // 0x04 (component) + WASM_COMP_EXTERN_INSTANCE = 0x05 // 0x05 (instance) +} WASMComponentExternDescType; + +// ----------------------------------------------------------------------------- +// Value Bound Tag - Distinguishes equality vs type bounds +// valuebound ::= 0x00 v: => (eq v) +// | 0x01 t: => (eq t) +// ----------------------------------------------------------------------------- +typedef enum WASMComponentValueBoundTag { + WASM_COMP_VALUEBOUND_EQ = 0x00, // 0x00 (equality bound) + WASM_COMP_VALUEBOUND_TYPE = 0x01 // 0x01 (type bound) +} WASMComponentValueBoundTag; + +// ----------------------------------------------------------------------------- +// Type Bound Tag - Distinguishes equality vs subtype bounds +// typebound ::= 0x00 t: => (eq t) +// | 0x01 t: => (sub t) +// ----------------------------------------------------------------------------- +typedef enum WASMComponentTypeBoundTag { + WASM_COMP_TYPEBOUND_EQ = 0x00, // 0x00 (equality bound) + WASM_COMP_TYPEBOUND_TYPE = 0x01 // 0x01 (subtype bound) +} WASMComponentTypeBoundTag; + +// ----------------------------------------------------------------------------- +// Alias Target Type - Identifies the kind of alias target +// aliastarget ::= 0x00 i: n: => export i n +// | 0x01 i: n: => core export i n +// | 0x02 ct: idx: => outer ct idx +// ----------------------------------------------------------------------------- +typedef enum WASMComponentAliasTargetType { + WASM_COMP_ALIAS_TARGET_EXPORT = 0x00, // 0x00 (export alias) + WASM_COMP_ALIAS_TARGET_CORE_EXPORT = 0x01, // 0x01 (core export alias) + WASM_COMP_ALIAS_TARGET_OUTER = 0x02 // 0x02 (outer alias) +} WASMComponentAliasTargetType; + +// ----------------------------------------------------------------------------- +// Optional Field Tag +// ? ::= 0x00 => +// | 0x01 t: => t +// ----------------------------------------------------------------------------- +typedef enum WASMComponentOptionalField { + WASM_COMP_OPTIONAL_FALSE = 0x00, // 0x00 (absent) + WASM_COMP_OPTIONAL_TRUE = 0x01, // 0x01 (present) +} WASMComponentOptionalField; + +// ----------------------------------------------------------------------------- +// Component Types Tag - Identifies the kind of type definition +// type ::= 0x63 pvt: => pvt +// | 0x72 lt*:vec() => (record lt*) +// | 0x71 case*:vec() => (variant case*) +// | 0x70 t: => (list t) +// | 0x67 t: len: => (list t len) +// | 0x6f t*:vec() => (tuple t*) +// | 0x6e l*:vec() => (flags l*) +// | 0x6d l*:vec() => (enum l*) +// | 0x6b t: => (option t) +// | 0x6a t?:? u?:? => (result t? u?) +// | 0x69 i: => (own i) +// | 0x68 i: => (borrow i) +// | 0x66 t?:? => (stream t?) +// | 0x65 t?:? => (future t?) +// | 0x40 pt*:vec() rt*:vec() => (func pt* rt*) +// | 0x41 ct*:vec() => (component ct*) +// | 0x42 it*:vec() => (instance it*) +// | 0x3f i: => (resource (rep i32) (dtor i)) +// | 0x3e i: => (resource (rep i32) (dtor i) (dtor i)) +// ----------------------------------------------------------------------------- +typedef enum WASMComponentTypesTag { + WASM_COMP_DEF_TYPE = 0x00, // defvaltype (internal tag) + WASM_COMP_FUNC_TYPE = 0x40, // functype + WASM_COMP_COMPONENT_TYPE = 0x41, // componenttype + WASM_COMP_INSTANCE_TYPE = 0x42, // instancetype + WASM_COMP_RESOURCE_TYPE_SYNC = 0x3f, // resourcetype (sync) + WASM_COMP_RESOURCE_TYPE_ASYNC = 0x3e, // resourcetype (async) + WASM_COMP_INVALID_TYPE = 0xFF // invalid type +} WASMComponentTypesTag; + +// ----------------------------------------------------------------------------- +// Instance Expression Tag - Distinguishes with/without args +// instanceexpr ::= 0x00 c: arg*:vec() => (instantiate c arg*) +// | 0x01 e*:vec() => e* +// ----------------------------------------------------------------------------- +typedef enum WASMComponentInstExpressionTag { + WASM_COMP_INSTANCE_EXPRESSION_WITH_ARGS = 0x00, + WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS = 0x01, +} WASMComponentInstExpressionTag; + +// ----------------------------------------------------------------------------- +// Result List Tag - Distinguishes with/without type +// instanceexpr ::= 0x00 c: arg*:vec() => (instantiate c arg*) +// | 0x01 e*:vec() => e* +// ----------------------------------------------------------------------------- +typedef enum WASMComponentResultListTag { + WASM_COMP_RESULT_LIST_WITH_TYPE = 0x00, + WASM_COMP_RESULT_LIST_EMPTY = 0x01, +} WASMComponentResultListTag; + +// ----------------------------------------------------------------------------- +// Component Declaration Tag - Identifies import vs instance declarations +// componentdecl ::= 0x03 id: => id +// | id: => id +// ----------------------------------------------------------------------------- +typedef enum WASMComponentComponentDeclTag { + WASM_COMP_COMPONENT_DECL_CORE_TYPE = 0x00, + WASM_COMP_COMPONENT_DECL_TYPE = 0x01, + WASM_COMP_COMPONENT_DECL_ALIAS = 0x02, + WASM_COMP_COMPONENT_DECL_IMPORT = 0x03, + WASM_COMP_COMPONENT_DECL_EXPORT = 0x04, +} WASMComponentComponentDeclTag; + +// ----------------------------------------------------------------------------- +// Instance Declaration Tag - Identifies the kind of instance declaration +// instancedecl ::= 0x00 t: => t +// | 0x01 t: => t +// | 0x02 a: => a +// | 0x04 ed: => ed +// ----------------------------------------------------------------------------- +typedef enum WASMComponentInstDeclTag { + WASM_COMP_COMPONENT_DECL_INSTANCE_CORE_TYPE = 0x00, + WASM_COMP_COMPONENT_DECL_INSTANCE_TYPE = 0x01, + WASM_COMP_COMPONENT_DECL_INSTANCE_ALIAS = 0x02, + WASM_COMP_COMPONENT_DECL_INSTANCE_EXPORTDECL = 0x04, +} WASMComponentInstDeclTag; + +// ----------------------------------------------------------------------------- +// Defined Value Type Tag - Identifies the kind of value type in defvaltype +// defvaltype ::= pvt: => pvt +// | 0x72 lt*:vec() => (record (field lt)*) +// | 0x71 case*:vec() => (variant case+) +// | 0x70 t: => (list t) +// | 0x67 t: len: => (list t len) +// | 0x6f t*:vec() => (tuple t+) +// | 0x6e l*:vec() => (flags l+) +// | 0x6d l*:vec() => (enum l+) +// | 0x6b t: => (option t) +// | 0x6a t?:? u?:? => (result t? (error u)?) +// | 0x69 i: => (own i) +// | 0x68 i: => (borrow i) +// | 0x66 t?:? => (stream t?) +// | 0x65 t?:? => (future t?) +// ----------------------------------------------------------------------------- +typedef enum WASMComponentDefValTypeTag { + // Primitive value type + WASM_COMP_DEF_VAL_PRIMVAL = 0x63, // pvt: + // Record type (labeled fields) + WASM_COMP_DEF_VAL_RECORD = 0x72, // 0x72 lt*:vec() + // Variant type (labeled cases) + WASM_COMP_DEF_VAL_VARIANT = 0x71, // 0x71 case*:vec() + // List types + WASM_COMP_DEF_VAL_LIST = 0x70, // 0x70 t: + WASM_COMP_DEF_VAL_LIST_LEN = 0x67, // 0x67 t: len: + // Tuple type + WASM_COMP_DEF_VAL_TUPLE = 0x6f, // 0x6f t*:vec() + // Flags type + WASM_COMP_DEF_VAL_FLAGS = 0x6e, // 0x6e l*:vec() + // Enum type + WASM_COMP_DEF_VAL_ENUM = 0x6d, // 0x6d l*:vec() + // Option type + WASM_COMP_DEF_VAL_OPTION = 0x6b, // 0x6b t: + // Result type + WASM_COMP_DEF_VAL_RESULT = 0x6a, // 0x6a t?:? u?:? + // Handle types + WASM_COMP_DEF_VAL_OWN = 0x69, // 0x69 i: + WASM_COMP_DEF_VAL_BORROW = 0x68, // 0x68 i: + // Async types + WASM_COMP_DEF_VAL_STREAM = 0x66, // 0x66 t?:? + WASM_COMP_DEF_VAL_FUTURE = 0x65, // 0x65 t?:? +} WASMComponentDefValTypeTag; + +// ----------------------------------------------------------------------------- +// Resource Representation Tag - Always i32 +// ----------------------------------------------------------------------------- +typedef enum WASMComponentResourceRepTag { + WASM_COMP_RESOURCE_REP_I32 = 0x7f, // Always 0x7f for i32 representation +} WASMComponentResourceRepTag; + +// ----------------------------------------------------------------------------- +// Case End Tag - Always 0x00 at end of case +// ----------------------------------------------------------------------------- +typedef enum WASMComponentCaseEndTag { + WASM_COMP_CASE_END = 0x00, // Always 0x00 at end of case +} WASMComponentCaseEndTag; + +// ----------------------------------------------------------------------------- +// Simple Structs +// ----------------------------------------------------------------------------- +// Core Name Structure - UTF-8 encoded name +// name ::= len: n:^len => n +// ----------------------------------------------------------------------------- +typedef struct WASMComponentCoreName { + uint32_t name_len; + char *name; +} WASMComponentCoreName; + +// ----------------------------------------------------------------------------- +// Sort Structure - Identifies the kind of definition +// sort ::= 0x00 s: => s +// | 0x01 => type +// | 0x02 => func +// | 0x03 => value +// | 0x04 => type +// | 0x05 => component +// | 0x06 => instance +// ----------------------------------------------------------------------------- +typedef struct WASMComponentSort { + uint8_t sort; // Main sort byte (0x00 for core sorts, 0x01..0x05 for others) + uint8_t core_sort; // If sort==0x00, this is the core sort; otherwise is ignored +} WASMComponentSort; + +// ----------------------------------------------------------------------------- +// Sort Index Structure - Combines sort with index +// sortidx ::= s: i: => s i +// ----------------------------------------------------------------------------- +typedef struct WASMComponentSortIdx { + WASMComponentSort *sort; + uint32_t idx; +} WASMComponentSortIdx; + +// ----------------------------------------------------------------------------- +// Value Type Structure - Primitive value or type index +// valtype ::= i: => i +// | pvt: => pvt +// ----------------------------------------------------------------------------- +typedef struct WASMComponentValueType { + WASMComponentValueTypeTag type; + union { + uint32_t type_idx; + uint8_t primval_type; + } type_specific; +} WASMComponentValueType; + +// ----------------------------------------------------------------------------- +// Value Bound Structure - Equality or type bound +// valuebound ::= 0x00 v: => (eq v) +// | 0x01 t: => (eq t) +// ----------------------------------------------------------------------------- +typedef struct WASMComponentValueBound { + WASMComponentValueBoundTag tag; + union { + uint32_t value_idx; + WASMComponentValueType *value_type; + } bound; +} WASMComponentValueBound; + +// ----------------------------------------------------------------------------- +// Type Bound Structure - Equality or subtype bound +// typebound ::= 0x00 t: => (eq t) +// | 0x01 t: => (sub t) +// ----------------------------------------------------------------------------- +typedef struct WASMComponentTypeBound { + WASMComponentTypeBoundTag tag; + uint32_t type_idx; +} WASMComponentTypeBound; + +// ----------------------------------------------------------------------------- +// External Descriptor Structure - Describes import/export kind +// externdesc ::= 0x00 0x11 i: => (core module (type i)) +// | 0x01 i: => (func (type i)) +// | 0x02 b: => (value b) +// | 0x03 b: => (type b) +// | 0x04 i: => (component (type i)) +// | 0x05 i: => (instance (type i)) +// ----------------------------------------------------------------------------- +typedef struct WASMComponentExternDesc { + WASMComponentExternDescType type; + union { + struct { uint8_t type_specific; uint32_t type_idx; } core_module; + struct { uint32_t type_idx; } func; + struct { WASMComponentValueBound *value_bound; } value; + struct { WASMComponentTypeBound *type_bound; } type; + struct { uint32_t type_idx; } component; + struct { uint32_t type_idx; } instance; + } extern_desc; +} WASMComponentExternDesc; + +// ----------------------------------------------------------------------------- +// Import Name Structure - Simple or versioned name +// importname' ::= 0x00 len: in: => in +// | 0x01 len: in: vs: => in vs +// ----------------------------------------------------------------------------- +typedef struct WASMComponentImportName { + WASMComponentImportExportTypeTag tag; + union { + struct { WASMComponentCoreName *name; } simple; + struct { WASMComponentCoreName *name; WASMComponentCoreName *version; } versioned; + } imported; +} WASMComponentImportName; + +// ----------------------------------------------------------------------------- +// Export Name Structure - Simple or versioned name +// exportname' ::= 0x00 len: ex: => ex +// | 0x01 len: ex: vs: => ex vs +// ----------------------------------------------------------------------------- +typedef struct WASMComponentExportName { + WASMComponentImportExportTypeTag tag; + union { + struct { WASMComponentCoreName *name; } simple; + struct { WASMComponentCoreName *name; WASMComponentCoreName *version; } versioned; + } exported; +} WASMComponentExportName; + +// ----------------------------------------------------------------------------- +// Section 0: Custom Section Structs +// ----------------------------------------------------------------------------- +// Custom Section Structure - Arbitrary named data sections +typedef struct WASMComponentCoreCustomSection { + char *name; // Name of the custom section + const uint8_t *data; // Pointer to the custom data + uint32_t data_len; // Length of the custom data +} WASMComponentCoreCustomSection; + +// ----------------------------------------------------------------------------- +// Section 1: Module Section Structs +// ----------------------------------------------------------------------------- +// Module Wrapper Structure - Contains core WebAssembly module +typedef struct WASMComponentCoreModuleWrapper { + struct WASMModule *module; + void *module_handle; +} WASMComponentCoreModuleWrapper; + +// ----------------------------------------------------------------------------- +// Section 2: Core Instance Section Structs +// ----------------------------------------------------------------------------- +// Core Instance Structure - Core WebAssembly instance +// Inline Export Structure - Exports from core instances +typedef struct WASMComponentInlineExport { + WASMComponentCoreName *name; + WASMComponentSortIdx *sort_idx; +} WASMComponentInlineExport; + +// Instantiate Argument Structure - Arguments for instantiation +typedef struct WASMComponentInstArg { + WASMComponentCoreName *name; + union { + WASMComponentSortIdx *sort_idx; + uint32_t instance_idx; + } idx; +} WASMComponentInstArg; + +typedef union WASMInstExpr { + struct { uint32_t idx; uint32_t arg_len; WASMComponentInstArg *args; } with_args; + struct { uint32_t inline_expr_len; WASMComponentInlineExport *inline_expr; } without_args; +} WASMInstExpr; + +typedef struct WASMComponentCoreInst { + WASMComponentInstExpressionTag instance_expression_tag; + WASMInstExpr expression; +} WASMComponentCoreInst; + +// Core Instance Section Structure - Vector of core instances +typedef struct WASMComponentCoreInstSection { + uint32_t count; + WASMComponentCoreInst *instances; +} WASMComponentCoreInstSection; + +// ----------------------------------------------------------------------------- +// Section 3: Type Section Structs (Core Types) +// ----------------------------------------------------------------------------- + +// Core Number Types - From WebAssembly Core spec +// numtype ::= 0x7F => i32 | 0x7E => i64 | 0x7D => f32 | 0x7C => f64 +typedef enum WASMCoreNumTypeTag { + WASM_CORE_NUM_TYPE_I32 = 0x7F, // i32 + WASM_CORE_NUM_TYPE_I64 = 0x7E, // i64 + WASM_CORE_NUM_TYPE_F32 = 0x7D, // f32 + WASM_CORE_NUM_TYPE_F64 = 0x7C, // f64 +} WASMCoreNumTypeTag; + +// Core Vector Types - From WebAssembly Core spec +// vectype ::= 0x7B => v128 +typedef enum WASMCoreVectorTypeTag { + WASM_CORE_VECTOR_TYPE_V128 = 0x7B, // v128 +} WASMCoreVectorTypeTag; + +// Core Packed Types - From WebAssembly Core spec +// packedtype ::= 0x78 => i8 | 0x77 => i16 +typedef enum WASMCorePackedTypeTag { + WASM_CORE_PACKED_TYPE_I8 = 0x78, // i8 + WASM_CORE_PACKED_TYPE_I16 = 0x77, // i16 +} WASMCorePackedTypeTag; + +// Core Abstract Heap Types - From WebAssembly Core spec +// absheaptype ::= 0x73 => nofunc | 0x72 => noextern | 0x71 => none | 0x70 => func +// | 0x6F => extern | 0x6E => any | 0x6D => eq | 0x6C => i31 +// | 0x6B => struct | 0x6A => array +typedef enum WASMCoreAbsHeapTypeTag { + WASM_CORE_ABS_HEAP_TYPE_NOFUNC = 0x73, // nofunc + WASM_CORE_ABS_HEAP_TYPE_NOEXTERN = 0x72, // noextern + WASM_CORE_ABS_HEAP_TYPE_NONE = 0x71, // none + WASM_CORE_ABS_HEAP_TYPE_FUNC = 0x70, // func + WASM_CORE_ABS_HEAP_TYPE_EXTERN = 0x6F, // extern + WASM_CORE_ABS_HEAP_TYPE_ANY = 0x6E, // any + WASM_CORE_ABS_HEAP_TYPE_EQ = 0x6D, // eq + WASM_CORE_ABS_HEAP_TYPE_I31 = 0x6C, // i31 + WASM_CORE_ABS_HEAP_TYPE_STRUCT = 0x6B, // struct + WASM_CORE_ABS_HEAP_TYPE_ARRAY = 0x6A, // array +} WASMCoreAbsHeapTypeTag; + +// Core Heap Type - Can be abstract heap type or type index +// heaptype ::= ht:absheaptype => ht | x:s33 => x (if x >= 0) +typedef enum WASMComponentCoreHeapTypeTag { + WASM_CORE_HEAP_TYPE_ABSTRACT, + WASM_CORE_HEAP_TYPE_CONCRETE +} WASMComponentCoreHeapTypeTag; + +typedef struct WASMComponentCoreHeapType { + WASMComponentCoreHeapTypeTag tag; + union { + WASMCoreAbsHeapTypeTag abstract_type; + uint32_t concrete_index; // Type index for heap type (s33) + } heap_type; +} WASMComponentCoreHeapType; + +// Core Value Type Structure - Can be number, vector, or reference type +// valtype ::= t:numtype => t | t:vectype => t | t:reftype => t +typedef enum WASMComponentCoreValTypeTag { + WASM_CORE_VALTYPE_NUM, + WASM_CORE_VALTYPE_VECTOR, + WASM_CORE_VALTYPE_REF +} WASMComponentCoreValTypeTag; + +typedef enum WASMComponentCoreRefType { + WASM_CORE_REFTYPE_FUNC_REF = 0x70, + WASM_CORE_REFTYPE_EXTERN_REF = 0x6F, +} WASMComponentCoreRefType; + +typedef struct WASMComponentCoreValType { + WASMComponentCoreValTypeTag tag; + union { + WASMCoreNumTypeTag num_type; + WASMCoreVectorTypeTag vector_type; + WASMComponentCoreRefType ref_type; + } type; +} WASMComponentCoreValType; + +// Core Storage Type - Can be value type or packed type +// storagetype ::= t:valtype => t | t:packedtype => t +typedef enum WASMComponentCoreStorageTypeTag { + WASM_CORE_STORAGETYPE_VAL, + WASM_CORE_STORAGETYPE_PACKED +} WASMComponentCoreStorageTypeTag; + +typedef struct WASMComponentCoreStorageType { + WASMComponentCoreStorageTypeTag tag; + union { + WASMComponentCoreValType val_type; + WASMCorePackedTypeTag packed_type; + } storage_type; +} WASMComponentCoreStorageType; + +// Core Field Type Structure - Has mutability and storage type +// fieldtype ::= st:storagetype m:mut => m st +typedef struct WASMComponentCoreFieldType { + bool is_mutable; // true for var, false for const + WASMComponentCoreStorageType storage_type; +} WASMComponentCoreFieldType; + +// Core Result Type Structure - Vector of value types +// resulttype ::= t*:vec(valtype) => [t*] +typedef struct WASMComponentCoreResultType { + uint32_t count; + WASMComponentCoreValType *val_types; +} WASMComponentCoreResultType; + +// Core Function Type Structure +// functype ::= rt1:resulttype rt2:resulttype => rt1 -> rt2 +typedef struct WASMComponentCoreFuncType { + WASMComponentCoreResultType params; // rt1 + WASMComponentCoreResultType results; // rt2 +} WASMComponentCoreFuncType; + +// Core Array Type Structure +// arraytype ::= ft:fieldtype => ft +typedef struct WASMComponentCoreArrayType { + WASMComponentCoreFieldType field_type; +} WASMComponentCoreArrayType; + +// Core Struct Type Structure - Vector of field types +// structtype ::= ft*:vec(fieldtype) => ft* +typedef struct WASMComponentCoreStructType { + uint32_t field_count; + WASMComponentCoreFieldType *fields; +} WASMComponentCoreStructType; + +// Core Composite Type Structure +// comptype ::= 0x5E at:arraytype => array at +// | 0x5F st:structtype => struct st +// | 0x60 ft:functype => func ft +typedef enum WASMComponentCoreCompTypeTag { + WASM_CORE_COMPTYPE_ARRAY = 0x5E, + WASM_CORE_COMPTYPE_STRUCT = 0x5F, + WASM_CORE_COMPTYPE_FUNC = 0x60 +} WASMComponentCoreCompTypeTag; + +typedef struct WASMComponentCoreCompType { + WASMComponentCoreCompTypeTag tag; + union { + WASMComponentCoreArrayType array_type; + WASMComponentCoreStructType struct_type; + WASMComponentCoreFuncType func_type; + } type; +} WASMComponentCoreCompType; + +// Core SubType Structure +// subtype ::= 0x50 x*:vec(typeidx) ct:comptype => sub x* ct +// | 0x4F x*:vec(typeidx) ct:comptype => sub final x* ct +// | ct:comptype => sub final ε ct +typedef struct WASMComponentCoreSubType { + bool is_final; + uint32_t supertype_count; + uint32_t *supertypes; // Vector of type indices (can be empty for final with no supertypes) + WASMComponentCoreCompType comptype; +} WASMComponentCoreSubType; + +// Core RecType Structure - Recursive type +// rectype ::= 0x4E st*:vec(subtype) => rec st* +// | st:subtype => rec st +typedef struct WASMComponentCoreRecType { + uint32_t subtype_count; + WASMComponentCoreSubType *subtypes; +} WASMComponentCoreRecType; + +// Core Module Type Structure + + +// Core Import and Import Description Structures +// Based on WebAssembly specification: https://webassembly.github.io/gc/core/binary/types.html +// core:import ::= nm: d: => (import nm d) +// core:importdesc ::= 0x00 ft: => (func (type ft)) +// | 0x01 tt: => (table tt) +// | 0x02 mt: => (memory mt) +// | 0x03 gt: => (global gt) + +typedef enum WASMComponentCoreImportDescType { + WASM_CORE_IMPORTDESC_FUNC = 0x00, // 0x00 ft: => (func (type ft)) + WASM_CORE_IMPORTDESC_TABLE = 0x01, // 0x01 tt: => (table tt) + WASM_CORE_IMPORTDESC_MEMORY = 0x02, // 0x02 mt: => (memory mt) + WASM_CORE_IMPORTDESC_GLOBAL = 0x03 // 0x03 gt: => (global gt) +} WASMComponentCoreImportDescType; + +typedef enum WASMComponentCoreLimitsTag { + WASM_CORE_LIMITS_MIN = 0x00, + WASM_CORE_LIMITS_MAX = 0x01 +} WASMComponentCoreLimitsTag; + +typedef struct WASMComponentCoreLimits { + WASMComponentCoreLimitsTag tag; + union { + struct { uint32_t min; } limits; + struct { uint32_t min; uint32_t max; } limits_max; + } lim; +} WASMComponentCoreLimits; + +typedef enum WASMComponentCoreGlobalTag { + WASM_CORE_GLOBAL_MUTABLE = 0x00, + WASM_CORE_GLOBAL_IMMUTABLE = 0x01 +} WASMComponentCoreGlobalTag; + +typedef struct WASMComponentCoreImportDesc { + WASMComponentCoreImportDescType type; + union { + uint32_t func_type_idx; + struct { + WASMComponentCoreRefType ref_type; + WASMComponentCoreLimits *limits; + } table_type; + struct { + WASMComponentCoreLimits *limits; + } memory_type; + struct { + WASMComponentCoreValType val_type; + bool is_mutable; + } global_type; + } desc; +} WASMComponentCoreImportDesc; + +typedef struct WASMComponentCoreImport { + WASMComponentCoreName *mod_name; + WASMComponentCoreName *nm; + WASMComponentCoreImportDesc *import_desc; +} WASMComponentCoreImport; + +// Core Export Declaration Structure +// core:exportdecl ::= nm: d: => (export nm d) +typedef struct WASMComponentCoreExportDecl { + WASMComponentCoreName *name; + WASMComponentCoreImportDesc *export_desc; +} WASMComponentCoreExportDecl; + +// Core Alias Structure +// core:alias ::= 0x00 x: n: => (alias outer x n) +// | 0x01 x: n: => (alias outer x n) +// | 0x02 x: n: => (alias outer x n) +// | 0x03 x: n: => (alias outer x n) + +typedef enum WASMComponentCoreAliasType { + WASM_CORE_ALIAS_FUNC = 0x00, // 0x00 x: n: => (alias outer x n) + WASM_CORE_ALIAS_TABLE = 0x01, // 0x01 x: n: => (alias outer x n) + WASM_CORE_ALIAS_MEMORY = 0x02, // 0x02 x: n: => (alias outer x n) + WASM_CORE_ALIAS_GLOBAL = 0x03 // 0x03 x: n: => (alias outer x n) +} WASMComponentCoreAliasType; + +typedef struct WASMComponentCoreAliasTarget { + uint32_t ct; + uint32_t index; +} WASMComponentCoreAliasTarget; + +typedef struct WASMComponentCoreAlias { + WASMComponentSort sort; + WASMComponentCoreAliasTarget alias_target; +} WASMComponentCoreAlias; + +// Core Module Declaration Structure +// moduletype ::= 0x50 md*:vec(moduledecl) => (module md*) +// moduledecl ::= 0x00 i: => i +// | 0x01 t: => t +// | 0x02 a: => a +// | 0x03 e: => e +typedef enum WASMComponentCoreModuleDeclTag { + WASM_CORE_MODULEDECL_IMPORT = 0x00, + WASM_CORE_MODULEDECL_TYPE = 0x01, + WASM_CORE_MODULEDECL_ALIAS = 0x02, + WASM_CORE_MODULEDECL_EXPORT = 0x03 +} WASMComponentCoreModuleDeclTag; + +typedef struct WASMComponentCoreModuleDecl { + WASMComponentCoreModuleDeclTag tag; + union { + struct { + WASMComponentCoreImport *import; + } import_decl; + struct { + struct WASMComponentCoreType *type; + } type_decl; + struct { + WASMComponentCoreAlias *alias; + } alias_decl; + struct { + WASMComponentCoreExportDecl *export_decl; + } export_decl; + } decl; +} WASMComponentCoreModuleDecl; + +typedef struct WASMComponentCoreModuleType { + uint32_t decl_count; + WASMComponentCoreModuleDecl *declarations; +} WASMComponentCoreModuleType; + +// Core DefType Structure +// core:deftype ::= rt: => rt (WebAssembly 3.0) +// | 0x00 0x50 x*:vec() ct: => sub x* ct (WebAssembly 3.0) +// | mt: => mt +typedef enum WASMComponentCoreDefTypeTag { + WASM_CORE_DEFTYPE_RECTYPE, + WASM_CORE_DEFTYPE_SUBTYPE, + WASM_CORE_DEFTYPE_MODULETYPE +} WASMComponentCoreDefTypeTag; + +typedef struct WASMComponentCoreModuleSubType { + uint32_t supertype_count; + uint32_t *supertypes; + WASMComponentCoreCompType *comptype; +} WASMComponentCoreModuleSubType; + +typedef struct WASMComponentCoreDefType { + WASMComponentCoreDefTypeTag tag; + union { + WASMComponentCoreRecType *rectype; + WASMComponentCoreModuleSubType *subtype; + WASMComponentCoreModuleType *moduletype; + } type; +} WASMComponentCoreDefType; + +// Core Type Structure +// core:type ::= dt: => (type dt) +typedef struct WASMComponentCoreType { + WASMComponentCoreDefType *deftype; +} WASMComponentCoreType; + +// Core Type Section Structure - Vector of core types +typedef struct WASMComponentCoreTypeSection { + uint32_t count; + WASMComponentCoreType *types; +} WASMComponentCoreTypeSection; + +// ----------------------------------------------------------------------------- +// Section 4: Component Section Structs +// ----------------------------------------------------------------------------- +// Note: Component structure is defined later in Main Component Structures + +// ----------------------------------------------------------------------------- +// Section 5: Instances Section Structs +// ----------------------------------------------------------------------------- +// Instance Structure - Component instance +typedef struct WASMComponentInst { + WASMComponentInstExpressionTag instance_expression_tag; + WASMInstExpr expression; +} WASMComponentInst; + +// Instance Section Structure - Vector of instances +typedef struct WASMComponentInstSection { + uint32_t count; + WASMComponentInst *instances; +} WASMComponentInstSection; + +// ----------------------------------------------------------------------------- +// Section 6: Alias Section Structs +// ----------------------------------------------------------------------------- +// Alias Target Structures - Used in alias definitions +typedef struct WASMComponentAliasTargetExport { + uint32_t instance_idx; + WASMComponentCoreName *name; +} WASMComponentAliasTargetExport; + +typedef struct WASMComponentAliasTargetCoreExport { + uint32_t instance_idx; + WASMComponentCoreName *name; +} WASMComponentAliasTargetCoreExport; + +typedef struct WASMComponentAliasTargetOuter { + uint32_t ct; + uint32_t idx; +} WASMComponentAliasTargetOuter; + +// Alias Definition Structure - Projects definitions from other components +// alias ::= s: t: => (alias t (s)) +typedef struct WASMComponentAliasDefinition { + WASMComponentSort *sort; + WASMComponentAliasTargetType alias_target_type; + union { + struct { + uint32_t instance_idx; + WASMComponentCoreName *name; + } exported; + struct { + uint32_t instance_idx; + WASMComponentCoreName *name; + } core_exported; + struct { + uint32_t ct; + uint32_t idx; + } outer; + } target; +} WASMComponentAliasDefinition; + +// Alias Section Structure - Vector of alias definitions +typedef struct WASMComponentAliasSection { + uint32_t count; + WASMComponentAliasDefinition *aliases; +} WASMComponentAliasSection; + +// ----------------------------------------------------------------------------- +// Section 7: Types Section Structs +// ----------------------------------------------------------------------------- +// Label-Value Type Structure - Labeled value type +// labelvaltype ::= l: t: => l t +typedef struct WASMComponentLabelValType { + WASMComponentCoreName *label; + WASMComponentValueType *value_type; +} WASMComponentLabelValType; + +// Case Value Type Structure - Labeled case type +// case ::= l: t?:? => l t? +typedef struct WASMComponentCaseValType { + WASMComponentCoreName *label; + WASMComponentValueType *value_type; +} WASMComponentCaseValType; + +// Record Type Structure - Labeled fields +// record ::= lt*:vec() => (record lt*) +typedef struct WASMComponentRecordType { + uint32_t count; + WASMComponentLabelValType *fields; +} WASMComponentRecordType; + +// Variant Type Structure - Labeled cases +// variant ::= case*:vec() => (variant case*) +typedef struct WASMComponentVariantType { + uint32_t count; + WASMComponentCaseValType *cases; +} WASMComponentVariantType; + +// List Type Structure - Homogeneous list +// list ::= t: => (list t) +typedef struct WASMComponentListType { + WASMComponentValueType *element_type; +} WASMComponentListType; + +// List Length Type Structure - Fixed-length list +// list-len ::= t: len: => (list t len) +typedef struct WASMComponentListLenType { + uint32_t len; + WASMComponentValueType *element_type; +} WASMComponentListLenType; + +// Tuple Type Structure - Heterogeneous tuple +// tuple ::= t*:vec() => (tuple t*) +typedef struct WASMComponentTupleType { + uint32_t count; + WASMComponentValueType *element_types; +} WASMComponentTupleType; + +// Flag Type Structure - Named flags +// flags ::= l*:vec() => (flags l*) +typedef struct WASMComponentFlagType { + uint32_t count; + WASMComponentCoreName *flags; +} WASMComponentFlagType; + +// Enum Type Structure - Named enum +// enum ::= l*:vec() => (enum l*) +typedef struct WASMComponentEnumType { + uint32_t count; + WASMComponentCoreName *labels; +} WASMComponentEnumType; + +// Option Type Structure - Optional value +// option ::= t: => (option t) +typedef struct WASMComponentOptionType { + WASMComponentValueType *element_type; +} WASMComponentOptionType; + +// Result Type Structure - Success/error result +// result ::= t?:? u?:? => (result t? u?) +typedef struct WASMComponentResultType { + WASMComponentValueType *result_type; // Optional (can be NULL) + WASMComponentValueType *error_type; // Optional (can be NULL) +} WASMComponentResultType; + +// Own Type Structure - Owned handle +// own ::= i: => (own i) +typedef struct WASMComponentOwnType { + uint32_t type_idx; +} WASMComponentOwnType; + +// Borrow Type Structure - Borrowed handle +// borrow ::= i: => (borrow i) +typedef struct WASMComponentBorrowType { + uint32_t type_idx; +} WASMComponentBorrowType; + +// Stream Type Structure - Async stream +// stream ::= t?:? => (stream t?) +typedef struct WASMComponentStreamType { + WASMComponentValueType *element_type; +} WASMComponentStreamType; + +// Future Type Structure - Async future +// future ::= t?:? => (future t?) +typedef struct WASMComponentFutureType { + WASMComponentValueType *element_type; +} WASMComponentFutureType; + +// DefValType Structure - Defined value type +// defvaltype ::= 0x63 pvt: => pvt +// | 0x72 lt*:vec() => (record lt*) +// | 0x71 case*:vec() => (variant case*) +// | 0x70 t: => (list t) +// | 0x67 t: len: => (list t len) +// | 0x6f t*:vec() => (tuple t*) +// | 0x6e l*:vec() => (flags l*) +// | 0x6d l*:vec() => (enum l*) +// | 0x6b t: => (option t) +// | 0x6a t?:? u?:? => (result t? u?) +// | 0x69 i: => (own i) +// | 0x68 i: => (borrow i) +// | 0x66 t?:? => (stream t?) +// | 0x65 t?:? => (future t?) +typedef struct WASMComponentDefValType { + WASMComponentDefValTypeTag tag; + union { + WASMComponentPrimValType primval; + WASMComponentRecordType *record; + WASMComponentVariantType *variant; + WASMComponentListType *list; + WASMComponentListLenType *list_len; + WASMComponentTupleType *tuple; + WASMComponentFlagType *flag; + WASMComponentEnumType *enum_type; + WASMComponentOptionType *option; + WASMComponentResultType *result; + WASMComponentOwnType *owned; + WASMComponentBorrowType *borrow; + WASMComponentStreamType *stream; + WASMComponentFutureType *future; + } def_val; +} WASMComponentDefValType; + +// Parameter List Structure - Function parameters +// paramtype ::= l: t: => l t +// paramlist ::= pt*:vec() => pt* +typedef struct WASMComponentParamList { + uint32_t count; + WASMComponentLabelValType *params; +} WASMComponentParamList; + +// Result List Structure - Function results +// resulttype ::= l: t: => l t +// resultlist ::= rt*:vec() => rt* +typedef struct WASMComponentResultList { + WASMComponentResultListTag tag; + WASMComponentValueType *results; +} WASMComponentResultList; + +// Function Type Structure - Function signature +// functype ::= pt*:vec() rt*:vec() => (func pt* rt*) +typedef struct WASMComponentFuncType { + WASMComponentParamList *params; + WASMComponentResultList *results; +} WASMComponentFuncType; + +// Import Declaration Structure - Component import +// importdecl ::= n: d: => (import n d) +typedef struct WASMComponentImportDecl { + WASMComponentImportName *import_name; + WASMComponentExternDesc *extern_desc; +} WASMComponentImportDecl; + +// Export Declaration Structure - Component export +// exportdecl ::= n: d: => (export n d) +typedef struct WASMComponentComponentDeclExport { + WASMComponentExportName *export_name; + WASMComponentExternDesc *extern_desc; +} WASMComponentComponentDeclExport; + +// Instance Declaration Structure - Instance definition +// instancedecl ::= 0x00 ct: => (core type ct) +// | 0x01 t: => (type t) +// | 0x02 a: => a +// | 0x04 ed: => ed +typedef struct WASMComponentInstDecl { + WASMComponentInstDeclTag tag; + union { + WASMComponentCoreType *core_type; + struct WASMComponentTypes *type; + WASMComponentAliasDefinition *alias; + WASMComponentComponentDeclExport *export_decl; + } decl; +} WASMComponentInstDecl; + +// Component Declaration Structure - Component definition +// componentdecl ::= 0x03 id: => id +// | 0x00 id: => id +typedef struct WASMComponentComponentDecl { + WASMComponentComponentDeclTag tag; + union { + WASMComponentImportDecl *import_decl; + WASMComponentInstDecl *instance_decl; + } decl; +} WASMComponentComponentDecl; + +// Component Type Structure - Component interface +// componenttype ::= ct*:vec() => (component ct*) +typedef struct WASMComponentComponentType { + uint32_t count; + WASMComponentComponentDecl *component_decls; +} WASMComponentComponentType; + +// Instance Type Structure - Instance interface +// instancetype ::= it*:vec() => (instance it*) +typedef struct WASMComponentInstType { + uint32_t count; + WASMComponentInstDecl *instance_decls; +} WASMComponentInstType; + +// Resource Type Sync Structure - Resource definition +// resourcetype ::= 0x3f i: => (resource (rep i32) (dtor i)) +typedef struct WASMComponentResourceTypeSync { + bool has_dtor; + uint32_t dtor_func_idx; +} WASMComponentResourceTypeSync; + +// Resource Type Async Structure - Resource definition +// resourcetype ::= 0x3e i: => (resource (rep i32) (dtor i) (dtor i)) +typedef struct WASMComponentResourceTypeAsync { + uint32_t dtor_func_idx; + uint32_t callback_func_idx; +} WASMComponentResourceTypeAsync; + +// Resource Type Structure - Resource definition +// resourcetype ::= 0x3f i: => (resource (rep i32) (dtor i)) +// | 0x3e i: => (resource (rep i32) (dtor i) (dtor i)) +typedef struct WASMComponentResourceType { + WASMComponentTypesTag tag; + union { + WASMComponentResourceTypeSync *sync; + WASMComponentResourceTypeAsync *async; + } resource; +} WASMComponentResourceType; + +// Types Structure - Union of all type kinds +// type ::= 0x63 pvt: => pvt +// | 0x72 lt*:vec() => (record lt*) +// | 0x71 case*:vec() => (variant case*) +// | 0x70 t: => (list t) +// | 0x67 t: len: => (list t len) +// | 0x6f t*:vec() => (tuple t*) +// | 0x6e l*:vec() => (flags l*) +// | 0x6d l*:vec() => (enum l*) +// | 0x6b t: => (option t) +// | 0x6a t?:? u?:? => (result t? u?) +// | 0x69 i: => (own i) +// | 0x68 i: => (borrow i) +// | 0x66 t?:? => (stream t?) +// | 0x65 t?:? => (future t?) +// | 0x40 pt*:vec() rt*:vec() => (func pt* rt*) +// | 0x41 ct*:vec() => (component ct*) +// | 0x42 it*:vec() => (instance it*) +// | 0x3f i: => (resource (rep i32) (dtor i)) +// | 0x3e i: => (resource (rep i32) (dtor i) (dtor i)) +typedef struct WASMComponentTypes { + WASMComponentTypesTag tag; + union { + struct WASMComponentDefValType *def_val_type; + struct WASMComponentFuncType *func_type; + struct WASMComponentComponentType *component_type; + struct WASMComponentInstType *instance_type; + struct WASMComponentResourceType *resource_type; + } type; +} WASMComponentTypes; + +// Type Section Structure - Vector of types +typedef struct WASMComponentTypeSection { + uint32_t count; + WASMComponentTypes *types; +} WASMComponentTypeSection; + +// ----------------------------------------------------------------------------- +// Section 8: Canons Section Structs +// ----------------------------------------------------------------------------- +// Canonical definitions for lifting/lowering and built-ins +typedef enum WASMComponentCanonType { + WASM_COMP_CANON_LIFT = 0x00, // canon lift + WASM_COMP_CANON_LOWER = 0x01, // canon lower + WASM_COMP_CANON_RESOURCE_NEW = 0x02, // canon resource.new + WASM_COMP_CANON_RESOURCE_DROP = 0x03, // canon resource.drop + WASM_COMP_CANON_RESOURCE_REP = 0x04, // canon resource.rep + WASM_COMP_CANON_RESOURCE_DROP_ASYNC = 0x07, // canon resource.drop async + WASM_COMP_CANON_BACKPRESSURE_SET = 0x08, // canon backpressure.set + WASM_COMP_CANON_TASK_RETURN = 0x09, // canon task.return + WASM_COMP_CANON_TASK_CANCEL = 0x05, // canon task.cancel + WASM_COMP_CANON_CONTEXT_GET = 0x0a, // canon context.get + WASM_COMP_CANON_CONTEXT_SET = 0x0b, // canon context.set + WASM_COMP_CANON_YIELD = 0x0c, // canon yield + WASM_COMP_CANON_SUBTASK_CANCEL = 0x06, // canon subtask.cancel + WASM_COMP_CANON_SUBTASK_DROP = 0x0d, // canon subtask.drop + WASM_COMP_CANON_STREAM_NEW = 0x0e, // canon stream.new + WASM_COMP_CANON_STREAM_READ = 0x0f, // canon stream.read + WASM_COMP_CANON_STREAM_WRITE = 0x10, // canon stream.write + WASM_COMP_CANON_STREAM_CANCEL_READ = 0x11, // canon stream.cancel-read + WASM_COMP_CANON_STREAM_CANCEL_WRITE = 0x12, // canon stream.cancel-write + WASM_COMP_CANON_STREAM_DROP_READABLE = 0x13, // canon stream.drop-readable + WASM_COMP_CANON_STREAM_DROP_WRITABLE = 0x14, // canon stream.drop-writable + WASM_COMP_CANON_FUTURE_NEW = 0x15, // canon future.new + WASM_COMP_CANON_FUTURE_READ = 0x16, // canon future.read + WASM_COMP_CANON_FUTURE_WRITE = 0x17, // canon future.write + WASM_COMP_CANON_FUTURE_CANCEL_READ = 0x18, // canon future.cancel-read + WASM_COMP_CANON_FUTURE_CANCEL_WRITE = 0x19, // canon future.cancel-write + WASM_COMP_CANON_FUTURE_DROP_READABLE = 0x1a, // canon future.drop-readable + WASM_COMP_CANON_FUTURE_DROP_WRITABLE = 0x1b, // canon future.drop-writable + WASM_COMP_CANON_ERROR_CONTEXT_NEW = 0x1c, // canon error-context.new + WASM_COMP_CANON_ERROR_CONTEXT_DEBUG = 0x1d, // canon error-context.debug-message + WASM_COMP_CANON_ERROR_CONTEXT_DROP = 0x1e, // canon error-context.drop + WASM_COMP_CANON_WAITABLE_SET_NEW = 0x1f, // canon waitable-set.new + WASM_COMP_CANON_WAITABLE_SET_WAIT = 0x20, // canon waitable-set.wait + WASM_COMP_CANON_WAITABLE_SET_POLL = 0x21, // canon waitable-set.poll + WASM_COMP_CANON_WAITABLE_SET_DROP = 0x22, // canon waitable-set.drop + WASM_COMP_CANON_WAITABLE_JOIN = 0x23, // canon waitable.join + WASM_COMP_CANON_THREAD_SPAWN_REF = 0x40, // canon thread.spawn_ref + WASM_COMP_CANON_THREAD_SPAWN_INDIRECT = 0x41, // canon thread.spawn_indirect + WASM_COMP_CANON_THREAD_AVAILABLE_PAR = 0x42 // canon thread.available_parallelism +} WASMComponentCanonType; + +// Canonical options for lift/lower operations +typedef enum WASMComponentCanonOptTag { + WASM_COMP_CANON_OPT_STRING_UTF8 = 0x00, // string-encoding=utf8 + WASM_COMP_CANON_OPT_STRING_UTF16 = 0x01, // string-encoding=utf16 + WASM_COMP_CANON_OPT_STRING_LATIN1_UTF16 = 0x02, // string-encoding=latin1+utf16 + WASM_COMP_CANON_OPT_MEMORY = 0x03, // (memory m) + WASM_COMP_CANON_OPT_REALLOC = 0x04, // (realloc f) + WASM_COMP_CANON_OPT_POST_RETURN = 0x05, // (post-return f) + WASM_COMP_CANON_OPT_ASYNC = 0x06, // async + WASM_COMP_CANON_OPT_CALLBACK = 0x07 // (callback f) +} WASMComponentCanonOptTag; + +// Canon option with payload, opts := vec where some options carry an immediate: +// - 0x03 (memory m) -> core:memidx (u32) +// - 0x04 (realloc f) -> core:funcidx (u32) +// - 0x05 (post-return f) -> core:funcidx (u32) +// - 0x07 (callback f) -> core:funcidx (u32) +// Others (string-encoding, async) carry no immediates. +typedef struct WASMComponentCanonOpt { + WASMComponentCanonOptTag tag; + union { + struct { /* no payload */ } string_utf8; /* 0x00 */ + struct { /* no payload */ } string_utf16; /* 0x01 */ + struct { /* no payload */ } string_latin1_utf16; /* 0x02 */ + struct { uint32_t mem_idx; } memory; /* 0x03 */ + struct { uint32_t func_idx; } realloc_opt; /* 0x04 */ + struct { uint32_t func_idx; } post_return; /* 0x05 */ + struct { /* no payload */ } async; /* 0x06 */ + struct { uint32_t func_idx; } callback; /* 0x07 */ + } payload; +} WASMComponentCanonOpt; + +typedef struct WASMComponentCanonOpts { + uint32_t canon_opts_count; + WASMComponentCanonOpt *canon_opts; +} WASMComponentCanonOpts; + +// Canonical definition structure +typedef struct WASMComponentCanon { + WASMComponentCanonType tag; + union { + // 0x00 0x00 f: opts: ft: + struct { + uint32_t core_func_idx; + struct WASMComponentCanonOpts *canon_opts; + uint32_t type_idx; + } lift; + // 0x01 0x00 f: opts: + struct { + uint32_t func_idx; + struct WASMComponentCanonOpts *canon_opts; + } lower; + // 0x02 rt: + struct { + uint32_t resource_type_idx; + } resource_new; + // 0x03 rt: or 0x07 rt: (async) + struct { + uint32_t resource_type_idx; + bool async; + } resource_drop; + // 0x04 rt: + struct { + uint32_t resource_type_idx; + } resource_rep; + // 0x08 (no parameters) + struct { + // No parameters + } backpressure_set; + // 0x09 rs: opts: + struct { + WASMComponentResultList *result_list; + struct WASMComponentCanonOpts *canon_opts; + } task_return; + // 0x05 (no parameters) + struct { + // No parameters + } task_cancel; + // 0x0a 0x7f i: or 0x0b 0x7f i: + struct { + uint32_t context_idx; + } context_get_set; + // 0x0c cancel?: + struct { + bool cancellable; + } yield; + // 0x06 async?: + struct { + bool async; + } subtask_cancel; + // 0x0d (no parameters) + struct { + // No parameters + } subtask_drop; + // 0x0e t: + struct { + uint32_t stream_type_idx; + } stream_new; + // 0x0f t: opts: or 0x10 t: opts: + struct { + uint32_t stream_type_idx; + struct WASMComponentCanonOpts *canon_opts; + } stream_read_write; + // 0x11 t: async?: or 0x12 t: async?: + struct { + uint32_t stream_type_idx; + bool async; + } stream_cancel_read_write; + // 0x13 t: or 0x14 t: + struct { + uint32_t stream_type_idx; + } stream_drop_readable_writable; + // 0x15 t: + struct { + uint32_t future_type_idx; + } future_new; + // 0x16 t: opts: or 0x17 t: opts: + struct { + uint32_t future_type_idx; + struct WASMComponentCanonOpts *canon_opts; + } future_read_write; + // 0x18 t: async?: or 0x19 t: async?: + struct { + uint32_t future_type_idx; + bool async; + } future_cancel_read_write; + // 0x1a t: or 0x1b t: + struct { + uint32_t future_type_idx; + } future_drop_readable_writable; + // 0x1c opts: or 0x1d opts: + struct { + struct WASMComponentCanonOpts *canon_opts; + } error_context_new_debug; + // 0x1e (no parameters) + struct { + // No parameters + } error_context_drop; + // 0x1f (no parameters) + struct { + // No parameters + } waitable_set_new; + // 0x20 cancel?: m: or 0x21 cancel?: m: + struct { + bool cancellable; + uint32_t mem_idx; + } waitable_set_wait_poll; + // 0x22 (no parameters) + struct { + // No parameters + } waitable_set_drop; + // 0x23 (no parameters) + struct { + // No parameters + } waitable_join; + // 0x40 ft: + struct { + uint32_t func_type_idx; + } thread_spawn_ref; + // 0x41 ft: tbl: + struct { + uint32_t func_type_idx; + uint32_t table_idx; + } thread_spawn_indirect; + // 0x42 (no parameters) + struct { + // No parameters + } thread_available_parallelism; + } canon_data; +} WASMComponentCanon; + +// Canonical section structure +typedef struct WASMComponentCanonSection { + uint32_t count; + WASMComponentCanon *canons; +} WASMComponentCanonSection; + +// ----------------------------------------------------------------------------- +// Section 9: Start Section Structs +// ----------------------------------------------------------------------------- +// Start definition for component-level start function +typedef struct WASMComponentStartSection { + uint32_t func_idx; // Function index to call + uint32_t value_args_count; // Number of value arguments + uint32_t *value_args; // Array of value indices for arguments + uint32_t result; // Number of result values to append to value index space +} WASMComponentStartSection; + +// ----------------------------------------------------------------------------- +// Section 10: Import Section Structs +// ----------------------------------------------------------------------------- +// Import Structure - Component import +typedef struct WASMComponentImport { + WASMComponentImportName *import_name; + WASMComponentExternDesc *extern_desc; +} WASMComponentImport; + +// Import Section Structure - Vector of imports +typedef struct WASMComponentImportSection { + uint32_t count; + WASMComponentImport *imports; +} WASMComponentImportSection; + +// ----------------------------------------------------------------------------- +// Section 11: Export Section Structs +// ----------------------------------------------------------------------------- +// Export Structure - Component export +typedef struct WASMComponentExport { + WASMComponentExportName *export_name; + WASMComponentSortIdx *sort_idx; + WASMComponentExternDesc *extern_desc; +} WASMComponentExport; + +// Export Section Structure - Vector of exports +typedef struct WASMComponentExportSection { + uint32_t count; + WASMComponentExport *exports; +} WASMComponentExportSection; + +// ----------------------------------------------------------------------------- +// Section 12: Values Section Structs +// ----------------------------------------------------------------------------- +// Value definition for component-level values +typedef struct WASMComponentValue { + WASMComponentValueType *val_type; // Type of the value + uint32_t core_data_len; // Length of the value data (len:) + const uint8_t *core_data; // Binary data of the value (v:) +} WASMComponentValue; + +// Values section structure +typedef struct WASMComponentValueSection { + uint32_t count; + WASMComponentValue *values; +} WASMComponentValueSection; + +// ----------------------------------------------------------------------------- +// Main Component Structures +// ----------------------------------------------------------------------------- +// Component Section Structure - Generic section container +typedef struct WASMComponentSection { + WASMComponentSectionType id; + const uint8_t *payload; + uint32_t payload_len; + union { + struct WASMComponentCoreCustomSection *core_custom; + struct WASMComponentCoreTypeSection *core_type_section; + struct WASMComponentCoreModuleWrapper *core_module; + struct WASMComponent *component; + struct WASMComponentAliasSection *alias_section; + struct WASMComponentImportSection *import_section; + struct WASMComponentExportSection *export_section; + struct WASMComponentInstSection *instance_section; + struct WASMComponentCoreInstSection *core_instance_section; + struct WASMComponentCanonSection *canon_section; + struct WASMComponentStartSection *start_section; + struct WASMComponentValueSection *value_section; + struct WASMComponentTypeSection *type_section; + void *any; + } parsed; +} WASMComponentSection; + +// Main Component Structure - Complete component +typedef struct WASMComponent { + WASMHeader header; + WASMComponentSection *sections; + uint32_t section_count; +#if WASM_ENABLE_LIBC_WASI != 0 + WASIArguments wasi_args; + bool import_wasi_api; +#endif +} WASMComponent; + +// ----------------------------------------------------------------------------- +// Function Declarations +// ----------------------------------------------------------------------------- +#ifdef __cplusplus +extern "C" { +#endif +void set_error_buf_ex(char *error_buf, uint32_t error_buf_size, const char *format, ...); + +bool parse_valtype(const uint8_t **payload, const uint8_t *end, WASMComponentValueType *out, char *error_buf, uint32_t error_buf_size); +bool parse_labelvaltype(const uint8_t **payload, const uint8_t *end, WASMComponentLabelValType *out, char *error_buf, uint32_t error_buf_size); +bool parse_case(const uint8_t **payload, const uint8_t *end, WASMComponentCaseValType *out, char *error_buf, uint32_t error_buf_size); +void free_labelvaltype(WASMComponentLabelValType *labelvaltype); +void free_case(WASMComponentCaseValType *case_valtype); +bool parse_sort(const uint8_t **payload, const uint8_t *end, WASMComponentSort *out, char *error_buf, uint32_t error_buf_size, bool is_core); +bool parse_sort_idx(const uint8_t **payload, const uint8_t *end, WASMComponentSortIdx *out, char *error_buf, uint32_t error_buf_size, bool is_core); +bool parse_extern_desc(const uint8_t **payload, const uint8_t *end, WASMComponentExternDesc *out, char *error_buf, uint32_t error_buf_size); +void free_extern_desc(WASMComponentExternDesc *desc); +bool parse_core_name(const uint8_t **payload, const uint8_t *end, WASMComponentCoreName **out, char *error_buf, uint32_t error_buf_size); +void free_core_name(WASMComponentCoreName *core_name); +bool parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMComponentImportName *out, char *error_buf, uint32_t error_buf_size); +bool parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMComponentExportName *out, char *error_buf, uint32_t error_buf_size); +void free_component_import_name(WASMComponentImportName *name_struct); +void free_component_export_name(WASMComponentExportName *name_struct); +bool parse_label_prime(const uint8_t **payload, const uint8_t *end, WASMComponentCoreName **out, char *error_buf, uint32_t error_buf_size); +bool parse_label_prime_vector(const uint8_t **payload, const uint8_t *end, WASMComponentCoreName **out_labels, uint32_t *out_count, char *error_buf, uint32_t error_buf_size); +void free_label_prime(WASMComponentCoreName *label); +void free_label_prime_vector(WASMComponentCoreName *labels, uint32_t count); + +// UTF-8 validation helpers for component values +// Validates that the given byte slice is well-formed UTF-8 (no overlongs, no surrogates, <= U+10FFFF) +bool wasm_component_validate_utf8(const uint8_t *bytes, uint32_t len); +// Validates that the given byte slice encodes exactly one UTF-8 scalar value +bool wasm_component_validate_single_utf8_scalar(const uint8_t *bytes, uint32_t len); + +bool parse_single_type(const uint8_t **payload, const uint8_t *end, WASMComponentTypes *out, char *error_buf, uint32_t error_buf_size); +bool parse_single_alias(const uint8_t **payload, const uint8_t *end, WASMComponentAliasDefinition *out, char *error_buf, uint32_t error_buf_size); +bool parse_single_core_type(const uint8_t **payload, const uint8_t *end, WASMComponentCoreDefType *out, char *error_buf, uint32_t error_buf_size); +bool parse_alias_target(const uint8_t **payload, const uint8_t *end, WASMComponentCoreAliasTarget *out, char *error_buf, uint32_t error_buf_size); +bool parse_core_export_decl(const uint8_t **payload, const uint8_t *end, WASMComponentCoreExportDecl *out, char *error_buf, uint32_t error_buf_size); +bool parse_component_decl(const uint8_t **payload, const uint8_t *end, WASMComponentComponentDecl **out, char *error_buf, uint32_t error_buf_size); +bool parse_component_type(const uint8_t **payload, const uint8_t *end, WASMComponentComponentType **out, char *error_buf, uint32_t error_buf_size); +bool parse_result_list(const uint8_t **payload, const uint8_t *end, WASMComponentResultList **out, char *error_buf, uint32_t error_buf_size); + +// Core Type Parsing Functions +bool parse_core_moduletype(const uint8_t **payload, const uint8_t *end, WASMComponentCoreModuleType *out, char *error_buf, uint32_t error_buf_size); +bool parse_core_valtype(const uint8_t **payload, const uint8_t *end, WASMComponentCoreValType *out, char *error_buf, uint32_t error_buf_size); + +bool is_wasm_component(WASMHeader header); +bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMComponent *out_component, LoadArgs *args, unsigned int depth); +bool wasm_component_parse_core_custom_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreCustomSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_core_module_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreModuleWrapper *out, LoadArgs *args, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_core_instance_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreInstSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_core_type_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreTypeSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_component_section(const uint8_t **payload, uint32_t payload_len, WASMComponent *out, char *error_buf, uint32_t error_buf_size, LoadArgs *args, unsigned int depth, uint32_t *consumed_len); +bool wasm_component_parse_instances_section(const uint8_t **payload, uint32_t payload_len, WASMComponentInstSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_alias_section(const uint8_t **payload, uint32_t payload_len, WASMComponentAliasSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_types_section(const uint8_t **payload, uint32_t payload_len, WASMComponentTypeSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_canons_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCanonSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_start_section(const uint8_t **payload, uint32_t payload_len, WASMComponentStartSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_imports_section(const uint8_t **payload, uint32_t payload_len, WASMComponentImportSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_exports_section(const uint8_t **payload, uint32_t payload_len, WASMComponentExportSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); +bool wasm_component_parse_values_section(const uint8_t **payload, uint32_t payload_len, WASMComponentValueSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len); + +// Free functions for each section +void wasm_component_free_start_section(WASMComponentSection *section); +void wasm_component_free_values_section(WASMComponentSection *section); +void wasm_component_free_core_custom_section(WASMComponentSection *section); +void wasm_component_free_core_module_section(WASMComponentSection *section); +void wasm_component_free_core_instance_section(WASMComponentSection *section); +void wasm_component_free_core_type_section(WASMComponentSection *section); +void wasm_component_free_component_section(WASMComponentSection *section); +void wasm_component_free_instances_section(WASMComponentSection *section); +void wasm_component_free_alias_section(WASMComponentSection *section); +void wasm_component_free_types_section(WASMComponentSection *section); +void wasm_component_free_canons_section(WASMComponentSection *section); +void wasm_component_free_imports_section(WASMComponentSection *section); +void wasm_component_free_exports_section(WASMComponentSection *section); + +void wasm_component_free(WASMComponent *component); +#ifdef __cplusplus +} +#endif + +// Utility functions +static inline bool is_primitive_type(uint8_t value) { + // Component-model primitive value types + // 0x7f=bool, 0x7e=s8, 0x7d=u8, 0x7c=s16, 0x7b=u16, 0x7a=s32, 0x79=u32, + // 0x78=s64, 0x77=u64, 0x76=f32, 0x75=f64, 0x74=char, 0x73=string, 0x64=error-context + switch (value) { + case WASM_COMP_PRIMVAL_BOOL: + case WASM_COMP_PRIMVAL_S8: + case WASM_COMP_PRIMVAL_U8: + case WASM_COMP_PRIMVAL_S16: + case WASM_COMP_PRIMVAL_U16: + case WASM_COMP_PRIMVAL_S32: + case WASM_COMP_PRIMVAL_U32: + case WASM_COMP_PRIMVAL_S64: + case WASM_COMP_PRIMVAL_U64: + case WASM_COMP_PRIMVAL_F32: + case WASM_COMP_PRIMVAL_F64: + case WASM_COMP_PRIMVAL_CHAR: + case WASM_COMP_PRIMVAL_STRING: + case WASM_COMP_PRIMVAL_ERROR_CONTEXT: + return true; + default: + return false; + } +} + +// Core type utility functions +static inline bool is_core_numtype(uint8_t value) { + // numtype ::= 0x7F => i32 | 0x7E => i64 | 0x7D => f32 | 0x7C => f64 + return (value >= WASM_CORE_NUM_TYPE_F64 && value <= WASM_CORE_NUM_TYPE_I32); +} + +static inline bool is_core_vectype(uint8_t value) { + // vectype ::= 0x7B => v128 + return (value == WASM_CORE_VECTOR_TYPE_V128); +} + +static inline bool is_core_reftype(uint8_t value) { + // reftype ::= 0x63 ht:heaptype => (ref ht) | 0x64 ht:heaptype => (ref null ht) + // heaptype ::= ht:absheaptype => ht | x:s33 => x (if x >= 0) + // absheaptype ::= 0x73 => nofunc | 0x72 => noextern | 0x71 => none | 0x70 => func + // | 0x6F => extern | 0x6E => any | 0x6D => eq | 0x6C => i31 + // | 0x6B => struct | 0x6A => array + return (value == 0x63 || value == 0x64) || + (value >= WASM_CORE_ABS_HEAP_TYPE_ARRAY && value <= WASM_CORE_ABS_HEAP_TYPE_NOFUNC); +} + +static inline bool is_core_absheaptype(uint8_t value) { + // absheaptype ::= 0x73 => nofunc | 0x72 => noextern | 0x71 => none | 0x70 => func + // | 0x6F => extern | 0x6E => any | 0x6D => eq | 0x6C => i31 + // | 0x6B => struct | 0x6A => array + return (value >= WASM_CORE_ABS_HEAP_TYPE_ARRAY && value <= WASM_CORE_ABS_HEAP_TYPE_NOFUNC); +} + +static inline bool is_core_packedtype(uint8_t value) { + // packedtype ::= 0x78 => i8 | 0x77 => i16 + return (value == WASM_CORE_PACKED_TYPE_I16 || value == WASM_CORE_PACKED_TYPE_I8); +} + +static inline bool is_core_storagetype(uint8_t value) { + // storagetype ::= t:valtype => t | t:packedtype => t + return is_core_numtype(value) || is_core_vectype(value) || + is_core_reftype(value) || is_core_packedtype(value); +} + +static inline bool is_core_comptype(uint8_t value) { + // comptype ::= 0x5E at:arraytype => array at + // | 0x5F st:structtype => struct st + // | 0x60 ft:functype => func ft + return (value == WASM_CORE_COMPTYPE_ARRAY || + value == WASM_CORE_COMPTYPE_STRUCT || + value == WASM_CORE_COMPTYPE_FUNC); +} + +// Core type parsing constants +#define CORE_TYPE_REC_GROUP_TAG 0x4E +#define CORE_TYPE_SUBTYPE_FINAL_TAG 0x4F +#define CORE_TYPE_SUBTYPE_NONFINAL_TAG 0x50 +#define CORE_TYPE_MODULE_TAG 0x50 +#define CORE_TYPE_REF_TAG 0x63 +#define CORE_TYPE_REF_NULL_TAG 0x64 + +// Core type parsing enums +typedef enum WASMCoreTypeParsingTag { + WASM_CORE_TYPE_REC_GROUP = 0x4E, + WASM_CORE_TYPE_SUBTYPE_FINAL = 0x4F, + WASM_CORE_TYPE_SUBTYPE_NONFINAL = 0x50, + WASM_CORE_TYPE_MODULE = 0x50, + WASM_CORE_TYPE_REF = 0x63, + WASM_CORE_TYPE_REF_NULL = 0x64 +} WASMCoreTypeParsingTag; + +// Core type parsing helper functions +static inline bool is_core_subtype_tag(uint8_t value) { + return value == WASM_CORE_TYPE_SUBTYPE_FINAL || value == WASM_CORE_TYPE_SUBTYPE_NONFINAL; +} + +static inline bool is_core_rectype_tag(uint8_t value) { + return value == WASM_CORE_TYPE_REC_GROUP; +} + +static inline bool is_core_moduletype_tag(uint8_t value) { + return value == WASM_CORE_TYPE_MODULE; +} + +// Core type validation functions +static inline bool is_valid_core_type_index(uint32_t index, uint32_t max_types) { + return index < max_types; +} + +static inline bool is_valid_core_heap_type_index(uint64_t index) { + // s33 validation - check if it's a valid signed 33-bit value + return index <= 0x1FFFFFFFF; // 2^33 - 1 +} + +// Additional utility functions for component model +bool is_defvaltype_tag(uint8_t byte); +WASMComponentTypesTag get_type_tag(uint8_t first_byte); + +// Additional helper functions for core type validation + +// Core type memory management functions +void free_core_resulttype(WASMComponentCoreResultType *resulttype); +void free_core_structtype(WASMComponentCoreStructType *structtype); +void free_core_type(WASMComponentCoreType *type); +void free_core_type_section(WASMComponentCoreTypeSection *section); + +// Additional helper functions for freeing core structures +void free_core_import_desc(WASMComponentCoreImportDesc *import_desc); +void free_core_import(WASMComponentCoreImport *import); +void free_core_export_decl(WASMComponentCoreExportDecl *export_decl); +void free_core_module_decl(WASMComponentCoreModuleDecl *module_decl); +void free_core_moduletype(WASMComponentCoreModuleType *moduletype); +void free_core_deftype(WASMComponentCoreDefType *deftype); +void free_core_functype(WASMComponentCoreFuncType *functype); +void free_core_rectype(WASMComponentCoreRecType *rectype); +void free_core_subtype(WASMComponentCoreSubType *subtype); +void free_core_module_subtype(WASMComponentCoreModuleSubType *module_subtype); +void free_core_comptype(WASMComponentCoreCompType *comptype); + +#endif // WASM_COMPONENT_H diff --git a/core/iwasm/common/component-model/wasm_component_alias_section.c b/core/iwasm/common/component-model/wasm_component_alias_section.c new file mode 100644 index 000000000..706c873d4 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_alias_section.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +bool parse_single_alias(const uint8_t **payload, const uint8_t *end, WASMComponentAliasDefinition *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + out->sort = wasm_runtime_malloc(sizeof(WASMComponentSort)); + if (!out->sort) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for alias sort"); + return false; + } + + // Parse the sort using the reusable parse_sort method + if (!parse_sort(&p, end, out->sort, error_buf, error_buf_size, false)) { + return false; + } + + // Read tag + uint8_t tag = *p++; + + // Parse alias target using switch + switch (tag) { + case WASM_COMP_ALIAS_TARGET_EXPORT: { + uint64_t instance_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &instance_idx, error_buf, error_buf_size)) { + return false; + } + WASMComponentCoreName *name = NULL; + if (!parse_core_name(&p, end, &name, error_buf, error_buf_size)) { + return false; + } + out->alias_target_type = WASM_COMP_ALIAS_TARGET_EXPORT; + out->target.exported.instance_idx = (uint32_t)instance_idx; + out->target.exported.name = name; + break; + } + case WASM_COMP_ALIAS_TARGET_CORE_EXPORT: { + uint64_t core_instance_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_instance_idx, error_buf, error_buf_size)) { + return false; + } + WASMComponentCoreName *core_name = NULL; + if (!parse_core_name(&p, end, &core_name, error_buf, error_buf_size)) { + return false; + } + out->alias_target_type = WASM_COMP_ALIAS_TARGET_CORE_EXPORT; + out->target.core_exported.instance_idx = (uint32_t)core_instance_idx; + out->target.core_exported.name = core_name; + break; + } + case WASM_COMP_ALIAS_TARGET_OUTER: { + uint64_t outer_ct = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &outer_ct, error_buf, error_buf_size)) { + return false; + } + uint64_t outer_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &outer_idx, error_buf, error_buf_size)) { + return false; + } + out->alias_target_type = WASM_COMP_ALIAS_TARGET_OUTER; + out->target.outer.ct = (uint32_t)outer_ct; + out->target.outer.idx = (uint32_t)outer_idx; + + bool valid_outer_sort = + (out->sort->sort == WASM_COMP_SORT_TYPE) + || (out->sort->sort == WASM_COMP_SORT_COMPONENT) + || (out->sort->sort == WASM_COMP_SORT_CORE_SORT + && out->sort->core_sort == WASM_COMP_CORE_SORT_MODULE); + if (!valid_outer_sort) { + set_error_buf_ex(error_buf, error_buf_size, "Outer alias sort must be type, component, or core module"); + return false; + } + break; + } + default: + snprintf(error_buf, error_buf_size, "Unknown alias target type: 0x%02X", tag); + return false; + } + + *payload = p; + return true; +} + +// Section 6: alias section +bool wasm_component_parse_alias_section(const uint8_t **payload, uint32_t payload_len, WASMComponentAliasSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + uint32_t alias_count = 0; + + // Read alias count + uint64_t alias_count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &alias_count_leb, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + alias_count = (uint32_t)alias_count_leb; + + out->count = alias_count; + if (alias_count > 0) { + out->aliases = wasm_runtime_malloc(sizeof(WASMComponentAliasDefinition) * alias_count); + if (!out->aliases) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + // Zero-initialize the aliases array + memset(out->aliases, 0, sizeof(WASMComponentAliasDefinition) * alias_count); + + for (uint32_t i = 0; i < alias_count; ++i) { + // Allocate memory for the sort field + if (!parse_single_alias(&p, end, &out->aliases[i], error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse alias %d", i); + return false; + } + } + } + + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + + // If binaries use alias ids, this parser will need to be extended. + return true; +} + +// Individual section free functions +void wasm_component_free_alias_section(WASMComponentSection *section) { + if (!section || !section->parsed.alias_section) return; + + WASMComponentAliasSection *alias_sec = section->parsed.alias_section; + if (alias_sec->aliases) { + for (uint32_t j = 0; j < alias_sec->count; ++j) { + WASMComponentAliasDefinition *alias = &alias_sec->aliases[j]; + + // Free sort + if (alias->sort) { + wasm_runtime_free(alias->sort); + alias->sort = NULL; + } + + // Free target-specific data + switch (alias->alias_target_type) { + case WASM_COMP_ALIAS_TARGET_EXPORT: + if (alias->target.exported.name) { + free_core_name(alias->target.exported.name); + wasm_runtime_free(alias->target.exported.name); + alias->target.exported.name = NULL; + } + break; + case WASM_COMP_ALIAS_TARGET_CORE_EXPORT: + if (alias->target.core_exported.name) { + free_core_name(alias->target.core_exported.name); + wasm_runtime_free(alias->target.core_exported.name); + alias->target.core_exported.name = NULL; + } + break; + case WASM_COMP_ALIAS_TARGET_OUTER: + // No dynamic allocations for outer aliases + break; + } + } + wasm_runtime_free(alias_sec->aliases); + alias_sec->aliases = NULL; + } + wasm_runtime_free(alias_sec); + section->parsed.alias_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_canons_section.c b/core/iwasm/common/component-model/wasm_component_canons_section.c new file mode 100644 index 000000000..0a86bf3ff --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_canons_section.c @@ -0,0 +1,850 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Local helpers to free nested allocations safely +static void free_canon_opts_struct(WASMComponentCanonOpts *opts) { + if (!opts) return; + if (opts->canon_opts) { + wasm_runtime_free(opts->canon_opts); + opts->canon_opts = NULL; + opts->canon_opts_count = 0; + } + wasm_runtime_free(opts); +} + +static void free_result_list_struct(WASMComponentResultList *rl) { + if (!rl) return; + if (rl->tag == WASM_COMP_RESULT_LIST_WITH_TYPE && rl->results) { + wasm_runtime_free(rl->results); + rl->results = NULL; + } + wasm_runtime_free(rl); +} + +static void free_single_canon_allocs(WASMComponentCanon *canon) { + if (!canon) return; + switch (canon->tag) { + case WASM_COMP_CANON_LIFT: + if (canon->canon_data.lift.canon_opts) { + free_canon_opts_struct(canon->canon_data.lift.canon_opts); + canon->canon_data.lift.canon_opts = NULL; + } + break; + case WASM_COMP_CANON_LOWER: + if (canon->canon_data.lower.canon_opts) { + free_canon_opts_struct(canon->canon_data.lower.canon_opts); + canon->canon_data.lower.canon_opts = NULL; + } + break; + case WASM_COMP_CANON_TASK_RETURN: + if (canon->canon_data.task_return.result_list) { + free_result_list_struct(canon->canon_data.task_return.result_list); + canon->canon_data.task_return.result_list = NULL; + } + if (canon->canon_data.task_return.canon_opts) { + free_canon_opts_struct(canon->canon_data.task_return.canon_opts); + canon->canon_data.task_return.canon_opts = NULL; + } + break; + case WASM_COMP_CANON_STREAM_READ: + case WASM_COMP_CANON_STREAM_WRITE: + if (canon->canon_data.stream_read_write.canon_opts) { + free_canon_opts_struct(canon->canon_data.stream_read_write.canon_opts); + canon->canon_data.stream_read_write.canon_opts = NULL; + } + break; + case WASM_COMP_CANON_FUTURE_READ: + case WASM_COMP_CANON_FUTURE_WRITE: + if (canon->canon_data.future_read_write.canon_opts) { + free_canon_opts_struct(canon->canon_data.future_read_write.canon_opts); + canon->canon_data.future_read_write.canon_opts = NULL; + } + break; + case WASM_COMP_CANON_ERROR_CONTEXT_NEW: + case WASM_COMP_CANON_ERROR_CONTEXT_DEBUG: + if (canon->canon_data.error_context_new_debug.canon_opts) { + free_canon_opts_struct(canon->canon_data.error_context_new_debug.canon_opts); + canon->canon_data.error_context_new_debug.canon_opts = NULL; + } + break; + default: + break; + } +} + +// Parse single canon option +static bool parse_canon_opt(const uint8_t **payload, const uint8_t *end, WASMComponentCanonOpt *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + uint8_t tag = *p++; + out->tag = tag; + switch (tag) { + case WASM_COMP_CANON_OPT_STRING_UTF8: // string-encoding=utf8 - 0x00 + case WASM_COMP_CANON_OPT_STRING_UTF16: // string-encoding=utf16 - 0x01 + case WASM_COMP_CANON_OPT_STRING_LATIN1_UTF16: // string-encoding=latin1+utf16 - 0x02 + break; + case WASM_COMP_CANON_OPT_MEMORY: { // (memory m) - 0x03 + uint64_t core_mem_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_mem_idx, error_buf, error_buf_size)) { + return false; + } + out->payload.memory.mem_idx = (uint32_t)core_mem_idx; + break; + } + case WASM_COMP_CANON_OPT_REALLOC: { // (realloc f) - 0x04 + uint64_t core_func_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_func_idx, error_buf, error_buf_size)) { + return false; + } + out->payload.realloc_opt.func_idx = (uint32_t)core_func_idx; + break; + } + case WASM_COMP_CANON_OPT_POST_RETURN: { // (post-return f) - 0x05 + uint64_t core_func_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_func_idx, error_buf, error_buf_size)) { + return false; + } + out->payload.post_return.func_idx = (uint32_t)core_func_idx; + break; + } + case WASM_COMP_CANON_OPT_ASYNC: { // async - 0x06 + break; + } + case WASM_COMP_CANON_OPT_CALLBACK: { // (callback f) - 0x07 + uint64_t core_func_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_func_idx, error_buf, error_buf_size)) { + return false; + } + out->payload.callback.func_idx = (uint32_t)core_func_idx; + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid canon opt tag: %02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +// Parsing canon options +static bool parse_canon_opts(const uint8_t **payload, const uint8_t *end, WASMComponentCanonOpts **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + *out = wasm_runtime_malloc(sizeof(WASMComponentCanonOpts)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for canon opts"); + return false; + } + + uint64_t canon_opts_count = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &canon_opts_count, error_buf, error_buf_size)) { + free_canon_opts_struct(*out); + *out = NULL; + return false; + } + (*out)->canon_opts_count = (uint32_t)canon_opts_count; + + if (canon_opts_count > 0) { + (*out)->canon_opts = wasm_runtime_malloc(sizeof(WASMComponentCanonOpt) * canon_opts_count); + if (!(*out)->canon_opts) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for canon opts"); + free_canon_opts_struct(*out); + *out = NULL; + return false; + } + + for (uint64_t i = 0; i < canon_opts_count; i++) { + if (!parse_canon_opt(&p, end, &(*out)->canon_opts[i], error_buf, error_buf_size)) { + free_canon_opts_struct(*out); + *out = NULL; + return false; + } + } + } else { + (*out)->canon_opts = NULL; + } + + bool has_string_encoding = false; + uint8_t seen_bits = 0; /* bits 0..4 for tags 0x03..0x07 */ + for (uint32_t i = 0; i < (uint32_t)canon_opts_count; i++) { + uint8_t t = (*out)->canon_opts[i].tag; + if (t == WASM_COMP_CANON_OPT_STRING_UTF8 + || t == WASM_COMP_CANON_OPT_STRING_UTF16 + || t == WASM_COMP_CANON_OPT_STRING_LATIN1_UTF16) { + if (has_string_encoding) { + set_error_buf_ex(error_buf, error_buf_size, "Conflicting or duplicate string-encoding canonopt"); + free_canon_opts_struct(*out); + *out = NULL; + return false; + } + has_string_encoding = true; + } else { + uint8_t bit = (uint8_t)(1u << (t - WASM_COMP_CANON_OPT_MEMORY)); + if (seen_bits & bit) { + set_error_buf_ex(error_buf, error_buf_size, "Duplicate canonopt: 0x%02x", t); + free_canon_opts_struct(*out); + *out = NULL; + return false; + } + seen_bits |= bit; + } + } + + *payload = p; + return true; +} + +// Parsing single canon +static bool parse_single_canon(const uint8_t **payload, const uint8_t *end, WASMComponentCanon *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + uint8_t tag = *p++; + out->tag = tag; + switch (tag) { + case WASM_COMP_CANON_LIFT: { // 0x00 0x00 f: opts: ft: + if (*p != 0x00) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid canon tag: %02x", tag); + return false; + } + p++; + + // Read core:funcidx + uint64_t core_func_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_func_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read core func idx"); + return false; + } + out->canon_data.lift.core_func_idx = (uint32_t)core_func_idx; + + // Read canon opts + if (!parse_canon_opts(&p, end, &out->canon_data.lift.canon_opts, error_buf, error_buf_size)) { + return false; + } + + // Read typeidx + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + // cleanup previously allocated opts + if (out->canon_data.lift.canon_opts) { + free_canon_opts_struct(out->canon_data.lift.canon_opts); + out->canon_data.lift.canon_opts = NULL; + } + return false; + } + out->canon_data.lift.type_idx = (uint32_t)type_idx; + + break; + } + + case WASM_COMP_CANON_LOWER: { // 0x01 0x00 f: opts: + if (*p != 0x00) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid canon tag: %02x", tag); + return false; + } + p++; + // Read funcidx + uint64_t func_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &func_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.lower.func_idx = (uint32_t)func_idx; + + // Read canon opts + if (!parse_canon_opts(&p, end, &out->canon_data.lower.canon_opts, error_buf, error_buf_size)) { + return false; + } + + break; + } + + case WASM_COMP_CANON_RESOURCE_NEW: { // 0x02 rt: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.resource_new.resource_type_idx = (uint32_t)type_idx; + + break; + } + + case WASM_COMP_CANON_RESOURCE_DROP: { // 0x03 rt: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.resource_drop.resource_type_idx = (uint32_t)type_idx; + out->canon_data.resource_drop.async = false; + break; + } + + case WASM_COMP_CANON_RESOURCE_DROP_ASYNC: { //0x07 rt: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.resource_drop.resource_type_idx = (uint32_t)type_idx; + out->canon_data.resource_drop.async = true; + + break; + } + + case WASM_COMP_CANON_RESOURCE_REP: { // 0x04 rt: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.resource_rep.resource_type_idx = (uint32_t)type_idx; + break; + } + + case WASM_COMP_CANON_BACKPRESSURE_SET: { //0x08 + break; + } + + case WASM_COMP_CANON_TASK_RETURN: { // 0x09 rs: opts: + if (!parse_result_list(&p, end, &out->canon_data.task_return.result_list, error_buf, error_buf_size)) { + // Best-effort cleanup if result_list was set + if (out->canon_data.task_return.result_list) { + free_result_list_struct(out->canon_data.task_return.result_list); + out->canon_data.task_return.result_list = NULL; + } + return false; + } + + if (!parse_canon_opts(&p, end, &out->canon_data.task_return.canon_opts, error_buf, error_buf_size)) { + // cleanup result_list allocated above before failing + if (out->canon_data.task_return.result_list) { + free_result_list_struct(out->canon_data.task_return.result_list); + out->canon_data.task_return.result_list = NULL; + } + return false; + } + break; + } + + case WASM_COMP_CANON_TASK_CANCEL: { // 0x05 (no parameters) + break; + } + + case WASM_COMP_CANON_CONTEXT_GET: { // 0x0a 0x7f i: + if (*p != 0x7f) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid canon tag: %02x", tag); + return false; + } + p++; + + uint64_t i = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &i, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read context idx"); + return false; + } + out->canon_data.context_get_set.context_idx = (uint32_t)i; + + break; + } + + case WASM_COMP_CANON_CONTEXT_SET: { // 0x0b 0x7f i: + if (*p != 0x7f) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid canon tag: %02x", tag); + return false; + } + p++; + + uint64_t i = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &i, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read context idx"); + return false; + } + out->canon_data.context_get_set.context_idx = (uint32_t)i; + + break; + } + + case WASM_COMP_CANON_YIELD: { // 0x0c cancel?: + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.yield.cancellable = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.yield.cancellable = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid cancel? tag: %02x", b); + return false; + } + break; + } + + case WASM_COMP_CANON_SUBTASK_CANCEL: { // 0x06 async?: + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.subtask_cancel.async = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.subtask_cancel.async = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid async? tag: %02x", b); + return false; + } + break; + } + + case WASM_COMP_CANON_SUBTASK_DROP: { // 0x0d + break; + } + + case WASM_COMP_CANON_STREAM_NEW: { // 0x0e t: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.stream_new.stream_type_idx = (uint32_t)type_idx; + break; + } + + case WASM_COMP_CANON_STREAM_READ: { // 0x0f t: opts: + // Read stream type idx + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.stream_read_write.stream_type_idx = (uint32_t)type_idx; + + // Read canon opts + if (!parse_canon_opts(&p, end, &out->canon_data.stream_read_write.canon_opts, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_CANON_STREAM_WRITE: { // 0x10 t: opts: + // Read stream type idx + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.stream_read_write.stream_type_idx = (uint32_t)type_idx; + + // Read canon opts + if (!parse_canon_opts(&p, end, &out->canon_data.stream_read_write.canon_opts, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_CANON_STREAM_CANCEL_READ: { // 0x11 t: async?: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.stream_cancel_read_write.stream_type_idx = (uint32_t)type_idx; + + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.stream_cancel_read_write.async = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.stream_cancel_read_write.async = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid async? tag: %02x", b); + return false; + } + + break; + } + + case WASM_COMP_CANON_STREAM_CANCEL_WRITE: { // 0x12 t: async?: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.stream_cancel_read_write.stream_type_idx = (uint32_t)type_idx; + + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.stream_cancel_read_write.async = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.stream_cancel_read_write.async = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid async? tag: %02x", b); + return false; + } + break; + } + + case WASM_COMP_CANON_STREAM_DROP_READABLE: { // 0x13 t: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.stream_drop_readable_writable.stream_type_idx = (uint32_t)type_idx; + + break; + } + + case WASM_COMP_CANON_STREAM_DROP_WRITABLE: { // 0x14 t: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.stream_drop_readable_writable.stream_type_idx = (uint32_t)type_idx; + break; + } + + case WASM_COMP_CANON_FUTURE_NEW: { // 0x15 t: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.future_new.future_type_idx = (uint32_t)type_idx; + break; + } + + case WASM_COMP_CANON_FUTURE_READ: { // 0x16 t: opts: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.future_read_write.future_type_idx = (uint32_t)type_idx; + + if (!parse_canon_opts(&p, end, &out->canon_data.future_read_write.canon_opts, error_buf, error_buf_size)) { + return false; + } + + break; + } + + case WASM_COMP_CANON_FUTURE_WRITE: { // 0x17 t: opts: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.future_read_write.future_type_idx = (uint32_t)type_idx; + + if (!parse_canon_opts(&p, end, &out->canon_data.future_read_write.canon_opts, error_buf, error_buf_size)) { + return false; + } + + break; + } + + case WASM_COMP_CANON_FUTURE_CANCEL_READ: { // 0x18 t: async?: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.future_cancel_read_write.future_type_idx = (uint32_t)type_idx; + + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.future_cancel_read_write.async = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.future_cancel_read_write.async = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid async? tag: %02x", b); + return false; + } + + break; + } + + case WASM_COMP_CANON_FUTURE_CANCEL_WRITE: { // 0x19 t: async?: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.future_cancel_read_write.future_type_idx = (uint32_t)type_idx; + + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.future_cancel_read_write.async = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.future_cancel_read_write.async = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid async? tag: %02x", b); + return false; + } + + break; + } + + case WASM_COMP_CANON_FUTURE_DROP_READABLE: { // 0x1a t: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.future_drop_readable_writable.future_type_idx = (uint32_t)type_idx; + + break; + } + + case WASM_COMP_CANON_FUTURE_DROP_WRITABLE: { // 0x1b t: + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->canon_data.future_drop_readable_writable.future_type_idx = (uint32_t)type_idx; + + break; + } + + case WASM_COMP_CANON_ERROR_CONTEXT_NEW: // 0x1c opts: + case WASM_COMP_CANON_ERROR_CONTEXT_DEBUG: { // 0x1d opts: + if (!parse_canon_opts(&p, end, &out->canon_data.error_context_new_debug.canon_opts, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_CANON_ERROR_CONTEXT_DROP: // 0x1e (no parameters) + case WASM_COMP_CANON_WAITABLE_SET_NEW: { // 0x1f (no parameters) + break; + } + + case WASM_COMP_CANON_WAITABLE_SET_WAIT: { // 0x20 cancel?: m: + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.waitable_set_wait_poll.cancellable = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.waitable_set_wait_poll.cancellable = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid cancel? tag: %02x", b); + return false; + } + + uint64_t core_mem_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_mem_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read core mem idx"); + return false; + } + out->canon_data.waitable_set_wait_poll.mem_idx = (uint32_t)core_mem_idx; + + break; + } + + case WASM_COMP_CANON_WAITABLE_SET_POLL: { //0x21 cancel?: m: + uint8_t b = *p++; + if (b == WASM_COMP_OPTIONAL_TRUE) { + out->canon_data.waitable_set_wait_poll.cancellable = true; + } else if (b == WASM_COMP_OPTIONAL_FALSE) { + out->canon_data.waitable_set_wait_poll.cancellable = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid cancel? tag: %02x", b); + return false; + } + + uint64_t core_mem_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_mem_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read core mem idx"); + return false; + } + out->canon_data.waitable_set_wait_poll.mem_idx = (uint32_t)core_mem_idx; + break; + } + + case WASM_COMP_CANON_WAITABLE_SET_DROP: // 0x22 (no parameters) + case WASM_COMP_CANON_WAITABLE_JOIN: { // 0x23 (no parameters) + break; + } + + case WASM_COMP_CANON_THREAD_SPAWN_REF: { // 0x40 ft: + uint64_t func_type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &func_type_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read func type idx"); + return false; + } + out->canon_data.thread_spawn_ref.func_type_idx = (uint32_t)func_type_idx; + break; + } + + case WASM_COMP_CANON_THREAD_SPAWN_INDIRECT: { //0x41 ft: tbl: + uint64_t func_type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &func_type_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read func type idx"); + return false; + } + out->canon_data.thread_spawn_indirect.func_type_idx = (uint32_t)func_type_idx; + + uint64_t core_table_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_table_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read core table idx"); + return false; + } + out->canon_data.thread_spawn_indirect.table_idx = (uint32_t)core_table_idx; + break; + } + + case WASM_COMP_CANON_THREAD_AVAILABLE_PAR: { // 0x42 (no parameters) + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid canon tag: %02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +// Section 8: canons (canonical function definitions) section +bool wasm_component_parse_canons_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCanonSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + + uint64_t canon_count = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &canon_count, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->count = (uint32_t)canon_count; + + if (canon_count > 0) { + out->canons = wasm_runtime_malloc(sizeof(WASMComponentCanon) * canon_count); + if (!out->canons) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for canons"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize all canons to zero to avoid garbage data + memset(out->canons, 0, sizeof(WASMComponentCanon) * canon_count); + + for (uint32_t i = 0; i < canon_count; ++i) { + // Check bounds before reading tag + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Buffer overflow when reading canon tag"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + if (!parse_single_canon(&p, end, &out->canons[i], error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse canon"); + // Free previously parsed canons to avoid leaks + for (uint32_t j = 0; j < i; ++j) { + free_single_canon_allocs(&out->canons[j]); + } + wasm_runtime_free(out->canons); + out->canons = NULL; + out->count = 0; + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + } + } + + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return true; +} + +// Individual section free functions +void wasm_component_free_canons_section(WASMComponentSection *section) { + if (!section || !section->parsed.canon_section || !section->parsed.canon_section->canons) { + return; + } + + WASMComponentCanonSection *canons_section = section->parsed.canon_section; + + for (uint32_t i = 0; i < canons_section->count; i++) { + WASMComponentCanon *canon = &canons_section->canons[i]; + + // Free canon options for each canon that has them + switch (canon->tag) { + case WASM_COMP_CANON_LIFT: + if (canon->canon_data.lift.canon_opts) { + if (canon->canon_data.lift.canon_opts->canon_opts) { + wasm_runtime_free(canon->canon_data.lift.canon_opts->canon_opts); + } + wasm_runtime_free(canon->canon_data.lift.canon_opts); + } + break; + + case WASM_COMP_CANON_LOWER: + if (canon->canon_data.lower.canon_opts) { + if (canon->canon_data.lower.canon_opts->canon_opts) { + wasm_runtime_free(canon->canon_data.lower.canon_opts->canon_opts); + } + wasm_runtime_free(canon->canon_data.lower.canon_opts); + } + break; + + case WASM_COMP_CANON_TASK_RETURN: + if (canon->canon_data.task_return.result_list) { + if (canon->canon_data.task_return.result_list->results) { + wasm_runtime_free(canon->canon_data.task_return.result_list->results); + } + wasm_runtime_free(canon->canon_data.task_return.result_list); + } + if (canon->canon_data.task_return.canon_opts) { + if (canon->canon_data.task_return.canon_opts->canon_opts) { + wasm_runtime_free(canon->canon_data.task_return.canon_opts->canon_opts); + } + wasm_runtime_free(canon->canon_data.task_return.canon_opts); + } + break; + + case WASM_COMP_CANON_STREAM_READ: + case WASM_COMP_CANON_STREAM_WRITE: + if (canon->canon_data.stream_read_write.canon_opts) { + if (canon->canon_data.stream_read_write.canon_opts->canon_opts) { + wasm_runtime_free(canon->canon_data.stream_read_write.canon_opts->canon_opts); + } + wasm_runtime_free(canon->canon_data.stream_read_write.canon_opts); + } + break; + + case WASM_COMP_CANON_FUTURE_READ: + case WASM_COMP_CANON_FUTURE_WRITE: + if (canon->canon_data.future_read_write.canon_opts) { + if (canon->canon_data.future_read_write.canon_opts->canon_opts) { + wasm_runtime_free(canon->canon_data.future_read_write.canon_opts->canon_opts); + } + wasm_runtime_free(canon->canon_data.future_read_write.canon_opts); + } + break; + + case WASM_COMP_CANON_ERROR_CONTEXT_NEW: + case WASM_COMP_CANON_ERROR_CONTEXT_DEBUG: + if (canon->canon_data.error_context_new_debug.canon_opts) { + if (canon->canon_data.error_context_new_debug.canon_opts->canon_opts) { + wasm_runtime_free(canon->canon_data.error_context_new_debug.canon_opts->canon_opts); + } + wasm_runtime_free(canon->canon_data.error_context_new_debug.canon_opts); + } + break; + + default: + // Other canon types don't have nested allocations + break; + } + } + + // Free the canons array itself + wasm_runtime_free(canons_section->canons); + canons_section->canons = NULL; + canons_section->count = 0; + // Free the section struct and null the pointer for consistency with other sections + wasm_runtime_free(canons_section); + section->parsed.canon_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_component_section.c b/core/iwasm/common/component-model/wasm_component_component_section.c new file mode 100644 index 000000000..caf561d45 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_component_section.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Section 4: component section +bool wasm_component_parse_component_section(const uint8_t **payload, uint32_t payload_len, WASMComponent *out, char *error_buf, uint32_t error_buf_size, LoadArgs *args, unsigned int depth, uint32_t *consumed_len) { + if (consumed_len) *consumed_len = 0; + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + // Check depth limit BEFORE recursive call + if (depth >= MAX_DEPTH_RECURSION) { + set_error_buf_ex(error_buf, error_buf_size, "Max depth of recursion for parsing component reached: %d", depth); + return false; + } + + // Increment depth BEFORE recursive call + unsigned int new_depth = depth + 1; + + // Parse the nested component with incremented depth + bool status = wasm_component_parse_sections(*payload, payload_len, out, args, new_depth); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Could not parse sub component with depth: %d", new_depth); + return false; + } + + if (consumed_len) *consumed_len = payload_len; + return true; +} + +// Individual section free functions +void wasm_component_free_component_section(WASMComponentSection *section) { + if (!section || !section->parsed.component) return; + + // Recursively free nested components + wasm_component_free(section->parsed.component); + wasm_runtime_free(section->parsed.component); + section->parsed.component = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_core_custom_section.c b/core/iwasm/common/component-model/wasm_component_core_custom_section.c new file mode 100644 index 000000000..1f8ad42bd --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_core_custom_section.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "../interpreter/wasm_runtime.h" +#include "wasm_export.h" +#include + +// Section 0: custom section +bool wasm_component_parse_core_custom_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreCustomSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (out) { + // Zero-initialize the output struct + memset(out, 0, sizeof(WASMComponentCoreCustomSection)); + } + if (consumed_len) *consumed_len = 0; + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + uint32_t name_len = 0; + + // Check bounds + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "unexpected end"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Read name length, validate, and copy name + uint64_t name_len_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &name_len_leb, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + name_len = (uint32_t)name_len_leb; + + // Validate name length bounds + if (name_len == 0) { + set_error_buf_ex(error_buf, error_buf_size, "Custom section name cannot be empty"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + if (p + name_len > end) { + set_error_buf_ex(error_buf, error_buf_size, "unexpected end"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // UTF-8 validation (reuse the same logic as load_user_section) + if (!wasm_check_utf8_str(p, name_len)) { + set_error_buf_ex(error_buf, error_buf_size, "invalid UTF-8 encoding"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Allocate and copy the section name + out->name = (char *)wasm_runtime_malloc(name_len + 1); + if (!out->name) { + set_error_buf_ex(error_buf, error_buf_size, "Memory allocation failed for custom section name"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + memcpy(out->name, p, name_len); + out->name[name_len] = '\0'; + p += name_len; + + // Set the data pointer and length + out->data = p; + out->data_len = (uint32_t)(end - p); + + // Calculate consumed length + if (consumed_len) { + *consumed_len = (uint32_t)(p - *payload) + out->data_len; + } + + return true; +} + +// Individual section free functions +void wasm_component_free_core_custom_section(WASMComponentSection *section) { + if (!section || !section->parsed.core_custom) return; + + if (section->parsed.core_custom->name) { + wasm_runtime_free(section->parsed.core_custom->name); + section->parsed.core_custom->name = NULL; + } + wasm_runtime_free(section->parsed.core_custom); + section->parsed.core_custom = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_core_instance_section.c b/core/iwasm/common/component-model/wasm_component_core_instance_section.c new file mode 100644 index 000000000..09bf4130c --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_core_instance_section.c @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + + +// Section 2: core:instance ::= ie: => (instance ie) +// core:instanceexpr ::= 0x00 m: arg*:vec() => (instantiate m arg*) +// core:instantiatearg ::= n: 0x12 i: => (with n (instance i)) +bool wasm_component_parse_core_instance_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreInstSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + + uint64_t instance_count = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &instance_count, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->count = (uint32_t)instance_count; + + if (instance_count > 0) { + out->instances = wasm_runtime_malloc(sizeof(WASMComponentCoreInst) * instance_count); + if (!out->instances) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core instances"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize all instances to zero to avoid garbage data + memset(out->instances, 0, sizeof(WASMComponentCoreInst) * instance_count); + + for (uint32_t i = 0; i < instance_count; ++i) { + // Check bounds before reading tag + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Buffer overflow when reading instance tag"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + uint8_t tag = *p++; + out->instances[i].instance_expression_tag = tag; + switch (tag) { + case WASM_COMP_INSTANCE_EXPRESSION_WITH_ARGS: { + // 0x00 m: arg*:vec() + uint64_t module_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &module_idx, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->instances[i].expression.with_args.idx = (uint32_t)module_idx; + + uint64_t arg_len = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &arg_len, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->instances[i].expression.with_args.arg_len = (uint32_t)arg_len; + + if (arg_len > 0) { + out->instances[i].expression.with_args.args = wasm_runtime_malloc(sizeof(WASMComponentInstArg) * arg_len); + if (!out->instances[i].expression.with_args.args) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core instantiate args"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize args to zero + memset(out->instances[i].expression.with_args.args, 0, sizeof(WASMComponentInstArg) * arg_len); + + for (uint32_t j = 0; j < arg_len; ++j) { + // core:instantiatearg ::= n: 0x12 i: + // Parse core:name (LEB128 length + UTF-8 bytes) + + // Check bounds before parsing name + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Buffer overflow when parsing core name"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + WASMComponentCoreName *core_name = NULL; + if (!parse_core_name(&p, end, &core_name, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Store the name in the instantiate arg structure + out->instances[i].expression.with_args.args[j].name = core_name; + + // Check bounds before reading 0x12 + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Buffer overflow when reading 0x12 flag"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Verify 0x12 for core:instantiatearg + if(*p++ != 0x12){ + set_error_buf_ex(error_buf, error_buf_size, "Failed to read 0x12 flag identifier for core instantiatearg field"); + free_core_name(core_name); + wasm_runtime_free(core_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // i: - this is a core instance index + uint64_t instance_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &instance_idx, error_buf, error_buf_size)) { + free_core_name(core_name); + wasm_runtime_free(core_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->instances[i].expression.with_args.args[j].idx.instance_idx = (uint32_t)instance_idx; + } + } else { + out->instances[i].expression.with_args.args = NULL; + } + break; + } + case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: { + // 0x01 e*:vec() => e* + uint64_t inline_expr_len = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &inline_expr_len, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + out->instances[i].expression.without_args.inline_expr_len = (uint32_t)inline_expr_len; + + if (inline_expr_len > 0) { + out->instances[i].expression.without_args.inline_expr = wasm_runtime_malloc(sizeof(WASMComponentInlineExport) * inline_expr_len); + if (!out->instances[i].expression.without_args.inline_expr) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core inline exports"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize inline exports to zero + memset(out->instances[i].expression.without_args.inline_expr, 0, sizeof(WASMComponentInlineExport) * inline_expr_len); + + for (uint32_t j = 0; j < inline_expr_len; j++) { + // core:inlineexport ::= n: si: + WASMComponentCoreName *name = NULL; + + // Debug: Check if we're about to go out of bounds + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Buffer overflow in inline exports parsing"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Parse core:name using the existing parse_core_name function + bool name_parse_success = parse_core_name(&p, end, &name, error_buf, error_buf_size); + if (!name_parse_success) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + out->instances[i].expression.without_args.inline_expr[j].name = name; + + // Check bounds before parsing sort index + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Buffer overflow when parsing core sort idx"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Parse core:sortidx (must use is_core=true for core instances) + WASMComponentSortIdx *sort_idx = wasm_runtime_malloc(sizeof(WASMComponentSortIdx)); + if (!sort_idx) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core sort idx"); + free_core_name(name); + wasm_runtime_free(name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + // Zero-initialize sort_idx + memset(sort_idx, 0, sizeof(WASMComponentSortIdx)); + + bool status = parse_sort_idx(&p, end, sort_idx, error_buf, error_buf_size, true); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse core sort idx"); + wasm_runtime_free(sort_idx); + free_core_name(name); + wasm_runtime_free(name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + out->instances[i].expression.without_args.inline_expr[j].sort_idx = sort_idx; + } + } else { + out->instances[i].expression.without_args.inline_expr = NULL; + } + + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Unknown core instance expression tag: 0x%02X", tag); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + } + } + } + if (consumed_len) *consumed_len = payload_len; + return true; +} + +// Individual section free functions +void wasm_component_free_core_instance_section(WASMComponentSection *section) { + if (!section || !section->parsed.core_instance_section) return; + + WASMComponentCoreInstSection *core_instance_sec = section->parsed.core_instance_section; + if (core_instance_sec->instances) { + for (uint32_t j = 0; j < core_instance_sec->count; ++j) { + WASMComponentCoreInst *instance = &core_instance_sec->instances[j]; + + switch (instance->instance_expression_tag) { + case WASM_COMP_INSTANCE_EXPRESSION_WITH_ARGS: + if (instance->expression.with_args.args) { + for (uint32_t k = 0; k < instance->expression.with_args.arg_len; ++k) { + WASMComponentInstArg *arg = &instance->expression.with_args.args[k]; + + // Free core name + if (arg->name) { + free_core_name(arg->name); + wasm_runtime_free(arg->name); + arg->name = NULL; + } + } + wasm_runtime_free(instance->expression.with_args.args); + instance->expression.with_args.args = NULL; + } + break; + + case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: + if (instance->expression.without_args.inline_expr) { + for (uint32_t k = 0; k < instance->expression.without_args.inline_expr_len; ++k) { + WASMComponentInlineExport *inline_export = &instance->expression.without_args.inline_expr[k]; + + // Free core export name + if (inline_export->name) { + free_core_name(inline_export->name); + wasm_runtime_free(inline_export->name); + inline_export->name = NULL; + } + + // Free core sort index + if (inline_export->sort_idx) { + if (inline_export->sort_idx->sort) { + wasm_runtime_free(inline_export->sort_idx->sort); + inline_export->sort_idx->sort = NULL; + } + wasm_runtime_free(inline_export->sort_idx); + inline_export->sort_idx = NULL; + } + } + wasm_runtime_free(instance->expression.without_args.inline_expr); + instance->expression.without_args.inline_expr = NULL; + } + break; + } + } + wasm_runtime_free(core_instance_sec->instances); + core_instance_sec->instances = NULL; + } + wasm_runtime_free(core_instance_sec); + section->parsed.core_instance_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_core_module_section.c b/core/iwasm/common/component-model/wasm_component_core_module_section.c new file mode 100644 index 000000000..df12e9774 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_core_module_section.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Section 1: module section +bool wasm_component_parse_core_module_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreModuleWrapper *out, LoadArgs *args, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (consumed_len) *consumed_len = 0; + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + LOG_DEBUG(" Module section: embedded Core WebAssembly module\n"); + + // Use the core wasm loader to parse the module + wasm_module_t mod = wasm_runtime_load_ex((uint8 *)*payload, payload_len, args, error_buf, error_buf_size); + if (!mod) { + LOG_DEBUG(" Failed to load embedded core wasm module: %s\n", error_buf); + return false; + } + + // Print some basic info about the embedded module + LOG_DEBUG(" Types: %u function types\n", wasm_runtime_get_import_count(mod)); + LOG_DEBUG(" Exports: %u exports\n", wasm_runtime_get_export_count(mod)); +#if WASM_ENABLE_INTERP != 0 + LOG_DEBUG(" Functions: %u functions\n", wasm_runtime_get_function_count(mod)); + LOG_DEBUG(" Tables: %u tables\n", wasm_runtime_get_table_count(mod)); + LOG_DEBUG(" Memories: %u memories\n", wasm_runtime_get_memories_count(mod)); + LOG_DEBUG(" Globals: %u globals\n", wasm_runtime_get_globals_count(mod)); +#endif + + // Check if the module has imports + int32_t import_count = wasm_runtime_get_import_count(mod); + if (import_count > 0) { + LOG_DEBUG(" Imports: %u imports\n", import_count); + for (int32_t i = 0; i < import_count; i++) { + wasm_import_t import; + wasm_runtime_get_import_type(mod, i, &import); + LOG_DEBUG(" Import %u: module=\"%s\", name=\"%s\", kind=%u\n", + i, + import.module_name ? import.module_name : "", + import.name ? import.name : "", + import.kind); + + // Print more details about the import + if (import.module_name && strlen(import.module_name) == 0) { + LOG_DEBUG(" WARNING: Empty module name - this will cause 'unknown import' error\n"); + } + if (import.name && strlen(import.name) == 0) { + LOG_DEBUG(" WARNING: Empty field name - this will cause 'unknown import' error\n"); + } + } + } + + // Check if the module has exports + int32_t export_count = wasm_runtime_get_export_count(mod); + if (export_count > 0) { + LOG_DEBUG(" Exports: %u exports\n", export_count); + for (int32_t i = 0; i < export_count; i++) { + wasm_export_t export; + wasm_runtime_get_export_type(mod, i, &export); + LOG_DEBUG(" Export %u: name=\"%s\", kind= %u\n", + i, + export.name ? export.name : "", + export.kind); + + // Print more details about the export + if (export.name && strlen(export.name) == 0) { + LOG_DEBUG(" WARNING: Empty field name - this will cause 'unknown export' error\n"); + } + } + } + + // Store the module pointer directly instead of copying + out->module_handle = (void*)mod; + out->module = NULL; // We don't need the actual module structure for now + if (consumed_len) *consumed_len = payload_len; + return true; +} + +// Individual section free functions +void wasm_component_free_core_module_section(WASMComponentSection *section) { + if (!section || !section->parsed.core_module) return; + + // Use the proper wasm_runtime_unload function to free the module + if (section->parsed.core_module->module_handle) { + wasm_runtime_unload((wasm_module_t)section->parsed.core_module->module_handle); + section->parsed.core_module->module_handle = NULL; + } + wasm_runtime_free(section->parsed.core_module); + section->parsed.core_module = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_core_type_section.c b/core/iwasm/common/component-model/wasm_component_core_type_section.c new file mode 100644 index 000000000..83faeb1d4 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_core_type_section.c @@ -0,0 +1,822 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +bool parse_core_limits(const uint8_t **payload, const uint8_t *end, WASMComponentCoreLimits *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + uint8_t tag = *p++; + + switch (tag) { + case WASM_CORE_LIMITS_MIN: { + uint64_t min = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &min, error_buf, error_buf_size)) { + return false; + } + + out->tag = WASM_CORE_LIMITS_MIN; + out->lim.limits.min = (uint32_t)min; + break; + } + case WASM_CORE_LIMITS_MAX: { + uint64_t min = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &min, error_buf, error_buf_size)) { + return false; + } + + uint64_t max = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &max, error_buf, error_buf_size)) { + return false; + } + + out->tag = WASM_CORE_LIMITS_MAX; + out->lim.limits_max.min = (uint32_t)min; + out->lim.limits_max.max = (uint32_t)max; + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid limits tag: %02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +static bool parse_core_heaptype(const uint8_t **payload, const uint8_t *end, WASMComponentCoreHeapType *out, char *error_buf, uint32_t error_buf_size) +{ + const uint8_t *p = *payload; + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end while parsing heaptype"); + return false; + } + + uint8_t first = *p; + // absheaptype short-form: 0x6A..0x73 + if (is_core_absheaptype(first)) { + out->tag = WASM_CORE_HEAP_TYPE_ABSTRACT; + out->heap_type.abstract_type = (WASMCoreAbsHeapTypeTag)first; + p++; + *payload = p; + return true; + } + + // Otherwise, parse as (positive) s33 index; we store as u32 + uint64_t idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &idx, error_buf, error_buf_size)) { + return false; + } + if (!is_valid_core_heap_type_index(idx)) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid heaptype index: %llu", (unsigned long long)idx); + return false; + } + + out->tag = WASM_CORE_HEAP_TYPE_CONCRETE; + out->heap_type.concrete_index = (uint32_t)idx; + *payload = p; + return true; +} + +bool parse_core_valtype(const uint8_t **payload, const uint8_t *end, WASMComponentCoreValType *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + uint8_t tag = *p++; + + // numtype ::= 0x7F (i32) | 0x7E (i64) | 0x7D (f32) | 0x7C (f64) + if (tag >= WASM_CORE_NUM_TYPE_F64 && tag <= WASM_CORE_NUM_TYPE_I32) { + out->tag = WASM_CORE_VALTYPE_NUM; + out->type.num_type = (WASMCoreNumTypeTag)tag; + *payload = p; + return true; + } + + // vectype ::= 0x7B (v128) + if (tag == WASM_CORE_VECTOR_TYPE_V128) { + out->tag = WASM_CORE_VALTYPE_VECTOR; + out->type.vector_type = WASM_CORE_VECTOR_TYPE_V128; + *payload = p; + return true; + } + + // reftype encodings (Preview 1 + GC): + // - 0x63 ht:heaptype => (ref null ht) + // - 0x64 ht:heaptype => (ref ht) + // - ht:absheaptype (0x6A..0x73) => short-form (ref null ht) + if (tag == 0x63 || tag == 0x64) { + WASMComponentCoreHeapType heap_type; + if (!parse_core_heaptype(&p, end, &heap_type, error_buf, error_buf_size)) { + return false; + } + if (heap_type.tag == WASM_CORE_HEAP_TYPE_ABSTRACT) { + if (heap_type.heap_type.abstract_type == WASM_CORE_ABS_HEAP_TYPE_FUNC) { + out->tag = WASM_CORE_VALTYPE_REF; + out->type.ref_type = WASM_CORE_REFTYPE_FUNC_REF; + *payload = p; + return true; + } + if (heap_type.heap_type.abstract_type == WASM_CORE_ABS_HEAP_TYPE_EXTERN) { + out->tag = WASM_CORE_VALTYPE_REF; + out->type.ref_type = WASM_CORE_REFTYPE_EXTERN_REF; + *payload = p; + return true; + } + } + set_error_buf_ex(error_buf, error_buf_size, "Unsupported reftype heaptype for core valtype"); + return false; + } + + // Short-form absheaptype for (ref null ht) + if (tag >= WASM_CORE_ABS_HEAP_TYPE_ARRAY && tag <= WASM_CORE_ABS_HEAP_TYPE_NOFUNC) { + if (tag == WASM_CORE_ABS_HEAP_TYPE_FUNC) { + out->tag = WASM_CORE_VALTYPE_REF; + out->type.ref_type = WASM_CORE_REFTYPE_FUNC_REF; + *payload = p; + return true; + } + if (tag == WASM_CORE_ABS_HEAP_TYPE_EXTERN) { + out->tag = WASM_CORE_VALTYPE_REF; + out->type.ref_type = WASM_CORE_REFTYPE_EXTERN_REF; + *payload = p; + return true; + } + set_error_buf_ex(error_buf, error_buf_size, "Unsupported short-form absheaptype %02x for core valtype", tag); + return false; + } + + set_error_buf_ex(error_buf, error_buf_size, "Invalid core valtype tag: %02x", tag); + return false; +} + +bool parse_core_import_desc(const uint8_t **payload, const uint8_t *end, WASMComponentCoreImportDesc *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + uint8_t tag = *p++; + + switch (tag) { + case WASM_CORE_IMPORTDESC_FUNC: { + uint64_t func_type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &func_type_idx, error_buf, error_buf_size)) { + return false; + } + + out->type = WASM_CORE_IMPORTDESC_FUNC; + out->desc.func_type_idx = (uint32_t)func_type_idx; + break; + } + + case WASM_CORE_IMPORTDESC_TABLE: { + uint8_t ref_type_tag = *p++; + if (ref_type_tag == WASM_CORE_REFTYPE_FUNC_REF) { + out->type = WASM_CORE_IMPORTDESC_TABLE; + out->desc.table_type.ref_type = WASM_CORE_REFTYPE_FUNC_REF; + } else if (ref_type_tag == WASM_CORE_REFTYPE_EXTERN_REF) { + out->type = WASM_CORE_IMPORTDESC_TABLE; + out->desc.table_type.ref_type = WASM_CORE_REFTYPE_EXTERN_REF; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid reference type tag: %02x", ref_type_tag); + return false; + } + + WASMComponentCoreLimits *limits = wasm_runtime_malloc(sizeof(WASMComponentCoreLimits)); + if (!limits) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating table limits"); + return false; + } + if (!parse_core_limits(&p, end, limits, error_buf, error_buf_size)) { + wasm_runtime_free(limits); + return false; + } + + out->type = WASM_CORE_IMPORTDESC_TABLE; + out->desc.table_type.limits = limits; + break; + } + + case WASM_CORE_IMPORTDESC_MEMORY: { + WASMComponentCoreLimits *limits = wasm_runtime_malloc(sizeof(WASMComponentCoreLimits)); + if (!limits) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating memory limits"); + return false; + } + if (!parse_core_limits(&p, end, limits, error_buf, error_buf_size)) { + wasm_runtime_free(limits); + return false; + } + + out->type = WASM_CORE_IMPORTDESC_MEMORY; + out->desc.memory_type.limits = limits; + break; + } + + case WASM_CORE_IMPORTDESC_GLOBAL: { + if (!parse_core_valtype(&p, end, &out->desc.global_type.val_type, error_buf, error_buf_size)) { + return false; + } + + // mut ::= 0x00 => const, 0x01 => var (spec) + uint8_t mutable_tag = *p++; + if (mutable_tag == WASM_CORE_GLOBAL_MUTABLE) { + out->desc.global_type.is_mutable = true; + } else if (mutable_tag == WASM_CORE_GLOBAL_IMMUTABLE) { + out->desc.global_type.is_mutable = false; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid mutable tag: %02x", mutable_tag); + return false; + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid import descriptor tag: %02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +bool parse_core_import(const uint8_t **payload, const uint8_t *end, WASMComponentCoreImport *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + WASMComponentCoreName *mod_name = NULL; + if (!parse_core_name(&p, end, &mod_name, error_buf, error_buf_size)) { + return false; + } + + out->mod_name = mod_name; + + WASMComponentCoreName *nm_name = NULL; + if (!parse_core_name(&p, end, &nm_name, error_buf, error_buf_size)) { + return false; + } + + out->nm = nm_name; + + WASMComponentCoreImportDesc *import_desc = wasm_runtime_malloc(sizeof(WASMComponentCoreImportDesc)); + if (!import_desc) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating import desc"); + return false; + } + if (!parse_core_import_desc(&p, end, import_desc, error_buf, error_buf_size)) { + wasm_runtime_free(import_desc); + return false; + } + + out->import_desc = import_desc; + + *payload = p; + return true; +} + +bool parse_alias_target(const uint8_t **payload, const uint8_t *end, WASMComponentCoreAliasTarget *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + uint8_t tag = *p++; + + if (tag == 0x01) { + uint64_t ct_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &ct_leb, error_buf, error_buf_size)) { + return false; + } + + out->ct = (uint32_t)ct_leb; + + uint64_t index_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &index_leb, error_buf, error_buf_size)) { + return false; + } + + out->index = (uint32_t)index_leb; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Invalid alias target tag: %02x", tag); + return false; + } + + *payload = p; + return true; +} + +bool parse_core_alias(const uint8_t **payload, const uint8_t *end, WASMComponentCoreAlias *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + /* no leading tag here; core:alias is parsed inside moduledecl */ + + if (!parse_sort(&p, end, &out->sort, error_buf, error_buf_size, true)) { + return false; + } + + if (!parse_alias_target(&p, end, &out->alias_target, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse alias target"); + return false; + } + + *payload = p; + return true; +} + +bool parse_core_export_decl(const uint8_t **payload, const uint8_t *end, WASMComponentCoreExportDecl *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + /* core:exportdecl ::= nm: d: */ + WASMComponentCoreName *mod_name = NULL; + if (!parse_core_name(&p, end, &mod_name, error_buf, error_buf_size)) { + return false; + } + out->name = mod_name; + + WASMComponentCoreImportDesc *export_desc = wasm_runtime_malloc(sizeof(WASMComponentCoreImportDesc)); + if (!export_desc) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating export desc"); + return false; + } + if (!parse_core_import_desc(&p, end, export_desc, error_buf, error_buf_size)) { + wasm_runtime_free(export_desc); + return false; + } + + out->export_desc = export_desc; + + *payload = p; + return true; +} + +bool parse_core_module_decl(const uint8_t **payload, const uint8_t *end, WASMComponentCoreModuleDecl *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + uint8_t tag = *p++; + out->tag = tag; + switch (tag) { + case WASM_CORE_MODULEDECL_IMPORT: { + out->decl.import_decl.import = wasm_runtime_malloc(sizeof(WASMComponentCoreImport)); + if (!out->decl.import_decl.import) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating module import decl"); + return false; + } + if (!parse_core_import(&p, end, out->decl.import_decl.import, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_CORE_MODULEDECL_TYPE: { + out->decl.type_decl.type = wasm_runtime_malloc(sizeof(WASMComponentCoreType)); + if (!out->decl.type_decl.type) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating module type decl"); + return false; + } + out->decl.type_decl.type->deftype = wasm_runtime_malloc(sizeof(WASMComponentCoreDefType)); + if (!out->decl.type_decl.type->deftype) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating core deftype"); + return false; + } + if (!parse_single_core_type(&p, end, out->decl.type_decl.type->deftype, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse type declaration"); + return false; + } + break; + } + + case WASM_CORE_MODULEDECL_ALIAS: { + out->decl.alias_decl.alias = wasm_runtime_malloc(sizeof(WASMComponentCoreAlias)); + if (!out->decl.alias_decl.alias) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating module alias decl"); + return false; + } + if (!parse_core_alias(&p, end, out->decl.alias_decl.alias, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse alias declaration"); + return false; + } + break; + } + + case WASM_CORE_MODULEDECL_EXPORT: { + out->decl.export_decl.export_decl = wasm_runtime_malloc(sizeof(WASMComponentCoreExportDecl)); + if (!out->decl.export_decl.export_decl) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating module export decl"); + return false; + } + if (!parse_core_export_decl(&p, end, out->decl.export_decl.export_decl, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse export declaration"); + return false; + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid module declaration tag: %02x", tag); + return false; + } + } + *payload = p; + return true; +} + +bool parse_core_moduletype(const uint8_t **payload, const uint8_t *end, WASMComponentCoreModuleType *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + // Expect vec(moduledecl): count then that many moduledecl + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + return false; + } + + uint32_t count = (uint32_t)count_leb; + out->decl_count = count; + + if (count > 0) { + out->declarations = wasm_runtime_malloc(sizeof(WASMComponentCoreModuleDecl) * count); + if (!out->declarations) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for declarations"); + return false; + } + // Zero-initialize declarations array + memset(out->declarations, 0, sizeof(WASMComponentCoreModuleDecl) * count); + + for (uint32_t i = 0; i < count; i++) { + if (!parse_core_module_decl(&p, end, &out->declarations[i], error_buf, error_buf_size)) { + return false; + } + } + } + + *payload = p; + return true; +} + +bool parse_single_core_type(const uint8_t **payload, const uint8_t *end, WASMComponentCoreDefType *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end while parsing core:deftype"); + return false; + } + + uint8_t b0 = *p; // peek only + + // 1) moduletype ::= 0x50 md*:vec(moduledecl) + if (b0 == 0x50) { + p++; // consume 0x50 + out->tag = WASM_CORE_DEFTYPE_MODULETYPE; + out->type.moduletype = wasm_runtime_malloc(sizeof(WASMComponentCoreModuleType)); + if (!out->type.moduletype) { + set_error_buf_ex(error_buf, error_buf_size, "OOM allocating core moduletype"); + return false; + } + if (!parse_core_moduletype(&p, end, out->type.moduletype, error_buf, error_buf_size)) { + return false; + } + *payload = p; + return true; + } + + // 2) rectype (GC): 0x4E ... + if (b0 == 0x4E) { + set_error_buf_ex(error_buf, error_buf_size, "WebAssembly 3.0 core:rectype (0x4E ...) not supported"); + return false; + } + + // 3) subtype (GC): 0x00 followed by {0x50,0x4F,0x5E,0x5F,0x60} + if (b0 == 0x00) { + if (p + 1 >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end of data after 0x00"); + return false; + } + uint8_t b1 = *(p + 1); + if (b1 == 0x50 || b1 == 0x4F || b1 == 0x5E || b1 == 0x5F || b1 == 0x60) { + set_error_buf_ex(error_buf, error_buf_size, "WebAssembly 3.0 core:subtype (0x00 0x%02x ...) not supported", b1); + return false; + } + } + + + + // Otherwise invalid in this context + set_error_buf_ex(error_buf, error_buf_size, "Invalid core:deftype tag: %02x", b0); + return false; +} + +// Section 3: type section (component model type section, not the core wasm type section) +bool wasm_component_parse_core_type_section(const uint8_t **payload, uint32_t payload_len, WASMComponentCoreTypeSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || payload_len == 0) { + return false; + } + if (consumed_len) *consumed_len = 0; + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + return false; + } + + uint32_t count = (uint32_t)count_leb; + out->count = count; + + if (count > 0) { + out->types = wasm_runtime_malloc(sizeof(WASMComponentCoreType) * count); + if (!out->types) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for types"); + return false; + } + + memset(out->types, 0, sizeof(WASMComponentCoreType) * count); + for (uint32_t i = 0; i < count; i++) { + WASMComponentCoreDefType *dt = wasm_runtime_malloc(sizeof(WASMComponentCoreDefType)); + if (!dt) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core deftype"); + return false; + } + memset(dt, 0, sizeof(WASMComponentCoreDefType)); + if (!parse_single_core_type(&p, end, dt, error_buf, error_buf_size)) { + wasm_runtime_free(dt); + return false; + } + out->types[i].deftype = dt; + } + } + + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return true; +} + +// Individual section free functions +void wasm_component_free_core_type_section(WASMComponentSection *section) { + if (!section || !section->parsed.core_type_section) { + return; + } + + WASMComponentCoreTypeSection *core_type_section = section->parsed.core_type_section; + + if (core_type_section->types) { + for (uint32_t i = 0; i < core_type_section->count; i++) { + if (core_type_section->types[i].deftype) { + free_core_deftype(core_type_section->types[i].deftype); + wasm_runtime_free(core_type_section->types[i].deftype); + } + } + wasm_runtime_free(core_type_section->types); + } + + wasm_runtime_free(core_type_section); + section->parsed.core_type_section = NULL; +} + +// Helper functions for freeing core structures +void free_core_import_desc(WASMComponentCoreImportDesc *import_desc) { + if (!import_desc) { + return; + } + + switch (import_desc->type) { + case WASM_CORE_IMPORTDESC_FUNC: + break; + case WASM_CORE_IMPORTDESC_TABLE: + if (import_desc->desc.table_type.limits) { + wasm_runtime_free(import_desc->desc.table_type.limits); + import_desc->desc.table_type.limits = NULL; + } + break; + case WASM_CORE_IMPORTDESC_MEMORY: + if (import_desc->desc.memory_type.limits) { + wasm_runtime_free(import_desc->desc.memory_type.limits); + import_desc->desc.memory_type.limits = NULL; + } + break; + case WASM_CORE_IMPORTDESC_GLOBAL: + // These are simple structures, no additional memory to free + break; + } +} + +void free_core_import(WASMComponentCoreImport *import) { + if (!import) { + return; + } + + if (import->mod_name) { + free_core_name(import->mod_name); + wasm_runtime_free(import->mod_name); + } + + if (import->nm) { + free_core_name(import->nm); + wasm_runtime_free(import->nm); + } + + if (import->import_desc) { + free_core_import_desc(import->import_desc); + wasm_runtime_free(import->import_desc); + } +} + +void free_core_export_decl(WASMComponentCoreExportDecl *export_decl) { + if (!export_decl) { + return; + } + + if (export_decl->name) { + free_core_name(export_decl->name); + wasm_runtime_free(export_decl->name); + } + + if (export_decl->export_desc) { + free_core_import_desc(export_decl->export_desc); + wasm_runtime_free(export_decl->export_desc); + } +} + +void free_core_module_decl(WASMComponentCoreModuleDecl *module_decl) { + if (!module_decl) { + return; + } + + switch (module_decl->tag) { + case WASM_CORE_MODULEDECL_IMPORT: + if (module_decl->decl.import_decl.import) { + free_core_import(module_decl->decl.import_decl.import); + wasm_runtime_free(module_decl->decl.import_decl.import); + } + break; + case WASM_CORE_MODULEDECL_TYPE: + if (module_decl->decl.type_decl.type) { + free_core_type(module_decl->decl.type_decl.type); + wasm_runtime_free(module_decl->decl.type_decl.type); + } + break; + case WASM_CORE_MODULEDECL_ALIAS: + if (module_decl->decl.alias_decl.alias) { + wasm_runtime_free(module_decl->decl.alias_decl.alias); + } + break; + case WASM_CORE_MODULEDECL_EXPORT: + if (module_decl->decl.export_decl.export_decl) { + free_core_export_decl(module_decl->decl.export_decl.export_decl); + wasm_runtime_free(module_decl->decl.export_decl.export_decl); + } + break; + } +} + +void free_core_moduletype(WASMComponentCoreModuleType *moduletype) { + if (!moduletype) { + return; + } + + if (moduletype->declarations) { + for (uint32_t i = 0; i < moduletype->decl_count; i++) { + free_core_module_decl(&moduletype->declarations[i]); + } + wasm_runtime_free(moduletype->declarations); + } +} + +void free_core_deftype(WASMComponentCoreDefType *deftype) { + if (!deftype) { + return; + } + + switch (deftype->tag) { + case WASM_CORE_DEFTYPE_RECTYPE: + if (deftype->type.rectype) { + free_core_rectype(deftype->type.rectype); + wasm_runtime_free(deftype->type.rectype); + } + break; + case WASM_CORE_DEFTYPE_SUBTYPE: + if (deftype->type.subtype) { + free_core_module_subtype(deftype->type.subtype); + wasm_runtime_free(deftype->type.subtype); + } + break; + case WASM_CORE_DEFTYPE_MODULETYPE: + if (deftype->type.moduletype) { + free_core_moduletype(deftype->type.moduletype); + wasm_runtime_free(deftype->type.moduletype); + } + break; + } +} + +void free_core_type(WASMComponentCoreType *type) { + if (!type) { + return; + } + + if (type->deftype) { + free_core_deftype(type->deftype); + wasm_runtime_free(type->deftype); + } +} + +void free_core_type_section(WASMComponentCoreTypeSection *section) { + if (!section) { + return; + } + + if (section->types) { + for (uint32_t i = 0; i < section->count; i++) { + free_core_type(§ion->types[i]); + } + wasm_runtime_free(section->types); + } +} + +// Additional helper functions for freeing core structures +void free_core_functype(WASMComponentCoreFuncType *functype) { + if (!functype) { + return; + } + + if (functype->params.val_types) { + wasm_runtime_free(functype->params.val_types); + } + + if (functype->results.val_types) { + wasm_runtime_free(functype->results.val_types); + } +} + +void free_core_rectype(WASMComponentCoreRecType *rectype) { + if (!rectype) { + return; + } + + if (rectype->subtypes) { + for (uint32_t i = 0; i < rectype->subtype_count; i++) { + free_core_subtype(&rectype->subtypes[i]); + } + wasm_runtime_free(rectype->subtypes); + } +} + +void free_core_resulttype(WASMComponentCoreResultType *resulttype) { + if (!resulttype) { + return; + } + + if (resulttype->val_types) { + wasm_runtime_free(resulttype->val_types); + } +} + +void free_core_structtype(WASMComponentCoreStructType *structtype) { + if (!structtype) { + return; + } + + if (structtype->fields) { + wasm_runtime_free(structtype->fields); + } +} + +void free_core_comptype(WASMComponentCoreCompType *comptype) { + if (!comptype) { + return; + } + + switch (comptype->tag) { + case WASM_CORE_COMPTYPE_FUNC: + free_core_functype(&comptype->type.func_type); + break; + case WASM_CORE_COMPTYPE_STRUCT: + if (comptype->type.struct_type.fields) { + wasm_runtime_free(comptype->type.struct_type.fields); + } + break; + case WASM_CORE_COMPTYPE_ARRAY: + // Array type is simple, no additional memory to free + break; + } +} + +void free_core_subtype(WASMComponentCoreSubType *subtype) { + if (!subtype) { + return; + } + + if (subtype->supertypes) { + wasm_runtime_free(subtype->supertypes); + } + + // Free the comptype + free_core_comptype(&subtype->comptype); +} + +void free_core_module_subtype(WASMComponentCoreModuleSubType *module_subtype) { + if (!module_subtype) { + return; + } + + if (module_subtype->supertypes) { + wasm_runtime_free(module_subtype->supertypes); + } + + if (module_subtype->comptype) { + free_core_comptype(module_subtype->comptype); + wasm_runtime_free(module_subtype->comptype); + } +} diff --git a/core/iwasm/common/component-model/wasm_component_export.c b/core/iwasm/common/component-model/wasm_component_export.c new file mode 100644 index 000000000..ad01b0501 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_export.c @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component_export.h" +#include "wasm_component.h" + +static bool is_component = false; + +bool is_component_runtime() { + return is_component; +} + +void set_component_runtime(bool type) { + is_component = type; +} diff --git a/core/iwasm/common/component-model/wasm_component_export.h b/core/iwasm/common/component-model/wasm_component_export.h new file mode 100644 index 000000000..e43a62848 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_export.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef WASM_COMPONENT_EXPORT_H +#define WASM_COMPONENT_EXPORT_H + +#include "stdbool.h" + +bool is_component_runtime(); +void set_component_runtime(bool type); + +#endif diff --git a/core/iwasm/common/component-model/wasm_component_exports_section.c b/core/iwasm/common/component-model/wasm_component_exports_section.c new file mode 100644 index 000000000..a5c7bbff9 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_exports_section.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Section 11: exports section +bool wasm_component_parse_exports_section(const uint8_t **payload, uint32_t payload_len,WASMComponentExportSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len){ + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end of buffer when reading exports count"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + uint64_t export_count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &export_count_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read exports count"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + uint32_t export_count = (uint32_t)export_count_leb; + out->count = export_count; + + if (export_count > 0) { + out->exports = wasm_runtime_malloc(sizeof(WASMComponentExport) * export_count); + if (!out->exports) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for exports"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + // Ensure all fields (including optional extern_desc) are initialized to NULL/0 + memset(out->exports, 0, sizeof(WASMComponentExport) * export_count); + + // Parsing every export + for (uint32_t i = 0; i < export_count; i++) { + // Parsing 'exportname' + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end of buffer when reading export name for export %u", i); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + WASMComponentExportName *export_name = wasm_runtime_malloc(sizeof(WASMComponentExportName)); + if (!export_name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for export_name"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + bool status = parse_component_export_name(&p, end, export_name, error_buf, error_buf_size); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component name for export %u", i); + wasm_runtime_free(export_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->exports[i].export_name = export_name; + + // Parsing 'sortidx' + out->exports[i].sort_idx = wasm_runtime_malloc(sizeof(WASMComponentSortIdx)); + if (!out->exports[i].sort_idx) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for sort_idx"); + wasm_runtime_free(export_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + status = parse_sort_idx(&p, end, out->exports[i].sort_idx, error_buf, error_buf_size, false); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse sort_idx for export %u", i); + wasm_runtime_free(out->exports[i].sort_idx); + wasm_runtime_free(export_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + LOG_DEBUG("Export section: name = \"%s\", sort idx = %d\n", out->exports[i].export_name->exported.simple.name->name, out->exports[i].sort_idx->sort->sort); + + // Parsing 'externdesc' (OPTIONAL) + if (p >= end) { + LOG_DEBUG("Parsing Extern desc\n"); + + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end of buffer when reading optional extern_desc for export %u", i); + wasm_runtime_free(out->exports[i].sort_idx->sort); + wasm_runtime_free(out->exports[i].sort_idx); + wasm_runtime_free(export_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + uint8_t opt_extern_desc = *p++; + if (opt_extern_desc == WASM_COMP_OPTIONAL_TRUE) { + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end of buffer when parsing extern_desc for export %u", i); + wasm_runtime_free(out->exports[i].sort_idx->sort); + wasm_runtime_free(out->exports[i].sort_idx); + wasm_runtime_free(export_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + WASMComponentExternDesc *extern_desc = wasm_runtime_malloc(sizeof(WASMComponentExternDesc)); + bool extern_status = parse_extern_desc(&p, end, extern_desc, error_buf, error_buf_size); + if (!extern_status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse extern_desc for export %u", i); + wasm_runtime_free(extern_desc); + wasm_runtime_free(out->exports[i].sort_idx->sort); + wasm_runtime_free(out->exports[i].sort_idx); + wasm_runtime_free(export_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->exports[i].extern_desc = extern_desc; + LOG_DEBUG("Extern desc added\n"); + } else if (opt_extern_desc == WASM_COMP_OPTIONAL_FALSE) { + // Explicitly mark absence of extern_desc + out->exports[i].extern_desc = NULL; + LOG_DEBUG("Extern desc set to NULL\n"); + } else { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", opt_extern_desc); + return false; + } + } + } + + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + + return true; +} + +// Individual section free functions +void wasm_component_free_exports_section(WASMComponentSection *section) { + if (!section || !section->parsed.export_section) return; + + WASMComponentExportSection *export_sec = section->parsed.export_section; + if (export_sec->exports) { + for (uint32_t j = 0; j < export_sec->count; ++j) { + WASMComponentExport *export = &export_sec->exports[j]; + + // Free export name + if (export->export_name) { + free_component_export_name(export->export_name); + wasm_runtime_free(export->export_name); + export->export_name = NULL; + } + + // Free sort index + if (export->sort_idx) { + if (export->sort_idx->sort) { + wasm_runtime_free(export->sort_idx->sort); + export->sort_idx->sort = NULL; + } + wasm_runtime_free(export->sort_idx); + export->sort_idx = NULL; + } + + // Free extern desc (optional) + if (export->extern_desc) { + free_extern_desc(export->extern_desc); + wasm_runtime_free(export->extern_desc); + export->extern_desc = NULL; + } + } + wasm_runtime_free(export_sec->exports); + export_sec->exports = NULL; + } + wasm_runtime_free(export_sec); + section->parsed.export_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_helpers.c b/core/iwasm/common/component-model/wasm_component_helpers.c new file mode 100644 index 000000000..c8a28a0e1 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_helpers.c @@ -0,0 +1,1126 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "../interpreter/wasm_runtime.h" +#include "wasm_export.h" +#include + +// Set an error message in the provided buffer, supporting printf-style formatting +void set_error_buf_ex(char *error_buf, uint32_t error_buf_size, const char *format, ...) { + // Standard error buffer formatting for all parsing errors + if (error_buf && error_buf_size > 0 && format) { + va_list args; + va_start(args, format); + vsnprintf(error_buf, error_buf_size, format, args); + va_end(args); + } +} + +bool +parse_result_list(const uint8_t **payload, const uint8_t *end, WASMComponentResultList **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the result list structure + *out = wasm_runtime_malloc(sizeof(WASMComponentResultList)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for result list"); + return false; + } + memset(*out, 0, sizeof(WASMComponentResultList)); + + uint8_t tag = *p; + (*out)->tag = tag; + p++; + + switch (tag) { + case WASM_COMP_RESULT_LIST_WITH_TYPE: { + // Allocate memory for the single result value type + (*out)->results = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->results) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for result value type"); + return false; + } + memset((*out)->results, 0, sizeof(WASMComponentValueType)); + + if (!parse_valtype(&p, end, (*out)->results, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse result"); + return false; + } + break; + } + case WASM_COMP_RESULT_LIST_EMPTY: { + (*out)->results = NULL; + // Binary.md encodes empty resultlist as 0x01 0x00 + uint8_t terminator = *p++; + if (terminator != 0x00) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid empty resultlist terminator: 0x%02x", terminator); + return false; + } + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid result list tag: 0x%02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +bool +parse_sort(const uint8_t **payload, const uint8_t *end, WASMComponentSort *out, char *error_buf, uint32_t error_buf_size, bool is_core) +{ + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + const uint8_t *p = *payload; + + if (!is_core) { + // Read the first byte, which is the main sort + out->sort = *p++; + out->core_sort = INVALID_VALUE; + + switch (out->sort) { + case WASM_COMP_SORT_CORE_SORT: // 0x00 + case WASM_COMP_SORT_FUNC: // 0x01 + case WASM_COMP_SORT_VALUE: // 0x02 + case WASM_COMP_SORT_TYPE: // 0x03 + case WASM_COMP_SORT_COMPONENT: // 0x04 + case WASM_COMP_SORT_INSTANCE: // 0x05 + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "Invalid sort value: 0x%02x", out->sort); + *payload = p; + return false; + } + } + else { + // Read the first byte, which is the core sort + out->sort = 0x00; + out->core_sort = *p++; + } + + // If the main sort is 0x00 (core), we must also read the specific core sort + if (out->sort == 0x00) { + // Check again if we've reached the end of the buffer + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end of buffer when parsing core_sort"); + *payload = p; // Update pointer even on error + return false; + } + // Read the second byte if is not core:sort + if(!is_core){ + out->core_sort = *p++; + } + } + + if (out->core_sort != INVALID_VALUE) { + switch (out->core_sort) { + case WASM_COMP_CORE_SORT_FUNC: // 0x00 + case WASM_COMP_CORE_SORT_TABLE: // 0x01 + case WASM_COMP_CORE_SORT_MEMORY: // 0x02 + case WASM_COMP_CORE_SORT_GLOBAL: // 0x03 + case WASM_COMP_CORE_SORT_TYPE: // 0x10 + case WASM_COMP_CORE_SORT_MODULE: // 0x11 + case WASM_COMP_CORE_SORT_INSTANCE: // 0x12 + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "Invalid core sort value: 0x%02x", out->core_sort); + *payload = p; + return false; + } + } + // For any other value of s->sort, the s->core_sort field remains 0 and is ignored. + + // Update the original pointer + *payload = p; + return true; +} + +bool +parse_sort_idx(const uint8_t **payload, const uint8_t *end, WASMComponentSortIdx *out, char *error_buf, uint32_t error_buf_size, bool is_core) +{ + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + // Allocate memory for the sort field using WAMR memory management + out->sort = wasm_runtime_malloc(sizeof(WASMComponentSort)); + if (!out->sort) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for sort"); + return false; + } + + // Parse the sort first + bool status = parse_sort(payload, end, out->sort, error_buf, error_buf_size, is_core); + if (!status) { + wasm_runtime_free(out->sort); + return false; + } + + // Parse the idx as LEB128-encoded value + uint64_t idx_leb = 0; + if (!read_leb((uint8_t **)payload, end, 32, false, &idx_leb, error_buf, error_buf_size)) { + wasm_runtime_free(out->sort); + return false; + } + + out->idx = (uint32_t)idx_leb; + return true; +} + +bool +parse_extern_desc(const uint8_t **payload, const uint8_t *end, WASMComponentExternDesc *out, char *error_buf, uint32_t error_buf_size){ + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + out->type = *p++; + + switch (out->type) { + case WASM_COMP_EXTERN_CORE_MODULE: { + // 0x00 0x11 i: => (core module (type i)) + // Read type_specific byte (should be 0x11) + uint8_t type_specific = *p++; + if (type_specific != 0x11) { + *payload = p; // Update pointer even on error + return false; + } + // Read core type index (LEB128-encoded) + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + out->extern_desc.core_module.type_specific = type_specific; + out->extern_desc.core_module.type_idx = (uint32_t)type_idx; + break; + } + case WASM_COMP_EXTERN_FUNC: { + // 0x01 i: => (func (type i)) + // Read function type index (LEB128-encoded) + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + out->extern_desc.func.type_idx = (uint32_t)type_idx; + break; + } + case WASM_COMP_EXTERN_VALUE: { + // 0x02 b: => (value b) + // valuebound ::= 0x00 i: => (eq i) + // | 0x01 t: => t + // Read value bound tag (0x00 = eq, 0x01 = type) + uint8_t value_bound_tag = *p++; + out->extern_desc.value.value_bound = wasm_runtime_malloc(sizeof(WASMComponentValueBound)); + if (!out->extern_desc.value.value_bound) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for value_bound"); + *payload = p; // Update pointer even on error + return false; + } + out->extern_desc.value.value_bound->tag = value_bound_tag; + switch (value_bound_tag) { + case WASM_COMP_VALUEBOUND_EQ: { + // 0x00 i: => (eq i) + // Read value index (LEB128-encoded) + uint64_t value_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &value_idx, error_buf, error_buf_size)) { + wasm_runtime_free(out->extern_desc.value.value_bound); + *payload = p; // Update pointer even on error + return false; + } + out->extern_desc.value.value_bound->bound.value_idx = (uint32_t)value_idx; + break; + } + case WASM_COMP_VALUEBOUND_TYPE: { + // 0x01 t: => t + // Allocate memory for value_type + out->extern_desc.value.value_bound->bound.value_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!out->extern_desc.value.value_bound->bound.value_type) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for value_type"); + wasm_runtime_free(out->extern_desc.value.value_bound); + *payload = p; // Update pointer even on error + return false; + } + + // Use the refactored parse_valtype function + if (!parse_valtype(&p, end, out->extern_desc.value.value_bound->bound.value_type, error_buf, error_buf_size)) { + wasm_runtime_free(out->extern_desc.value.value_bound->bound.value_type); + wasm_runtime_free(out->extern_desc.value.value_bound); + *payload = p; // Update pointer even on error + return false; + } + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Unknown value bound tag: 0x%02X", value_bound_tag); + wasm_runtime_free(out->extern_desc.value.value_bound); + *payload = p; // Update pointer even on error + return false; + } + } + break; + } + case WASM_COMP_EXTERN_TYPE: { + // Parse typebound for extern_desc type + // typebound ::= 0x00 i: => (eq i) + // | 0x01 => (sub resource) + uint8_t type_bound_tag = *p++; + out->extern_desc.type.type_bound = wasm_runtime_malloc(sizeof(WASMComponentTypeBound)); + if (!out->extern_desc.type.type_bound) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for type_bound"); + *payload = p; // Update pointer even on error + return false; + } + // Always set the tag field + out->extern_desc.type.type_bound->tag = type_bound_tag; + + if (type_bound_tag == WASM_COMP_TYPEBOUND_EQ) { + // 0x00 i: => (eq i) + // Read a type index (LEB128-encoded) + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + wasm_runtime_free(out->extern_desc.type.type_bound); + *payload = p; // Update pointer even on error + return false; + } + out->extern_desc.type.type_bound->type_idx = (uint32_t)type_idx; + } else if (type_bound_tag != WASM_COMP_TYPEBOUND_TYPE) { + // 0x01 => (sub resource) — valid but no extra data + // anything else is malformed + set_error_buf_ex(error_buf, error_buf_size, "Invalid typebound tag: 0x%02x", type_bound_tag); + wasm_runtime_free(out->extern_desc.type.type_bound); + *payload = p; + return false; + } + break; + } + case WASM_COMP_EXTERN_COMPONENT: { + // 0x04 i: => (component (type i)) + // Read component type index (LEB128-encoded) + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + out->extern_desc.component.type_idx = (uint32_t)type_idx; + break; + } + case WASM_COMP_EXTERN_INSTANCE: { + // 0x05 i: => (instance (type i)) + // Read instance type index (LEB128-encoded) + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + out->extern_desc.instance.type_idx = (uint32_t)type_idx; + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Unknown extern_desc type: 0x%02X", out->type); + *payload = p; // Update pointer even on error + return false; + } + } + + // Update the original pointer + *payload = p; + return true; +} + +void +free_extern_desc(WASMComponentExternDesc *desc) +{ + if (!desc) { + return; + } + + switch (desc->type) { + case WASM_COMP_EXTERN_VALUE: { + WASMComponentValueBound *vb = desc->extern_desc.value.value_bound; + if (vb) { + if (vb->tag == WASM_COMP_VALUEBOUND_TYPE && vb->bound.value_type) { + wasm_runtime_free(vb->bound.value_type); + vb->bound.value_type = NULL; + } + wasm_runtime_free(vb); + desc->extern_desc.value.value_bound = NULL; + } + break; + } + case WASM_COMP_EXTERN_TYPE: { + if (desc->extern_desc.type.type_bound) { + wasm_runtime_free(desc->extern_desc.type.type_bound); + desc->extern_desc.type.type_bound = NULL; + } + break; + } + default: + // Other extern types don't have nested allocations + break; + } + + // Note: Do NOT free desc itself - it's part of a larger structure + // that will be freed by the parent +} + +// Parse a simple core:name (LEB128 length + UTF-8 bytes) +bool +parse_core_name(const uint8_t **payload, const uint8_t *end, WASMComponentCoreName **out, char *error_buf, uint32_t error_buf_size) +{ + if (!payload || !*payload || !end || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + uint64_t name_len_leb = 0; + + if (!read_leb((uint8_t **)&p, end, 32, false, &name_len_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read core name length"); + *payload = p; // Update pointer even on error + return false; + } + + // Handle zero-length names (empty strings) + if (name_len_leb == 0) { + WASMComponentCoreName *result = wasm_runtime_malloc(sizeof(WASMComponentCoreName)); + if (!result) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core name structure"); + *payload = p; // Update pointer even on error + return false; + } + + result->name_len = 0; + result->name = wasm_runtime_malloc(1); // Allocate 1 byte for null terminator + if (!result->name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core name string"); + wasm_runtime_free(result); + *payload = p; // Update pointer even on error + return false; + } + + result->name[0] = '\0'; // Empty string + *payload = p; + *out = result; + return true; + } + + // Check bounds before proceeding + if (p + name_len_leb > end) { + set_error_buf_ex(error_buf, error_buf_size, "Core name extends beyond buffer"); + *payload = p; // Update pointer even on error + return false; + } + + // Validate UTF-8 encoding before allocating memory + if (!wasm_check_utf8_str(p, (uint32_t)name_len_leb)) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid UTF-8 encoding in core name"); + *payload = p; // Update pointer even on error + return false; + } + + WASMComponentCoreName *result = wasm_runtime_malloc(sizeof(WASMComponentCoreName)); + if (!result) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core name structure"); + *payload = p; // Update pointer even on error + return false; + } + + result->name_len = (uint32_t)name_len_leb; + result->name = wasm_runtime_malloc(name_len_leb + 1); + if (!result->name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core name string"); + wasm_runtime_free(result); + *payload = p; // Update pointer even on error + return false; + } + + memcpy(result->name, p, name_len_leb); + result->name[name_len_leb] = '\0'; + p += name_len_leb; + + // Update the original pointer + *payload = p; + *out = result; + return true; +} + +// Free a core name structure +void +free_core_name(WASMComponentCoreName *core_name) +{ + if (core_name && core_name->name) { + wasm_runtime_free(core_name->name); + core_name->name = NULL; + } +} + +bool +parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMComponentImportName *out, char *error_buf, uint32_t error_buf_size) +{ + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + uint8_t tag = *p++; + + switch (tag) { + case WASM_COMP_IMPORTNAME_SIMPLE: { + out->tag = WASM_COMP_IMPORTNAME_SIMPLE; + WASMComponentCoreName *name = NULL; + if (!parse_core_name(&p, end, &name, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + out->imported.simple.name = name; + break; + } + case WASM_COMP_IMPORTNAME_VERSIONED: { + out->tag = WASM_COMP_IMPORTNAME_VERSIONED; + WASMComponentCoreName *name = NULL; + if (!parse_core_name(&p, end, &name, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + + WASMComponentCoreName *version = NULL; + if (!parse_core_name(&p, end, &version, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read version name"); + free_core_name(name); + wasm_runtime_free(name); + *payload = p; // Update pointer even on error + return false; + } + + // Merge into "name@version", check first char for @ + bool version_has_at = (version->name_len > 0 && version->name[0] == '@'); + uint32_t sep_len = version_has_at ? 0 : 1; + uint32_t full_len = name->name_len + sep_len + version->name_len; + char *full = wasm_runtime_malloc(full_len + 1); + if (!full) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate versioned name"); + free_core_name(name); + wasm_runtime_free(name); + free_core_name(version); + wasm_runtime_free(version); + *payload = p; + return false; + } + memcpy(full, name->name, name->name_len); + if (!version_has_at) full[name->name_len] = '@'; + memcpy(full + name->name_len + sep_len, version->name, version->name_len); + full[full_len] = '\0'; + + wasm_runtime_free(name->name); + name->name = full; + name->name_len = full_len; + + free_core_name(version); + wasm_runtime_free(version); + + out->imported.versioned.name = name; + out->imported.versioned.version = NULL; + break; + } + default: + set_error_buf_ex(error_buf, error_buf_size, "Unknown import/export name tag: 0x%02X", tag); + *payload = p; // Update pointer even on error + return false; + } + + // Update the original pointer + *payload = p; + return true; +} + +bool +parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMComponentExportName *out, char *error_buf, uint32_t error_buf_size) +{ + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + uint8_t tag = *p++; + + switch (tag) { + case WASM_COMP_IMPORTNAME_SIMPLE: { + out->tag = WASM_COMP_IMPORTNAME_SIMPLE; + WASMComponentCoreName *name = NULL; + if (!parse_core_name(&p, end, &name, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + out->exported.simple.name = name; + break; + } + case WASM_COMP_IMPORTNAME_VERSIONED: { + out->tag = WASM_COMP_IMPORTNAME_VERSIONED; + WASMComponentCoreName *name = NULL; + if (!parse_core_name(&p, end, &name, error_buf, error_buf_size)) { + *payload = p; // Update pointer even on error + return false; + } + + WASMComponentCoreName *version = NULL; + if (!parse_core_name(&p, end, &version, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read version name"); + free_core_name(name); + wasm_runtime_free(name); + *payload = p; // Update pointer even on error + return false; + } + + // Merge into "name@version", check first char for @ + bool version_has_at = (version->name_len > 0 && version->name[0] == '@'); + uint32_t sep_len = version_has_at ? 0 : 1; + uint32_t full_len = name->name_len + sep_len + version->name_len; + char *full = wasm_runtime_malloc(full_len + 1); + if (!full) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate versioned name"); + free_core_name(name); + wasm_runtime_free(name); + free_core_name(version); + wasm_runtime_free(version); + *payload = p; + return false; + } + memcpy(full, name->name, name->name_len); + if (!version_has_at) full[name->name_len] = '@'; + memcpy(full + name->name_len + sep_len, version->name, version->name_len); + full[full_len] = '\0'; + + wasm_runtime_free(name->name); + name->name = full; + name->name_len = full_len; + + free_core_name(version); + wasm_runtime_free(version); + + out->exported.versioned.name = name; + out->exported.versioned.version = NULL; + break; + } + default: + set_error_buf_ex(error_buf, error_buf_size, "Unknown import/export name tag: 0x%02X", tag); + *payload = p; // Update pointer even on error + return false; + } + + // Update the original pointer + *payload = p; + return true; +} + + +void +free_component_import_name(WASMComponentImportName *name_struct) +{ + if (!name_struct) { + return; + } + + switch (name_struct->tag) { + case WASM_COMP_IMPORTNAME_SIMPLE: + if (name_struct->imported.simple.name) { + free_core_name(name_struct->imported.simple.name); + wasm_runtime_free(name_struct->imported.simple.name); + name_struct->imported.simple.name = NULL; + } + break; + case WASM_COMP_IMPORTNAME_VERSIONED: + if (name_struct->imported.versioned.name) { + free_core_name(name_struct->imported.versioned.name); + wasm_runtime_free(name_struct->imported.versioned.name); + name_struct->imported.versioned.name = NULL; + } + if (name_struct->imported.versioned.version) { + free_core_name(name_struct->imported.versioned.version); + wasm_runtime_free(name_struct->imported.versioned.version); + name_struct->imported.versioned.version = NULL; + } + break; + } + + // Note: Do NOT free name_struct itself - it's part of a larger structure + // that will be freed by the parent +} + +void +free_component_export_name(WASMComponentExportName *name_struct) +{ + if (!name_struct) { + return; + } + + switch (name_struct->tag) { + case WASM_COMP_IMPORTNAME_SIMPLE: + if (name_struct->exported.simple.name) { + free_core_name(name_struct->exported.simple.name); + wasm_runtime_free(name_struct->exported.simple.name); + name_struct->exported.simple.name = NULL; + } + break; + case WASM_COMP_IMPORTNAME_VERSIONED: + if (name_struct->exported.versioned.name) { + free_core_name(name_struct->exported.versioned.name); + wasm_runtime_free(name_struct->exported.versioned.name); + name_struct->exported.versioned.name = NULL; + } + if (name_struct->exported.versioned.version) { + free_core_name(name_struct->exported.versioned.version); + wasm_runtime_free(name_struct->exported.versioned.version); + name_struct->exported.versioned.version = NULL; + } + break; + } + + // Note: Do NOT free name_struct itself - it's part of a larger structure + // that will be freed by the parent +} + +// ----------------------------------------------------------------------------- +// Type Section Helper Functions +// ----------------------------------------------------------------------------- + +bool is_defvaltype_tag(uint8_t byte) { + // Check if it's a primitive type + if (is_primitive_type(byte)) { + return true; + } + + // Check if it's a defvaltype constructor + switch (byte) { + case 0x72: // record + case 0x71: // variant + case 0x70: // list + case 0x67: // list with length + case 0x6f: // tuple + case 0x6e: // flags + case 0x6d: // enum + case 0x6b: // option + case 0x6a: // result + case 0x69: // own + case 0x68: // borrow + case 0x66: // stream + case 0x65: // future + return true; + default: + return false; + } +} + +WASMComponentTypesTag get_type_tag(uint8_t first_byte) { + // Check if it's a defvaltype (primitive types or defvaltype constructors) + if (is_defvaltype_tag(first_byte)) { + return WASM_COMP_DEF_TYPE; + } + + // Check other types + switch (first_byte) { + case 0x40: // functype + case 0x43: // functype (async) + return WASM_COMP_FUNC_TYPE; + case 0x41: // componenttype + return WASM_COMP_COMPONENT_TYPE; + case 0x42: // instancetype + return WASM_COMP_INSTANCE_TYPE; + case 0x3f: // resourcetype + return WASM_COMP_RESOURCE_TYPE_SYNC; + case 0x3e: // resourcetype (async variant) + return WASM_COMP_RESOURCE_TYPE_ASYNC; + default: + return WASM_COMP_INVALID_TYPE; + } +} + +bool parse_valtype(const uint8_t **payload, const uint8_t *end, WASMComponentValueType *out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + uint8_t first_byte = **payload; + + // Check if it's a primitive type + if (is_primitive_type(first_byte)) { + out->type = WASM_COMP_VAL_TYPE_PRIMVAL; // Indicates primitive + out->type_specific.primval_type = first_byte; + (*payload)++; // Advance pointer + return true; + } else { + // Parse as type index (LEB128) + uint64_t type_idx = 0; + if (!read_leb((uint8_t **)payload, end, 32, false, &type_idx, error_buf, error_buf_size)) { + return false; + } + out->type = WASM_COMP_VAL_TYPE_IDX; // Indicates type index + out->type_specific.type_idx = (uint32_t)type_idx; + return true; + } +} + +bool parse_labelvaltype(const uint8_t **payload, const uint8_t *end, WASMComponentLabelValType *out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + // Parse the label (core name) + if (!parse_core_name(payload, end, &out->label, error_buf, error_buf_size)) { + return false; + } + + // Parse the value type (required) + out->value_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!out->value_type) { + free_core_name(out->label); + wasm_runtime_free(out->label); + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for label value type"); + return false; + } + memset(out->value_type, 0, sizeof(WASMComponentValueType)); + if (!parse_valtype(payload, end, out->value_type, error_buf, error_buf_size)) { + wasm_runtime_free(out->value_type); + out->value_type = NULL; + free_core_name(out->label); + wasm_runtime_free(out->label); + out->label = NULL; + return false; + } + + return true; +} + +bool parse_case(const uint8_t **payload, const uint8_t *end, WASMComponentCaseValType *out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + // Parse the label (core name) + if (!parse_core_name(payload, end, &out->label, error_buf, error_buf_size)) { + return false; + } + + // Parse optional valtype + uint8_t optional_tag = *(*payload)++; + + if (optional_tag == WASM_COMP_OPTIONAL_TRUE) { + // Present - parse valtype + out->value_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!out->value_type) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for case value type"); + free_core_name(out->label); + return false; + } + + if (!parse_valtype(payload, end, out->value_type, error_buf, error_buf_size)) { + wasm_runtime_free(out->value_type); + free_core_name(out->label); + return false; + } + } else if (optional_tag == WASM_COMP_OPTIONAL_FALSE) { + // Absent - set to NULL + out->value_type = NULL; + } else { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", optional_tag); + return false; + } + + // Parse the ending 0x00 + uint8_t ending_byte = *(*payload)++; + if (ending_byte != WASM_COMP_CASE_END) { + set_error_buf_ex(error_buf, error_buf_size, "Expected 0x00 at end of case, got 0x%02x", ending_byte); + if (out->value_type) { + wasm_runtime_free(out->value_type); + } + free_core_name(out->label); + return false; + } + + return true; +} + +// Parse a label' (length-prefixed label) for flags and enum types +bool parse_label_prime(const uint8_t **payload, const uint8_t *end, + WASMComponentCoreName **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Read the length prefix + uint64_t len_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &len_leb, error_buf, error_buf_size)) { + return false; + } + uint32_t len = (uint32_t)len_leb; + + // Check if we have enough bytes for the label + if ((uint32_t)(end - p) < len) { + set_error_buf_ex(error_buf, error_buf_size, "Insufficient bytes for label: expected %u, got %zu", + len, (size_t)(end - p)); + return false; + } + + // Check that the core name structure is allocated + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for label"); + return false; + } + + // Allocate and copy the label string + (*out)->name = wasm_runtime_malloc(len + 1); + if (!(*out)->name) { + wasm_runtime_free(*out); + *out = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for label string"); + return false; + } + + memcpy((*out)->name, p, len); + (*out)->name[len] = '\0'; // Null-terminate + (*out)->name_len = len; + + p += len; + *payload = p; + + return true; +} + +// Helper function to fill an already-allocated label structure +static bool fill_label_prime(const uint8_t **payload, const uint8_t *end, + WASMComponentCoreName *out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Read the length prefix + uint64_t len_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &len_leb, error_buf, error_buf_size)) { + return false; + } + uint32_t len = (uint32_t)len_leb; + + // Check if we have enough bytes for the label + if ((uint32_t)(end - p) < len) { + set_error_buf_ex(error_buf, error_buf_size, "Insufficient bytes for label: expected %u, got %zu", + len, (size_t)(end - p)); + return false; + } + + // Allocate and copy the label string + out->name = wasm_runtime_malloc(len + 1); + if (!out->name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for label string"); + return false; + } + + memcpy(out->name, p, len); + out->name[len] = '\0'; // Null-terminate + out->name_len = len; + + p += len; + *payload = p; + + return true; +} + +// Parse vec for flags and enum types +bool parse_label_prime_vector(const uint8_t **payload, const uint8_t *end, WASMComponentCoreName **out_labels, uint32_t *out_count, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out_labels || !out_count || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Read the vector length + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + return false; + } + uint32_t count = (uint32_t)count_leb; + + if (count > 0) { + // Allocate the labels array + *out_labels = wasm_runtime_malloc(sizeof(WASMComponentCoreName) * count); + if (!*out_labels) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for labels array"); + return false; + } + + // Initialize to zero + memset(*out_labels, 0, sizeof(WASMComponentCoreName) * count); + + // Parse each label + for (uint32_t i = 0; i < count; i++) { + if (!fill_label_prime(&p, end, &((*out_labels)[i]), error_buf, error_buf_size)) { + // Clean up already parsed labels + for (uint32_t j = 0; j < i; j++) { + if ((*out_labels)[j].name) { + wasm_runtime_free((*out_labels)[j].name); + } + } + wasm_runtime_free(*out_labels); + *out_labels = NULL; + return false; + } + } + } else { + *out_labels = NULL; + } + + *out_count = count; + *payload = p; + return true; +} + +// Free a label_prime (single label') +void free_label_prime(WASMComponentCoreName *label) { + if (label) { + if (label->name) { + wasm_runtime_free(label->name); + label->name = NULL; + } + } +} + +// Free a label_prime_vector (array of labels) +void free_label_prime_vector(WASMComponentCoreName *labels, uint32_t count) { + if (labels) { + for (uint32_t i = 0; i < count; i++) { + if (labels[i].name) { + wasm_runtime_free(labels[i].name); + } + } + wasm_runtime_free(labels); + } +} + +void free_labelvaltype(WASMComponentLabelValType *labelvaltype) { + if (labelvaltype) { + if (labelvaltype->label) { + free_core_name(labelvaltype->label); + wasm_runtime_free(labelvaltype->label); + labelvaltype->label = NULL; + } + if (labelvaltype->value_type) { + wasm_runtime_free(labelvaltype->value_type); + labelvaltype->value_type = NULL; + } + } +} + +void free_case(WASMComponentCaseValType *case_valtype) { + if (case_valtype) { + if (case_valtype->label) { + free_core_name(case_valtype->label); + wasm_runtime_free(case_valtype->label); + case_valtype->label = NULL; + } + if (case_valtype->value_type) { + wasm_runtime_free(case_valtype->value_type); + case_valtype->value_type = NULL; + } + } +} + +// Validate a UTF-8 sequence for general correctness (delegates to wasm_check_utf8_str) +bool wasm_component_validate_utf8(const uint8_t *bytes, uint32_t len) { + if (!bytes && len != 0) { + return false; + } + return wasm_check_utf8_str(bytes, len); +} + +// Validate that bytes encode exactly one UTF-8 scalar value +bool wasm_component_validate_single_utf8_scalar(const uint8_t *bytes, uint32_t len) { + if (!bytes || len < 1 || len > 4) { + return false; + } + + const uint8_t b0 = bytes[0]; + + if (b0 <= 0x7F) { + // 1-byte ASCII + return len == 1; + } + + if (b0 >= 0xC2 && b0 <= 0xDF) { + // 2-byte non-overlong + if (len != 2) return false; + const uint8_t b1 = bytes[1]; + return (b1 >= 0x80 && b1 <= 0xBF); + } + + if (b0 == 0xE0) { + // 3-byte, first continuation restricted to avoid overlongs + if (len != 3) return false; + const uint8_t b1 = bytes[1], b2 = bytes[2]; + return (b1 >= 0xA0 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF); + } + if (b0 >= 0xE1 && b0 <= 0xEC) { + if (len != 3) return false; + const uint8_t b1 = bytes[1], b2 = bytes[2]; + return (b1 >= 0x80 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF); + } + if (b0 == 0xED) { + // 0xED leads into UTF-16 surrogate range; disallow 0x80..0x9F second byte + if (len != 3) return false; + const uint8_t b1 = bytes[1], b2 = bytes[2]; + return (b1 >= 0x80 && b1 <= 0x9F) ? false : (b1 >= 0xA0 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF); + } + if (b0 >= 0xEE && b0 <= 0xEF) { + if (len != 3) return false; + const uint8_t b1 = bytes[1], b2 = bytes[2]; + return (b1 >= 0x80 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF); + } + + if (b0 == 0xF0) { + // 4-byte, restrict second byte to avoid overlong + if (len != 4) return false; + const uint8_t b1 = bytes[1], b2 = bytes[2], b3 = bytes[3]; + return (b1 >= 0x90 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF) && (b3 >= 0x80 && b3 <= 0xBF); + } + if (b0 >= 0xF1 && b0 <= 0xF3) { + if (len != 4) return false; + const uint8_t b1 = bytes[1], b2 = bytes[2], b3 = bytes[3]; + return (b1 >= 0x80 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF) && (b3 >= 0x80 && b3 <= 0xBF); + } + if (b0 == 0xF4) { + // Limit to U+10FFFF -> second byte <= 0x8F + if (len != 4) return false; + const uint8_t b1 = bytes[1], b2 = bytes[2], b3 = bytes[3]; + return (b1 >= 0x80 && b1 <= 0x8F) && (b2 >= 0x80 && b2 <= 0xBF) && (b3 >= 0x80 && b3 <= 0xBF); + } + + // Invalid leading byte or overlong prefix (0xC0, 0xC1) or > 0xF4 + return false; +} diff --git a/core/iwasm/common/component-model/wasm_component_imports_section.c b/core/iwasm/common/component-model/wasm_component_imports_section.c new file mode 100644 index 000000000..1e41489c8 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_imports_section.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Section 10: imports section +bool wasm_component_parse_imports_section(const uint8_t **payload, uint32_t payload_len, WASMComponentImportSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + + // import ::= in: ed: => (import in ed) + // Read the count of imports (LEB128-encoded) + uint64_t import_count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &import_count_leb, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + uint32_t import_count = (uint32_t)import_count_leb; + out->count = import_count; + + if (import_count > 0) { + out->imports = wasm_runtime_malloc(sizeof(WASMComponentImport) * import_count); + if (!out->imports) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for imports"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize all imports to zero to avoid garbage data + memset(out->imports, 0, sizeof(WASMComponentImport) * import_count); + + for (uint32_t i = 0; i < import_count; ++i) { + // importname' ::= 0x00 len: in: => in (if len = |in|) + // | 0x01 len: in: vs: => in vs (if len = |in|) + // Parse import name (simple or versioned) + WASMComponentImportName *import_name = wasm_runtime_malloc(sizeof(WASMComponentImportName)); + if (!import_name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for import_name"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + // Initialize the struct to zero to avoid garbage data + memset(import_name, 0, sizeof(WASMComponentImportName)); + + bool status = parse_component_import_name(&p, end, import_name, error_buf, error_buf_size); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component name for import %u", i); + wasm_runtime_free(import_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // externdesc ::= 0x00 0x11 i: => (core module (type i)) + // | 0x01 i: => (func (type i)) + // | 0x02 b: => (value b) + // | 0x03 b: => (type b) + // | 0x04 i: => (component (type i)) + // | 0x05 i: => (instance (type i)) + // Parse externdesc (core module, func, value, type, component, instance) + WASMComponentExternDesc *extern_desc = wasm_runtime_malloc(sizeof(WASMComponentExternDesc)); + if (!extern_desc) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for extern_desc"); + wasm_runtime_free(import_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + // Initialize the struct to zero to avoid garbage data + memset(extern_desc, 0, sizeof(WASMComponentExternDesc)); + + status = parse_extern_desc(&p, end, extern_desc, error_buf, error_buf_size); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse extern_desc for import %u", i); + wasm_runtime_free(extern_desc); + wasm_runtime_free(import_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Store the parsed import (importname' + externdesc) + out->imports[i].import_name = import_name; + out->imports[i].extern_desc = extern_desc; + } + } + + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return true; +} + +// Individual section free functions +void wasm_component_free_imports_section(WASMComponentSection *section) { + if (!section || !section->parsed.import_section) return; + + WASMComponentImportSection *import_sec = section->parsed.import_section; + if (import_sec->imports) { + for (uint32_t j = 0; j < import_sec->count; ++j) { + WASMComponentImport *import = &import_sec->imports[j]; + + // Free import name + if (import->import_name) { + free_component_import_name(import->import_name); + wasm_runtime_free(import->import_name); + import->import_name = NULL; + } + + // Free extern desc + if (import->extern_desc) { + free_extern_desc(import->extern_desc); + wasm_runtime_free(import->extern_desc); + import->extern_desc = NULL; + } + } + wasm_runtime_free(import_sec->imports); + import_sec->imports = NULL; + } + wasm_runtime_free(import_sec); + section->parsed.import_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_instances_section.c b/core/iwasm/common/component-model/wasm_component_instances_section.c new file mode 100644 index 000000000..7279b2597 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_instances_section.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Section 5: instances section +// Binary.md: instance ::= ie: => (instance ie) +// instanceexpr ::= 0x00 c: arg*:vec() => (instantiate c arg*) +// instantiatearg ::= n: si: => (with n si) +bool wasm_component_parse_instances_section(const uint8_t **payload, uint32_t payload_len, WASMComponentInstSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + + uint64_t instance_count = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &instance_count, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->count = (uint32_t)instance_count; + + if (instance_count > 0) { + out->instances = wasm_runtime_malloc(sizeof(WASMComponentInst) * instance_count); + if (!out->instances) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for instances"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize all instances to zero to avoid garbage data + memset(out->instances, 0, sizeof(WASMComponentInst) * instance_count); + + for (uint32_t i = 0; i < instance_count; ++i) { + // Check bounds before reading tag + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Buffer overflow when reading instance tag"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + uint8_t tag = *p++; + out->instances[i].instance_expression_tag = tag; + switch (tag) { + case WASM_COMP_INSTANCE_EXPRESSION_WITH_ARGS: { + // 0x00 c: arg*:vec() + uint64_t component_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &component_idx, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->instances[i].expression.with_args.idx = (uint32_t)component_idx; + + uint64_t arg_len = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &arg_len, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + out->instances[i].expression.with_args.arg_len = (uint32_t)arg_len; + + if (arg_len > 0) { + out->instances[i].expression.with_args.args = wasm_runtime_malloc(sizeof(WASMComponentInstArg) * arg_len); + if (!out->instances[i].expression.with_args.args) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component instantiate args"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize args to zero + memset(out->instances[i].expression.with_args.args, 0, sizeof(WASMComponentInstArg) * arg_len); + + for (uint32_t j = 0; j < arg_len; ++j) { + // Parse core:name (LEB128 length + UTF-8 bytes) + WASMComponentCoreName *core_name = NULL; + if (!parse_core_name(&p, end, &core_name, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Store the name in the instantiate arg structure + out->instances[i].expression.with_args.args[j].name = core_name; + + // si: - this is a component-level sort index (non-core) + out->instances[i].expression.with_args.args[j].idx.sort_idx = wasm_runtime_malloc(sizeof(WASMComponentSortIdx)); + if (!out->instances[i].expression.with_args.args[j].idx.sort_idx) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component arg sort idx"); + free_core_name(core_name); + wasm_runtime_free(core_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + // Zero-initialize sort_idx + memset(out->instances[i].expression.with_args.args[j].idx.sort_idx, 0, sizeof(WASMComponentSortIdx)); + + // Parse component sort index + bool status = parse_sort_idx(&p, end, out->instances[i].expression.with_args.args[j].idx.sort_idx, error_buf, error_buf_size, false); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component arg sort idx"); + free_core_name(core_name); + wasm_runtime_free(core_name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + } + } else { + out->instances[i].expression.with_args.args = NULL; + } + break; + } + case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: { + // 0x01 e*:vec() => e* + uint64_t inline_expr_len = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &inline_expr_len, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + out->instances[i].expression.without_args.inline_expr_len = (uint32_t)inline_expr_len; + + if (inline_expr_len > 0) { + out->instances[i].expression.without_args.inline_expr = wasm_runtime_malloc(sizeof(WASMComponentInlineExport) * inline_expr_len); + if (!out->instances[i].expression.without_args.inline_expr) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component inline exports"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize inline exports to zero + memset(out->instances[i].expression.without_args.inline_expr, 0, sizeof(WASMComponentInlineExport) * inline_expr_len); + + for (uint32_t j = 0; j < inline_expr_len; j++) { + // inlineexport ::= n: si: + WASMComponentCoreName *name = wasm_runtime_malloc(sizeof(WASMComponentCoreName)); + if (!name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component export name"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Parse export name (component-level name) + bool name_parse_success = parse_core_name(&p, end, &name, error_buf, error_buf_size); + if (!name_parse_success) { + free_core_name(name); + wasm_runtime_free(name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + out->instances[i].expression.without_args.inline_expr[j].name = name; + + // Parse component sort index + WASMComponentSortIdx *sort_idx = wasm_runtime_malloc(sizeof(WASMComponentSortIdx)); + if (!sort_idx) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component sort idx"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + // Zero-initialize sort_idx + memset(sort_idx, 0, sizeof(WASMComponentSortIdx)); + + bool status = parse_sort_idx(&p, end, sort_idx, error_buf, error_buf_size, false); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component sort idx"); + wasm_runtime_free(sort_idx); + free_core_name(name); + wasm_runtime_free(name); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + out->instances[i].expression.without_args.inline_expr[j].sort_idx = sort_idx; + } + } else { + out->instances[i].expression.without_args.inline_expr = NULL; + } + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Unknown instance expression tag: 0x%02X", tag); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + } + } + } + if (consumed_len) *consumed_len = payload_len; + return true; +} + +// Individual section free functions +void wasm_component_free_instances_section(WASMComponentSection *section) { + if (!section || !section->parsed.instance_section) return; + + WASMComponentInstSection *instance_sec = section->parsed.instance_section; + if (instance_sec->instances) { + for (uint32_t j = 0; j < instance_sec->count; ++j) { + WASMComponentInst *instance = &instance_sec->instances[j]; + + switch (instance->instance_expression_tag) { + case WASM_COMP_INSTANCE_EXPRESSION_WITH_ARGS: + if (instance->expression.with_args.args) { + for (uint32_t k = 0; k < instance->expression.with_args.arg_len; ++k) { + WASMComponentInstArg *arg = &instance->expression.with_args.args[k]; + + // Free component name + if (arg->name) { + free_core_name(arg->name); + wasm_runtime_free(arg->name); + arg->name = NULL; + } + + // Free component sort index + if (arg->idx.sort_idx) { + if (arg->idx.sort_idx->sort) { + wasm_runtime_free(arg->idx.sort_idx->sort); + arg->idx.sort_idx->sort = NULL; + } + wasm_runtime_free(arg->idx.sort_idx); + arg->idx.sort_idx = NULL; + } + } + wasm_runtime_free(instance->expression.with_args.args); + instance->expression.with_args.args = NULL; + } + break; + + case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: + if (instance->expression.without_args.inline_expr) { + for (uint32_t k = 0; k < instance->expression.without_args.inline_expr_len; ++k) { + WASMComponentInlineExport *inline_export = &instance->expression.without_args.inline_expr[k]; + + // Free component export name + if (inline_export->name) { + free_core_name(inline_export->name); + wasm_runtime_free(inline_export->name); + inline_export->name = NULL; + } + + // Free component sort index + if (inline_export->sort_idx) { + if (inline_export->sort_idx->sort) { + wasm_runtime_free(inline_export->sort_idx->sort); + inline_export->sort_idx->sort = NULL; + } + wasm_runtime_free(inline_export->sort_idx); + inline_export->sort_idx = NULL; + } + } + wasm_runtime_free(instance->expression.without_args.inline_expr); + instance->expression.without_args.inline_expr = NULL; + } + break; + } + } + wasm_runtime_free(instance_sec->instances); + instance_sec->instances = NULL; + } + wasm_runtime_free(instance_sec); + section->parsed.instance_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_start_section.c b/core/iwasm/common/component-model/wasm_component_start_section.c new file mode 100644 index 000000000..b954c6d05 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_start_section.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +// Section 9: start section +bool wasm_component_parse_start_section(const uint8_t **payload, uint32_t payload_len, WASMComponentStartSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (consumed_len) *consumed_len = 0; + if (!payload || !*payload || !out || payload_len == 0) { + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = p + payload_len; + + // Initialize outputs + out->func_idx = 0; + out->value_args_count = 0; + out->value_args = NULL; + out->result = 0; + + uint64_t func_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &func_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read func idx"); + return false; + } + out->func_idx = (uint32_t)func_idx; + + uint64_t args_count = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &args_count, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read args count"); + return false; + } + out->value_args_count = (uint32_t)args_count; + + if (args_count > 0) { + out->value_args = wasm_runtime_malloc(sizeof(uint32_t) * args_count); + if (!out->value_args) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for value args"); + return false; + } + + for (uint64_t i = 0; i < args_count; i++) { + uint64_t value_idx = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &value_idx, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read value idx"); + // cleanup + wasm_runtime_free(out->value_args); + out->value_args = NULL; + out->value_args_count = 0; + return false; + } + out->value_args[i] = (uint32_t)value_idx; + } + } + + uint64_t result_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &result_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to read result count"); + if (out->value_args) { + wasm_runtime_free(out->value_args); + out->value_args = NULL; + out->value_args_count = 0; + } + return false; + } + out->result = (uint32_t)result_leb; + + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return true; +} + +// Individual section free functions +void wasm_component_free_start_section(WASMComponentSection *section) { + if (!section || !section->parsed.start_section) { + return; + } + + WASMComponentStartSection *start_section = section->parsed.start_section; + if (start_section->value_args) { + wasm_runtime_free(start_section->value_args); + } + wasm_runtime_free(start_section); + section->parsed.start_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_types_section.c b/core/iwasm/common/component-model/wasm_component_types_section.c new file mode 100644 index 000000000..a40695742 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_types_section.c @@ -0,0 +1,1947 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_runtime_common.h" +#include "wasm_export.h" +#include + +static void free_component_instance_decl(WASMComponentInstDecl *decl); + +// Free helpers for nested component/instance/resource types +static void free_component_types_entry(WASMComponentTypes *type); + +// Helper function to parse record types +static bool parse_record_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Parse vec + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse variant type"); + return false; + } + uint32_t count = (uint32_t)count_leb; + + if (count > 0) { + // Allocate the record structure + (*out)->def_val.record = wasm_runtime_malloc(sizeof(WASMComponentRecordType)); + if (!(*out)->def_val.record) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for record type"); + return false; + } + + // Allocate the fields array + (*out)->def_val.record->fields = wasm_runtime_malloc(sizeof(WASMComponentLabelValType) * count); + if (!(*out)->def_val.record->fields) { + wasm_runtime_free((*out)->def_val.record); + (*out)->def_val.record = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for record fields"); + return false; + } + + (*out)->def_val.record->count = count; + + // Initialize all fields to zero + memset((*out)->def_val.record->fields, 0, sizeof(WASMComponentLabelValType) * count); + + // Parse each field + for (uint32_t i = 0; i < count; i++) { + if (!parse_labelvaltype(&p, end, &(*out)->def_val.record->fields[i], error_buf, error_buf_size)) { + // Clean up already parsed fields + for (uint32_t j = 0; j < i; j++) { + free_labelvaltype(&(*out)->def_val.record->fields[j]); + } + wasm_runtime_free((*out)->def_val.record->fields); + wasm_runtime_free((*out)->def_val.record); + (*out)->def_val.record = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse record type"); + return false; + } + } + } else { + set_error_buf_ex(error_buf, error_buf_size, "record type must have at least one field"); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse variant types +static bool parse_variant_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Parse vec + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + return false; + } + uint32_t count = (uint32_t)count_leb; + + if (count > 0) { + // Allocate the variant structure + (*out)->def_val.variant = wasm_runtime_malloc(sizeof(WASMComponentVariantType)); + if (!(*out)->def_val.variant) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for variant type"); + return false; + } + + // Allocate the cases array + (*out)->def_val.variant->cases = wasm_runtime_malloc(sizeof(WASMComponentCaseValType) * count); + if (!(*out)->def_val.variant->cases) { + wasm_runtime_free((*out)->def_val.variant); + (*out)->def_val.variant = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for variant cases"); + return false; + } + + (*out)->def_val.variant->count = count; + + // Initialize all cases to zero + memset((*out)->def_val.variant->cases, 0, sizeof(WASMComponentCaseValType) * count); + + // Parse each case + for (uint32_t i = 0; i < count; i++) { + if (!parse_case(&p, end, &(*out)->def_val.variant->cases[i], error_buf, error_buf_size)) { + // Clean up already parsed cases + for (uint32_t j = 0; j < i; j++) { + free_case(&(*out)->def_val.variant->cases[j]); + } + wasm_runtime_free((*out)->def_val.variant->cases); + wasm_runtime_free((*out)->def_val.variant); + (*out)->def_val.variant = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse variant type"); + return false; + } + } + } else { + set_error_buf_ex(error_buf, error_buf_size, "variant type must have at least one field"); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse tuple types +static bool parse_tuple_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Parse vec + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + return false; + } + uint32_t count = (uint32_t)count_leb; + + if (count > 0) { + // Allocate the tuple structure + (*out)->def_val.tuple = wasm_runtime_malloc(sizeof(WASMComponentTupleType)); + if (!(*out)->def_val.tuple) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for tuple type"); + return false; + } + + // Allocate the element types array + (*out)->def_val.tuple->element_types = wasm_runtime_malloc(sizeof(WASMComponentValueType) * count); + if (!(*out)->def_val.tuple->element_types) { + wasm_runtime_free((*out)->def_val.tuple); + (*out)->def_val.tuple = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for tuple element types"); + return false; + } + + (*out)->def_val.tuple->count = count; + + // Initialize all element types to zero + memset((*out)->def_val.tuple->element_types, 0, sizeof(WASMComponentValueType) * count); + + // Parse each element type + for (uint32_t i = 0; i < count; i++) { + if (!parse_valtype(&p, end, &(*out)->def_val.tuple->element_types[i], error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.tuple->element_types); + wasm_runtime_free((*out)->def_val.tuple); + (*out)->def_val.tuple = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse tuple element type %u", i); + return false; + } + } + } else { + set_error_buf_ex(error_buf, error_buf_size, "tuple type must have at least one field"); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse vec for flags and enum types +static bool parse_flags_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Parse vec + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + return false; + } + uint32_t count = (uint32_t)count_leb; + + if (count > 0 && count <= 32) { + // Allocate the flag structure + (*out)->def_val.flag = wasm_runtime_malloc(sizeof(WASMComponentFlagType)); + if (!(*out)->def_val.flag) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for flag type"); + return false; + } + + // Allocate the labels array + (*out)->def_val.flag->flags = wasm_runtime_malloc(sizeof(WASMComponentCoreName) * count); + if (!(*out)->def_val.flag->flags) { + wasm_runtime_free((*out)->def_val.flag); + (*out)->def_val.flag = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for flag labels"); + return false; + } + + (*out)->def_val.flag->count = count; + + // Initialize all labels to zero + memset((*out)->def_val.flag->flags, 0, sizeof(WASMComponentCoreName) * count); + + // Parse each label + for (uint32_t i = 0; i < count; i++) { + WASMComponentCoreName *temp_ptr = &(*out)->def_val.flag->flags[i]; + if (!parse_label_prime(&p, end, &temp_ptr, error_buf, error_buf_size)) { + // Clean up on error + for (uint32_t j = 0; j < i; j++) { + free_label_prime(&(*out)->def_val.flag->flags[j]); + } + wasm_runtime_free((*out)->def_val.flag->flags); + wasm_runtime_free((*out)->def_val.flag); + (*out)->def_val.flag = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse flag label %u", i); + return false; + } + } + } else { + set_error_buf_ex(error_buf, error_buf_size, "Flags type must have 0 < count <= 32, got %u", count); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse vec for enum types +static bool parse_enum_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Parse vec + uint64_t count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + return false; + } + uint32_t count = (uint32_t)count_leb; + + if (count > 0) { + // Allocate the enum structure + (*out)->def_val.enum_type = wasm_runtime_malloc(sizeof(WASMComponentEnumType)); + if (!(*out)->def_val.enum_type) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for enum type"); + return false; + } + + // Allocate the labels array + (*out)->def_val.enum_type->labels = wasm_runtime_malloc(sizeof(WASMComponentCoreName) * count); + if (!(*out)->def_val.enum_type->labels) { + wasm_runtime_free((*out)->def_val.enum_type); + (*out)->def_val.enum_type = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for enum labels"); + return false; + } + + (*out)->def_val.enum_type->count = count; + + // Initialize all labels to zero + memset((*out)->def_val.enum_type->labels, 0, sizeof(WASMComponentCoreName) * count); + + // Parse each label + for (uint32_t i = 0; i < count; i++) { + WASMComponentCoreName *temp_ptr = &(*out)->def_val.enum_type->labels[i]; + if (!parse_label_prime(&p, end, &temp_ptr, error_buf, error_buf_size)) { + // Clean up on error + for (uint32_t j = 0; j < i; j++) { + free_label_prime(&(*out)->def_val.enum_type->labels[j]); + } + wasm_runtime_free((*out)->def_val.enum_type->labels); + wasm_runtime_free((*out)->def_val.enum_type); + (*out)->def_val.enum_type = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse enum label %u", i); + return false; + } + } + } else { + set_error_buf_ex(error_buf, error_buf_size, "enum type must have at least one field"); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse option types +static bool parse_option_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Allocate the option structure + (*out)->def_val.option = wasm_runtime_malloc(sizeof(WASMComponentOptionType)); + if (!(*out)->def_val.option) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for option type"); + return false; + } + + // Allocate the element type + (*out)->def_val.option->element_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->def_val.option->element_type) { + wasm_runtime_free((*out)->def_val.option); + (*out)->def_val.option = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for option element type"); + return false; + } + + // Initialize element type to zero + memset((*out)->def_val.option->element_type, 0, sizeof(WASMComponentValueType)); + + // Parse option type + if (!parse_valtype(&p, end, (*out)->def_val.option->element_type, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.option->element_type); + wasm_runtime_free((*out)->def_val.option); + (*out)->def_val.option = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse option type"); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse result types +static bool parse_result_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Allocate the result structure + (*out)->def_val.result = wasm_runtime_malloc(sizeof(WASMComponentResultType)); + if (!(*out)->def_val.result) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for result type"); + return false; + } + + // Initialize to NULL + (*out)->def_val.result->result_type = NULL; + (*out)->def_val.result->error_type = NULL; + + // Parse in Binary.md order: result t? then error u? + // Optional result type (t?) + uint8_t has_result_type = *p++; + if (has_result_type == WASM_COMP_OPTIONAL_TRUE) { + (*out)->def_val.result->result_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->def_val.result->result_type) { + wasm_runtime_free((*out)->def_val.result); + (*out)->def_val.result = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for result result type"); + return false; + } + memset((*out)->def_val.result->result_type, 0, sizeof(WASMComponentValueType)); + if (!parse_valtype(&p, end, (*out)->def_val.result->result_type, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.result->result_type); + wasm_runtime_free((*out)->def_val.result); + (*out)->def_val.result = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse result result type"); + return false; + } + } else if (has_result_type != WASM_COMP_OPTIONAL_FALSE) { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", has_result_type); + return false; + } + + // Optional error type (u?) + uint8_t has_error_type = *p++; + if (has_error_type == WASM_COMP_OPTIONAL_TRUE) { + (*out)->def_val.result->error_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->def_val.result->error_type) { + if ((*out)->def_val.result->result_type) { + wasm_runtime_free((*out)->def_val.result->result_type); + } + wasm_runtime_free((*out)->def_val.result); + (*out)->def_val.result = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for result error type"); + return false; + } + memset((*out)->def_val.result->error_type, 0, sizeof(WASMComponentValueType)); + if (!parse_valtype(&p, end, (*out)->def_val.result->error_type, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.result->error_type); + if ((*out)->def_val.result->result_type) { + wasm_runtime_free((*out)->def_val.result->result_type); + } + wasm_runtime_free((*out)->def_val.result); + (*out)->def_val.result = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse result error type"); + return false; + } + } else if (has_error_type != WASM_COMP_OPTIONAL_FALSE) { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", has_error_type); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse own types +static bool parse_own_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + (*out)->def_val.owned = wasm_runtime_malloc(sizeof(WASMComponentOwnType)); + if (!(*out)->def_val.owned) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for own type"); + return false; + } + + // Parse own type + uint64_t type_idx_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx_leb, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.owned); + (*out)->def_val.owned = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse own type"); + return false; + } + (*out)->def_val.owned->type_idx = (uint32_t)type_idx_leb; + + *payload = p; + return true; +} + +// Helper function to parse borrow types +// 0x68 i: => (borrow i) +static bool parse_borrow_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + (*out)->def_val.borrow = wasm_runtime_malloc(sizeof(WASMComponentBorrowType)); + if (!(*out)->def_val.borrow) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for borrow type"); + return false; + } + + // Parse borrow type + uint64_t type_idx_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_idx_leb, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.borrow); + (*out)->def_val.borrow = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse borrow type"); + return false; + } + (*out)->def_val.borrow->type_idx = (uint32_t)type_idx_leb; + + *payload = p; + return true; +} + +// Helper function to parse stream types +static bool parse_stream_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Allocate the stream structure + (*out)->def_val.stream = wasm_runtime_malloc(sizeof(WASMComponentStreamType)); + if (!(*out)->def_val.stream) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for stream type"); + return false; + } + + // Initialize to NULL + (*out)->def_val.stream->element_type = NULL; + + // Parse optional element type + uint8_t has_element_type = *p++; + if (has_element_type == WASM_COMP_OPTIONAL_TRUE) { + // Allocate the element type + (*out)->def_val.stream->element_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->def_val.stream->element_type) { + wasm_runtime_free((*out)->def_val.stream); + (*out)->def_val.stream = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for stream element type"); + return false; + } + + // Initialize element type to zero + memset((*out)->def_val.stream->element_type, 0, sizeof(WASMComponentValueType)); + + if (!parse_valtype(&p, end, (*out)->def_val.stream->element_type, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.stream->element_type); + wasm_runtime_free((*out)->def_val.stream); + (*out)->def_val.stream = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse stream element type"); + return false; + } + } else if (has_element_type != WASM_COMP_OPTIONAL_FALSE) { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", has_element_type); + return false; + } + + *payload = p; + return true; +} + +// Helper function to parse future types +static bool parse_future_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Allocate the future structure + (*out)->def_val.future = wasm_runtime_malloc(sizeof(WASMComponentFutureType)); + if (!(*out)->def_val.future) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for future type"); + return false; + } + + // Initialize to NULL + (*out)->def_val.future->element_type = NULL; + + // Parse optional element type + uint8_t has_element_type = *p++; + if (has_element_type == WASM_COMP_OPTIONAL_TRUE) { + // Allocate the element type + (*out)->def_val.future->element_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->def_val.future->element_type) { + wasm_runtime_free((*out)->def_val.future); + (*out)->def_val.future = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for future element type"); + return false; + } + + // Initialize element type to zero + memset((*out)->def_val.future->element_type, 0, sizeof(WASMComponentValueType)); + + if (!parse_valtype(&p, end, (*out)->def_val.future->element_type, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.future->element_type); + wasm_runtime_free((*out)->def_val.future); + (*out)->def_val.future = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse future element type"); + return false; + } + } else if (has_element_type != WASM_COMP_OPTIONAL_FALSE) { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", has_element_type); + return false; + } + + *payload = p; + return true; +} + +// Validation wrapper for parse_list_type with len +static bool parse_list_type_with_len(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + + // Allocate the list_len structure + (*out)->def_val.list_len = wasm_runtime_malloc(sizeof(WASMComponentListLenType)); + if (!(*out)->def_val.list_len) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for list_len type"); + return false; + } + + // Allocate the element_type + (*out)->def_val.list_len->element_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->def_val.list_len->element_type) { + wasm_runtime_free((*out)->def_val.list_len); + (*out)->def_val.list_len = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for list_len element type"); + return false; + } + + // Parse the length + uint64_t len_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &len_leb, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.list_len->element_type); + wasm_runtime_free((*out)->def_val.list_len); + (*out)->def_val.list_len = NULL; + return false; + } + + // Binary.md: "if len > 0" - fixed-size list length must be greater than 0 + if (len_leb == 0) { + set_error_buf_ex(error_buf, error_buf_size, "Fixed-size list length must be greater than 0"); + wasm_runtime_free((*out)->def_val.list_len->element_type); + wasm_runtime_free((*out)->def_val.list_len); + (*out)->def_val.list_len = NULL; + return false; + } + + if (!parse_valtype(&p, end, (*out)->def_val.list_len->element_type, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.list_len->element_type); + wasm_runtime_free((*out)->def_val.list_len); + (*out)->def_val.list_len = NULL; + return false; + } + + (*out)->def_val.list_len->len = (uint32_t)len_leb; + + *payload = p; + return true; +} + +// Validation wrapper for parse_list_type without len +static bool parse_list_type(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out || !end) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + return false; + } + + const uint8_t *p = *payload; + // Allocate the list structure + (*out)->def_val.list = wasm_runtime_malloc(sizeof(WASMComponentListType)); + if (!(*out)->def_val.list) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for list type"); + return false; + } + + // Allocate the element_type + (*out)->def_val.list->element_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!(*out)->def_val.list->element_type) { + wasm_runtime_free((*out)->def_val.list); + (*out)->def_val.list = NULL; + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for list element type"); + return false; + } + + if (!parse_valtype(&p, end, (*out)->def_val.list->element_type, error_buf, error_buf_size)) { + wasm_runtime_free((*out)->def_val.list->element_type); + wasm_runtime_free((*out)->def_val.list); + (*out)->def_val.list = NULL; + return false; + } + + *payload = p; + return true; +} + +// Helper function to free a defvaltype structure +static void free_defvaltype(WASMComponentDefValType *def_val_type) { + if (!def_val_type) { + return; + } + + switch (def_val_type->tag) { + case WASM_COMP_DEF_VAL_RECORD: { + if (def_val_type->def_val.record) { + if (def_val_type->def_val.record->fields) { + for (uint32_t i = 0; i < def_val_type->def_val.record->count; i++) { + free_labelvaltype(&def_val_type->def_val.record->fields[i]); + } + wasm_runtime_free(def_val_type->def_val.record->fields); + } + wasm_runtime_free(def_val_type->def_val.record); + def_val_type->def_val.record = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_VARIANT: { + if (def_val_type->def_val.variant) { + if (def_val_type->def_val.variant->cases) { + for (uint32_t i = 0; i < def_val_type->def_val.variant->count; i++) { + free_case(&def_val_type->def_val.variant->cases[i]); + } + wasm_runtime_free(def_val_type->def_val.variant->cases); + } + wasm_runtime_free(def_val_type->def_val.variant); + def_val_type->def_val.variant = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_LIST: { + if (def_val_type->def_val.list) { + if (def_val_type->def_val.list->element_type) { + wasm_runtime_free(def_val_type->def_val.list->element_type); + def_val_type->def_val.list->element_type = NULL; + } + wasm_runtime_free(def_val_type->def_val.list); + def_val_type->def_val.list = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_LIST_LEN: { + if (def_val_type->def_val.list_len) { + if (def_val_type->def_val.list_len->element_type) { + wasm_runtime_free(def_val_type->def_val.list_len->element_type); + def_val_type->def_val.list_len->element_type = NULL; + } + wasm_runtime_free(def_val_type->def_val.list_len); + def_val_type->def_val.list_len = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_TUPLE: { + if (def_val_type->def_val.tuple) { + if (def_val_type->def_val.tuple->element_types) { + wasm_runtime_free(def_val_type->def_val.tuple->element_types); + def_val_type->def_val.tuple->element_types = NULL; + } + wasm_runtime_free(def_val_type->def_val.tuple); + def_val_type->def_val.tuple = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_FLAGS: { + if (def_val_type->def_val.flag) { + if (def_val_type->def_val.flag->flags) { + for (uint32_t i = 0; i < def_val_type->def_val.flag->count; i++) { + free_label_prime(&def_val_type->def_val.flag->flags[i]); + } + wasm_runtime_free(def_val_type->def_val.flag->flags); + } + wasm_runtime_free(def_val_type->def_val.flag); + def_val_type->def_val.flag = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_ENUM: { + if (def_val_type->def_val.enum_type) { + if (def_val_type->def_val.enum_type->labels) { + for (uint32_t i = 0; i < def_val_type->def_val.enum_type->count; i++) { + free_label_prime(&def_val_type->def_val.enum_type->labels[i]); + } + wasm_runtime_free(def_val_type->def_val.enum_type->labels); + } + wasm_runtime_free(def_val_type->def_val.enum_type); + def_val_type->def_val.enum_type = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_OPTION: { + if (def_val_type->def_val.option) { + if (def_val_type->def_val.option->element_type) { + wasm_runtime_free(def_val_type->def_val.option->element_type); + def_val_type->def_val.option->element_type = NULL; + } + wasm_runtime_free(def_val_type->def_val.option); + def_val_type->def_val.option = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_RESULT: { + if (def_val_type->def_val.result) { + if (def_val_type->def_val.result->result_type) { + wasm_runtime_free(def_val_type->def_val.result->result_type); + def_val_type->def_val.result->result_type = NULL; + } + if (def_val_type->def_val.result->error_type) { + wasm_runtime_free(def_val_type->def_val.result->error_type); + def_val_type->def_val.result->error_type = NULL; + } + wasm_runtime_free(def_val_type->def_val.result); + def_val_type->def_val.result = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_OWN: { + if (def_val_type->def_val.owned) { + wasm_runtime_free(def_val_type->def_val.owned); + def_val_type->def_val.owned = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_BORROW: { + if (def_val_type->def_val.borrow) { + wasm_runtime_free(def_val_type->def_val.borrow); + def_val_type->def_val.borrow = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_STREAM: { + if (def_val_type->def_val.stream) { + if (def_val_type->def_val.stream->element_type) { + wasm_runtime_free(def_val_type->def_val.stream->element_type); + def_val_type->def_val.stream->element_type = NULL; + } + wasm_runtime_free(def_val_type->def_val.stream); + def_val_type->def_val.stream = NULL; + } + break; + } + case WASM_COMP_DEF_VAL_FUTURE: { + if (def_val_type->def_val.future) { + if (def_val_type->def_val.future->element_type) { + wasm_runtime_free(def_val_type->def_val.future->element_type); + def_val_type->def_val.future->element_type = NULL; + } + wasm_runtime_free(def_val_type->def_val.future); + def_val_type->def_val.future = NULL; + } + break; + } + default: + // For primitive types, no cleanup needed + break; + } +} + +// Validation wrapper for parse_defvaltype +static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMComponentDefValType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out) { + return false; + } + + const uint8_t *p = *payload; + uint8_t tag = *p; + + // Allocate memory for the def_val_type + *out = wasm_runtime_malloc(sizeof(WASMComponentDefValType)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for def_val_type"); + return false; + } + memset(*out, 0, sizeof(WASMComponentDefValType)); + + // Check if it's a primitive type + if (is_primitive_type(tag)) { + (*out)->tag = WASM_COMP_DEF_VAL_PRIMVAL; + (*out)->def_val.primval = tag; + p++; + *payload = p; + return true; + } + + (*out)->tag = tag; + p++; + switch (tag) { + case WASM_COMP_DEF_VAL_RECORD: + if (!parse_record_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + + case WASM_COMP_DEF_VAL_VARIANT: + if (!parse_variant_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + + case WASM_COMP_DEF_VAL_LIST: + if (!parse_list_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + + case WASM_COMP_DEF_VAL_LIST_LEN: + if (!parse_list_type_with_len(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + + case WASM_COMP_DEF_VAL_TUPLE: { + if (!parse_tuple_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + case WASM_COMP_DEF_VAL_FLAGS: { + if (!parse_flags_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + case WASM_COMP_DEF_VAL_ENUM: { + if (!parse_enum_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + case WASM_COMP_DEF_VAL_OPTION: { + if (!parse_option_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + case WASM_COMP_DEF_VAL_RESULT: { + if (!parse_result_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + case WASM_COMP_DEF_VAL_OWN: { + if (!parse_own_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + case WASM_COMP_DEF_VAL_BORROW: { + if (!parse_borrow_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + case WASM_COMP_DEF_VAL_STREAM: { + if (!parse_stream_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + case WASM_COMP_DEF_VAL_FUTURE: { + if (!parse_future_type(&p, end, out, error_buf, error_buf_size)) { + wasm_runtime_free(*out); + *out = NULL; + return false; + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid defvaltype tag: 0x%02x", tag); + wasm_runtime_free(*out); + *out = NULL; + return false; + } + } + + *payload = p; + return true; +} + +static bool parse_param_list(const uint8_t **payload, const uint8_t *end, WASMComponentParamList **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the param list structure + *out = wasm_runtime_malloc(sizeof(WASMComponentParamList)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for param list"); + return false; + } + memset(*out, 0, sizeof(WASMComponentParamList)); + + // Parse the param list count + uint64_t param_count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, ¶m_count_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse param count"); + return false; + } + + uint32_t param_count = (uint32_t)param_count_leb; + (*out)->count = param_count; + + // Allocate memory for the param list + if (param_count > 0) { + (*out)->params = wasm_runtime_malloc(sizeof(WASMComponentLabelValType) * param_count); + if (!(*out)->params) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for param list"); + return false; + } + + // Parse the param list + for (uint32_t i = 0; i < param_count; i++) { + if (!parse_labelvaltype(&p, end, &(*out)->params[i], error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse param %d", i); + return false; + } + } + } else { + (*out)->params = NULL; + } + + *payload = p; + return true; +} + +bool parse_func_type(const uint8_t **payload, const uint8_t *end, WASMComponentFuncType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out) { + return false; + } + + const uint8_t *p = *payload; + + // Allocate memory for the func_type + *out = wasm_runtime_malloc(sizeof(WASMComponentFuncType)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for func_type"); + return false; + } + memset(*out, 0, sizeof(WASMComponentFuncType)); + + // Parse the param list + if (!parse_param_list(&p, end, &(*out)->params, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse param list"); + return false; + } + + // Parse the result list + if (!parse_result_list(&p, end, &(*out)->results, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse result list"); + return false; + } + + *payload = p; + return true; +} + +bool parse_component_decl_import_decl(const uint8_t **payload, const uint8_t *end, WASMComponentImportDecl **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the import decl + *out = wasm_runtime_malloc(sizeof(WASMComponentImportDecl)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for import decl"); + return false; + } + memset(*out, 0, sizeof(WASMComponentImportDecl)); + + // Parse the import name + WASMComponentImportName *import_name = wasm_runtime_malloc(sizeof(WASMComponentImportName)); + if (!import_name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for import_name"); + return false; + } + // Initialize the struct to zero to avoid garbage data + memset(import_name, 0, sizeof(WASMComponentImportName)); + + bool status = parse_component_import_name(&p, end, import_name, error_buf, error_buf_size); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component name for import"); + wasm_runtime_free(import_name); + return false; + } + + (*out)->import_name = import_name; + + WASMComponentExternDesc *extern_desc = wasm_runtime_malloc(sizeof(WASMComponentExternDesc)); + if (!extern_desc) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for extern desc"); + wasm_runtime_free(import_name); + return false; + } + memset(extern_desc, 0, sizeof(WASMComponentExternDesc)); + + // Parse the extern desc + if (!parse_extern_desc(&p, end, extern_desc, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse extern desc"); + wasm_runtime_free(extern_desc); + wasm_runtime_free(import_name); + return false; + } + + (*out)->extern_desc = extern_desc; + + *payload = p; + return true; +} + +bool parse_component_decl_core_type(const uint8_t **payload, const uint8_t *end, WASMComponentCoreType **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the core type + *out = wasm_runtime_malloc(sizeof(WASMComponentCoreType)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core type"); + return false; + } + memset(*out, 0, sizeof(WASMComponentCoreType)); + + // Allocate memory fore the core def type + WASMComponentCoreDefType *deftype = wasm_runtime_malloc(sizeof(WASMComponentCoreDefType)); + if (!deftype) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for core def type"); + return false; + } + memset(deftype, 0, sizeof(WASMComponentCoreDefType)); + + // Support both encodings: + // 1) Inline core:deftype per Binary.md (preferred) + // 2) Producer variation: core type index (u32) at this position + // This handles cases where instancedecl 0x00 is followed by a u32 index + // instead of inline core:deftype, which wasmparser handles gracefully + if (p < end) { + uint8_t b0 = *p; + bool looks_like_inline = (b0 == 0x50) /* moduletype */ + || (b0 == 0x4E) /* rec group (GC, unsupported here) */ + || (b0 == 0x4F) /* final subtype (GC, unsupported here) */ + || (b0 == 0x5E) || (b0 == 0x5F) || (b0 == 0x60) /* comptype prefixes (GC) */ + || (b0 == 0x00 && (p + 1) < end && + (*(p + 1) == 0x50 || *(p + 1) == 0x4E || *(p + 1) == 0x4F || + *(p + 1) == 0x5E || *(p + 1) == 0x5F || *(p + 1) == 0x60)); + + if (!looks_like_inline) { + // Treat as core type index (producer variation) + uint64_t idx = 0; + const uint8_t *p_before = p; + if (!read_leb((uint8_t **)&p, end, 32, false, &idx, error_buf, error_buf_size)) { + wasm_runtime_free(deftype); + wasm_runtime_free(*out); + *out = NULL; + *payload = p_before; + return false; + } + + // Store as unresolved reference by leaving deftype NULL for now. + // The index %llu will need to be resolved later against the core type section + (*out)->deftype = NULL; + + // IMPORTANT: After parsing a core type index, we need to continue parsing + // the rest of the instancedecl. The core type index is just the first part. + // We'll let the caller continue parsing from this point. + *payload = p; + return true; + } + } + + // Parse the core type inline (Binary.md: instancedecl 0x00 t: where core:type ::= dt:) + if (!parse_single_core_type(&p, end, deftype, error_buf, error_buf_size)) { + // cleanup on failure + wasm_runtime_free(deftype); + wasm_runtime_free(*out); + *out = NULL; + *payload = p; // propagate consumption + return false; + } + + (*out)->deftype = deftype; + *payload = p; + return true; +} + +bool parse_component_decl_type(const uint8_t **payload, const uint8_t *end, WASMComponentTypes **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the types + *out = wasm_runtime_malloc(sizeof(WASMComponentTypes)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for types"); + return false; + } + memset(*out, 0, sizeof(WASMComponentTypes)); + + // Parse the type + if (!parse_single_type(&p, end, *out, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse type"); + return false; + } + + *payload = p; + return true; +} + +bool parse_component_decl_alias(const uint8_t **payload, const uint8_t *end, WASMComponentAliasDefinition **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the alias definition + *out = wasm_runtime_malloc(sizeof(WASMComponentAliasDefinition)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for alias definition"); + return false; + } + memset(*out, 0, sizeof(WASMComponentAliasDefinition)); + + // Parse the alias definition + if (!parse_single_alias(&p, end, *out, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse alias"); + return false; + } + + *payload = p; + return true; +} + +bool parse_component_decl_export(const uint8_t **payload, const uint8_t *end, WASMComponentComponentDeclExport **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the types + *out = wasm_runtime_malloc(sizeof(WASMComponentComponentDeclExport)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for types"); + return false; + } + memset(*out, 0, sizeof(WASMComponentComponentDeclExport)); + + // Parse the import name + WASMComponentExportName *export_name = wasm_runtime_malloc(sizeof(WASMComponentExportName)); + if (!export_name) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for export_name"); + return false; + } + // Initialize the struct to zero to avoid garbage data + memset(export_name, 0, sizeof(WASMComponentExportName)); + + bool status = parse_component_export_name(&p, end, export_name, error_buf, error_buf_size); + if (!status) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component name for export"); + wasm_runtime_free(export_name); + return false; + } + + (*out)->export_name = export_name; + + WASMComponentExternDesc *extern_desc = wasm_runtime_malloc(sizeof(WASMComponentExternDesc)); + if (!extern_desc) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for extern desc"); + wasm_runtime_free(export_name); + return false; + } + memset(extern_desc, 0, sizeof(WASMComponentExternDesc)); + + // Parse the extern desc + if (!parse_extern_desc(&p, end, extern_desc, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse extern desc"); + wasm_runtime_free(extern_desc); + wasm_runtime_free(export_name); + return false; + } + + (*out)->extern_desc = extern_desc; + + *payload = p; + return true; +} + +bool parse_component_instance_decl(const uint8_t **payload, const uint8_t *end, WASMComponentInstDecl **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the instance decl + *out = wasm_runtime_malloc(sizeof(WASMComponentInstDecl)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for instance decl"); + return false; + } + memset(*out, 0, sizeof(WASMComponentInstDecl)); + + uint8_t tag = *p; + (*out)->tag = tag; + p++; + switch (tag) { + case WASM_COMP_COMPONENT_DECL_CORE_TYPE: { + if (!parse_component_decl_core_type(&p, end, &(*out)->decl.core_type, error_buf, error_buf_size)) { + return false; + } + // After parsing a core type, the instancedecl is complete + // The core type (either inline or index) is the entire content + break; + } + case WASM_COMP_COMPONENT_DECL_TYPE: { + if (!parse_component_decl_type(&p, end, &(*out)->decl.type, error_buf, error_buf_size)) { + return false; + } + break; + } + case WASM_COMP_COMPONENT_DECL_ALIAS: { + if (!parse_component_decl_alias(&p, end, &(*out)->decl.alias, error_buf, error_buf_size)) { + return false; + } + break; + } + case WASM_COMP_COMPONENT_DECL_EXPORT: { + if (!parse_component_decl_export(&p, end, &(*out)->decl.export_decl, error_buf, error_buf_size)) { + return false; + } + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid instance decl tag: 0x%02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +bool parse_component_decl(const uint8_t **payload, const uint8_t *end, WASMComponentComponentDecl **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + uint8_t tag = *p; + (*out)->tag = tag; + if (tag == WASM_COMP_COMPONENT_DECL_IMPORT) { + p++; + if (!parse_component_decl_import_decl(&p, end, &(*out)->decl.import_decl, error_buf, error_buf_size)) { + return false; + } + } else { + if (!parse_component_instance_decl(&p, end, &(*out)->decl.instance_decl, error_buf, error_buf_size)) { + return false; + } + } + + *payload = p; + return true; +} + +bool parse_component_type(const uint8_t **payload, const uint8_t *end, WASMComponentComponentType **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the component type + *out = wasm_runtime_malloc(sizeof(WASMComponentComponentType)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component type"); + return false; + } + memset(*out, 0, sizeof(WASMComponentComponentType)); + + // Read the component type count + uint64_t component_count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &component_count_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component count"); + return false; + } + + uint32_t component_count = (uint32_t)component_count_leb; + (*out)->count = component_count; + + // Allocate memory for the component list + if (component_count > 0) { + (*out)->component_decls = wasm_runtime_malloc(sizeof(WASMComponentComponentDecl) * component_count); + if (!(*out)->component_decls) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component list"); + return false; + } + + // Parse the component list + for (uint32_t i = 0; i < component_count; i++) { + WASMComponentComponentDecl *component_decl = wasm_runtime_malloc(sizeof(WASMComponentComponentDecl)); + if (!component_decl) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for component decl"); + return false; + } + memset(component_decl, 0, sizeof(WASMComponentComponentDecl)); + + if (!parse_component_decl(&p, end, &component_decl, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse component %d", i); + wasm_runtime_free(component_decl); + return false; + } + + (*out)->component_decls[i] = *component_decl; + wasm_runtime_free(component_decl); // free shell + } + } else { + (*out)->component_decls = NULL; + } + *payload = p; + return true; +} + +bool parse_component_instance_type(const uint8_t **payload, const uint8_t *end, WASMComponentInstType **out, char *error_buf, uint32_t error_buf_size) { + if (!payload || !*payload || !out) { + return false; + } + + const uint8_t *p = *payload; + WASMComponentInstDecl *instance_decls = NULL; + WASMComponentInstDecl *instance_decl = NULL; + uint64_t instance_count_leb = 0; + uint32_t instance_count = 0; + uint32_t populated = 0; + bool ret = true; + + *out = wasm_runtime_malloc(sizeof(WASMComponentInstType)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for instance type"); + return false; + } + memset(*out, 0, sizeof(WASMComponentInstType)); + + // Read the instance type count + if (!read_leb((uint8_t **)&p, end, 32, false, &instance_count_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse instance count"); + goto fail; + } + + instance_count = (uint32_t)instance_count_leb; + (*out)->count = instance_count; + + // Allocate memory for the instance list + if (instance_count > 0) { + instance_decls = wasm_runtime_malloc(sizeof(WASMComponentInstDecl) * instance_count); + if (!instance_decls) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for instance list"); + goto fail; + } + + // Parse the instance list + for (uint32_t i = 0; i < instance_count; i++) { + if (p >= end) { + set_error_buf_ex(error_buf, error_buf_size, "Unexpected end of buffer at instancedecl %d", i); + goto fail; + } + + instance_decl = NULL; + if (!parse_component_instance_decl(&p, end, &instance_decl, error_buf, error_buf_size)) { + goto fail; + } + + instance_decls[i] = *instance_decl; + wasm_runtime_free(instance_decl); // free shell + instance_decl = NULL; + populated++; + } + + (*out)->instance_decls = instance_decls; + } + *payload = p; + goto done; + +fail: + ret = false; + free_component_instance_decl(instance_decl); + wasm_runtime_free(instance_decl); + + for (uint32_t j = 0; j < populated; j++) { + free_component_instance_decl(&instance_decls[j]); + } + + wasm_runtime_free(instance_decls); + wasm_runtime_free(*out); + *out = NULL; +done: + return ret; +} + +bool parse_resource_type_sync(const uint8_t **payload, const uint8_t *end, WASMComponentResourceTypeSync **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the resource type sync + *out = wasm_runtime_malloc(sizeof(WASMComponentResourceTypeSync)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for resource type sync"); + return false; + } + memset(*out, 0, sizeof(WASMComponentResourceTypeSync)); + + uint8_t has_result_type = *p++; + // Read optional f?:? + if (has_result_type == WASM_COMP_OPTIONAL_TRUE) { + // Read the dtor funcidx + uint64_t dtor_func_idx_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &dtor_func_idx_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse resource type sync"); + return false; + } + (*out)->has_dtor = true; + (*out)->dtor_func_idx = (uint32_t)dtor_func_idx_leb; + } else if (has_result_type != WASM_COMP_OPTIONAL_FALSE) { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", has_result_type); + return false; + } + + *payload = p; + return true; +} + +bool parse_resource_type_async(const uint8_t **payload, const uint8_t *end, WASMComponentResourceTypeAsync **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the resource type async + + *out = wasm_runtime_malloc(sizeof(WASMComponentResourceTypeAsync)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for resource type async"); + return false; + } + memset(*out, 0, sizeof(WASMComponentResourceTypeAsync)); + + // Read the dtor funcidx + uint64_t dtor_func_idx_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &dtor_func_idx_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse resource type async"); + return false; + } + (*out)->dtor_func_idx = (uint32_t)dtor_func_idx_leb; + + // Read optional cb?:? + uint8_t has_result_type = *p++; + if (has_result_type == WASM_COMP_OPTIONAL_TRUE) { + // Read the cb funcidx + uint64_t callback_func_idx_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &callback_func_idx_leb, error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse resource type async"); + return false; + } + (*out)->callback_func_idx = (uint32_t)callback_func_idx_leb; + } else if (has_result_type != WASM_COMP_OPTIONAL_FALSE) { + set_error_buf_ex(error_buf, error_buf_size, "Malformed binary: invalid optional tag 0x%02x", has_result_type); + return false; + } + + *payload = p; + return true; +} + +bool parse_resource_type(const uint8_t **payload, const uint8_t *end, WASMComponentResourceType **out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Allocate memory for the resource type + *out = wasm_runtime_malloc(sizeof(WASMComponentResourceType)); + if (!*out) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for resource type"); + return false; + } + memset(*out, 0, sizeof(WASMComponentResourceType)); + + // Read the resource type tag + uint8_t tag = *p++; + (*out)->tag = tag; + + // Read the resource type rep + if (*p++ != WASM_COMP_RESOURCE_REP_I32) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid resource type rep: 0x%02x", *p); + return false; + } + + switch (tag) { + case WASM_COMP_RESOURCE_TYPE_SYNC: { + if (!parse_resource_type_sync(&p, end, &(*out)->resource.sync, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_RESOURCE_TYPE_ASYNC: { + if (!parse_resource_type_async(&p, end, &(*out)->resource.async, error_buf, error_buf_size)) { + return false; + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid resource type tag: 0x%02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +// Helper function to parse a type individually +bool parse_single_type(const uint8_t **payload, const uint8_t *end, WASMComponentTypes *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + uint8_t tag = *p; + WASMComponentTypesTag type_tag = get_type_tag(tag); + out->tag = type_tag; + + // Only advance past the tag for non-defval types. For defvaltype, the tag + // is part of the inner grammar and must be consumed by parse_defvaltype. + if (type_tag != WASM_COMP_DEF_TYPE) { + p++; + } + + switch (type_tag) { + case WASM_COMP_DEF_TYPE: { + if (!parse_defvaltype(&p, end, &out->type.def_val_type, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_FUNC_TYPE: { + if (!parse_func_type(&p, end, &out->type.func_type, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_COMPONENT_TYPE: { + // componenttype ::= 0x41 cd*:vec() + if (!parse_component_type(&p, end, &out->type.component_type, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_INSTANCE_TYPE: { + // instancetype ::= 0x42 id*:vec() + if (!parse_component_instance_type(&p, end, &out->type.instance_type, error_buf, error_buf_size)) { + return false; + } + break; + } + + case WASM_COMP_RESOURCE_TYPE_SYNC: + case WASM_COMP_RESOURCE_TYPE_ASYNC: { + // resourcetype ::= 0x3f 0x7f f?:? => (resource (rep i32) (dtor f)?) + // | 0x3e 0x7f f: cb?:? => (resource (rep i32) (dtor async f (callback cb)?)) + // Note: We already consumed the leading tag byte above. Rewind so the + // resource parser can read the tag and rep as specified by Binary.md. + p--; + if (!parse_resource_type(&p, end, &out->type.resource_type, error_buf, error_buf_size)) { + return false; + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "Invalid type tag: 0x%02x", tag); + return false; + } + } + + *payload = p; + return true; +} + +// Section 7: types section +bool wasm_component_parse_types_section(const uint8_t **payload, uint32_t payload_len, WASMComponentTypeSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || !out || payload_len == 0) { + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + uint32_t type_count = 0; + + // Read type count + uint64_t type_count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &type_count_leb, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + type_count = (uint32_t)type_count_leb; + out->count = type_count; + + if (type_count > 0) { + // Allocate the types array + out->types = wasm_runtime_malloc(sizeof(WASMComponentTypes) * type_count); + if (!out->types) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for types array"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize all types to zero + memset(out->types, 0, sizeof(WASMComponentTypes) * type_count); + + for (uint32_t i = 0; i < type_count; ++i) { + if (!parse_single_type(&p, end, &out->types[i], error_buf, error_buf_size)) { + wasm_runtime_free(out->types); + out->types = NULL; + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + } + } else { + out->types = NULL; + } + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return true; +} + +static void free_component_instance_decl(WASMComponentInstDecl *decl) { + if (!decl) return; + switch (decl->tag) { + case WASM_COMP_COMPONENT_DECL_INSTANCE_CORE_TYPE: + if (decl->decl.core_type) { + if (decl->decl.core_type->deftype) { + free_core_deftype(decl->decl.core_type->deftype); + wasm_runtime_free(decl->decl.core_type->deftype); + } + wasm_runtime_free(decl->decl.core_type); + decl->decl.core_type = NULL; + } + break; + case WASM_COMP_COMPONENT_DECL_INSTANCE_TYPE: + if (decl->decl.type) { + free_component_types_entry(decl->decl.type); + wasm_runtime_free(decl->decl.type); + decl->decl.type = NULL; + } + break; + case WASM_COMP_COMPONENT_DECL_INSTANCE_ALIAS: + if (decl->decl.alias) { + // Free sort + if (decl->decl.alias->sort) { + wasm_runtime_free(decl->decl.alias->sort); + decl->decl.alias->sort = NULL; + } + // Free target-specific fields + switch (decl->decl.alias->alias_target_type) { + case WASM_COMP_ALIAS_TARGET_EXPORT: + if (decl->decl.alias->target.exported.name) { + free_core_name(decl->decl.alias->target.exported.name); + wasm_runtime_free(decl->decl.alias->target.exported.name); + decl->decl.alias->target.exported.name = NULL; + } + break; + case WASM_COMP_ALIAS_TARGET_CORE_EXPORT: + if (decl->decl.alias->target.core_exported.name) { + free_core_name(decl->decl.alias->target.core_exported.name); + wasm_runtime_free(decl->decl.alias->target.core_exported.name); + decl->decl.alias->target.core_exported.name = NULL; + } + break; + case WASM_COMP_ALIAS_TARGET_OUTER: + break; + } + wasm_runtime_free(decl->decl.alias); + decl->decl.alias = NULL; + } + break; + case WASM_COMP_COMPONENT_DECL_INSTANCE_EXPORTDECL: + if (decl->decl.export_decl) { + if (decl->decl.export_decl->export_name) { + free_component_export_name(decl->decl.export_decl->export_name); + wasm_runtime_free(decl->decl.export_decl->export_name); + decl->decl.export_decl->export_name = NULL; + } + if (decl->decl.export_decl->extern_desc) { + free_extern_desc(decl->decl.export_decl->extern_desc); + wasm_runtime_free(decl->decl.export_decl->extern_desc); + decl->decl.export_decl->extern_desc = NULL; + } + wasm_runtime_free(decl->decl.export_decl); + decl->decl.export_decl = NULL; + } + break; + } +} + +static void free_component_decl(WASMComponentComponentDecl *decl) { + if (!decl) return; + switch (decl->tag) { + case WASM_COMP_COMPONENT_DECL_IMPORT: + if (decl->decl.import_decl) { + if (decl->decl.import_decl->import_name) { + free_component_import_name(decl->decl.import_decl->import_name); + wasm_runtime_free(decl->decl.import_decl->import_name); + decl->decl.import_decl->import_name = NULL; + } + if (decl->decl.import_decl->extern_desc) { + free_extern_desc(decl->decl.import_decl->extern_desc); + wasm_runtime_free(decl->decl.import_decl->extern_desc); + decl->decl.import_decl->extern_desc = NULL; + } + wasm_runtime_free(decl->decl.import_decl); + decl->decl.import_decl = NULL; + } + break; + default: + // Instance decl branch handles tags 0x00/0x01/0x02/0x04 inside nested decl + if (decl->decl.instance_decl) { + free_component_instance_decl(decl->decl.instance_decl); + wasm_runtime_free(decl->decl.instance_decl); + decl->decl.instance_decl = NULL; + } + break; + } +} + +static void free_resource_type(WASMComponentResourceType *rt) { + if (!rt) return; + switch (rt->tag) { + case WASM_COMP_RESOURCE_TYPE_SYNC: + if (rt->resource.sync) { + wasm_runtime_free(rt->resource.sync); + rt->resource.sync = NULL; + } + break; + case WASM_COMP_RESOURCE_TYPE_ASYNC: + if (rt->resource.async) { + wasm_runtime_free(rt->resource.async); + rt->resource.async = NULL; + } + break; + default: + break; + } +} + +static void free_component_types_entry(WASMComponentTypes *type) { + if (!type) return; + switch (type->tag) { + case WASM_COMP_DEF_TYPE: + if (type->type.def_val_type) { + free_defvaltype(type->type.def_val_type); + wasm_runtime_free(type->type.def_val_type); + type->type.def_val_type = NULL; + } + break; + case WASM_COMP_FUNC_TYPE: + if (type->type.func_type) { + if (type->type.func_type->params) { + if (type->type.func_type->params->params) { + for (uint32_t j = 0; j < type->type.func_type->params->count; j++) { + if (type->type.func_type->params->params[j].label) { + free_core_name(type->type.func_type->params->params[j].label); + wasm_runtime_free(type->type.func_type->params->params[j].label); + } + if (type->type.func_type->params->params[j].value_type) { + wasm_runtime_free(type->type.func_type->params->params[j].value_type); + } + } + wasm_runtime_free(type->type.func_type->params->params); + } + wasm_runtime_free(type->type.func_type->params); + type->type.func_type->params = NULL; + } + if (type->type.func_type->results) { + if (type->type.func_type->results->results) { + wasm_runtime_free(type->type.func_type->results->results); + } + wasm_runtime_free(type->type.func_type->results); + type->type.func_type->results = NULL; + } + wasm_runtime_free(type->type.func_type); + type->type.func_type = NULL; + } + break; + case WASM_COMP_COMPONENT_TYPE: + if (type->type.component_type) { + if (type->type.component_type->component_decls) { + for (uint32_t k = 0; k < type->type.component_type->count; k++) { + free_component_decl(&type->type.component_type->component_decls[k]); + } + wasm_runtime_free(type->type.component_type->component_decls); + type->type.component_type->component_decls = NULL; + } + wasm_runtime_free(type->type.component_type); + type->type.component_type = NULL; + } + break; + case WASM_COMP_INSTANCE_TYPE: + if (type->type.instance_type) { + if (type->type.instance_type->instance_decls) { + for (uint32_t k = 0; k < type->type.instance_type->count; k++) { + free_component_instance_decl(&type->type.instance_type->instance_decls[k]); + } + wasm_runtime_free(type->type.instance_type->instance_decls); + type->type.instance_type->instance_decls = NULL; + } + wasm_runtime_free(type->type.instance_type); + type->type.instance_type = NULL; + } + break; + case WASM_COMP_RESOURCE_TYPE_SYNC: + case WASM_COMP_RESOURCE_TYPE_ASYNC: + if (type->type.resource_type) { + free_resource_type(type->type.resource_type); + wasm_runtime_free(type->type.resource_type); + type->type.resource_type = NULL; + } + break; + default: + break; + } +} + +// Individual section free functions +void wasm_component_free_types_section(WASMComponentSection *section) { + if (!section || !section->parsed.type_section) { + return; + } + + WASMComponentTypeSection *type_section = section->parsed.type_section; + + if (type_section->types) { + for (uint32_t i = 0; i < type_section->count; i++) { + WASMComponentTypes *type = &type_section->types[i]; + + free_component_types_entry(type); + } + wasm_runtime_free(type_section->types); + type_section->types = NULL; + } + + // Free the type section structure itself + wasm_runtime_free(type_section); + section->parsed.type_section = NULL; +} diff --git a/core/iwasm/common/component-model/wasm_component_validate.c b/core/iwasm/common/component-model/wasm_component_validate.c new file mode 100644 index 000000000..1a9beb832 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_validate.c @@ -0,0 +1,2186 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component_validate.h" + +#define CONSTRUCTOR_PREFIX "[constructor]" +#define METHOD_PREFIX "[method]" +#define STATIC_PREFIX "[static]" +#define CONSTRUCTOR_PREFIX_LEN 13 +#define METHOD_PREFIX_LEN 8 +#define STATIC_PREFIX_LEN 8 + +static bool defvaltype_subtype(WASMComponentDefValType *a, WASMComponentDefValType *b, WASMComponentValidationContext *ctx); +static bool defvaltype_equal(WASMComponentDefValType *a, WASMComponentDefValType *b, WASMComponentValidationContext *ctx); + +// Grow types[] and type_is_local[] if needed, then record the entry at ctx->type_count. +static bool ctx_push_type(WASMComponentValidationContext *ctx, WASMComponentTypes *type, bool is_local, char *error_buf, uint32_t error_buf_size) { + if (ctx->type_count >= ctx->types_capacity) { + uint32_t new_cap = ctx->types_capacity == 0 ? 8 : ctx->types_capacity * 2; + WASMComponentTypes **new_types = (WASMComponentTypes **)wasm_runtime_malloc(new_cap * sizeof(WASMComponentTypes *)); + bool *new_is_local = wasm_runtime_malloc(new_cap * sizeof(bool)); + if (!new_types || !new_is_local) { + if (new_types) + wasm_runtime_free((void *)new_types); + + if (new_is_local) + wasm_runtime_free(new_is_local); + + set_error_buf_ex(error_buf, error_buf_size, "out of memory allocating type lookup array"); + return false; + } + + // Copy the existing entries into the new buffers + if (ctx->types) { + memcpy((void *)new_types, (const void *)ctx->types, ctx->type_count * sizeof(WASMComponentTypes *)); + memcpy(new_is_local, ctx->type_is_local, ctx->type_count * sizeof(bool)); + wasm_runtime_free((void *)ctx->types); + wasm_runtime_free(ctx->type_is_local); + } + + ctx->types = new_types; + ctx->type_is_local = new_is_local; + ctx->types_capacity = new_cap; + } + + // Save type pointer at the current slot. NULL is a valid entry + ctx->types[ctx->type_count] = type; + ctx->type_is_local[ctx->type_count] = is_local; + return true; +} + +// Grow value_consumed[] if needed, then record false (not yet consumed) at ctx->value_count. +static bool ctx_push_value(WASMComponentValidationContext *ctx, char *error_buf, uint32_t error_buf_size) { + if (ctx->value_count >= ctx->value_consumed_capacity) { + uint32_t new_cap = ctx->value_consumed_capacity == 0 ? 8 : ctx->value_consumed_capacity * 2; + bool *new_consumed = wasm_runtime_malloc(new_cap * sizeof(bool)); + if (!new_consumed) { + set_error_buf_ex(error_buf, error_buf_size, "out of memory allocating value consumed array"); + return false; + } + if (ctx->value_consumed) { + memcpy(new_consumed, ctx->value_consumed, ctx->value_count * sizeof(bool)); + wasm_runtime_free(ctx->value_consumed); + } + ctx->value_consumed = new_consumed; + ctx->value_consumed_capacity = new_cap; + } + ctx->value_consumed[ctx->value_count] = false; + return true; +} + +// Grow func_type_indexes[] if needed, then save the type index at ctx->func_count. +static bool ctx_push_func_type(WASMComponentValidationContext *ctx, uint32_t type_idx, char *error_buf, uint32_t error_buf_size) { + if (ctx->func_count >= ctx->func_type_indexes_capacity) { + uint32_t new_cap = ctx->func_type_indexes_capacity == 0 ? 8 : ctx->func_type_indexes_capacity * 2; + uint32_t *new_arr = wasm_runtime_malloc(new_cap * sizeof(uint32_t)); + if (!new_arr) { + set_error_buf_ex(error_buf, error_buf_size, "out of memory allocating func type indexes array"); + return false; + } + if (ctx->func_type_indexes) { + memcpy(new_arr, ctx->func_type_indexes, ctx->func_count * sizeof(uint32_t)); + wasm_runtime_free(ctx->func_type_indexes); + } + ctx->func_type_indexes = new_arr; + ctx->func_type_indexes_capacity = new_cap; + } + ctx->func_type_indexes[ctx->func_count] = type_idx; + return true; +} + +// Mark value at idx as consumed. Errors on out-of-bounds or double consumption. +static bool ctx_consume_value(WASMComponentValidationContext *ctx, uint32_t idx, char *error_buf, uint32_t error_buf_size) { + if (idx >= ctx->value_count) { + set_error_buf_ex(error_buf, error_buf_size, "value idx %u out of bounds", idx); + return false; + } + if (ctx->value_consumed[idx]) { + set_error_buf_ex(error_buf, error_buf_size, "value %u consumed more than once", idx); + return false; + } + ctx->value_consumed[idx] = true; + return true; +} + +// Compare two WASMComponentValueType* for structural equality. +static bool valtype_equal(WASMComponentValueType *a, WASMComponentValueType *b, WASMComponentValidationContext *ctx) { + if (a == b) return true; + if (!a || !b) return false; + + // Both are primitive value types + if (a->type == WASM_COMP_VAL_TYPE_PRIMVAL && b->type == WASM_COMP_VAL_TYPE_PRIMVAL) + return a->type_specific.primval_type == b->type_specific.primval_type; + + // Both are type index references - resolve and compare structurally + if (a->type == WASM_COMP_VAL_TYPE_IDX && b->type == WASM_COMP_VAL_TYPE_IDX) { + if (a->type_specific.type_idx == b->type_specific.type_idx) + return true; + + // Resolve both and compare structurally + uint32_t idx_a = a->type_specific.type_idx; + uint32_t idx_b = b->type_specific.type_idx; + if (idx_a >= ctx->type_count || idx_b >= ctx->type_count) + return false; + if (!ctx->types[idx_a] || !ctx->types[idx_b]) + return false; + + // Both must be def types with the same structure + WASMComponentTypes *ta = ctx->types[idx_a]; + WASMComponentTypes *tb = ctx->types[idx_b]; + if (ta->tag != WASM_COMP_DEF_TYPE || tb->tag != WASM_COMP_DEF_TYPE) + return ta->tag == tb->tag; + + return defvaltype_equal(ta->type.def_val_type, tb->type.def_val_type, ctx); + } + + // Mixed (eg one primval, one idx) - not equal + return false; +} + +// Compare two functype for structural equality +static bool functype_equal(WASMComponentFuncType *a, WASMComponentFuncType *b, WASMComponentValidationContext *ctx) { + if (a == b) return true; + if (!a || !b) return false; + + // Compare params + uint32_t pa = a->params ? a->params->count : 0; + uint32_t pb = b->params ? b->params->count : 0; + if (pa != pb) return false; + + for (uint32_t i = 0; i < pa; i++) { + if (strcmp(a->params->params[i].label->name, b->params->params[i].label->name) != 0) + return false; + if (!valtype_equal(a->params->params[i].value_type, b->params->params[i].value_type, ctx)) + return false; + } + + // Compare results + if (!a->results && !b->results) return true; + if (!a->results || !b->results) return false; + if (a->results->tag != b->results->tag) return false; + if (a->results->tag == WASM_COMP_RESULT_LIST_EMPTY) return true; + + return valtype_equal(a->results->results, b->results->results, ctx); +} + +// Compare two WASMComponentDefValType* for structural equality +static bool defvaltype_equal(WASMComponentDefValType *a, WASMComponentDefValType *b, WASMComponentValidationContext *ctx) { + if (a == b) return true; + if (!a || !b) return false; + if (a->tag != b->tag) return false; + + switch (a->tag) { + case WASM_COMP_DEF_VAL_PRIMVAL: + return a->def_val.primval == b->def_val.primval; + + case WASM_COMP_DEF_VAL_RECORD: { + WASMComponentRecordType *ra = a->def_val.record; + WASMComponentRecordType *rb = b->def_val.record; + if (ra->count != rb->count) return false; + for (uint32_t i = 0; i < ra->count; i++) { + if (strcmp(ra->fields[i].label->name, rb->fields[i].label->name) != 0) + return false; + if (!valtype_equal(ra->fields[i].value_type, rb->fields[i].value_type, ctx)) + return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_VARIANT: { + WASMComponentVariantType *va = a->def_val.variant; + WASMComponentVariantType *vb = b->def_val.variant; + if (va->count != vb->count) return false; + for (uint32_t i = 0; i < va->count; i++) { + if (strcmp(va->cases[i].label->name, vb->cases[i].label->name) != 0) + return false; + if (!valtype_equal(va->cases[i].value_type, vb->cases[i].value_type, ctx)) + return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_LIST: + return valtype_equal(a->def_val.list->element_type, b->def_val.list->element_type, ctx); + + case WASM_COMP_DEF_VAL_LIST_LEN: + if (a->def_val.list_len->len != b->def_val.list_len->len) + return false; + return valtype_equal(a->def_val.list_len->element_type, b->def_val.list_len->element_type, ctx); + + case WASM_COMP_DEF_VAL_TUPLE: { + WASMComponentTupleType *ta = a->def_val.tuple; + WASMComponentTupleType *tb = b->def_val.tuple; + if (ta->count != tb->count) return false; + for (uint32_t i = 0; i < ta->count; i++) { + if (!valtype_equal(&ta->element_types[i], &tb->element_types[i], ctx)) + return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_FLAGS: { + const WASMComponentFlagType *fa = a->def_val.flag; + const WASMComponentFlagType *fb = b->def_val.flag; + if (fa->count != fb->count) return false; + for (uint32_t i = 0; i < fa->count; i++) { + if (strcmp(fa->flags[i].name, fb->flags[i].name) != 0) + return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_ENUM: { + const WASMComponentEnumType *ea = a->def_val.enum_type; + const WASMComponentEnumType *eb = b->def_val.enum_type; + if (ea->count != eb->count) return false; + for (uint32_t i = 0; i < ea->count; i++) { + if (strcmp(ea->labels[i].name, eb->labels[i].name) != 0) + return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_OPTION: + return valtype_equal(a->def_val.option->element_type, b->def_val.option->element_type, ctx); + + case WASM_COMP_DEF_VAL_RESULT: + return valtype_equal(a->def_val.result->result_type, b->def_val.result->result_type, ctx) && valtype_equal(a->def_val.result->error_type, b->def_val.result->error_type, ctx); + + case WASM_COMP_DEF_VAL_OWN: + return a->def_val.owned->type_idx == b->def_val.owned->type_idx; + + case WASM_COMP_DEF_VAL_BORROW: + return a->def_val.borrow->type_idx == b->def_val.borrow->type_idx; + + case WASM_COMP_DEF_VAL_STREAM: + return valtype_equal(a->def_val.stream->element_type, b->def_val.stream->element_type, ctx); + + case WASM_COMP_DEF_VAL_FUTURE: + return valtype_equal(a->def_val.future->element_type, b->def_val.future->element_type, ctx); + + default: + return false; + } +} + +// Compare two top-level WASMComponentTypes* for structural equality. +static bool component_type_equal(WASMComponentTypes *a, WASMComponentTypes *b, WASMComponentValidationContext *ctx) { + if (a == b) return true; + if (!a || !b) return false; + if (a->tag != b->tag) return false; + + switch (a->tag) { + case WASM_COMP_DEF_TYPE: + return defvaltype_equal(a->type.def_val_type, b->type.def_val_type, ctx); + case WASM_COMP_FUNC_TYPE: + return functype_equal(a->type.func_type, b->type.func_type, ctx); + case WASM_COMP_RESOURCE_TYPE_SYNC: + case WASM_COMP_RESOURCE_TYPE_ASYNC: // Resource types are generative - each definition creates a unique type + default: + // Component types and instance types - structural comparison would + // require walking their declaration lists. For now, same-pointer only. + return false; + } +} + + +// Check if valtype A is a subtype of valtype B. +static bool valtype_subtype(WASMComponentValueType *a, WASMComponentValueType *b, WASMComponentValidationContext *ctx) { + if (a == b) return true; + if (!a || !b) return false; + + if (a->type == WASM_COMP_VAL_TYPE_PRIMVAL && b->type == WASM_COMP_VAL_TYPE_PRIMVAL) + return a->type_specific.primval_type == b->type_specific.primval_type; + + if (a->type == WASM_COMP_VAL_TYPE_IDX && b->type == WASM_COMP_VAL_TYPE_IDX) { + if (a->type_specific.type_idx == b->type_specific.type_idx) + return true; + + uint32_t idx_a = a->type_specific.type_idx; + uint32_t idx_b = b->type_specific.type_idx; + if (idx_a >= ctx->type_count || idx_b >= ctx->type_count) + return false; + // If either type is opaque (NULL from import/alias), it cannot structurally compare and assume valid + if (!ctx->types[idx_a] || !ctx->types[idx_b]) + return true; + + WASMComponentTypes *ta = ctx->types[idx_a]; + WASMComponentTypes *tb = ctx->types[idx_b]; + if (ta->tag != WASM_COMP_DEF_TYPE || tb->tag != WASM_COMP_DEF_TYPE) + return ta->tag == tb->tag; + + return defvaltype_subtype(ta->type.def_val_type, tb->type.def_val_type, ctx); + } + + return false; +} + +// Check if functype A is a subtype of functype B. +// Params are CONTRAVARIANT (B's param types subtype of A's), +// results are COVARIANT (A's result types subtype of B's). +static bool functype_subtype(WASMComponentFuncType *a, WASMComponentFuncType *b, WASMComponentValidationContext *ctx) { + if (a == b) return true; + if (!a || !b) return false; + + uint32_t pa = a->params ? a->params->count : 0; + uint32_t pb = b->params ? b->params->count : 0; + if (pa != pb) return false; + + for (uint32_t i = 0; i < pa; i++) { + if (strcmp(a->params->params[i].label->name, + b->params->params[i].label->name) != 0) + return false; + // CONTRAVARIANT: B's param must be subtype of A's param + if (!valtype_subtype(b->params->params[i].value_type, + a->params->params[i].value_type, ctx)) + return false; + } + + if (!a->results && !b->results) return true; + if (!a->results || !b->results) return false; + if (a->results->tag != b->results->tag) return false; + if (a->results->tag == WASM_COMP_RESULT_LIST_EMPTY) return true; + + // COVARIANT: A's result must be subtype of B's result + return valtype_subtype(a->results->results, b->results->results, ctx); +} + +// Check if defvaltype A is a subtype of defvaltype B. +static bool defvaltype_subtype(WASMComponentDefValType *a, WASMComponentDefValType *b, WASMComponentValidationContext *ctx) { + uint32_t i = 0, j = 0; + + if (a == b) return true; + if (!a || !b) return false; + if (a->tag != b->tag) return false; + + switch (a->tag) { + case WASM_COMP_DEF_VAL_PRIMVAL: + return a->def_val.primval == b->def_val.primval; + + case WASM_COMP_DEF_VAL_RECORD: { + // A must have ALL of B's fields, with subtype values. + // A may have extra fields. + const WASMComponentRecordType *ra = a->def_val.record; + const WASMComponentRecordType *rb = b->def_val.record; + for (i = 0; i < rb->count; i++) { + bool found = false; + for (j = 0; j < ra->count; j++) { + if (strcmp(ra->fields[j].label->name, rb->fields[i].label->name) == 0) { + if (!valtype_subtype(ra->fields[j].value_type, rb->fields[i].value_type, ctx)) + return false; + found = true; + break; + } + } + if (!found) return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_VARIANT: { + // Every case in A must exist in B, with subtype values. + const WASMComponentVariantType *va = a->def_val.variant; + const WASMComponentVariantType *vb = b->def_val.variant; + for (i = 0; i < va->count; i++) { + bool found = false; + for (j = 0; j < vb->count; j++) { + if (strcmp(va->cases[i].label->name, vb->cases[j].label->name) == 0) { + if (!valtype_subtype(va->cases[i].value_type, vb->cases[j].value_type, ctx)) + return false; + found = true; + break; + } + } + if (!found) return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_LIST: + return valtype_subtype(a->def_val.list->element_type, b->def_val.list->element_type, ctx); + + case WASM_COMP_DEF_VAL_LIST_LEN: + if (a->def_val.list_len->len != b->def_val.list_len->len) + return false; + return valtype_subtype(a->def_val.list_len->element_type, b->def_val.list_len->element_type, ctx); + + case WASM_COMP_DEF_VAL_TUPLE: { + const WASMComponentTupleType *ta = a->def_val.tuple; + const WASMComponentTupleType *tb = b->def_val.tuple; + if (ta->count != tb->count) return false; + for (i = 0; i < ta->count; i++) { + if (!valtype_subtype(&ta->element_types[i], &tb->element_types[i], ctx)) + return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_FLAGS: { + // A's flags must be a SUBSET of B's flags + const WASMComponentFlagType *fa = a->def_val.flag; + const WASMComponentFlagType *fb = b->def_val.flag; + for (i = 0; i < fa->count; i++) { + bool found = false; + for (j = 0; j < fb->count; j++) { + if (strcmp(fa->flags[i].name, fb->flags[j].name) == 0) { + found = true; + break; + } + } + if (!found) return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_ENUM: { + // A's labels must be a SUBSET of B's labels + const WASMComponentEnumType *ea = a->def_val.enum_type; + const WASMComponentEnumType *eb = b->def_val.enum_type; + for (i = 0; i < ea->count; i++) { + bool found = false; + for (j = 0; j < eb->count; j++) { + if (strcmp(ea->labels[i].name, eb->labels[j].name) == 0) { + found = true; + break; + } + } + if (!found) return false; + } + return true; + } + + case WASM_COMP_DEF_VAL_OPTION: + return valtype_subtype(a->def_val.option->element_type, b->def_val.option->element_type, ctx); + + case WASM_COMP_DEF_VAL_RESULT: + return valtype_subtype(a->def_val.result->result_type, b->def_val.result->result_type, ctx) && valtype_subtype(a->def_val.result->error_type, b->def_val.result->error_type, ctx); + + case WASM_COMP_DEF_VAL_OWN: { + uint32_t ia = a->def_val.owned->type_idx; + uint32_t ib = b->def_val.owned->type_idx; + if (ia == ib) return true; + // Resolve through types array - same pointer means same resource + if (ia >= ctx->type_count || ib >= ctx->type_count) return false; + // If either is opaque (NULL), assume valid + if (!ctx->types[ia] || !ctx->types[ib]) return true; + return ctx->types[ia] == ctx->types[ib]; + } + + case WASM_COMP_DEF_VAL_BORROW: { + uint32_t ia = a->def_val.borrow->type_idx; + uint32_t ib = b->def_val.borrow->type_idx; + if (ia == ib) return true; + if (ia >= ctx->type_count || ib >= ctx->type_count) return false; + if (!ctx->types[ia] || !ctx->types[ib]) return true; + return ctx->types[ia] == ctx->types[ib]; + } + + case WASM_COMP_DEF_VAL_STREAM: + return valtype_subtype(a->def_val.stream->element_type, b->def_val.stream->element_type, ctx); + + case WASM_COMP_DEF_VAL_FUTURE: + return valtype_subtype(a->def_val.future->element_type, b->def_val.future->element_type, ctx); + + default: + return false; + } +} + +// Check if top-level component type A is a subtype of B. +static bool component_type_subtype(WASMComponentTypes *a, WASMComponentTypes *b, WASMComponentValidationContext *ctx) { + if (a == b) return true; + if (!a || !b) return false; + if (a->tag != b->tag) return false; + + switch (a->tag) { + case WASM_COMP_DEF_TYPE: + return defvaltype_subtype(a->type.def_val_type, b->type.def_val_type, ctx); + case WASM_COMP_FUNC_TYPE: + return functype_subtype(a->type.func_type, b->type.func_type, ctx); + case WASM_COMP_RESOURCE_TYPE_SYNC: + case WASM_COMP_RESOURCE_TYPE_ASYNC: + default: + return false; + } +} + +// Check if a value type resolves to own, returning the resource type_idx or UINT32_MAX +static uint32_t valtype_get_own_resource(WASMComponentValueType *vt, WASMComponentValidationContext *ctx) { + if (!vt || vt->type != WASM_COMP_VAL_TYPE_IDX) + return UINT32_MAX; + + uint32_t idx = vt->type_specific.type_idx; + if (idx >= ctx->type_count || !ctx->types[idx]) + return UINT32_MAX; + + WASMComponentTypes *t = ctx->types[idx]; + if (t->tag != WASM_COMP_DEF_TYPE) + return UINT32_MAX; + + if (t->type.def_val_type->tag == WASM_COMP_DEF_VAL_OWN) + return t->type.def_val_type->def_val.owned->type_idx; + + return UINT32_MAX; +} + +// Check if a value type resolves to borrow, returning the resource type_idx or UINT32_MAX +static uint32_t valtype_get_borrow_resource(WASMComponentValueType *vt, WASMComponentValidationContext *ctx) { + if (!vt || vt->type != WASM_COMP_VAL_TYPE_IDX) + return UINT32_MAX; + + uint32_t idx = vt->type_specific.type_idx; + if (idx >= ctx->type_count || !ctx->types[idx]) + return UINT32_MAX; + + WASMComponentTypes *t = ctx->types[idx]; + if (t->tag != WASM_COMP_DEF_TYPE) + return UINT32_MAX; + + if (t->type.def_val_type->tag == WASM_COMP_DEF_VAL_BORROW) + return t->type.def_val_type->def_val.borrow->type_idx; + + return UINT32_MAX; +} + +// Check if result type is (own $R) or (result (own $R) E?) +static bool result_is_own_or_result_own(WASMComponentFuncType *ft, WASMComponentValidationContext *ctx) { + if (!ft || !ft->results) + return false; + + if (ft->results->tag != WASM_COMP_RESULT_LIST_WITH_TYPE || !ft->results->results) + return false; + + WASMComponentValueType *rv = ft->results->results; + + // Direct own + if (valtype_get_own_resource(rv, ctx) != UINT32_MAX) + return true; + + // result, E?> — the result_type of a result type must be own + if (rv->type == WASM_COMP_VAL_TYPE_IDX) { + uint32_t idx = rv->type_specific.type_idx; + if (idx < ctx->type_count && ctx->types[idx] && ctx->types[idx]->tag == WASM_COMP_DEF_TYPE && ctx->types[idx]->type.def_val_type->tag == WASM_COMP_DEF_VAL_RESULT) { + WASMComponentResultType *res = ctx->types[idx]->type.def_val_type->def_val.result; + if (valtype_get_own_resource(res->result_type, ctx) != UINT32_MAX) + return true; + } + } + + return false; +} + +// Validate [constructor]/[method]/[static] annotations on a func import or export. +static bool validate_func_name_annotation(WASMComponentValidationContext *ctx, const char *name, uint32_t ft_idx, char *error_buf, uint32_t error_buf_size) { + if (!name) + return true; + + WASMComponentFuncType *ft = NULL; + if (ft_idx != UINT32_MAX && ft_idx < ctx->type_count && ctx->types[ft_idx] && ctx->types[ft_idx]->tag == WASM_COMP_FUNC_TYPE) { + ft = ctx->types[ft_idx]->type.func_type; + } + + if (strncmp(name, CONSTRUCTOR_PREFIX, CONSTRUCTOR_PREFIX_LEN) == 0) { + // [constructor]R — result must be (own $R) or (result (own $R) E?) + if (!ft) { + set_error_buf_ex(error_buf, error_buf_size, "[constructor] annotation requires a known functype"); + return false; + } + if (!result_is_own_or_result_own(ft, ctx)) { + set_error_buf_ex(error_buf, error_buf_size, "[constructor] result must be (own $R) or (result (own $R) E?)"); + return false; + } + } else if (strncmp(name, METHOD_PREFIX, METHOD_PREFIX_LEN) == 0) { + // [method]R.name — first param must be (param "self" (borrow $R)) + if (!ft) { + set_error_buf_ex(error_buf, error_buf_size, "[method] annotation requires a known functype"); + return false; + } + if (!ft->params || ft->params->count == 0) { + set_error_buf_ex(error_buf, error_buf_size, "[method] functype must have at least one parameter"); + return false; + } + WASMComponentLabelValType *first_param = &ft->params->params[0]; + if (!first_param->label || strcmp(first_param->label->name, "self") != 0) { + set_error_buf_ex(error_buf, error_buf_size, "[method] first parameter label must be \"self\""); + return false; + } + if (valtype_get_borrow_resource(first_param->value_type, ctx) == UINT32_MAX) { + set_error_buf_ex(error_buf, error_buf_size, "[method] first parameter type must be borrow"); + return false; + } + } else if (strncmp(name, STATIC_PREFIX, STATIC_PREFIX_LEN) == 0) { + // [static]R.name — R must match a preceding resource import/export name + const char *rest = name + STATIC_PREFIX_LEN; + // Extract R (everything before the first '.') + const char *dot = strchr(rest, '.'); + if (!dot || dot == rest) { + set_error_buf_ex(error_buf, error_buf_size, "[static] annotation must have form [static]R.name"); + return false; + } + size_t r_len = dot - rest; + char r_name[256]; + if (r_len >= sizeof(r_name)) { + set_error_buf_ex(error_buf, error_buf_size, "[static] resource name too long"); + return false; + } + memcpy(r_name, rest, r_len); + r_name[r_len] = '\0'; + + if (!bh_hash_map_find(ctx->resource_type_names, (void *)r_name)) { + set_error_buf_ex(error_buf, error_buf_size, "[static] resource name \"%s\" not found in scope", r_name); + return false; + } + } + + return true; +} + +// Return true if vt (or any type it transitively references) contains borrow. +// If a referenced type index is out of range or was imported/aliased (NULL entry) return false +static bool valtype_has_borrow(WASMComponentValueType *vt, WASMComponentValidationContext *ctx) { + // A null type or a primitive value type (like u32, bool, char) can never be borrow + if (!vt) return false; + if (vt->type == WASM_COMP_VAL_TYPE_PRIMVAL) return false; + + uint32_t idx = vt->type_specific.type_idx; + if (idx >= ctx->type_count || !ctx->types[idx]) return false; + + WASMComponentTypes *t = ctx->types[idx]; + if (t->tag != WASM_COMP_DEF_TYPE) return false; + + // Walk the structure recursively + WASMComponentDefValType *dvt = t->type.def_val_type; + switch (dvt->tag) { + case WASM_COMP_DEF_VAL_BORROW: + return true; + case WASM_COMP_DEF_VAL_OWN: + return false; + case WASM_COMP_DEF_VAL_RECORD: { + // Check every field of the record + WASMComponentRecordType *rec = dvt->def_val.record; + for (uint32_t i = 0; i < rec->count; i++) + if (valtype_has_borrow(rec->fields[i].value_type, ctx)) + return true; + return false; + } + case WASM_COMP_DEF_VAL_VARIANT: { + // A borrow in any variant case is enough to reject it in result position + WASMComponentVariantType *var = dvt->def_val.variant; + for (uint32_t i = 0; i < var->count; i++) + if (valtype_has_borrow(var->cases[i].value_type, ctx)) + return true; + return false; + } + case WASM_COMP_DEF_VAL_TUPLE: { + WASMComponentTupleType *tup = dvt->def_val.tuple; + for (uint32_t i = 0; i < tup->count; i++) + if (valtype_has_borrow(&tup->element_types[i], ctx)) + return true; + return false; + } + // For single-element containers, just recurse into the element type + case WASM_COMP_DEF_VAL_OPTION: + return valtype_has_borrow(dvt->def_val.option->element_type, ctx); + case WASM_COMP_DEF_VAL_RESULT: + return valtype_has_borrow(dvt->def_val.result->result_type, ctx) || valtype_has_borrow(dvt->def_val.result->error_type, ctx); + case WASM_COMP_DEF_VAL_LIST: + return valtype_has_borrow(dvt->def_val.list->element_type, ctx); + case WASM_COMP_DEF_VAL_LIST_LEN: + return valtype_has_borrow(dvt->def_val.list_len->element_type, ctx); + case WASM_COMP_DEF_VAL_FUTURE: + return valtype_has_borrow(dvt->def_val.future->element_type, ctx); + default: + // flags, enum, stream, etc - none of these can contain borrows + return false; + } +} + +static bool valtype_has_list_or_string(WASMComponentValueType *vt, WASMComponentValidationContext *ctx) { + if (!vt) return false; + + if (vt->type == WASM_COMP_VAL_TYPE_PRIMVAL) + return vt->type_specific.primval_type == WASM_COMP_PRIMVAL_STRING; + + uint32_t idx = vt->type_specific.type_idx; + if (idx >= ctx->type_count || !ctx->types[idx]) return false; + + WASMComponentTypes *t = ctx->types[idx]; + if (t->tag != WASM_COMP_DEF_TYPE) return false; + + WASMComponentDefValType *dvt = t->type.def_val_type; + switch (dvt->tag) { + case WASM_COMP_DEF_VAL_LIST: + case WASM_COMP_DEF_VAL_LIST_LEN: + return true; + case WASM_COMP_DEF_VAL_RECORD: { + WASMComponentRecordType *rec = dvt->def_val.record; + for (uint32_t i = 0; i < rec->count; i++) + if (valtype_has_list_or_string(rec->fields[i].value_type, ctx)) + return true; + return false; + } + case WASM_COMP_DEF_VAL_VARIANT: { + WASMComponentVariantType *var = dvt->def_val.variant; + for (uint32_t i = 0; i < var->count; i++) + if (valtype_has_list_or_string(var->cases[i].value_type, ctx)) + return true; + return false; + } + case WASM_COMP_DEF_VAL_TUPLE: { + WASMComponentTupleType *tup = dvt->def_val.tuple; + for (uint32_t i = 0; i < tup->count; i++) + if (valtype_has_list_or_string(&tup->element_types[i], ctx)) + return true; + return false; + } + case WASM_COMP_DEF_VAL_OPTION: + return valtype_has_list_or_string(dvt->def_val.option->element_type, ctx); + case WASM_COMP_DEF_VAL_RESULT: + return valtype_has_list_or_string(dvt->def_val.result->result_type, ctx) || valtype_has_list_or_string(dvt->def_val.result->error_type, ctx); + default: + return false; + } +} + +static bool functype_params_has_list_or_string(WASMComponentFuncType *ft, WASMComponentValidationContext *ctx) { + if (!ft || !ft->params) return false; + + for (uint32_t i = 0; i < ft->params->count; i++) + if (valtype_has_list_or_string(ft->params->params[i].value_type, ctx)) + return true; + + return false; +} + +static bool functype_results_has_list_or_string(WASMComponentFuncType *ft, WASMComponentValidationContext *ctx) { + if (!ft) return false; + + if (ft->results && ft->results->tag == WASM_COMP_RESULT_LIST_WITH_TYPE && ft->results->results) { + if (valtype_has_list_or_string(ft->results->results, ctx)) + return true; + } + + return false; +} + +static bool functype_has_list_or_string(WASMComponentFuncType *ft, WASMComponentValidationContext *ctx) { + return functype_params_has_list_or_string(ft, ctx) || functype_results_has_list_or_string(ft, ctx); +} + +// Core instances are created either by instantiating a core module with named import args, +// or by gathering existing core exports into an inline synthetic instance. +static bool validate_core_instance_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentCoreInst *core_inst = NULL; + for (uint32_t i = 0; i < section->parsed.core_instance_section->count; i++) { + core_inst = §ion->parsed.core_instance_section->instances[i]; + switch (core_inst->instance_expression_tag) { + case WASM_COMP_INSTANCE_EXPRESSION_WITH_ARGS: { + // The module being instantiated must already be in the index space + if (core_inst->expression.with_args.idx >= ctx->core_module_count) { + set_error_buf_ex(error_buf, error_buf_size, "module idx is greater than core_module_count"); + return false; + } + + // Each arg supplies a core instance as a named import; check bounds and uniqueness + for (uint32_t j = 0; j < core_inst->expression.with_args.arg_len; j++) { + if (core_inst->expression.with_args.args[j].idx.instance_idx >= ctx->core_instance_count) { + set_error_buf_ex(error_buf, error_buf_size, "instance idx is greater than core_instance_count"); + return false; + } + + // Import module names must be unique + for (uint32_t k = j + 1; k < core_inst->expression.with_args.arg_len; k++) { + if (strcmp(core_inst->expression.with_args.args[j].name->name, core_inst->expression.with_args.args[k].name->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "names are not unique"); + return false; + } + } + } + + break; + } + + case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: { + // Each export must refer to a valid index. + for (uint32_t j = 0; j < core_inst->expression.without_args.inline_expr_len; j++) { + WASMComponentInlineExport *exp = &core_inst->expression.without_args.inline_expr[j]; + uint32_t idx = exp->sort_idx->idx; + uint8_t core_sort = exp->sort_idx->sort->core_sort; + bool in_bounds = false; + // Check the idx against the relevant counter for that sort + switch (core_sort) { + case WASM_COMP_CORE_SORT_FUNC: + in_bounds = idx < ctx->core_func_count; + break; + case WASM_COMP_CORE_SORT_TABLE: + in_bounds = idx < ctx->core_table_count; + break; + case WASM_COMP_CORE_SORT_MEMORY: + in_bounds = idx < ctx->core_memory_count; + break; + case WASM_COMP_CORE_SORT_GLOBAL: + in_bounds = idx < ctx->core_global_count; + break; + case WASM_COMP_CORE_SORT_TYPE: + in_bounds = idx < ctx->core_type_count; + break; + case WASM_COMP_CORE_SORT_MODULE: + in_bounds = idx < ctx->core_module_count; + break; + case WASM_COMP_CORE_SORT_INSTANCE: + in_bounds = idx < ctx->core_instance_count; + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid core sort in inline export: 0x%02x", core_sort); + return false; + } + if (!in_bounds) { + set_error_buf_ex(error_buf, error_buf_size, "inline export idx %u out of bounds for core sort 0x%02x", idx, core_sort); + return false; + } + + // Export names within a single instance must be unique + for (uint32_t k = j + 1; k < core_inst->expression.without_args.inline_expr_len; k++) { + if (strcmp(core_inst->expression.without_args.inline_expr[j].name->name, core_inst->expression.without_args.inline_expr[k].name->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate export name in core instance"); + return false; + } + } + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "failed to validate core instance section"); + return false; + } + } + + // Each successfully validated core instance occupies the next slot in the core instance index space + ctx->core_instance_count++; + } + + return true; +} + +// Support only moduletypes. rectype/subtype are not not supported, reject to avoid silently accepting malformed binaries +static bool validate_core_type_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentCoreType *core_type_section = NULL; + for (uint32_t i = 0; i < section->parsed.core_type_section->count; i++) { + core_type_section = §ion->parsed.core_type_section->types[i]; + + switch (core_type_section->deftype->tag) { + case WASM_CORE_DEFTYPE_RECTYPE: + case WASM_CORE_DEFTYPE_SUBTYPE: { + set_error_buf_ex(error_buf, error_buf_size, "unsupported core deftype"); + return false; + } + + case WASM_CORE_DEFTYPE_MODULETYPE: { + WASMComponentCoreModuleType *moduletype = core_type_section->deftype->type.moduletype; + for (uint32_t j = 0; j < moduletype->decl_count; j++) { + switch (moduletype->declarations[j].tag) { + case WASM_CORE_MODULEDECL_IMPORT: { + const WASMComponentCoreImport *imp = moduletype->declarations[j].decl.import_decl.import; + // Each pair (module, name) must be unique within the moduletype + for (uint32_t k = 0; k < j; k++) { + if (moduletype->declarations[k].tag != WASM_CORE_MODULEDECL_IMPORT) + continue; + + const WASMComponentCoreImport *prev = moduletype->declarations[k].decl.import_decl.import; + if (strcmp(imp->mod_name->name, prev->mod_name->name) == 0 && strcmp(imp->nm->name, prev->nm->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate import (module, name) in moduledecl"); + return false; + } + } + break; + } + + case WASM_CORE_MODULEDECL_TYPE: { + // A module cannot declare another module as an inline type + if (moduletype->declarations[j].decl.type_decl.type->deftype->tag == WASM_CORE_DEFTYPE_MODULETYPE) { + set_error_buf_ex(error_buf, error_buf_size, "type declarator inside moduledecl must not be a moduletype"); + return false; + } + break; + } + + case WASM_CORE_MODULEDECL_ALIAS: { + // Alias declarations inside a moduletype can only alias types + if (moduletype->declarations[j].decl.alias_decl.alias->sort.core_sort != WASM_COMP_CORE_SORT_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "invalid core sort"); + return false; + } + break; + } + + case WASM_CORE_MODULEDECL_EXPORT: { + const WASMComponentCoreExportDecl *exp = moduletype->declarations[j].decl.export_decl.export_decl; + // Export names must be unique within the moduletype + for (uint32_t k = 0; k < j; k++) { + if (moduletype->declarations[k].tag != WASM_CORE_MODULEDECL_EXPORT) + continue; + + const WASMComponentCoreExportDecl *prev = moduletype->declarations[k].decl.export_decl.export_decl; + if (strcmp(exp->name->name, prev->name->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate export name in moduledecl"); + return false; + } + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "invalid moduletype tag"); + return false; + } + } + } + + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "invalid deftype tag"); + return false; + } + } + + ctx->core_type_count++; + } + + return true; +} + +// Nested component is validated recursively +static bool validate_component_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + bool ok = wasm_component_validate(section->parsed.component, ctx, error_buf, error_buf_size); + if (ok) ctx->component_count++; + return ok; +} + +// Each one either instantiates a component with named args, or bundles existing component-level definitions into a synthetic instance via inline exports +static bool validate_instances_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentInst *inst = NULL; + for (uint32_t i = 0; i < section->parsed.instance_section->count; i++) { + inst = §ion->parsed.instance_section->instances[i]; + + switch (inst->instance_expression_tag) { + case WASM_COMP_INSTANCE_EXPRESSION_WITH_ARGS: { + if (inst->expression.with_args.idx >= ctx->component_count) { + set_error_buf_ex(error_buf, error_buf_size, "component idx is greater than component_count"); + return false; + } + + // Each argument is a pair (name, sort+idx) that satisfies one of the import + for (uint32_t j = 0; j < inst->expression.with_args.arg_len; j++) { + WASMComponentSortIdx *sidx = inst->expression.with_args.args[j].idx.sort_idx; + bool in_bounds = false; + switch (sidx->sort->sort) { + case WASM_COMP_SORT_CORE_SORT: + if (sidx->sort->core_sort != 0x11) { + set_error_buf_ex(error_buf, error_buf_size, "only core module sort allowed in component instantiate arg"); + return false; + } + in_bounds = sidx->idx < ctx->core_module_count; + break; + case WASM_COMP_SORT_FUNC: + in_bounds = sidx->idx < ctx->func_count; + break; + case WASM_COMP_SORT_VALUE: + in_bounds = sidx->idx < ctx->value_count; + break; + case WASM_COMP_SORT_TYPE: + in_bounds = sidx->idx < ctx->type_count; + break; + case WASM_COMP_SORT_COMPONENT: + in_bounds = sidx->idx < ctx->component_count; + break; + case WASM_COMP_SORT_INSTANCE: + in_bounds = sidx->idx < ctx->instance_count; + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid sort in component instantiate arg: 0x%02x", sidx->sort->sort); + return false; + } + if (!in_bounds) { + set_error_buf_ex(error_buf, error_buf_size, "arg idx %u out of bounds for sort 0x%02x", sidx->idx, sidx->sort->sort); + return false; + } + + if (sidx->sort->sort == WASM_COMP_SORT_VALUE) { + if (!ctx_consume_value(ctx, sidx->idx, error_buf, error_buf_size)) + return false; + } + + // Argument names must be unique + for (uint32_t k = j + 1; k < inst->expression.with_args.arg_len; k++) { + if (strcmp(inst->expression.with_args.args[j].name->name, inst->expression.with_args.args[k].name->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate arg name in component instance"); + return false; + } + } + } + + break; + } + + case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: { + for (uint32_t j = 0; j < inst->expression.without_args.inline_expr_len; j++) { + WASMComponentInlineExport *exp = &inst->expression.without_args.inline_expr[j]; + uint32_t idx = exp->sort_idx->idx; + uint8_t comp_sort = exp->sort_idx->sort->sort; + bool in_bounds = false; + + switch (comp_sort) { + case WASM_COMP_SORT_CORE_SORT: + if (exp->sort_idx->sort->core_sort != 0x11) { + set_error_buf_ex(error_buf, error_buf_size, "only core module sort allowed in component inline export"); + return false; + } + in_bounds = idx < ctx->core_module_count; + break; + case WASM_COMP_SORT_FUNC: + in_bounds = idx < ctx->func_count; + break; + case WASM_COMP_SORT_VALUE: + in_bounds = idx < ctx->value_count; + break; + case WASM_COMP_SORT_TYPE: + in_bounds = idx < ctx->type_count; + break; + case WASM_COMP_SORT_COMPONENT: + in_bounds = idx < ctx->component_count; + break; + case WASM_COMP_SORT_INSTANCE: + in_bounds = idx < ctx->instance_count; + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid sort in component inline export: 0x%02x", comp_sort); + return false; + } + + if (!in_bounds) { + set_error_buf_ex(error_buf, error_buf_size, "inline export idx %u out of bounds for sort 0x%02x", idx, comp_sort); + return false; + } + + if (comp_sort == WASM_COMP_SORT_VALUE) { + if (!ctx_consume_value(ctx, idx, error_buf, error_buf_size)) + return false; + } + + // Export names within the synthetic instance must be unique + for (uint32_t k = j + 1; k < inst->expression.without_args.inline_expr_len; k++) { + if (strcmp(inst->expression.without_args.inline_expr[j].name->name, inst->expression.without_args.inline_expr[k].name->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate export name in component instance"); + return false; + } + } + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "failed to validate instance section"); + return false; + } + } + + ctx->instance_count++; + } + + return true; +} + +static bool validate_aliases_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentAliasSection *alias_section = section->parsed.alias_section; + for (uint32_t i = 0; i < alias_section->count; i++) { + WASMComponentAliasDefinition *alias_def = &alias_section->aliases[i]; + WASMComponentTypes *outer_type_propagate = NULL; + + switch (alias_def->alias_target_type) { + case WASM_COMP_ALIAS_TARGET_EXPORT: { + // The instance must already exist in the component instance index space + if (alias_def->target.exported.instance_idx >= ctx->instance_count) { + set_error_buf_ex(error_buf, error_buf_size, "invalid instance index for alias export"); + return false; + } + break; + } + + case WASM_COMP_ALIAS_TARGET_CORE_EXPORT: { + // The instance must already exist in the core component instance index space + if (alias_def->target.core_exported.instance_idx >= ctx->core_instance_count) { + set_error_buf_ex(error_buf, error_buf_size, "invalid instance index for core alias export"); + return false; + } + break; + } + + case WASM_COMP_ALIAS_TARGET_OUTER: { + // Outer aliases reach into an enclosing component's scope. ct (component traversal) is the number of component boundaries to cross + uint32_t ct = alias_def->target.outer.ct; + uint32_t idx = alias_def->target.outer.idx; + + // outer alias sort restricted to type, module (core), or component + if (alias_def->sort->sort == WASM_COMP_SORT_CORE_SORT) { + uint8_t cs = alias_def->sort->core_sort; + if (cs != WASM_COMP_CORE_SORT_TYPE && cs != WASM_COMP_CORE_SORT_MODULE) { + set_error_buf_ex(error_buf, error_buf_size, "outer alias core sort restricted to type or module"); + return false; + } + } else { + uint8_t s = alias_def->sort->sort; + if (s != WASM_COMP_SORT_TYPE && s != WASM_COMP_SORT_COMPONENT) { + set_error_buf_ex(error_buf, error_buf_size, "outer alias sort restricted to type or component"); + return false; + } + } + + // Walk up the parent chain ct levels to reach the target ancestor + WASMComponentValidationContext *ancestor = ctx; + for (uint32_t level = 0; level < ct; level++) { + ancestor = ancestor->parent; + if (!ancestor) { + set_error_buf_ex(error_buf, error_buf_size, "outer alias ct exceeds component nesting depth"); + return false; + } + } + + bool in_bounds = false; + if (alias_def->sort->sort == WASM_COMP_SORT_CORE_SORT) { + switch (alias_def->sort->core_sort) { + case WASM_COMP_CORE_SORT_TYPE: + in_bounds = idx < ancestor->core_type_count; + break; + case WASM_COMP_CORE_SORT_MODULE: + in_bounds = idx < ancestor->core_module_count; + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid core sort in outer alias"); + return false; + } + } else { + switch (alias_def->sort->sort) { + case WASM_COMP_SORT_TYPE: + in_bounds = idx < ancestor->type_count; + // If the ancestor has a types[] entry for this index, carry it into + // the current scope so own/borrow checks can still resolve it + if (in_bounds && ancestor->types) { + outer_type_propagate = ancestor->types[idx]; + if (outer_type_propagate && (outer_type_propagate->tag == WASM_COMP_RESOURCE_TYPE_SYNC || outer_type_propagate->tag == WASM_COMP_RESOURCE_TYPE_ASYNC)) { + set_error_buf_ex(error_buf, error_buf_size, "outer alias of resource type is not allowed"); + return false; + } + } + break; + case WASM_COMP_SORT_COMPONENT: in_bounds = idx < ancestor->component_count; break; + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid sort in outer alias"); + return false; + } + } + if (!in_bounds) { + set_error_buf_ex(error_buf, error_buf_size, "outer alias idx %u out of bounds", idx); + return false; + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "unknown alias target type"); + return false; + } + } + + // Every alias introduces a new entry into the matching index space + if (alias_def->sort->sort == WASM_COMP_SORT_CORE_SORT) { + switch (alias_def->sort->core_sort) { + case WASM_COMP_CORE_SORT_FUNC: + ctx->core_func_count++; + break; + case WASM_COMP_CORE_SORT_TABLE: + ctx->core_table_count++; + break; + case WASM_COMP_CORE_SORT_MEMORY: + ctx->core_memory_count++; + break; + case WASM_COMP_CORE_SORT_GLOBAL: + ctx->core_global_count++; + break; + case WASM_COMP_CORE_SORT_TYPE: + ctx->core_type_count++; + break; + case WASM_COMP_CORE_SORT_MODULE: + ctx->core_module_count++; + break; + case WASM_COMP_CORE_SORT_INSTANCE: + ctx->core_instance_count++; + break; + default: { + set_error_buf_ex(error_buf, error_buf_size, "invalid core sort in alias"); + return false; + } + } + } else { + switch (alias_def->sort->sort) { + case WASM_COMP_SORT_FUNC: + if (!ctx_push_func_type(ctx, UINT32_MAX, error_buf, error_buf_size)) + return false; + ctx->func_count++; + break; + case WASM_COMP_SORT_VALUE: + if (!ctx_push_value(ctx, error_buf, error_buf_size)) + return false; + ctx->value_count++; + break; + case WASM_COMP_SORT_TYPE: + // For type aliases we also record an entry in types[]. If this was an outer + // alias we have a real pointer; otherwise we push NULL + if (!ctx_push_type(ctx, outer_type_propagate, false, error_buf, error_buf_size)) + return false; + ctx->type_count++; + break; + case WASM_COMP_SORT_COMPONENT: + ctx->component_count++; + break; + case WASM_COMP_SORT_INSTANCE: + ctx->instance_count++; + break; + default: { + set_error_buf_ex(error_buf, error_buf_size, "invalid sort in alias: 0x%02x", alias_def->sort->sort); + return false; + } + } + } + } + + return true; +} + +// Each new type appended here gets a slot in the flat types[] array so later sections can do O(1) tag checks via type index +static bool validate_type_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentTypes *type_section = NULL; + for (uint32_t i = 0; i < section->parsed.type_section->count; i++) { + type_section = §ion->parsed.type_section->types[i]; + switch (type_section->tag) { + case WASM_COMP_DEF_TYPE: { + // defvaltype covers all the value-carrying types + WASMComponentDefValType *dvt = type_section->type.def_val_type; + switch (dvt->tag) { + case WASM_COMP_DEF_VAL_OWN: { + // own must wrap a resource type + uint32_t idx = dvt->def_val.owned->type_idx; + if (idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "own type idx %u out of bounds", idx); + return false; + } + if (ctx->types[idx] && ctx->types[idx]->tag != WASM_COMP_RESOURCE_TYPE_SYNC && ctx->types[idx]->tag != WASM_COMP_RESOURCE_TYPE_ASYNC) { + set_error_buf_ex(error_buf, error_buf_size, "own type idx must refer to a resource type"); + return false; + } + break; + } + case WASM_COMP_DEF_VAL_BORROW: { + // borrow must be a resource type + uint32_t idx = dvt->def_val.borrow->type_idx; + if (idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "borrow type idx %u out of bounds", idx); + return false; + } + if (ctx->types[idx] && ctx->types[idx]->tag != WASM_COMP_RESOURCE_TYPE_SYNC && ctx->types[idx]->tag != WASM_COMP_RESOURCE_TYPE_ASYNC) { + set_error_buf_ex(error_buf, error_buf_size, "borrow type idx must refer to a resource type"); + return false; + } + break; + } + case WASM_COMP_DEF_VAL_STREAM: { + // The spec explicitly bans (stream char) because it would conflict with the string type, which already has its own dedicated encoding options + WASMComponentStreamType *st = dvt->def_val.stream; + if (st->element_type && st->element_type->type == WASM_COMP_VAL_TYPE_PRIMVAL && st->element_type->type_specific.primval_type == WASM_COMP_PRIMVAL_CHAR) { + set_error_buf_ex(error_buf, error_buf_size, "(stream char) is not allowed"); + return false; + } + if (st->element_type && valtype_has_borrow(st->element_type, ctx)) { + set_error_buf_ex(error_buf, error_buf_size, "borrow type must not appear in stream element type"); + return false; + } + break; + } + case WASM_COMP_DEF_VAL_FUTURE: { + WASMComponentFutureType *ft = dvt->def_val.future; + if (ft->element_type && ft->element_type->type == WASM_COMP_VAL_TYPE_PRIMVAL && ft->element_type->type_specific.primval_type == WASM_COMP_PRIMVAL_CHAR) { + set_error_buf_ex(error_buf, error_buf_size, "(future char) is not allowed"); + return false; + } + if (ft->element_type && valtype_has_borrow(ft->element_type, ctx)) { + set_error_buf_ex(error_buf, error_buf_size, "borrow type must not appear in future element type"); + return false; + } + break; + } + case WASM_COMP_DEF_VAL_RECORD: { + // Record field names must all be unique + const WASMComponentRecordType *rec = dvt->def_val.record; + for (uint32_t j = 0; j < rec->count; j++) { + for (uint32_t k = j + 1; k < rec->count; k++) { + if (strcmp(rec->fields[j].label->name, rec->fields[k].label->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate field label in record type"); + return false; + } + } + } + break; + } + case WASM_COMP_DEF_VAL_VARIANT: { + // Variant case names must be unique + const WASMComponentVariantType *var = dvt->def_val.variant; + for (uint32_t j = 0; j < var->count; j++) { + for (uint32_t k = j + 1; k < var->count; k++) { + if (strcmp(var->cases[j].label->name, var->cases[k].label->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate case label in variant type"); + return false; + } + } + } + break; + } + case WASM_COMP_DEF_VAL_FLAGS: { + // Flag names duplicates would make the bitfield ambiguous so reject them + const WASMComponentFlagType *fl = dvt->def_val.flag; + for (uint32_t j = 0; j < fl->count; j++) { + for (uint32_t k = j + 1; k < fl->count; k++) { + if (strcmp(fl->flags[j].name, fl->flags[k].name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate label in flags type"); + return false; + } + } + } + break; + } + case WASM_COMP_DEF_VAL_ENUM: { + // Enum labels map to consecutive integer values, duplicates are invalid + const WASMComponentEnumType *en = dvt->def_val.enum_type; + for (uint32_t j = 0; j < en->count; j++) { + for (uint32_t k = j + 1; k < en->count; k++) { + if (strcmp(en->labels[j].name, en->labels[k].name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate label in enum type"); + return false; + } + } + } + break; + } + default: + break; + } + break; + } + + case WASM_COMP_FUNC_TYPE: { + const WASMComponentFuncType *ft = type_section->type.func_type; + // Parameter labels needs to be unique + if (ft->params) { + for (uint32_t j = 0; j < ft->params->count; j++) { + for (uint32_t k = j + 1; k < ft->params->count; k++) { + if (strcmp(ft->params->params[j].label->name, ft->params->params[k].label->name) == 0) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate parameter label in functype"); + return false; + } + } + } + } + // borrow is a caller-scoped lend and returning it across a function boundary would extend its lifetime past the call + if (ft->results && ft->results->tag == WASM_COMP_RESULT_LIST_WITH_TYPE && valtype_has_borrow(ft->results->results, ctx)) { + set_error_buf_ex(error_buf, error_buf_size, "borrow type must not appear in functype result position"); + return false; + } + break; + } + + case WASM_COMP_COMPONENT_TYPE: { + // Resource types embed one inside a componenttype would violate that uniqueness guarantee + const WASMComponentComponentType *ct = type_section->type.component_type; + for (uint32_t j = 0; j < ct->count; j++) { + WASMComponentComponentDecl *cdecl = &ct->component_decls[j]; + if (cdecl->tag == WASM_COMP_COMPONENT_DECL_TYPE) { + WASMComponentInstDecl *id = cdecl->decl.instance_decl; + if (id->tag == WASM_COMP_COMPONENT_DECL_INSTANCE_TYPE) { + const WASMComponentTypes *inner = id->decl.type; + if (inner->tag == WASM_COMP_RESOURCE_TYPE_SYNC || inner->tag == WASM_COMP_RESOURCE_TYPE_ASYNC) { + set_error_buf_ex(error_buf, error_buf_size, "resource type not allowed inside componenttype"); + return false; + } + } + } + } + break; + } + + case WASM_COMP_INSTANCE_TYPE: { + // Resource types in instancetype bodies would be shared across all instances that match the type + const WASMComponentInstType *it = type_section->type.instance_type; + for (uint32_t j = 0; j < it->count; j++) { + WASMComponentInstDecl *decl = &it->instance_decls[j]; + if (decl->tag == WASM_COMP_COMPONENT_DECL_INSTANCE_TYPE) { + const WASMComponentTypes *inner = decl->decl.type; + if (inner->tag == WASM_COMP_RESOURCE_TYPE_SYNC || inner->tag == WASM_COMP_RESOURCE_TYPE_ASYNC) { + set_error_buf_ex(error_buf, error_buf_size, "resource type not allowed inside instancetype"); + return false; + } + } + // sort restricted to type (0x03) or instance (0x05) + if (decl->tag == WASM_COMP_COMPONENT_DECL_INSTANCE_ALIAS) { + uint8_t sort = decl->decl.alias->sort->sort; + if (sort != WASM_COMP_SORT_TYPE && sort != WASM_COMP_SORT_INSTANCE) { + set_error_buf_ex(error_buf, error_buf_size, "alias inside instancedecl must be type or instance sort"); + return false; + } + } + } + break; + } + + case WASM_COMP_RESOURCE_TYPE_SYNC: { + // A sync resource may optionally declare a destructor. If it does, the destructor must be a core function that's already in scope + const WASMComponentResourceTypeSync *rs = type_section->type.resource_type->resource.sync; + if (rs->has_dtor && rs->dtor_func_idx >= ctx->core_func_count) { + set_error_buf_ex(error_buf, error_buf_size, "resource sync dtor func idx out of bounds"); + return false; + } + break; + } + + case WASM_COMP_RESOURCE_TYPE_ASYNC: { + // Async resources always have a destructor and a callback; both must be valid + const WASMComponentResourceTypeAsync *ra = type_section->type.resource_type->resource.async; + if (ra->dtor_func_idx >= ctx->core_func_count) { + set_error_buf_ex(error_buf, error_buf_size, "resource async dtor func idx out of bounds"); + return false; + } + if (ra->callback_func_idx >= ctx->core_func_count) { + set_error_buf_ex(error_buf, error_buf_size, "resource async callback func idx out of bounds"); + return false; + } + break; + } + + default: { + set_error_buf_ex(error_buf, error_buf_size, "invalid type section tag"); + return false; + } + } + + // Save the type in the flat lookup array so subsequent definitions can reference + // it by index. is_local=true distinguishes types defined here from imported/aliased ones + if (!ctx_push_type(ctx, type_section, true, error_buf, error_buf_size)) + return false; + ctx->type_count++; + } + + return true; +} + +// Options can appear in any order but each may appear at most once, and some combinations are illegal (e.g., realloc without memory) +static bool validate_canon_opts(WASMComponentValidationContext *ctx, WASMComponentCanonOpts *opts, bool is_lift, WASMComponentFuncType *ft, char *error_buf, uint32_t error_buf_size) { + if (!opts) return true; + + // Track which options have been seen so we can detect duplicates and illegal combinations + bool seen_string_enc = false; + bool has_memory = false; + bool has_realloc = false; + bool has_post_return = false; + for (uint32_t i = 0; i < opts->canon_opts_count; i++) { + WASMComponentCanonOpt *opt = &opts->canon_opts[i]; + switch (opt->tag) { + case WASM_COMP_CANON_OPT_STRING_UTF8: + case WASM_COMP_CANON_OPT_STRING_UTF16: + case WASM_COMP_CANON_OPT_STRING_LATIN1_UTF16: + // Only one string encoding may be specified + if (seen_string_enc) { + set_error_buf_ex(error_buf, error_buf_size, "string-encoding specified more than once in canonopt"); + return false; + } + seen_string_enc = true; + break; + case WASM_COMP_CANON_OPT_MEMORY: + if (has_memory) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate memory in canonopt"); + return false; + } + if (opt->payload.memory.mem_idx >= ctx->core_memory_count) { + set_error_buf_ex(error_buf, error_buf_size, "canonopt memory idx out of bounds"); + return false; + } + has_memory = true; + break; + case WASM_COMP_CANON_OPT_REALLOC: + if (has_realloc) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate realloc in canonopt"); + return false; + } + if (opt->payload.realloc_opt.func_idx >= ctx->core_func_count) { + set_error_buf_ex(error_buf, error_buf_size, "canonopt realloc func idx out of bounds"); + return false; + } + has_realloc = true; + break; + case WASM_COMP_CANON_OPT_POST_RETURN: + // post-return is called after the caller is done with returned memory and it only makes sense on lift + if (has_post_return) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate post-return in canonopt"); + return false; + } + if (!is_lift) { + set_error_buf_ex(error_buf, error_buf_size, "post-return canonopt only allowed on canon lift"); + return false; + } + if (opt->payload.post_return.func_idx >= ctx->core_func_count) { + set_error_buf_ex(error_buf, error_buf_size, "canonopt post-return func idx out of bounds"); + return false; + } + has_post_return = true; + break; + case WASM_COMP_CANON_OPT_ASYNC: + case WASM_COMP_CANON_OPT_CALLBACK: + set_error_buf_ex(error_buf, error_buf_size, "async canonopt is not supported"); + return false; + default: + set_error_buf_ex(error_buf, error_buf_size, "unknown canonopt tag: 0x%02x", opt->tag); + return false; + } + } + + if (has_realloc && !has_memory) { + set_error_buf_ex(error_buf, error_buf_size, "realloc canonopt requires memory to also be present"); + return false; + } + + if (ft && functype_has_list_or_string(ft, ctx)) { + if (!has_memory) { + set_error_buf_ex(error_buf, error_buf_size, "canon %s requires memory when functype contains list or string", is_lift ? "lift" : "lower"); + return false; + } + // realloc is needed for canon lift when params have list/string (to write incoming data), + // and for canon lower when results have list/string (to write outgoing data) + bool needs_realloc = is_lift ? functype_params_has_list_or_string(ft, ctx) : functype_results_has_list_or_string(ft, ctx); + if (needs_realloc && !has_realloc) { + set_error_buf_ex(error_buf, error_buf_size, "canon %s requires realloc when functype %s contain list or string", is_lift ? "lift" : "lower", is_lift ? "params" : "results"); + return false; + } + } + + return true; +} + +// The resource operations manage the lifetime of opaque handles passed across component boundaries +static bool validate_canons_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentCanon *canon_section = NULL; + for (uint32_t i = 0; i < section->parsed.canon_section->count; i++) { + canon_section = §ion->parsed.canon_section->canons[i]; + + switch (canon_section->tag) { + case WASM_COMP_CANON_LIFT: { + // The core func must already exist, and the type it's lifted to must be a functype + if (canon_section->canon_data.lift.core_func_idx >= ctx->core_func_count) { + set_error_buf_ex(error_buf, error_buf_size, "canon lift core func idx out of bounds"); + return false; + } + uint32_t lift_type_idx = canon_section->canon_data.lift.type_idx; + if (lift_type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "canon lift type idx out of bounds"); + return false; + } + // The type idx must refer to a functype + if (ctx->types[lift_type_idx] && ctx->types[lift_type_idx]->tag != WASM_COMP_FUNC_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "canon lift type must be a functype"); + return false; + } + WASMComponentFuncType *lift_ft = (ctx->types[lift_type_idx] && ctx->types[lift_type_idx]->tag == WASM_COMP_FUNC_TYPE) ? ctx->types[lift_type_idx]->type.func_type : NULL; + if (!validate_canon_opts(ctx, canon_section->canon_data.lift.canon_opts, true, lift_ft, error_buf, error_buf_size)) + return false; + // Lifting a core function introduces a new entry in the component function index space + if (!ctx_push_func_type(ctx, lift_type_idx, error_buf, error_buf_size)) + return false; + ctx->func_count++; + break; + } + + case WASM_COMP_CANON_LOWER: { + uint32_t lower_func_idx = canon_section->canon_data.lower.func_idx; + if (lower_func_idx >= ctx->func_count) { + set_error_buf_ex(error_buf, error_buf_size, "canon lower func idx out of bounds"); + return false; + } + // Look up the functype via func-to-type tracking + WASMComponentFuncType *lower_ft = NULL; + uint32_t lower_ft_idx = ctx->func_type_indexes[lower_func_idx]; + if (lower_ft_idx != UINT32_MAX && lower_ft_idx < ctx->type_count && ctx->types[lower_ft_idx] && ctx->types[lower_ft_idx]->tag == WASM_COMP_FUNC_TYPE) { + lower_ft = ctx->types[lower_ft_idx]->type.func_type; + } + if (!validate_canon_opts(ctx, canon_section->canon_data.lower.canon_opts, false, lower_ft, error_buf, error_buf_size)) + return false; + ctx->core_func_count++; + break; + } + + case WASM_COMP_CANON_RESOURCE_NEW: { + uint32_t rt_idx = canon_section->canon_data.resource_new.resource_type_idx; + if (rt_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.new type idx out of bounds"); + return false; + } + if (!ctx->type_is_local[rt_idx]) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.new type must be locally defined"); + return false; + } + if (ctx->types[rt_idx] && ctx->types[rt_idx]->tag != WASM_COMP_RESOURCE_TYPE_SYNC && ctx->types[rt_idx]->tag != WASM_COMP_RESOURCE_TYPE_ASYNC) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.new type must be a resource type"); + return false; + } + ctx->core_func_count++; + break; + } + + case WASM_COMP_CANON_RESOURCE_DROP: { + // resource.drop accepts both local and imported resource types + uint32_t rt_idx = canon_section->canon_data.resource_drop.resource_type_idx; + if (rt_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.drop type idx out of bounds"); + return false; + } + if (ctx->types[rt_idx] && ctx->types[rt_idx]->tag != WASM_COMP_RESOURCE_TYPE_SYNC && ctx->types[rt_idx]->tag != WASM_COMP_RESOURCE_TYPE_ASYNC) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.drop type must be a resource type"); + return false; + } + ctx->core_func_count++; + break; + } + + case WASM_COMP_CANON_RESOURCE_REP: { + uint32_t rt_idx = canon_section->canon_data.resource_rep.resource_type_idx; + if (rt_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.rep type idx out of bounds"); + return false; + } + if (!ctx->type_is_local[rt_idx]) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.rep type must be locally defined"); + return false; + } + if (ctx->types[rt_idx] && ctx->types[rt_idx]->tag != WASM_COMP_RESOURCE_TYPE_SYNC && ctx->types[rt_idx]->tag != WASM_COMP_RESOURCE_TYPE_ASYNC) { + set_error_buf_ex(error_buf, error_buf_size, "canon resource.rep type must be a resource type"); + return false; + } + ctx->core_func_count++; + break; + } + + default: + set_error_buf_ex(error_buf, error_buf_size, "unsupported canon opcode: 0x%02x", (unsigned)canon_section->tag); + return false; + } + } + + return true; +} + +static bool validate_start_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentStartSection *start_section = section->parsed.start_section; + if (start_section->func_idx >= ctx->func_count) { + set_error_buf_ex(error_buf, error_buf_size, "start function index is greater than func count"); + return false; + } + + // Verify that the start function's param/result arity matches the arg/result counts + uint32_t start_ft_idx = ctx->func_type_indexes[start_section->func_idx]; + if (start_ft_idx != UINT32_MAX && start_ft_idx < ctx->type_count && ctx->types[start_ft_idx] && ctx->types[start_ft_idx]->tag == WASM_COMP_FUNC_TYPE) { + WASMComponentFuncType *start_ft = ctx->types[start_ft_idx]->type.func_type; + uint32_t expected_params = start_ft->params ? start_ft->params->count : 0; + uint32_t expected_results = 0; + if (start_ft->results && start_ft->results->tag == WASM_COMP_RESULT_LIST_WITH_TYPE) + expected_results = 1; + + if (start_section->value_args_count != expected_params) { + set_error_buf_ex(error_buf, error_buf_size, "start section arg count %u does not match functype param count %u", + start_section->value_args_count, expected_params); + return false; + } + if (start_section->result != expected_results) { + set_error_buf_ex(error_buf, error_buf_size, "start section result count %u does not match functype result count %u", + start_section->result, expected_results); + return false; + } + } + + // Each value arg must refer to an already-defined value, and consumes it + for (uint32_t i = 0; i < start_section->value_args_count; i++) { + if (start_section->value_args[i] >= ctx->value_count) { + set_error_buf_ex(error_buf, error_buf_size, "start value arg idx %u out of bounds", start_section->value_args[i]); + return false; + } + if (!ctx_consume_value(ctx, start_section->value_args[i], error_buf, error_buf_size)) + return false; + } + // The r result values produced by start become new (unconsumed) entries in the value index space + for (uint32_t i = 0; i < start_section->result; i++) { + if (!ctx_push_value(ctx, error_buf, error_buf_size)) + return false; + ctx->value_count++; + } + + return true; +} + +// The name must be unique +static bool validate_imports_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentImport *imp = NULL; + for (uint32_t i = 0; i < section->parsed.import_section->count; i++) { + imp = §ion->parsed.import_section->imports[i]; + + // Extract the import name - either a plain string or a name with a semver suffix + const char *name = NULL; + if (imp->import_name->tag == WASM_COMP_IMPORTNAME_SIMPLE) { + name = imp->import_name->imported.simple.name->name; + } else { + name = imp->import_name->imported.versioned.name->name; + } + + if (bh_hash_map_find(ctx->import_names, (void *)name)) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate import name"); + return false; + } + bh_hash_map_insert(ctx->import_names, (void *)name, (void *)(uintptr_t)1); // NOLINT(performance-no-int-to-ptr); + + WASMComponentExternDesc *desc = imp->extern_desc; + switch (desc->type) { + case WASM_COMP_EXTERN_CORE_MODULE: + if (desc->extern_desc.core_module.type_idx >= ctx->core_type_count) { + set_error_buf_ex(error_buf, error_buf_size, "import core module type idx out of bounds"); + return false; + } + ctx->core_module_count++; + break; + case WASM_COMP_EXTERN_FUNC: { + uint32_t func_type_idx = desc->extern_desc.func.type_idx; + if (func_type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "import func type idx out of bounds"); + return false; + } + if (ctx->types[func_type_idx] && ctx->types[func_type_idx]->tag != WASM_COMP_FUNC_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "import func type idx must refer to a functype"); + return false; + } + if (!validate_func_name_annotation(ctx, name, func_type_idx, error_buf, error_buf_size)) + return false; + if (!ctx_push_func_type(ctx, func_type_idx, error_buf, error_buf_size)) + return false; + ctx->func_count++; + break; + } + case WASM_COMP_EXTERN_VALUE: { + WASMComponentValueBound *vb = desc->extern_desc.value.value_bound; + if (vb->tag == WASM_COMP_VALUEBOUND_EQ) { + if (vb->bound.value_idx >= ctx->value_count) { + set_error_buf_ex(error_buf, error_buf_size, "import value eq idx out of bounds"); + return false; + } + } else { + const WASMComponentValueType *vt = vb->bound.value_type; + if (vt->type == WASM_COMP_VAL_TYPE_IDX + && vt->type_specific.type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "import value type idx out of bounds"); + return false; + } + } + if (!ctx_push_value(ctx, error_buf, error_buf_size)) + return false; + ctx->value_count++; + break; + } + case WASM_COMP_EXTERN_TYPE: { + // Importing a type introduces a new opaque entry in the type index space + const WASMComponentTypeBound *tb = desc->extern_desc.type.type_bound; + if (tb->tag == WASM_COMP_TYPEBOUND_EQ + && tb->type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "import type eq idx out of bounds"); + return false; + } + // Sub-resource import: save the name for [static] annotation validation + if (tb->tag == WASM_COMP_TYPEBOUND_TYPE) { + bh_hash_map_insert(ctx->resource_type_names, (void *)name, (void *)(uintptr_t)1); // NOLINT(performance-no-int-to-ptr); + } + if (!ctx_push_type(ctx, NULL, false, error_buf, error_buf_size)) + return false; + ctx->type_count++; + break; + } + case WASM_COMP_EXTERN_COMPONENT: { + uint32_t comp_type_idx = desc->extern_desc.component.type_idx; + if (comp_type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "import component type idx out of bounds"); + return false; + } + if (ctx->types[comp_type_idx] && ctx->types[comp_type_idx]->tag != WASM_COMP_COMPONENT_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "import component type idx must refer to a componenttype"); + return false; + } + ctx->component_count++; + break; + } + case WASM_COMP_EXTERN_INSTANCE: { + uint32_t inst_type_idx = desc->extern_desc.instance.type_idx; + if (inst_type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "import instance type idx out of bounds"); + return false; + } + if (ctx->types[inst_type_idx] && ctx->types[inst_type_idx]->tag != WASM_COMP_INSTANCE_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "import instance type idx must refer to an instancetype"); + return false; + } + ctx->instance_count++; + break; + } + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid extern desc type in import"); + return false; + } + } + return true; +} + +// Each export name must be unique within this component, and the thing being exported must already be defined +static bool validate_exports_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + WASMComponentExport *exp = NULL; + for (uint32_t i = 0; i < section->parsed.export_section->count; i++) { + exp = §ion->parsed.export_section->exports[i]; + const char *name = NULL; + if (exp->export_name->tag == WASM_COMP_IMPORTNAME_SIMPLE) { + name = exp->export_name->exported.simple.name->name; + } else { + name = exp->export_name->exported.versioned.name->name; + } + + // Each export name must be unique + if (bh_hash_map_find(ctx->export_names, (void *)name)) { + set_error_buf_ex(error_buf, error_buf_size, "duplicate export name"); + return false; + } + bh_hash_map_insert(ctx->export_names, (void *)name, (void *)(uintptr_t)1); // NOLINT(performance-no-int-to-ptr); + + // Check that the referenced item is within bounds for its sort + uint32_t idx = exp->sort_idx->idx; + bool in_bounds = false; + if (exp->sort_idx->sort->sort == WASM_COMP_SORT_CORE_SORT) { + if (exp->sort_idx->sort->core_sort != WASM_COMP_CORE_SORT_MODULE) { + set_error_buf_ex(error_buf, error_buf_size, "only core module sort allowed in component export"); + return false; + } + in_bounds = idx < ctx->core_module_count; + } else { + switch (exp->sort_idx->sort->sort) { + case WASM_COMP_SORT_FUNC: + in_bounds = idx < ctx->func_count; + break; + case WASM_COMP_SORT_VALUE: + in_bounds = idx < ctx->value_count; + break; + case WASM_COMP_SORT_TYPE: + in_bounds = idx < ctx->type_count; + break; + case WASM_COMP_SORT_COMPONENT: + in_bounds = idx < ctx->component_count; + break; + case WASM_COMP_SORT_INSTANCE: + in_bounds = idx < ctx->instance_count; + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid sort in component export: 0x%02x", exp->sort_idx->sort->sort); + return false; + } + } + if (!in_bounds) { + set_error_buf_ex(error_buf, error_buf_size, "export sort idx %u out of bounds", idx); + return false; + } + + // Validate [constructor]/[method]/[static] annotations on func exports + if (exp->sort_idx->sort->sort == WASM_COMP_SORT_FUNC) { + uint32_t exp_ft_idx = (idx < ctx->func_count && ctx->func_type_indexes) ? ctx->func_type_indexes[idx] : UINT32_MAX; + if (!validate_func_name_annotation(ctx, name, exp_ft_idx, error_buf, error_buf_size)) + return false; + } + + // If an optional externdesc is present on the export, verify the + // exported item's type matches the declared externdesc type. + if (exp->extern_desc) { + uint8_t sort = exp->sort_idx->sort->sort; + + // externdesc sort must match the exported sort + if (sort == WASM_COMP_SORT_FUNC && exp->extern_desc->type != WASM_COMP_EXTERN_FUNC) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc sort mismatch for func"); + return false; + } + if (sort == WASM_COMP_SORT_TYPE && exp->extern_desc->type != WASM_COMP_EXTERN_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc sort mismatch for type"); + return false; + } + if (sort == WASM_COMP_SORT_COMPONENT && exp->extern_desc->type != WASM_COMP_EXTERN_COMPONENT) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc sort mismatch for component"); + return false; + } + if (sort == WASM_COMP_SORT_INSTANCE && exp->extern_desc->type != WASM_COMP_EXTERN_INSTANCE) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc sort mismatch for instance"); + return false; + } + + // For func exports: bounds + kind check, then subtype check + if (sort == WASM_COMP_SORT_FUNC) { + uint32_t decl_ft_idx = exp->extern_desc->extern_desc.func.type_idx; + if (decl_ft_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc func type idx out of bounds"); + return false; + } + if (ctx->types[decl_ft_idx] && ctx->types[decl_ft_idx]->tag != WASM_COMP_FUNC_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc func type idx must refer to a functype"); + return false; + } + + // Subtype check: exported func type <: externdesc func type + uint32_t exp_ft_idx = (idx < ctx->func_count && ctx->func_type_indexes) ? ctx->func_type_indexes[idx] : UINT32_MAX; + if (exp_ft_idx != UINT32_MAX && exp_ft_idx != decl_ft_idx && exp_ft_idx < ctx->type_count && ctx->types[exp_ft_idx] && ctx->types[decl_ft_idx]) { + if (!component_type_subtype(ctx->types[exp_ft_idx], ctx->types[decl_ft_idx], ctx)) { + set_error_buf_ex(error_buf, error_buf_size, "export func type is not a subtype of externdesc" " (type idx %u vs %u)", exp_ft_idx, decl_ft_idx); + return false; + } + } + } + + // For type exports with eq bound: verify the type_idx is in bounds + if (sort == WASM_COMP_SORT_TYPE && exp->extern_desc->extern_desc.type.type_bound) { + const WASMComponentTypeBound *bound = exp->extern_desc->extern_desc.type.type_bound; + if (bound->type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc type bound idx out of bounds"); + return false; + } + } + + // For component exports: verify the type_idx refers to a componenttype + if (sort == WASM_COMP_SORT_COMPONENT) { + uint32_t comp_type_idx = exp->extern_desc->extern_desc.component.type_idx; + if (comp_type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc component type idx out of bounds"); + return false; + } + if (ctx->types[comp_type_idx] && ctx->types[comp_type_idx]->tag != WASM_COMP_COMPONENT_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc component type idx must refer to a componenttype"); + return false; + } + } + + // For instance exports: verify the type_idx refers to an instancetype + if (sort == WASM_COMP_SORT_INSTANCE) { + uint32_t inst_type_idx = exp->extern_desc->extern_desc.instance.type_idx; + if (inst_type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc instance type idx out of bounds"); + return false; + } + if (ctx->types[inst_type_idx] && ctx->types[inst_type_idx]->tag != WASM_COMP_INSTANCE_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "export externdesc instance type idx must refer to an instancetype"); + return false; + } + } + } + + // Track resource type names for [static] annotation validation + if (exp->sort_idx->sort->sort == WASM_COMP_SORT_TYPE && idx < ctx->type_count && ctx->types[idx] && (ctx->types[idx]->tag == WASM_COMP_RESOURCE_TYPE_SYNC || ctx->types[idx]->tag == WASM_COMP_RESOURCE_TYPE_ASYNC)) { + bh_hash_map_insert(ctx->resource_type_names, (void *)name, (void *)(uintptr_t)1); // NOLINT(performance-no-int-to-ptr); + } + + // Exporting a value consumes the original entry in the value index space + if (exp->sort_idx->sort->sort == WASM_COMP_SORT_VALUE) { + if (!ctx_consume_value(ctx, idx, error_buf, error_buf_size)) + return false; + } + + // Each export that validates successfully also claims the next slot in its index space + if (exp->sort_idx->sort->sort == WASM_COMP_SORT_CORE_SORT) { + ctx->core_module_count++; + } else { + switch (exp->sort_idx->sort->sort) { + case WASM_COMP_SORT_FUNC: { + // Copy the type index from the original function being exported + uint32_t orig_ft = (idx < ctx->func_count && ctx->func_type_indexes) ? ctx->func_type_indexes[idx] : UINT32_MAX; + if (!ctx_push_func_type(ctx, orig_ft, error_buf, error_buf_size)) + return false; + ctx->func_count++; + break; + } + case WASM_COMP_SORT_VALUE: + // The re-exported value slot is immediately consumed by this export + if (!ctx_push_value(ctx, error_buf, error_buf_size)) + return false; + ctx->value_consumed[ctx->value_count] = true; + ctx->value_count++; + break; + case WASM_COMP_SORT_TYPE: + if (!ctx_push_type(ctx, NULL, false, error_buf, error_buf_size)) + return false; + ctx->type_count++; + break; + case WASM_COMP_SORT_COMPONENT: + ctx->component_count++; + break; + case WASM_COMP_SORT_INSTANCE: + ctx->instance_count++; + break; + default: + break; + } + } + } + + return true; +} + +static bool validate_values_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { + for (uint32_t i = 0; i < section->parsed.value_section->count; i++) { + WASMComponentValue *val = §ion->parsed.value_section->values[i]; + if (val->val_type->type == WASM_COMP_VAL_TYPE_IDX) { + uint32_t type_idx = val->val_type->type_specific.type_idx; + if (type_idx >= ctx->type_count) { + set_error_buf_ex(error_buf, error_buf_size, "value type idx out of bounds"); + return false; + } + // A value's type must be a defvaltype + if (ctx->types[type_idx] && ctx->types[type_idx]->tag != WASM_COMP_DEF_TYPE) { + set_error_buf_ex(error_buf, error_buf_size, "value type idx must refer to a defvaltype"); + return false; + } + } + if (valtype_has_borrow(val->val_type, ctx)) { + set_error_buf_ex(error_buf, error_buf_size, "borrow type must not appear in value type"); + return false; + } + if (!ctx_push_value(ctx, error_buf, error_buf_size)) + return false; + ctx->value_count++; + } + + return true; +} + +bool wasm_component_validate(WASMComponent *comp, WASMComponentValidationContext *parent, char *error_buf, uint32_t error_buf_size) { + if (!comp) { + set_error_buf_ex(error_buf, error_buf_size, "invalid component"); + return false; + } + + WASMComponentValidationContext ctx; + memset(&ctx, 0, sizeof(WASMComponentValidationContext)); + ctx.parent = parent; + + ctx.import_names = bh_hash_map_create(32, false, (HashFunc)wasm_string_hash, (KeyEqualFunc)wasm_string_equal, NULL, NULL); + if (!ctx.import_names) { + set_error_buf_ex(error_buf, error_buf_size, "could not allocate hashmap for import names"); + return false; + } + + ctx.export_names = bh_hash_map_create(32, false, (HashFunc)wasm_string_hash, (KeyEqualFunc)wasm_string_equal, NULL, NULL); + if (!ctx.export_names) { + bh_hash_map_destroy(ctx.import_names); + set_error_buf_ex(error_buf, error_buf_size, "could not allocate hashmap for export names"); + return false; + } + + ctx.resource_type_names = bh_hash_map_create(16, false, (HashFunc)wasm_string_hash, (KeyEqualFunc)wasm_string_equal, NULL, NULL); + if (!ctx.resource_type_names) { + bh_hash_map_destroy(ctx.import_names); + bh_hash_map_destroy(ctx.export_names); + set_error_buf_ex(error_buf, error_buf_size, "could not allocate hashmap for resource type names"); + return false; + } + + bool ok = true; + for (uint32_t i = 0; i < comp->section_count && ok; i++) { + WASMComponentSection *section = &comp->sections[i]; + + switch (section->id) { + case WASM_COMP_SECTION_CORE_CUSTOM: + break; + case WASM_COMP_SECTION_CORE_MODULE: + // Core modules are validated by the regular wasm loader when the binary is loaded + ctx.core_module_count++; + break; + case WASM_COMP_SECTION_CORE_INSTANCE: + ok = validate_core_instance_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_CORE_TYPE: + ok = validate_core_type_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_COMPONENT: + ok = validate_component_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_INSTANCES: + ok = validate_instances_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_ALIASES: + ok = validate_aliases_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_TYPE: + ok = validate_type_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_CANONS: + ok = validate_canons_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_START: + ok = validate_start_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_IMPORTS: + ok = validate_imports_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_EXPORTS: + ok = validate_exports_section(&ctx, section, error_buf, error_buf_size); + break; + case WASM_COMP_SECTION_VALUES: + ok = validate_values_section(&ctx, section, error_buf, error_buf_size); + break; + default: + set_error_buf_ex(error_buf, error_buf_size, "invalid section id: %d", section->id); + ok = false; + break; + } + } + + // Every value must have been consumed exactly once + if (ok) { + for (uint32_t i = 0; i < ctx.value_count; i++) { + if (!ctx.value_consumed[i]) { + set_error_buf_ex(error_buf, error_buf_size, "value %u is never consumed", i); + ok = false; + break; + } + } + } + + bh_hash_map_destroy(ctx.import_names); + bh_hash_map_destroy(ctx.export_names); + bh_hash_map_destroy(ctx.resource_type_names); + + if (ctx.types) + wasm_runtime_free((void *)ctx.types); + + if (ctx.type_is_local) + wasm_runtime_free(ctx.type_is_local); + + if (ctx.value_consumed) + wasm_runtime_free(ctx.value_consumed); + + if (ctx.func_type_indexes) + wasm_runtime_free(ctx.func_type_indexes); + + return ok; +} diff --git a/core/iwasm/common/component-model/wasm_component_validate.h b/core/iwasm/common/component-model/wasm_component_validate.h new file mode 100644 index 000000000..89d1207d5 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_validate.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef WASM_COMPONENT_VALIDATE_H +#define WASM_COMPONENT_VALIDATE_H + +#include "bh_hashmap.h" +#include "wasm_component.h" + +typedef struct WASMComponentValidationContext { + // Index spaces + uint32_t type_count; + uint32_t func_count; + uint32_t instance_count; + uint32_t component_count; + uint32_t value_count; + uint32_t core_type_count; + uint32_t core_module_count; + uint32_t core_instance_count; + uint32_t core_table_count; + uint32_t core_memory_count; // needed for canon memory opts + uint32_t core_global_count; + uint32_t core_func_count; // needed for canon realloc/post-return checks + + struct WASMComponentValidationContext *parent; + + // name uniqueness + HashMap *import_names; + HashMap *export_names; + + // Flat type lookup array: types[i] is the WASMComponentTypes* for type index i + // NULL for types introduced via import or alias + // type_is_local[i] is true if the type was defined in a local type section + WASMComponentTypes **types; + bool *type_is_local; + uint32_t types_capacity; + + // Consumption tracking: value_consumed[i] is true once value i has been consumed exactly once + bool *value_consumed; + uint32_t value_consumed_capacity; + + // Func-to-type tracking: func_type_indexes[i] is the type index for function i + // UINT32_MAX for functions whose type is unknown (e.g. aliased) + uint32_t *func_type_indexes; + uint32_t func_type_indexes_capacity; + + // Resource type names: tracks import/export names that introduce resource types + // Used for [static] annotation validation + HashMap *resource_type_names; +} WASMComponentValidationContext; + +bool wasm_component_validate(WASMComponent *comp, WASMComponentValidationContext *parent, char *error_buf, uint32_t error_buf_size); + +#endif diff --git a/core/iwasm/common/component-model/wasm_component_values_section.c b/core/iwasm/common/component-model/wasm_component_values_section.c new file mode 100644 index 000000000..f6abdc429 --- /dev/null +++ b/core/iwasm/common/component-model/wasm_component_values_section.c @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_component.h" +#include +#include +#include +#include +#include "wasm_loader_common.h" +#include "wasm_export.h" +#include + +// Helper function to parse a value +// Helper to check if f32 bytes represent canonical NaN +static bool is_canonical_f32_nan(const uint8_t *bytes) { + return bytes[0] == 0x00 && bytes[1] == 0x00 && + bytes[2] == 0xC0 && bytes[3] == 0x7F; +} + +// Helper to check if f64 bytes represent canonical NaN +static bool is_canonical_f64_nan(const uint8_t *bytes) { + return bytes[0] == 0x00 && bytes[1] == 0x00 && bytes[2] == 0x00 && + bytes[3] == 0x00 && bytes[4] == 0x00 && bytes[5] == 0x00 && + bytes[6] == 0xF8 && bytes[7] == 0x7F; +} + +// Helper to check if f32/f64 bytes represent any NaN (for rejection) +static bool is_any_nan(const uint8_t *bytes, bool is_f64) { + if (is_f64) { + // Check f64 NaN pattern (exponent all 1s, mantissa non-zero) + uint64_t bits = 0; + memcpy(&bits, bytes, 8); + return ((bits >> 52) & 0x7FF) == 0x7FF && (bits & 0xFFFFFFFFFFFFF) != 0; + } else { + // Check f32 NaN pattern (exponent all 1s, mantissa non-zero) + uint32_t bits = 0; + memcpy(&bits, bytes, 4); + return ((bits >> 23) & 0xFF) == 0xFF && (bits & 0x7FFFFF) != 0; + } +} + +// value ::= t: len: v: => (value t v) (where len = ||v||) +static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMComponentValue *out, char *error_buf, uint32_t error_buf_size) { + const uint8_t *p = *payload; + + // Parse the value type + WASMComponentValueType *val_type = NULL; + val_type = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + if (!val_type) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for value type"); + return false; + } + if (!parse_valtype(&p, end, val_type, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + + out->val_type = val_type; + + uint64_t core_data_len_u32_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &core_data_len_u32_leb, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + + out->core_data_len = (uint32_t)core_data_len_u32_leb; + + // Now parse v: according to t. Advance `p` per case and ensure + // the declared len matches the actual encoding size for handled cases. + if ((uint32_t)(end - p) < out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "Insufficient bytes for value payload: need %u, have %zu", out->core_data_len, (size_t)(end - p)); + wasm_runtime_free(val_type); + return false; + } + + const uint8_t *v_start = p; + + if (val_type->type == WASM_COMP_VAL_TYPE_PRIMVAL) { + switch (val_type->type_specific.primval_type) { + case WASM_COMP_PRIMVAL_BOOL: { + if (out->core_data_len != 1) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid bool length: %u (expected 1)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + uint8_t b = *p; + if (b != 0x00 && b != 0x01) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid bool value byte: 0x%02x", b); + wasm_runtime_free(val_type); + return false; + } + p += 1; + break; + } + + case WASM_COMP_PRIMVAL_U8: { + if (out->core_data_len != 1) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid u8 length: %u (expected 1)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + p += 1; + break; + } + + case WASM_COMP_PRIMVAL_S8: { + if (out->core_data_len != 1) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid s8 length: %u (expected 1)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + p += 1; + break; + } + + case WASM_COMP_PRIMVAL_S16: { + // signed LEB128 (1..3 bytes for 16-bit) + if (out->core_data_len < 1 || out->core_data_len > 3) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid s16 LEB length: %u (expected 1..3)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + uint64_t tmp = 0; + uint8_t *q = (uint8_t *)p; + const uint8_t *before = p; + if (!read_leb(&q, end, 16, true, &tmp, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + if ((uint32_t)(q - before) != out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "s16 len mismatch: declared %u, decoded %u", out->core_data_len, (uint32_t)(q - before)); + wasm_runtime_free(val_type); + return false; + } + p = (const uint8_t *)q; + break; + } + + case WASM_COMP_PRIMVAL_U16: { + // unsigned LEB128 (1..3 bytes for 16-bit) + if (out->core_data_len < 1 || out->core_data_len > 3) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid u16 LEB length: %u (expected 1..3)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + uint64_t tmp = 0; + uint8_t *q = (uint8_t *)p; + const uint8_t *before = p; + if (!read_leb(&q, end, 16, false, &tmp, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + if ((uint32_t)(q - before) != out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "u16 len mismatch: declared %u, decoded %u", out->core_data_len, (uint32_t)(q - before)); + wasm_runtime_free(val_type); + return false; + } + p = (const uint8_t *)q; + break; + } + + case WASM_COMP_PRIMVAL_S32: { + // signed LEB128 (1..5 bytes) + if (out->core_data_len < 1 || out->core_data_len > 5) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid s32 LEB length: %u (expected 1..5)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + uint64_t tmp = 0; + uint8_t *q = (uint8_t *)p; + const uint8_t *before = p; + if (!read_leb(&q, end, 32, true, &tmp, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + if ((uint32_t)(q - before) != out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "s32 len mismatch: declared %u, decoded %u", out->core_data_len, (uint32_t)(q - before)); + wasm_runtime_free(val_type); + return false; + } + p = (const uint8_t *)q; + break; + } + + case WASM_COMP_PRIMVAL_U32: { + // unsigned LEB128 (1..5 bytes) + if (out->core_data_len < 1 || out->core_data_len > 5) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid u32 LEB length: %u (expected 1..5)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + uint64_t tmp = 0; + uint8_t *q = (uint8_t *)p; + const uint8_t *before = p; + if (!read_leb(&q, end, 32, false, &tmp, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + if ((uint32_t)(q - before) != out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "u32 len mismatch: declared %u, decoded %u", out->core_data_len, (uint32_t)(q - before)); + wasm_runtime_free(val_type); + return false; + } + p = (const uint8_t *)q; + break; + } + + case WASM_COMP_PRIMVAL_S64: { + // signed LEB128 (1..10 bytes) + if (out->core_data_len < 1 || out->core_data_len > 10) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid s64 LEB length: %u (expected 1..10)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + uint64_t tmp = 0; + uint8_t *q = (uint8_t *)p; + const uint8_t *before = p; + if (!read_leb(&q, end, 64, true, &tmp, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + if ((uint32_t)(q - before) != out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "s64 len mismatch: declared %u, decoded %u", out->core_data_len, (uint32_t)(q - before)); + wasm_runtime_free(val_type); + return false; + } + p = (const uint8_t *)q; + break; + } + + case WASM_COMP_PRIMVAL_U64: { + // unsigned LEB128 (1..10 bytes) + if (out->core_data_len < 1 || out->core_data_len > 10) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid u64 LEB length: %u (expected 1..10)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + uint64_t tmp = 0; + uint8_t *q = (uint8_t *)p; + const uint8_t *before = p; + if (!read_leb(&q, end, 64, false, &tmp, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + if ((uint32_t)(q - before) != out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "u64 len mismatch: declared %u, decoded %u", out->core_data_len, (uint32_t)(q - before)); + wasm_runtime_free(val_type); + return false; + } + p = (const uint8_t *)q; + break; + } + + case WASM_COMP_PRIMVAL_F32: { + if (out->core_data_len != 4) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid f32 length: %u (expected 4)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + if (is_canonical_f32_nan(p)) { + p += 4; + break; + } else if (is_any_nan(p, false)) { + // Reject non-canonical NaN + set_error_buf_ex(error_buf, error_buf_size, "Non-canonical NaN not allowed"); + wasm_runtime_free(val_type); + return false; + } + p += 4; + break; + } + + case WASM_COMP_PRIMVAL_F64: { + if (out->core_data_len != 8) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid f64 length: %u (expected 8)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + if (is_canonical_f64_nan(p)) { + p += 8; + break; + } else if (is_any_nan(p, true)) { + // Reject non-canonical NaN + set_error_buf_ex(error_buf, error_buf_size, "Non-canonical NaN not allowed"); + wasm_runtime_free(val_type); + return false; + } + + p += 8; + break; + } + + case WASM_COMP_PRIMVAL_CHAR: { + // val(char) ::= b*:* => c (where b* = core:utf8(c)) + // Expect 1..4 bytes and ensure exactly one UTF-8 scalar + if (out->core_data_len < 1 || out->core_data_len > 4) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid char length: %u (expected 1..4)", out->core_data_len); + wasm_runtime_free(val_type); + return false; + } + if (!wasm_component_validate_single_utf8_scalar(p, out->core_data_len)) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid UTF-8 scalar for char"); + wasm_runtime_free(val_type); + return false; + } + p += out->core_data_len; + break; + } + + case WASM_COMP_PRIMVAL_STRING: { + // val(string) ::= v: => v + // core:name = name_len_leb + name_bytes; require outer len == leb_len + name_len + const uint8_t *before = p; + uint8_t *q = (uint8_t *)p; + uint64_t name_len = 0; + if (!read_leb(&q, end, 32, false, &name_len, error_buf, error_buf_size)) { + wasm_runtime_free(val_type); + return false; + } + uint32_t leb_len = (uint32_t)(q - before); + if ((uint32_t)(end - q) < (uint32_t)name_len) { + set_error_buf_ex(error_buf, error_buf_size, "Insufficient bytes for string payload: need %llu, have %zu", (unsigned long long)name_len, (size_t)(end - q)); + wasm_runtime_free(val_type); + return false; + } + if ((uint32_t)name_len + leb_len != out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, "string len mismatch: declared %u, decoded %u", out->core_data_len, (uint32_t)name_len + leb_len); + wasm_runtime_free(val_type); + return false; + } + if (!wasm_component_validate_utf8(q, (uint32_t)name_len)) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid UTF-8 in string"); + wasm_runtime_free(val_type); + return false; + } + p = q + name_len; + break; + } + default: { + set_error_buf_ex(error_buf, error_buf_size, + "Unknown primitive value type 0x%02x", + val_type->type_specific.primval_type); + wasm_runtime_free(val_type); + return false; + } + } + } else { + // valtype in the values section must be either primval or typeidx + if (val_type->type != WASM_COMP_VAL_TYPE_IDX) { + set_error_buf_ex(error_buf, error_buf_size, + "Unsupported valtype tag %u in values section (expected typeidx)", + (unsigned)val_type->type); + wasm_runtime_free(val_type); + return false; + } + + // Minimal mode for type-indexed values: + // - core_data will be set to v_start (the start of v:) + // - just advance by the declared len and validate bounds + if ((uint32_t)(end - p) < out->core_data_len) { + set_error_buf_ex(error_buf, error_buf_size, + "Insufficient bytes for type-indexed value payload: need %u, have %zu", + out->core_data_len, (size_t)(end - p)); + wasm_runtime_free(val_type); + return false; + } + p += out->core_data_len; + } + + // Keep a borrowed pointer to the raw value bytes window + out->core_data = v_start; + + *payload = p; + return true; +} + +// Section 12: values section +bool wasm_component_parse_values_section(const uint8_t **payload, uint32_t payload_len, WASMComponentValueSection *out, char *error_buf, uint32_t error_buf_size, uint32_t *consumed_len) { + if (!payload || !*payload || payload_len == 0 || !out) { + set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + if (consumed_len) *consumed_len = 0; + return false; + } + + const uint8_t *p = *payload; + const uint8_t *end = *payload + payload_len; + + // values ::= count: value: => (values count value) + // Read the count of values (LEB128-encoded) + uint64_t value_count_leb = 0; + if (!read_leb((uint8_t **)&p, end, 32, false, &value_count_leb, error_buf, error_buf_size)) { + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + uint32_t value_count = (uint32_t)value_count_leb; + out->count = value_count; + + if (value_count > 0) { + out->values = wasm_runtime_malloc(sizeof(WASMComponentValue) * value_count); + if (!out->values) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for values"); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + + // Initialize all values to zero to avoid garbage data + memset(out->values, 0, sizeof(WASMComponentValue) * value_count); + + for (uint32_t i = 0; i < value_count; ++i) { + if (!parse_value(&p, end, &out->values[i], error_buf, error_buf_size)) { + set_error_buf_ex(error_buf, error_buf_size, "Failed to parse value %u", i); + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return false; + } + } + } + + if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + return true; +} + +// Individual section free functions +void wasm_component_free_values_section(WASMComponentSection *section) { + if (!section || !section->parsed.value_section) { + return; + } + + WASMComponentValueSection *value_section = section->parsed.value_section; + if (value_section->values) { + for (uint32_t i = 0; i < value_section->count; i++) { + // Free the allocated val_type structures + if (value_section->values[i].val_type) { + wasm_runtime_free(value_section->values[i].val_type); + value_section->values[i].val_type = NULL; + } + // core_data points into the original payload; do not free + } + wasm_runtime_free(value_section->values); + value_section->values = NULL; + } + wasm_runtime_free(value_section); + section->parsed.value_section = NULL; +} diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index 7bbd43d16..b30b799ae 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -4,6 +4,7 @@ */ #include "bh_platform.h" +#include "wasm_ieee754.h" #if WASM_ENABLE_INTERP != 0 #include "../interpreter/wasm_runtime.h" #endif @@ -50,13 +51,6 @@ runtime_malloc(uint64 size, WASMModuleInstanceCommon *module_inst, return mem; } -static union { - int a; - char b; -} __ue = { .a = 1 }; - -#define is_little_endian() (__ue.b == 1) /* NOLINT */ - /** * Implementation of wasm_application_execute_main() */ @@ -311,47 +305,6 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, * Implementation of wasm_application_execute_func() */ -union ieee754_float { - float f; - - /* This is the IEEE 754 single-precision format. */ - union { - struct { - unsigned int negative : 1; - unsigned int exponent : 8; - unsigned int mantissa : 23; - } ieee_big_endian; - struct { - unsigned int mantissa : 23; - unsigned int exponent : 8; - unsigned int negative : 1; - } ieee_little_endian; - } ieee; -}; - -union ieee754_double { - double d; - - /* This is the IEEE 754 double-precision format. */ - union { - struct { - unsigned int negative : 1; - unsigned int exponent : 11; - /* Together these comprise the mantissa. */ - unsigned int mantissa0 : 20; - unsigned int mantissa1 : 32; - } ieee_big_endian; - - struct { - /* Together these comprise the mantissa. */ - unsigned int mantissa1 : 32; - unsigned int mantissa0 : 20; - unsigned int exponent : 11; - unsigned int negative : 1; - } ieee_little_endian; - } ieee; -}; - static bool execute_func(WASMModuleInstanceCommon *module_inst, const char *name, int32 argc, char *argv[]) diff --git a/core/iwasm/common/wasm_ieee754.h b/core/iwasm/common/wasm_ieee754.h new file mode 100644 index 000000000..612c94026 --- /dev/null +++ b/core/iwasm/common/wasm_ieee754.h @@ -0,0 +1,60 @@ +#ifndef _WASM_IEEE754_H +#define _WASM_IEEE754_H + +#ifdef __cplusplus +extern "C" { +#endif + +union ieee754_float { + float f; + + /* This is the IEEE 754 single-precision format. */ + union { + struct { + unsigned int negative : 1; + unsigned int exponent : 8; + unsigned int mantissa : 23; + } ieee_big_endian; + struct { + unsigned int mantissa : 23; + unsigned int exponent : 8; + unsigned int negative : 1; + } ieee_little_endian; + } ieee; +}; + +union ieee754_double { + double d; + + /* This is the IEEE 754 double-precision format. */ + union { + struct { + unsigned int negative : 1; + unsigned int exponent : 11; + /* Together these comprise the mantissa. */ + unsigned int mantissa0 : 20; + unsigned int mantissa1 : 32; + } ieee_big_endian; + + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1 : 32; + unsigned int mantissa0 : 20; + unsigned int exponent : 11; + unsigned int negative : 1; + } ieee_little_endian; + } ieee; +}; + +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) /* NOLINT */ + +#ifdef __cplusplus +} +#endif + +#endif /* end of _WASM_IEEE754_H */ diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 98686c3f4..c78e55d8c 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -652,6 +652,41 @@ wasm_runtime_init_internal(void) return true; } +bool wasm_decode_header(const uint8_t *buf, uint32_t size, WASMHeader *out_header) { + if (!buf || size < 8) { + return false; + } + + // WASM binary is little-endian + uint32_t magic = (uint32_t)buf[0] | ((uint32_t)buf[1] << 8) | ((uint32_t)buf[2] << 16) | ((uint32_t)buf[3] << 24); + + // Decode version and layer fields + // For Preview 1 modules: version=0x0001, layer=0x0000 (combined: 0x00000001) + // For Preview 2 components: version=0x000d, layer=0x0001 + uint16_t version = (uint16_t)buf[4] | ((uint16_t)buf[5] << 8); + uint16_t layer = (uint16_t)buf[6] | ((uint16_t)buf[7] << 8); + + out_header->magic = magic; + out_header->version = version; + out_header->layer = layer; + + return true; +} + +bool is_wasm_module(WASMHeader header) { + if (header.magic != WASM_MAGIC_NUMBER) { + return false; + } + + // For Preview 1 modules, the combined version+layer should equal 0x00000001 + uint32_t combined_version = ((uint32_t)header.layer << 16) | (uint32_t)header.version; + if (combined_version != WASM_CURRENT_VERSION) { + return false; + } + + return true; +} + bool wasm_runtime_init() { @@ -4512,6 +4547,76 @@ wasm_runtime_get_export_count(WASMModuleCommon *const module) return -1; } +#if WASM_ENABLE_INTERP != 0 +int32 +wasm_runtime_get_function_count(WASMModuleCommon *const module) +{ + if (!module) { + bh_assert(0); + return -1; + } + + + if (module->module_type == Wasm_Module_Bytecode) { + const WASMModule *wasm_module = (const WASMModule *)module; + return (int32)wasm_module->function_count; + } + + return -1; +} + +int32 +wasm_runtime_get_table_count(WASMModuleCommon *const module) +{ + if (!module) { + bh_assert(0); + return -1; + } + + + if (module->module_type == Wasm_Module_Bytecode) { + const WASMModule *wasm_module = (const WASMModule *)module; + return (int32)wasm_module->table_count; + } + + return -1; +} + +int32 +wasm_runtime_get_memories_count(WASMModuleCommon *const module) +{ + if (!module) { + bh_assert(0); + return -1; + } + + + if (module->module_type == Wasm_Module_Bytecode) { + const WASMModule *wasm_module = (const WASMModule *)module; + return (int32)wasm_module->memory_count; + } + + return -1; +} + +int32 +wasm_runtime_get_globals_count(WASMModuleCommon *const module) +{ + if (!module) { + bh_assert(0); + return -1; + } + + + if (module->module_type == Wasm_Module_Bytecode) { + const WASMModule *wasm_module = (const WASMModule *)module; + return (int32)wasm_module->global_count; + } + + return -1; +} +#endif + void wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index, wasm_export_t *export_type) diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 86f7c22b1..772e60703 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -90,6 +90,13 @@ typedef struct WASMMemory WASMMemoryType; #endif typedef WASMMemoryType *wasm_memory_type_t; +// WASM Header Structure +typedef struct WASMHeader { + uint32_t magic; // Magic number (0x6d736100 for both) + uint16_t version; // Version field + uint16_t layer; // Layer field +} WASMHeader; + typedef struct wasm_import_t { const char *module_name; const char *name; @@ -118,6 +125,11 @@ typedef struct wasm_export_t { struct WASMModuleInstanceCommon; typedef struct WASMModuleInstanceCommon *wasm_module_inst_t; +#if WASM_ENABLE_COMPONENT_MODEL != 0 +struct WASMComponentInstance; +typedef struct WASMComponentInstance WASMComponentInstance; +#endif + /* Function instance */ typedef void WASMFunctionInstanceCommon; typedef WASMFunctionInstanceCommon *wasm_function_inst_t; @@ -275,6 +287,9 @@ typedef struct LoadArgs { wasm_runtime_load_ex has to be followed by a wasm_runtime_resolve_symbols call */ bool no_resolve; +#if WASM_ENABLE_COMPONENT_MODEL != 0 + bool is_component; +#endif /* TODO: more fields? */ } LoadArgs; #endif /* LOAD_ARGS_OPTION_DEFINED */ @@ -354,6 +369,20 @@ typedef struct SharedHeapInitArgs { void *pre_allocated_addr; } SharedHeapInitArgs; +/** + * Decode a WASM file header into WASMHeader structure + * + * @return true if success, false otherwise + */ +bool wasm_decode_header(const uint8_t *buf, uint32_t size, WASMHeader *out_header); + +/** + * Check if header is a WASM Preview 1 + * + * @return true if success, false otherwise + */ +bool is_wasm_module(WASMHeader header); + /** * Initialize the WASM runtime environment, and also initialize * the memory allocator with system allocator, which calls os_malloc @@ -1602,6 +1631,48 @@ wasm_runtime_get_import_type(const wasm_module_t module, int32_t import_index, WASM_RUNTIME_API_EXTERN int32_t wasm_runtime_get_export_count(const wasm_module_t module); +#if WASM_ENABLE_INTERP != 0 +/** + * Get the number of function count for a WASM module + * + * @param module the WASM module + * + * @return the number of functions (zero for none), or -1 for failure + */ +WASM_RUNTIME_API_EXTERN int32_t +wasm_runtime_get_function_count(const wasm_module_t module); + +/** + * Get the number of table count for a WASM module + * + * @param module the WASM module + * + * @return the number of tables (zero for none), or -1 for failure + */ +WASM_RUNTIME_API_EXTERN int32_t +wasm_runtime_get_table_count(const wasm_module_t module); + +/** + * Get the number of memory count for a WASM module + * + * @param module the WASM module + * + * @return the number of memories (zero for none), or -1 for failure + */ +WASM_RUNTIME_API_EXTERN int32_t +wasm_runtime_get_memories_count(const wasm_module_t module); + +/** + * Get the number of global count for a WASM module + * + * @param module the WASM module + * + * @return the number of globals (zero for none), or -1 for failure + */ +WASM_RUNTIME_API_EXTERN int32_t +wasm_runtime_get_globals_count(const wasm_module_t module); +#endif + /** * Get information about a specific WASM module export * diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index c60349d10..f3a88330b 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -154,6 +154,8 @@ typedef void *table_elem_type_t; #define WASM_MAGIC_NUMBER 0x6d736100 #define WASM_CURRENT_VERSION 1 +#define WASM_COMPONENT_VERSION 0x000d // 0x0d 0x00 +#define WASM_COMPONENT_LAYER 0x0001 // 0x01 0x00 #define SECTION_TYPE_USER 0 #define SECTION_TYPE_TYPE 1 diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index a2c67bea2..079975e35 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -7108,7 +7108,7 @@ load(const uint8 *buf, uint32 size, WASMModule *module, module->package_version = version; if (!create_sections(buf, size, §ion_list, error_buf, error_buf_size) - || !load_from_sections(module, section_list, true, wasm_binary_freeable, + || !load_from_sections(module, section_list, false, wasm_binary_freeable, no_resolve, error_buf, error_buf_size)) { destroy_sections(section_list); return false; @@ -7130,7 +7130,10 @@ check_wasi_abi_compatibility(const WASMModule *module, #if WASM_ENABLE_MULTI_MODULE != 0 bool main_module, #endif - char *error_buf, uint32 error_buf_size) +#if WASM_ENABLE_COMPONENT_MODEL != 0 + bool is_component, +#endif + char *error_buf, uint32 error_buf_size) { /** * be careful with: @@ -7215,13 +7218,14 @@ check_wasi_abi_compatibility(const WASMModule *module, if (!module->import_wasi_api && !start && !initialize) { return true; } - +#if WASM_ENABLE_COMPONENT_MODEL != 0 /* should have one at least */ if (module->import_wasi_api && !start && !initialize) { + if (!is_component) LOG_WARNING("warning: a module with WASI apis should be either " "a command or a reactor"); } - +#endif /* * there is at least one of `_start` and `_initialize` in below cases. * according to the assumption, they should be all wasi compatible @@ -7296,7 +7300,10 @@ wasm_loader_load(uint8 *buf, uint32 size, #if WASM_ENABLE_MULTI_MODULE != 0 main_module, #endif - error_buf, error_buf_size)) { +#if WASM_ENABLE_COMPONENT_MODEL != 0 + args->is_component, +#endif + error_buf, error_buf_size)) { goto fail; } #endif diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index e41cb4d8e..4cccd9776 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -12,6 +12,10 @@ #include "mem_alloc.h" #include "../common/wasm_runtime_common.h" #include "../common/wasm_memory.h" +#if WASM_ENABLE_COMPONENT_MODEL != 0 +#include "../common/component-model/wasm_component_export.h" +#include "../common/component-model/wasm_component.h" +#endif #if WASM_ENABLE_GC != 0 #include "../common/gc/gc_object.h" #endif @@ -173,7 +177,11 @@ wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function) if (function->func_ptr_linked) { return true; } - +#if WASM_ENABLE_COMPONENT_MODEL != 0 + if (is_component_runtime()) { + return true; + } +#endif #if WASM_ENABLE_MULTI_MODULE != 0 if (!wasm_runtime_is_built_in_module(function->module_name)) { sub_module = (WASMModule *)wasm_runtime_load_depended_module( @@ -1494,6 +1502,38 @@ export_functions_instantiate(const WASMModule *module, return export_funcs; } +/** + * Instantiate export tables in a module. + */ +static WASMExportTabInstance * +export_tables_instantiate(const WASMModule *module, + WASMModuleInstance *module_inst, + uint32 export_table_count, char *error_buf, + uint32 error_buf_size) +{ + WASMExportTabInstance *export_tables, *export_table; + WASMExport *export = module->exports; + uint32 i; + uint64 total_size = + sizeof(WASMExportTabInstance) * (uint64)export_table_count; + + if (!(export_table = export_tables = + runtime_malloc(total_size, error_buf, error_buf_size))) { + return NULL; + } + + for (i = 0; i < module->export_count; i++, export ++) + if (export->kind == EXPORT_KIND_TABLE) { + export_table->name = export->name; + export_table->table = module_inst->tables[export->index]; + export_table++; + } + + bh_assert((uint32)(export_table - export_tables) == export_table_count); + return export_tables; +} + + #if WASM_ENABLE_TAGS != 0 /** * Destroy export function instances. @@ -1540,6 +1580,13 @@ export_tags_instantiate(const WASMModule *module, } #endif /* end of WASM_ENABLE_TAGS != 0 */ +static void +export_tables_deinstantiate(WASMExportTabInstance *tables) +{ + if (tables) + wasm_runtime_free(tables); +} + #if WASM_ENABLE_MULTI_MEMORY != 0 static void export_memories_deinstantiate(WASMExportMemInstance *memories) @@ -1961,6 +2008,7 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, return ret; } +#if WASM_ENABLE_COMPONENT_MODEL == 0 static bool check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, uint32 error_buf_size) @@ -2045,6 +2093,7 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, return true; } +#endif #if WASM_ENABLE_JIT != 0 static bool @@ -2623,7 +2672,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, module_inst->export_memory_count = get_export_count(module, EXPORT_KIND_MEMORY); #endif -#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_COMPONENT_MODEL != 0 module_inst->export_table_count = get_export_count(module, EXPORT_KIND_TABLE); #if WASM_ENABLE_TAGS != 0 @@ -2643,6 +2692,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, && !(module_inst->tables = tables_instantiate(module, module_inst, first_table, error_buf, error_buf_size))) + || (module_inst->export_table_count > 0 + && !(module_inst->export_tables = export_tables_instantiate( + module, module_inst, module_inst->export_table_count, + error_buf, error_buf_size))) || (module_inst->e->function_count > 0 && !(module_inst->e->functions = functions_instantiate( module, module_inst, error_buf, error_buf_size))) @@ -2779,11 +2832,11 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, } bh_assert(global_data == global_data_end); } - +#if WASM_ENABLE_COMPONENT_MODEL == 0 if (!check_linked_symbol(module_inst, error_buf, error_buf_size)) { goto fail; } - +#endif /* Initialize the memory data with data segment section */ for (i = 0; i < module->data_seg_count; i++) { WASMMemoryInstance *memory = NULL; @@ -3460,6 +3513,7 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) #endif globals_deinstantiate(module_inst->e->globals); export_functions_deinstantiate(module_inst->export_functions); + export_tables_deinstantiate(module_inst->export_tables); #if WASM_ENABLE_TAGS != 0 export_tags_deinstantiate(module_inst->e->export_tags); #endif diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 98913e9fe..daff3faef 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -28,6 +28,10 @@ typedef struct WASMGlobalInstance WASMGlobalInstance; typedef struct WASMTagInstance WASMTagInstance; #endif +#if WASM_ENABLE_COMPONENT_MODEL != 0 +#include "../common/component-model/wasm_component.h" +#endif + /** * When LLVM JIT, WAMR compiler or AOT is enabled, we should ensure that * some offsets of the same field in the interpreter module instance and @@ -204,7 +208,7 @@ struct WASMGlobalInstance { #if WASM_ENABLE_GC != 0 WASMRefType *ref_type; #endif -#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_COMPONENT_MODEL != 0 /* just for import, keep the reference here */ WASMModuleInstance *import_module_inst; WASMGlobalInstance *import_global_inst; @@ -237,7 +241,7 @@ struct WASMFunctionInstance { WASMFunctionImport *func_import; WASMFunction *func; } u; -#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_COMPONENT_MODEL != 0 WASMModuleInstance *import_module_inst; WASMFunctionInstance *import_func_inst; #endif @@ -249,6 +253,12 @@ struct WASMFunctionInstance { /* children execution time */ uint64 children_exec_time; #endif +#if WASM_ENABLE_COMPONENT_MODEL != 0 + WASMModuleInstance *module_instance; + uint32 func_idx; + bool is_canon_func; + WASMComponentCanonType canon_type; +#endif }; #if WASM_ENABLE_TAGS != 0 @@ -466,6 +476,11 @@ struct WASMModuleInstance { uint32 default_wasm_stack_size; uint32 reserved[7]; +#if WASM_ENABLE_COMPONENT_MODEL != 0 + WASMComponentInstance *comp_instance; + uint32 core_instance_idx; +#endif + /* * +------------------------------+ <-- memories * | WASMMemoryInstance[mem_count], mem_count is always 1 for LLVM JIT/AOT diff --git a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c index 5ab189e71..5b76231b4 100644 --- a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c +++ b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c @@ -2158,7 +2158,6 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data, *ro_data_len = 0; error = wasi_sock_recv_from(exec_env, sock, ri_data, ri_data_len, ri_flags, NULL, ro_data_len); - return error; } diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 4b7fbfd9f..5eef0b27e 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -45,6 +45,7 @@ add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) | [WAMR_BUILD_AOT_STACK_FRAME](#aot-stack-frame-feature) | AoT stack frame | | [WAMR_BUILD_AOT_VALIDATOR](#aot-validator) | AoT validator | | [WAMR_BUILD_BULK_MEMORY](#bulk-memory-feature) | bulk memory | +| [WAMR_BUILD_COMPONENT_MODEL](#component-model) | Component Model support | | [WAMR_BUILD_COPY_CALL_STACK](#copy-call-stack) | copy call stack | | [WAMR_BUILD_CUSTOM_NAME_SECTION](#name-section) | name section | | [WAMR_BUILD_DEBUG_AOT](#source-debugging-features) | debug AoT | @@ -222,6 +223,16 @@ Use fast jit as the first tier and LLVM JIT as the second tier. - **WAMR_BUILD_BULK_MEMORY**=1/0, default to off. +### **Component Model** + +- **WAMR_BUILD_COMPONENT_MODEL**=1/0, default to on. + +> [!NOTE] +> When enabled, the runtime can load and parse WebAssembly Component Model binaries according to the [Component Model MVP specification](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md). This includes parsing all 13 section types (core custom, core module, core instance, core type, component, instances, aliases, types, canonicals, start, imports, exports, and values). + +> [!WARNING] +> Gated features and WebAssembly 3.0 features (eg: rectype, subtype in core type sections) and async/callback canonical options are not yet supported. + ### **memory64 feature** - **WAMR_BUILD_MEMORY64**=1/0, default to off. diff --git a/product-mini/platforms/linux/CMakeLists.txt b/product-mini/platforms/linux/CMakeLists.txt index a0c0675d5..381e4e624 100644 --- a/product-mini/platforms/linux/CMakeLists.txt +++ b/product-mini/platforms/linux/CMakeLists.txt @@ -79,6 +79,11 @@ if (NOT DEFINED WAMR_BUILD_LIBC_WASI) set (WAMR_BUILD_LIBC_WASI 1) endif () +if (NOT DEFINED WAMR_BUILD_COMPONENT_MODEL) + # Enable Component Model by default + set (WAMR_BUILD_COMPONENT_MODEL 1) +endif () + if (NOT DEFINED WAMR_BUILD_FAST_INTERP) # Enable fast interpreter set (WAMR_BUILD_FAST_INTERP 1) diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index d99d991bb..c9bca7c55 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -76,45 +76,7 @@ FetchContent_MakeAvailable(googletest) include(GoogleTest) enable_testing() -add_subdirectory(wasm-vm) -add_subdirectory(interpreter) -add_subdirectory(wasm-c-api) -add_subdirectory(libc-builtin) -add_subdirectory(shared-utils) -add_subdirectory(linear-memory-wasm) -add_subdirectory(linear-memory-aot) -add_subdirectory(linux-perf) -add_subdirectory(gc) -add_subdirectory(tid-allocator) -add_subdirectory(unsupported-features) -add_subdirectory(smart-tests) -add_subdirectory(exception-handling) -add_subdirectory(running-modes) - -if(WAMR_BUILD_TARGET STREQUAL "X86_64") - add_subdirectory(aot-stack-frame) - - # should enable 32-bit llvm when X86_32 - add_subdirectory (aot) - add_subdirectory (custom-section) - add_subdirectory (compilation) - - add_subdirectory (memory64) - add_subdirectory (shared-heap) - - # HW_BOUND_CHECK is not supported on X86_32 - add_subdirectory (runtime-common) +if(DEFINED UNITTEST_FOLDER AND NOT "${UNITTEST_FOLDER}" STREQUAL "") + add_subdirectory("${UNITTEST_FOLDER}") + return() endif() - -if(WAMR_BUILD_TARGET STREQUAL "AARCH64") - add_subdirectory(aot-stack-frame) - - add_subdirectory (aot) - add_subdirectory (custom-section) - add_subdirectory (compilation) - - add_subdirectory (memory64) - add_subdirectory (shared-heap) - - add_subdirectory (runtime-common) -endif () diff --git a/tests/unit/aot-stack-frame/wasm-apps/CMakeLists.txt b/tests/unit/aot-stack-frame/wasm-apps/CMakeLists.txt index 7d80bbfbf..311c3e51a 100644 --- a/tests/unit/aot-stack-frame/wasm-apps/CMakeLists.txt +++ b/tests/unit/aot-stack-frame/wasm-apps/CMakeLists.txt @@ -11,6 +11,10 @@ if (WAMR_BUILD_TARGET STREQUAL "X86_32") set (WAMRC_OPTION ${WAMRC_OPTION} --target=i386) endif () +find_program(WAT2WASM wat2wasm + PATHS /opt/wabt/bin /usr/local/bin /usr/bin + REQUIRED) + add_custom_target( aot-stack-frame-test-wasm ALL @@ -20,7 +24,7 @@ add_custom_target( COMMAND cmake --build ${CMAKE_CURRENT_BINARY_DIR}/build-wamrc # Step 2: Compile .wast to .wasm - COMMAND /opt/wabt/bin/wat2wasm + COMMAND ${WAT2WASM} -o ${CMAKE_CURRENT_BINARY_DIR}/test.wasm ${CMAKE_CURRENT_LIST_DIR}/test.wast # Step 3: Compile .wasm to .aot using wamrc @@ -38,4 +42,3 @@ add_custom_target( -n test_aot ${CMAKE_CURRENT_BINARY_DIR}/test.aot ) - diff --git a/tests/unit/common/test_helper.h b/tests/unit/common/test_helper.h index f15c26bef..e63c431fb 100644 --- a/tests/unit/common/test_helper.h +++ b/tests/unit/common/test_helper.h @@ -71,7 +71,7 @@ class WAMRInstance public: WAMRInstance(WAMRModule &module, uint32_t stack_size = 8192, - uint32_t heap_size = 8192) + uint32_t heap_size = 32768) { module_inst_ = wasm_runtime_instantiate(module.get(), stack_size, heap_size, NULL, 0); @@ -336,4 +336,4 @@ class AppData app_addr_); } uint32_t get_app_addr() const { return app_addr_; } -}; \ No newline at end of file +}; diff --git a/tests/unit/component/CMakeLists.txt b/tests/unit/component/CMakeLists.txt new file mode 100644 index 000000000..a5e779bae --- /dev/null +++ b/tests/unit/component/CMakeLists.txt @@ -0,0 +1,64 @@ +# Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required(VERSION 3.28) + +project (test-component) + +add_definitions (-DRUN_ON_LINUX) + +add_definitions (-Dattr_container_malloc=malloc) +add_definitions (-Dattr_container_free=free) + +set (WAMR_BUILD_INTERP 1) +set (WAMR_BUILD_LIBC_WASI 1) +set (WAMR_BUILD_COMPONENT_MODEL 1) +set (WAMR_BUILD_APP_FRAMEWORK 1) +set (WAMR_BUILD_AOT 0) +set (WAMR_BUILD_REF_TYPES 1) +set (WAMR_BUILD_MULTI_MODULE 0) +set (WAMR_BUILD_LOAD_CUSTOM_SECTION 1) +set (WAMR_BUILD_SIMD 0) + +include (../unit_common.cmake) + +include_directories (${CMAKE_CURRENT_SOURCE_DIR}) + +file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc) + +set (UNIT_SOURCE ${source_all}) + +aux_source_directory(. SRC_LIST) + +set (unit_test_sources + ${UNIT_SOURCE} + ${PLATFORM_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE} + ${MEM_ALLOC_SHARED_SOURCE} + ${NATIVE_INTERFACE_SOURCE} + ${LIBC_BUILTIN_SOURCE} + ${LIBC_WASI_SOURCE} + ${IWASM_COMMON_SOURCE} + ${IWASM_COMPONENT_SOURCE} + ${IWASM_INTERP_SOURCE} + ${UNCOMMON_SHARED_SOURCE} + ) + +# Now simply link against gtest or gtest_main as needed. Eg +add_executable (component ${unit_test_sources}) + +target_include_directories(component PRIVATE ${LIBC_WASI_P2_INCLUDE_DIRS}) + +find_package(Threads REQUIRED) +target_link_libraries (component ${LLVM_AVAILABLE_LIBS} ${WAMR_TEST_OPENSSL_LIBS} gmock gtest_main Threads::Threads) + +target_compile_definitions(component PRIVATE WAMR_BUILD_COMPONENT_MODEL=1) + +add_custom_command(TARGET component POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps/*.wasm + ${CMAKE_CURRENT_BINARY_DIR}/ + COMMENT "Copy test wasm files to the directory of google test" + ) + +gtest_discover_tests(component) diff --git a/tests/unit/component/helpers.cc b/tests/unit/component/helpers.cc new file mode 100644 index 000000000..edab92ded --- /dev/null +++ b/tests/unit/component/helpers.cc @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "helpers.h" +#include "wasm_component.h" +#include "bh_read_file.h" +#include +#include +#include +#include +#include + +ComponentHelper::ComponentHelper() {} + +void +ComponentHelper::do_setup() +{ + printf("Starting setup\n"); + memset(&init_args, 0, sizeof(RuntimeInitArgs)); + + init_args.mem_alloc_type = Alloc_With_Pool; + init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; + init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); + + if (!wasm_runtime_full_init(&init_args)) { + printf("Failed to initialize WAMR runtime.\n"); + runtime_init = false; + } else { + runtime_init = true; + } + + printf("Ending setup\n"); +} + +void +ComponentHelper::do_teardown() +{ + printf("Starting teardown\n"); + + if (component_init) { + printf("Starting to unload component\n"); + if (component) { + wasm_component_free(component); + component = NULL; + } + if (component_raw) { + BH_FREE(component_raw); + component_raw = NULL; + } + component_init = false; + } + + if (runtime_init) { + printf("Starting to destroy runtime\n"); + wasm_runtime_destroy(); + runtime_init = false; + } + + printf("Ending teardown\n"); +} + +bool +ComponentHelper::read_wasm_file(const char *wasm_file) { + const char *file = wasm_file; + + printf("Reading wasm component\n"); + component_raw = + (unsigned char *)bh_read_file_to_buffer(file, &wasm_file_size); + if (!component_raw) { + printf("Failed to read wasm component from file\n"); + return false; + } + + printf("Loaded wasm component size: %u\n", wasm_file_size); + return true; +} + +bool +ComponentHelper::load_component() +{ + printf("Loading wasm component in memory\n"); + + // Allocate component structure if not already allocated + if (!component) { + component = (WASMComponent *)wasm_runtime_malloc(sizeof(WASMComponent)); + if (!component) { + printf("Failed to allocate component structure\n"); + return false; + } + memset(component, 0, sizeof(WASMComponent)); + } + + // First decode the header + if (!wasm_decode_header(component_raw, wasm_file_size, &component->header)) { + printf("Not a valid WASM component file (header mismatch).\n"); + BH_FREE(component_raw); + component_raw = NULL; + wasm_runtime_free(component); + component = NULL; + return false; + } + + // Second check if it's a valid component + if (!is_wasm_component(component->header)) { + printf("Not a valid WASM component file (header mismatch).\n"); + BH_FREE(component_raw); + component_raw = NULL; + wasm_runtime_free(component); + component = NULL; + return false; + } + + // Parse the component sections + LoadArgs load_args = {0, false, false, false, false}; + char name_buf[32]; + std::memset(name_buf, 0, sizeof(name_buf)); + std::snprintf(name_buf, sizeof(name_buf), "%s", "Test Component"); + load_args.name = name_buf; // provide non-null, mutable name as required by loader + load_args.wasm_binary_freeable = false; + load_args.clone_wasm_binary = false; + load_args.no_resolve = false; + load_args.is_component = true; + + if (!wasm_component_parse_sections(component_raw, wasm_file_size, component, &load_args, 0)) { + printf("Failed to parse WASM component sections.\n"); + BH_FREE(component_raw); + component_raw = NULL; + wasm_runtime_free(component); + component = NULL; + return false; + } + + printf("Component loaded successfully with %u sections\n", component->section_count); + component_init = true; + + printf("Finished to load wasm component\n"); + return true; +} + +uint32_t ComponentHelper::get_section_count() const { + if (!component) { + return 0; + } + return component->section_count; +} + +bool ComponentHelper::is_loaded() const { + return component_init && component && component->section_count > 0; +} + +void ComponentHelper::reset_component() { + if (component) { + wasm_component_free(component); + component = NULL; + } + component_init = false; +} + +std::vector ComponentHelper::get_section(WASMComponentSectionType section_id) const { + if (section_id < 0) return {}; + + if (!component) return {}; + + std::vector sections; + + for(uint32_t i = 0; i < component->section_count; i++) { + if (component->sections[i].id == section_id) { + sections.push_back(&component->sections[i]); + } + } + + return sections; +} + +void ComponentHelper::load_memory_offsets(const std::string& filename){ +std::ifstream file(filename); + if (!file.is_open()) { + throw std::runtime_error("Could not open layout file: " + filename); + } + + std::string line; + while (std::getline(file, line)) { + line.erase(std::remove(line.begin(), line.end(), '"'), line.end()); + + if (line.empty()) continue; + + std::stringstream ss(line); + std::string segment; + + while (std::getline(ss, segment, ',')) { + size_t eqPos = segment.find('='); + if (eqPos != std::string::npos) { + + std::string key = segment.substr(0, eqPos); + + key.erase(0, key.find_first_not_of(" \t\n\r")); + + std::string valueStr = segment.substr(eqPos + 1); + uint32_t value = std::stoul(valueStr); + + // Store + offsets[key] = value; + } + } + } +} + +uint32_t ComponentHelper::get_memory_offsets(const std::string& key) { + if (offsets.find(key) == offsets.end()) { + throw std::runtime_error("Key not found in layout: " + key); + } + return offsets[key]; +} diff --git a/tests/unit/component/helpers.h b/tests/unit/component/helpers.h new file mode 100644 index 000000000..01403da55 --- /dev/null +++ b/tests/unit/component/helpers.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef HELPERS_H +#define HELPERS_H + +#include "wasm_export.h" +#include "wasm_component.h" +#include "wasm_memory.h" +#include +#include +#include +#include +#include + +#define HEAP_SIZE (100 * 1024 * 1024) // 100 MB + +class ComponentHelper { +public: + RuntimeInitArgs init_args; + unsigned char *component_raw = NULL; + WASMComponent *component = NULL; + + uint32_t wasm_file_size = 0; + uint32_t stack_size = 16 * 1024; // 16 KB + uint32_t heap_size = HEAP_SIZE; // 100 MB + + char error_buf[128]; + char global_heap_buf[HEAP_SIZE]; // 100 MB + + bool runtime_init = false; + bool component_init = false; + bool component_instantiated = false; + + std::unordered_map offsets; // Memory offsets + + ComponentHelper(); + + bool read_wasm_file(const char *wasm_file); + bool load_component(); + + // Helpers for tests + uint32_t get_section_count() const; + bool is_loaded() const; + void reset_component(); + + void do_setup(); + void do_teardown(); + + std::vector get_section(WASMComponentSectionType section_id) const; + + void load_memory_offsets(const std::string& filename); // Loading the memory offsets from text file + uint32_t get_memory_offsets(const std::string& key); // Get memory offsets from map +}; +#endif diff --git a/tests/unit/component/test_binary_parser.cc b/tests/unit/component/test_binary_parser.cc new file mode 100644 index 000000000..2eb8d66d6 --- /dev/null +++ b/tests/unit/component/test_binary_parser.cc @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2026 Airbus Defence and Space Romania SRL. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include "helpers.h" +#include +#include +#include +#include +#include + +static std::vector component_files = { + "add.wasm", + "complex_with_host.wasm", + "complex.wasm", + "logging-service.component.wasm", + "processor_and_logging_merged_wac_plug.wasm", + "processor-service.component.wasm", + "sampletypes.wasm" +}; + +class BinaryParserTest : public testing::Test +{ + public: + std::unique_ptr helper; + BinaryParserTest() {} + ~BinaryParserTest() {} + + virtual void SetUp() { + helper = std::make_unique(); + helper->do_setup(); + } + + virtual void TearDown() { + helper->do_teardown(); + helper = nullptr; + } +}; + +TEST_F(BinaryParserTest, TestAllComponentsLoadAndUnload) +{ + // Load and unload every listed component + for (const std::string &name : component_files) { + helper->reset_component(); + std::string path = name; + printf("LoadAndUnloadComponent: %s\n", path.c_str()); + bool ret = helper->read_wasm_file(path.c_str()); + ASSERT_TRUE(ret); + ret = helper->load_component(); + ASSERT_TRUE(ret); + ASSERT_TRUE(helper->is_loaded()); + + // Unload component and free raw buffer to simulate full unload + helper->reset_component(); + if (helper->component_raw) { + BH_FREE(helper->component_raw); + helper->component_raw = NULL; + } + ASSERT_FALSE(helper->is_loaded()); + ASSERT_EQ(helper->get_section_count(), 0u); + } +} + +TEST_F(BinaryParserTest, TestLoadCorruptComponent) +{ + // Corrupt header and expect load failure + helper->reset_component(); + bool ret = helper->read_wasm_file((std::string("add.wasm").c_str())); + ASSERT_TRUE(ret); + ASSERT_TRUE(helper->component_raw != NULL); + helper->component_raw[0] ^= 0xFF; // corrupt + ret = helper->load_component(); + ASSERT_FALSE(ret); +} + +TEST_F(BinaryParserTest, TestDecodeHeaderValid) +{ + helper->reset_component(); + bool ret = helper->read_wasm_file("logging-service.component.wasm"); + ASSERT_TRUE(ret); + ASSERT_TRUE(helper->component_raw != NULL); + + WASMHeader header; + bool ok = wasm_decode_header(helper->component_raw, + helper->wasm_file_size, + &header); + ASSERT_TRUE(ok); + ASSERT_EQ(header.magic, WASM_MAGIC_NUMBER); + ASSERT_EQ(header.version, WASM_COMPONENT_VERSION); + ASSERT_EQ(header.layer, WASM_COMPONENT_LAYER); +} + +TEST_F(BinaryParserTest, TestDecodeHeaderInvalid) +{ + helper->reset_component(); + bool ret = helper->read_wasm_file("logging-service.component.wasm"); + ASSERT_TRUE(ret); + ASSERT_TRUE(helper->component_raw != NULL); + + std::vector corrupted(helper->component_raw, + helper->component_raw + helper->wasm_file_size); + corrupted[0] ^= 0xFF; // corrupt magic byte + + WASMHeader header; + ret = wasm_decode_header(corrupted.data(), + (uint32_t)corrupted.size(), + &header); + ASSERT_TRUE(ret); + ASSERT_FALSE(is_wasm_component(header)); +} + +TEST_F(BinaryParserTest, TestSectionAliasIndividual) +{ + helper->reset_component(); + bool ret = helper->read_wasm_file((std::string("add.wasm").c_str())); + ASSERT_TRUE(ret); + ASSERT_TRUE(helper->component_raw != NULL); + ret = helper->load_component(); + ASSERT_TRUE(ret); + ASSERT_TRUE(helper->is_loaded()); + + std::string check_against = "test:project/my-interface@0.1.0#add"; + + auto sections = helper->get_section(WASM_COMP_SECTION_ALIASES); + bool found = false; + for (auto section: sections) { + ASSERT_EQ(section->id, WASM_COMP_SECTION_ALIASES); + + WASMComponentAliasSection *alias_section = section->parsed.alias_section; + for (uint32_t id = 0; id < alias_section->count; id++) { + WASMComponentAliasDefinition* alias_def = &alias_section->aliases[id]; + + if (alias_def->alias_target_type == WASM_COMP_ALIAS_TARGET_CORE_EXPORT) { + if (std::string{alias_def->target.core_exported.name->name} == check_against) { + found = true; + } + } + } + } + + ASSERT_TRUE(found); +} diff --git a/tests/unit/component/wasm-apps/add.wasm b/tests/unit/component/wasm-apps/add.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b26cbdf61b62ca940cf0a13ca2b6ed267d80c5c7 GIT binary patch literal 53310 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/`!JfuN9OEF2=7&jno} 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 z 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 literal 0 HcmV?d00001 diff --git a/tests/unit/component/wasm-apps/processor_and_logging_merged_wac_plug.wasm b/tests/unit/component/wasm-apps/processor_and_logging_merged_wac_plug.wasm new file mode 100644 index 0000000000000000000000000000000000000000..9e971634fe98cd23fa0d9394f00bb9ca5aa8c41f GIT binary patch literal 333023 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 z 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 i!BeEJuED%u8tT> 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 literal 0 HcmV?d00001 diff --git a/tests/unit/component/wasm-apps/sampletypes.wasm b/tests/unit/component/wasm-apps/sampletypes.wasm new file mode 100644 index 0000000000000000000000000000000000000000..93dacf214bed23cec666c3f049ea802c747a37a7 GIT binary patch literal 191847 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 /dev/null 2>&1 # collect all code coverage data # for lcov 2.x: ignore-errors mismatch,negative -lcov -q -o ${SRC_TEMP_COV_FILE} -c -d . --rc lcov_branch_coverage=1 --rc geninfo_unexecuted_blocks=1 +lcov -q -o ${SRC_TEMP_COV_FILE} -c -d . --rc branch_coverage=1 --rc geninfo_unexecuted_blocks=1 \ + --ignore-errors mismatch,negative # extract code coverage data of WAMR source files # for lcov 2.x: ignore-errors unused lcov -q -r ${SRC_TEMP_COV_FILE} -o ${SRC_TEMP_COV_FILE} \ - -rc lcov_branch_coverage=1\ + -rc branch_coverage=1 \ + --ignore-errors unused \ "*/usr/*" "*/_deps/*" "*/deps/*" "*/tests/unit/*" \ "*/llvm/include/*" "*/include/llvm/*" "*/samples/*" \ "*/test-tools/*" "*/tests/standalone/*" "*/tests/*" @@ -41,7 +43,8 @@ lcov -q -r ${SRC_TEMP_COV_FILE} -o ${SRC_TEMP_COV_FILE} \ if [[ -s ${SRC_TEMP_COV_FILE} ]]; then if [[ -s ${DST_COV_FILE} ]]; then # merge code coverage data - lcov --rc lcov_branch_coverage=1 \ + lcov --rc branch_coverage=1 \ + --ignore-errors mismatch,negative,unused \ --add-tracefile ${SRC_TEMP_COV_FILE} \ -a ${DST_COV_FILE} -o ${SRC_COV_FILE} # backup the original lcov file @@ -64,7 +67,8 @@ if [[ -s ${SRC_TEMP_COV_FILE} ]]; then # generate html output for merged code coverage data rm -fr ${DST_COV_DIR}/wamr-lcov genhtml -q -t "WAMR Code Coverage" \ - --rc lcov_branch_coverage=1 --prefix=${prefix_full_path} \ + --rc branch_coverage=1 --prefix=${prefix_full_path} \ + --ignore-errors source,mismatch,unmapped \ -o ${DST_COV_DIR}/wamr-lcov \ ${DST_COV_FILE} diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 73b8f7dea..abc468dbc 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -22,6 +22,8 @@ function help() echo " riscv32|riscv32_ilp32f|riscv32_ilp32d|riscv64|" echo " riscv64_lp64f|riscv64_lp64d|aarch64|aarch64_vfp)" echo "-t set compile type of iwasm(classic-interp|fast-interp|jit|aot|fast-jit|multi-tier-jit)" + echo "-u choose unit test folder(s) to run - only available with -s flag set to 'unit'" + echo " accepts multiple folders: -u canonical-abi component-instantiation" echo "-M enable multi module feature" echo "-p enable multi thread feature" echo "-S enable SIMD feature" @@ -58,6 +60,8 @@ WABT_BINARY_RELEASE="NO" TYPE=("classic-interp" "fast-interp" "jit" "aot" "fast-jit" "multi-tier-jit") #default target TARGET="X86_64" +UNITTEST_FOUND="NO" +UNITTEST_FOLDERS=() ENABLE_WASI_THREADS=0 ENABLE_MULTI_MODULE=0 ENABLE_MULTI_THREAD=0 @@ -93,7 +97,7 @@ REQUIREMENT_NAME="" # Initialize an empty array for subrequirement IDs SUBREQUIREMENT_IDS=() -while getopts ":s:cabgvt:m:MCpSXexwWEPGQF:j:T:r:A:N" opt +while getopts ":s:cu:abgvt:m:MCpSXexwWEPGQF:j:T:r:A:N" opt do OPT_PARSED="TRUE" case $opt in @@ -110,6 +114,7 @@ do OPTIND=$((OPTIND+1)) eval "nxarg=\${$((OPTIND))}" done + UNITTEST_FOUND="YES" echo "test following cases: ${TEST_CASE_ARR[@]}" ;; c) @@ -120,6 +125,21 @@ do echo "cleaned all reports and temp files" fi exit 0;; + u) + if [ ${UNITTEST_FOUND} == "YES" ]; then + UNITTEST_FOLDERS+=($OPTARG) + eval "nxarg=\${$((OPTIND))}" + while [[ "${nxarg}" != -* && ${nxarg} ]]; do + UNITTEST_FOLDERS+=(${nxarg}) + OPTIND=$((OPTIND+1)) + eval "nxarg=\${$((OPTIND))}" + done + echo "running unit tests: ${UNITTEST_FOLDERS[@]}" + else + echo "suite flag -s is not set to unit tests" + exit 1 + fi + ;; a) TEST_ALL_AOT_RUNTIME="all" echo "test all runtimes in sightglass_aot" @@ -129,11 +149,11 @@ do echo "use a WABT binary release instead of compiling from source code" ;; t) - echo "set compile type of wamr " ${OPTARG} + echo "set compile type of wamr:" ${OPTARG} if [[ ${OPTARG} != "classic-interp" && ${OPTARG} != "fast-interp" \ && ${OPTARG} != "jit" && ${OPTARG} != "aot" && ${OPTARG} != "fast-jit" && ${OPTARG} != "multi-tier-jit" ]]; then - echo "*----- please varify a type of compile when using -t! -----*" + echo "*----- please verify a type of compile when using -t! -----*" help exit 1 fi @@ -141,7 +161,7 @@ do TYPE=(${OPTARG}) ;; m) - echo "set compile target of wamr" ${OPTARG} + echo "set compile target of wamr:" ${OPTARG} TARGET=$(echo "$OPTARG" | tr '[a-z]' '[A-Z]') # set target to uppercase if input x86_32 or x86_64 --> X86_32 and X86_64 ;; w) @@ -331,14 +351,118 @@ function unit_test() echo "Now start unit tests" cd ${WORK_DIR} - rm -fr unittest-build + local UNIT_DIR="${WORK_DIR}/../../unit" + local FAILED_LOG_DIR="${WORK_DIR}/unittest-failed-logs" + rm -rf "$FAILED_LOG_DIR" - echo "Build unit test" touch ${REPORT_DIR}/unit_test_report.txt - cmake -S ${WORK_DIR}/../../unit -B unittest-build \ - -DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE} - cmake --build unittest-build - ctest --test-dir unittest-build --output-on-failure | tee -a ${REPORT_DIR}/unit_test_report.txt + + local folders=() + if [[ ${#UNITTEST_FOLDERS[@]} -gt 0 ]]; then + folders=("${UNITTEST_FOLDERS[@]}") + else + folders=( + wasm-vm interpreter wasm-c-api libc-builtin shared-utils + linear-memory-wasm linear-memory-aot + linux-perf gc tid-allocator component unsupported-features smart-tests + exception-handling + ) + if [[ "${TARGET}" != "X86_32" ]]; then + folders+=( + aot-stack-frame aot custom-section compilation running-modes + memory64 shared-heap runtime-common + ) + fi + fi + + local summaries=() + local total_passed=0 + local total_failed=0 + local total_tests=0 + + for folder in "${folders[@]}"; do + echo "" + echo "========== Unit test: $folder ==========" + + local build_dir="${WORK_DIR}/unittest-build-${folder}" + rm -rf "$build_dir" + mkdir -p "$build_dir" + cd "$build_dir" + + local build_ok=true + cmake "${UNIT_DIR}" \ + -DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE} \ + -DUNITTEST_FOLDER="${folder}" || build_ok=false + + if $build_ok; then + make -j || build_ok=false + fi + + if ! $build_ok; then + summaries+=("$folder: BUILD FAILED") + total_failed=$((total_failed + 1)) + total_tests=$((total_tests + 1)) + cd ${WORK_DIR} + continue + fi + + local tmplog=$(mktemp) + set +e + script -qec "make test" /dev/null | tee "$tmplog" + local test_exit=${PIPESTATUS[0]} + set -e + + local output=$(sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' "$tmplog" | tr -d '\r') + rm -f "$tmplog" + + local result_line=$(echo "$output" | grep -E '[0-9]+% tests passed' || true) + if [[ -n "$result_line" ]]; then + local failed=$(echo "$result_line" | sed -E 's/.* ([0-9]+) tests failed.*/\1/') + local count=$(echo "$result_line" | sed -E 's/.* out of ([0-9]+)/\1/') + local passed=$((count - failed)) + total_passed=$((total_passed + passed)) + total_failed=$((total_failed + failed)) + total_tests=$((total_tests + count)) + + if [[ "$failed" -gt 0 ]]; then + mkdir -p "$FAILED_LOG_DIR" + local log_path="$FAILED_LOG_DIR/${folder}-LastTest.log" + local ctest_log="${build_dir}/Testing/Temporary/LastTest.log" + + if [[ -f "$ctest_log" ]]; then + cp "$ctest_log" "$log_path" + fi + summaries+=("$folder: $passed passed, $failed failed out of $count") + summaries+=(" Log: $log_path") + local failed_names=$(echo "$output" | sed -n '/The following tests FAILED:/,/^$/p' | grep -E '^\s+[0-9]' || true) + if [[ -n "$failed_names" ]]; then + summaries+=(" FAILED:$failed_names") + fi + else + summaries+=("$folder: $passed passed, $failed failed out of $count") + fi + else + summaries+=("$folder: NO RESULT (exit code $test_exit)") + fi + + cd ${WORK_DIR} + done + + echo "" + echo "======================================" + echo " UNIT TEST SUMMARY" + echo "======================================" + for s in "${summaries[@]}"; do + echo " $s" + done + echo "--------------------------------------" + echo " TOTAL: $total_passed passed, $total_failed failed out of $total_tests" + echo "======================================" | tee -a ${REPORT_DIR}/unit_test_report.txt + + if [[ $total_failed -gt 0 ]]; then + echo "Unit tests FAILED" | tee -a ${REPORT_DIR}/unit_test_report.txt + exit 1 + fi echo "Finish unit tests" } @@ -411,7 +535,7 @@ function setup_wabt() echo "wabt not exist, clone it from github" git clone --recursive https://github.com/WebAssembly/wabt fi - echo "upate wabt" + echo "update wabt" cd wabt \ && git fetch origin \ && git reset --hard origin/main \ @@ -882,8 +1006,10 @@ function collect_coverage() fi pushd ${WORK_DIR} > /dev/null 2>&1 - echo "Collect code coverage of iwasm" - ./collect_coverage.sh ${CODE_COV_FILE} ${IWASM_LINUX_ROOT_DIR}/build + if [[ $1 != "unit" && -d ${IWASM_LINUX_ROOT_DIR}/build ]]; then + echo "Collect code coverage of iwasm" + ./collect_coverage.sh ${CODE_COV_FILE} ${IWASM_LINUX_ROOT_DIR}/build + fi if [[ $1 == "llvm-aot" ]]; then echo "Collect code coverage of wamrc" ./collect_coverage.sh ${CODE_COV_FILE} ${WAMR_DIR}/wamr-compiler/build @@ -891,7 +1017,13 @@ function collect_coverage() for suite in "${TEST_CASE_ARR[@]}"; do if [[ ${suite} = "unit" ]]; then echo "Collect code coverage of unit test" - ./collect_coverage.sh ${CODE_COV_FILE} ${WORK_DIR}/unittest-build + if [[ ${#UNITTEST_FOLDERS[@]} -gt 0 ]]; then + for folder in "${UNITTEST_FOLDERS[@]}"; do + ./collect_coverage.sh ${CODE_COV_FILE} ${WORK_DIR}/unittest-build-${folder} + done + else + ./collect_coverage.sh ${CODE_COV_FILE} ${WORK_DIR}/unittest-build + fi break fi done @@ -1092,6 +1224,10 @@ function trigger() # if we're running the wasi certification tests. if [[ $TEST_CASE_ARR ]]; then for test in "${TEST_CASE_ARR[@]}"; do + if [[ "$test" == "unit" ]]; then + EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_LIBC_WASI=1 -DWAMR_BUILD_COMPONENT_MODEL=1" + break + fi if [[ "$test" == "wasi_certification" ]]; then EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_WASI_TEST=1" fi