diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 4c6ba63be..d2df55624 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -53,9 +53,9 @@ bh_static_assert(offsetof(AOTModuleInstance, c_api_func_imports) bh_static_assert(offsetof(AOTModuleInstance, global_table_data) == 13 * sizeof(uint64) + 128 + 14 * sizeof(uint64) #if WASM_ENABLE_COMPONENT_MODEL != 0 - + sizeof(void *) + sizeof(uint64) + + 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/wasm_component.c b/core/iwasm/common/component-model/wasm_component.c index db53fad3c..15cec3189 100644 --- a/core/iwasm/common/component-model/wasm_component.c +++ b/core/iwasm/common/component-model/wasm_component.c @@ -14,8 +14,13 @@ #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) { +// 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; } @@ -30,7 +35,8 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon const uint8_t *end = buf + size; uint32_t section_capacity = 8; - WASMComponentSection *sections = wasm_runtime_malloc(section_capacity * sizeof(WASMComponentSection)); + WASMComponentSection *sections = + wasm_runtime_malloc(section_capacity * sizeof(WASMComponentSection)); if (!sections) { return false; } @@ -40,11 +46,11 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon // 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))) { + if (!read_leb((uint8_t **)&p, end, 32, false, &payload_len, error_buf, + sizeof(error_buf))) { wasm_runtime_free(sections); return false; // Error handling } @@ -57,7 +63,8 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon // Store section info if (section_count == section_capacity) { section_capacity *= 2; - WASMComponentSection *new_sections = wasm_runtime_realloc(sections, section_capacity * sizeof(WASMComponentSection)); + WASMComponentSection *new_sections = wasm_runtime_realloc( + sections, section_capacity * sizeof(WASMComponentSection)); if (!new_sections) { wasm_runtime_free(sections); return false; @@ -70,77 +77,109 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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 + 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); + + // 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: { + 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); + 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); + 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); + LOG_DEBUG("FATAL ERROR: Custom section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } - } else { + } + else { sections[current_section_index].parsed.core_custom = custom; } break; } // Section 1: module section - case WASM_COMP_SECTION_CORE_MODULE: { + 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); + 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); + 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); + LOG_DEBUG("FATAL ERROR: Module section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } - } else { + } + 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Core Instances section " + "consumed %u bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -148,21 +187,32 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Core types section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -170,49 +220,71 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon break; } // Section 4: component section - case WASM_COMP_SECTION_COMPONENT: { + case WASM_COMP_SECTION_COMPONENT: + { // Parse and load the embedded component - WASMComponent *component = wasm_runtime_malloc(sizeof(WASMComponent)); + WASMComponent *component = + wasm_runtime_malloc(sizeof(WASMComponent)); if (!component) { - LOG_DEBUG("Failed to allocate memory for nested component\n"); + 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); + 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); + 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; + } + 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Instances section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -220,22 +292,32 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon break; } // Section 6: aliases section for imports/exports - case WASM_COMP_SECTION_ALIASES: { + 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Alias section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -243,21 +325,31 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Types section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -265,21 +357,31 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Canons section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -287,21 +389,31 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Start section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -309,22 +421,34 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Imports section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -332,21 +456,32 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Exports section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -354,21 +489,31 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon 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); + 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 { + 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); + 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); + LOG_DEBUG("FATAL ERROR: Values section consumed %u " + "bytes but expected %lu\n", + consumed_len, payload_len); wasm_runtime_free(sections); return false; } @@ -377,15 +522,16 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon } default: // Unknown/unsupported section id - LOG_DEBUG("FATAL ERROR: Unknown/unsupported section (id=%u, size=%lu)\n", section_id, payload_len); + 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); @@ -399,76 +545,81 @@ bool wasm_component_parse_sections(const uint8_t *buf, uint32_t size, WASMCompon } // 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) { +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; - +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 + case WASM_COMP_SECTION_CORE_CUSTOM: // Section 0 wasm_component_free_core_custom_section(sec); break; - - case WASM_COMP_SECTION_CORE_MODULE: // Section 1 + + case WASM_COMP_SECTION_CORE_MODULE: // Section 1 wasm_component_free_core_module_section(sec); break; - - case WASM_COMP_SECTION_CORE_INSTANCE: // Section 2 + + case WASM_COMP_SECTION_CORE_INSTANCE: // Section 2 wasm_component_free_core_instance_section(sec); break; - - case WASM_COMP_SECTION_CORE_TYPE: // Section 3 + + case WASM_COMP_SECTION_CORE_TYPE: // Section 3 wasm_component_free_core_type_section(sec); break; - - case WASM_COMP_SECTION_COMPONENT: // Section 4 + + case WASM_COMP_SECTION_COMPONENT: // Section 4 wasm_component_free_component_section(sec); break; - - case WASM_COMP_SECTION_INSTANCES: // Section 5 + + case WASM_COMP_SECTION_INSTANCES: // Section 5 wasm_component_free_instances_section(sec); break; - - case WASM_COMP_SECTION_ALIASES: // Section 6 + + case WASM_COMP_SECTION_ALIASES: // Section 6 wasm_component_free_alias_section(sec); break; - - case WASM_COMP_SECTION_TYPE: // Section 7 + + case WASM_COMP_SECTION_TYPE: // Section 7 wasm_component_free_types_section(sec); break; - - case WASM_COMP_SECTION_CANONS: // Section 8 + + case WASM_COMP_SECTION_CANONS: // Section 8 wasm_component_free_canons_section(sec); break; - - case WASM_COMP_SECTION_START: // Section 9 + + case WASM_COMP_SECTION_START: // Section 9 wasm_component_free_start_section(sec); break; - - case WASM_COMP_SECTION_IMPORTS: // Section 10 + + case WASM_COMP_SECTION_IMPORTS: // Section 10 wasm_component_free_imports_section(sec); break; - - case WASM_COMP_SECTION_EXPORTS: // Section 11 + + case WASM_COMP_SECTION_EXPORTS: // Section 11 wasm_component_free_exports_section(sec); break; - - case WASM_COMP_SECTION_VALUES: // Section 12 + + 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 @@ -479,7 +630,7 @@ void wasm_component_free(WASMComponent *component) { break; } } - + wasm_runtime_free(component->sections); component->sections = NULL; component->section_count = 0; diff --git a/core/iwasm/common/component-model/wasm_component.h b/core/iwasm/common/component-model/wasm_component.h index 1891ac696..0a1482483 100644 --- a/core/iwasm/common/component-model/wasm_component.h +++ b/core/iwasm/common/component-model/wasm_component.h @@ -17,11 +17,11 @@ // ----------------------------------------------------------------------------- // 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 +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 @@ -53,8 +53,8 @@ struct WASMComponentInlineExport; // ----------------------------------------------------------------------------- // Constants and Macros // ----------------------------------------------------------------------------- -#define INVALID_VALUE (uint8_t)0xFF -#define MAX_DEPTH_RECURSION 100 +#define INVALID_VALUE (uint8_t)0xFF +#define MAX_DEPTH_RECURSION 100 // ----------------------------------------------------------------------------- // Enums @@ -62,62 +62,63 @@ struct WASMComponentInlineExport; // 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 + 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 + 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 +// 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 + 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()) + 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; // ----------------------------------------------------------------------------- @@ -126,8 +127,8 @@ typedef enum WASMComponentSectionType { // | 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) + WASM_COMP_IMPORTNAME_SIMPLE = 0x00, // 0x00 (simple name) + WASM_COMP_IMPORTNAME_VERSIONED = 0x01 // 0x01 (versioned name) } WASMComponentImportExportTypeTag; // ----------------------------------------------------------------------------- @@ -136,8 +137,8 @@ typedef enum WASMComponentImportExportTypeTag { // | pvt: => pvt // ----------------------------------------------------------------------------- typedef enum WASMComponentValueTypeTag { - WASM_COMP_VAL_TYPE_IDX = 0x00, // 0x00 (type index) - WASM_COMP_VAL_TYPE_PRIMVAL = 0x01 // 0x01 (primitive value) + WASM_COMP_VAL_TYPE_IDX = 0x00, // 0x00 (type index) + WASM_COMP_VAL_TYPE_PRIMVAL = 0x01 // 0x01 (primitive value) } WASMComponentValueTypeTag; // ----------------------------------------------------------------------------- @@ -150,12 +151,12 @@ typedef enum WASMComponentValueTypeTag { // | 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) + 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; // ----------------------------------------------------------------------------- @@ -164,8 +165,8 @@ typedef enum WASMComponentExternDescType { // | 0x01 t: => (eq t) // ----------------------------------------------------------------------------- typedef enum WASMComponentValueBoundTag { - WASM_COMP_VALUEBOUND_EQ = 0x00, // 0x00 (equality bound) - WASM_COMP_VALUEBOUND_TYPE = 0x01 // 0x01 (type bound) + WASM_COMP_VALUEBOUND_EQ = 0x00, // 0x00 (equality bound) + WASM_COMP_VALUEBOUND_TYPE = 0x01 // 0x01 (type bound) } WASMComponentValueBoundTag; // ----------------------------------------------------------------------------- @@ -174,8 +175,8 @@ typedef enum WASMComponentValueBoundTag { // | 0x01 t: => (sub t) // ----------------------------------------------------------------------------- typedef enum WASMComponentTypeBoundTag { - WASM_COMP_TYPEBOUND_EQ = 0x00, // 0x00 (equality bound) - WASM_COMP_TYPEBOUND_TYPE = 0x01 // 0x01 (subtype bound) + WASM_COMP_TYPEBOUND_EQ = 0x00, // 0x00 (equality bound) + WASM_COMP_TYPEBOUND_TYPE = 0x01 // 0x01 (subtype bound) } WASMComponentTypeBoundTag; // ----------------------------------------------------------------------------- @@ -185,19 +186,19 @@ typedef enum WASMComponentTypeBoundTag { // | 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) + 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 => +// ? ::= 0x00 => // | 0x01 t: => t // ----------------------------------------------------------------------------- typedef enum WASMComponentOptionalField { - WASM_COMP_OPTIONAL_FALSE = 0x00, // 0x00 (absent) - WASM_COMP_OPTIONAL_TRUE = 0x01, // 0x01 (present) + WASM_COMP_OPTIONAL_FALSE = 0x00, // 0x00 (absent) + WASM_COMP_OPTIONAL_TRUE = 0x01, // 0x01 (present) } WASMComponentOptionalField; // ----------------------------------------------------------------------------- @@ -223,18 +224,19 @@ typedef enum WASMComponentOptionalField { // | 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 + 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*) +// instanceexpr ::= 0x00 c: arg*:vec() => +// (instantiate c arg*) // | 0x01 e*:vec() => e* // ----------------------------------------------------------------------------- typedef enum WASMComponentInstExpressionTag { @@ -244,7 +246,8 @@ typedef enum WASMComponentInstExpressionTag { // ----------------------------------------------------------------------------- // Result List Tag - Distinguishes with/without type -// instanceexpr ::= 0x00 c: arg*:vec() => (instantiate c arg*) +// instanceexpr ::= 0x00 c: arg*:vec() => +// (instantiate c arg*) // | 0x01 e*:vec() => e* // ----------------------------------------------------------------------------- typedef enum WASMComponentResultListTag { @@ -298,45 +301,45 @@ typedef enum WASMComponentInstDeclTag { // ----------------------------------------------------------------------------- typedef enum WASMComponentDefValTypeTag { // Primitive value type - WASM_COMP_DEF_VAL_PRIMVAL = 0x63, // pvt: + WASM_COMP_DEF_VAL_PRIMVAL = 0x63, // pvt: // Record type (labeled fields) - WASM_COMP_DEF_VAL_RECORD = 0x72, // 0x72 lt*:vec() + WASM_COMP_DEF_VAL_RECORD = 0x72, // 0x72 lt*:vec() // Variant type (labeled cases) - WASM_COMP_DEF_VAL_VARIANT = 0x71, // 0x71 case*:vec() + 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: + 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() + WASM_COMP_DEF_VAL_TUPLE = 0x6f, // 0x6f t*:vec() // Flags type - WASM_COMP_DEF_VAL_FLAGS = 0x6e, // 0x6e l*:vec() + WASM_COMP_DEF_VAL_FLAGS = 0x6e, // 0x6e l*:vec() // Enum type - WASM_COMP_DEF_VAL_ENUM = 0x6d, // 0x6d l*:vec() + WASM_COMP_DEF_VAL_ENUM = 0x6d, // 0x6d l*:vec() // Option type - WASM_COMP_DEF_VAL_OPTION = 0x6b, // 0x6b t: + WASM_COMP_DEF_VAL_OPTION = 0x6b, // 0x6b t: // Result type - WASM_COMP_DEF_VAL_RESULT = 0x6a, // 0x6a t?:? u?:? + 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: + 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?:? + 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 + 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; + WASM_COMP_CASE_END = 0x00, // Always 0x00 at end of case +} WASMComponentCaseEndTag; // ----------------------------------------------------------------------------- // Simple Structs @@ -360,8 +363,9 @@ typedef struct WASMComponentCoreName { // | 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 + 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; // ----------------------------------------------------------------------------- @@ -370,7 +374,7 @@ typedef struct WASMComponentSort { // ----------------------------------------------------------------------------- typedef struct WASMComponentSortIdx { WASMComponentSort *sort; - uint32_t idx; + uint32_t idx; } WASMComponentSortIdx; // ----------------------------------------------------------------------------- @@ -421,12 +425,25 @@ typedef struct WASMComponentTypeBound { 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; + 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; @@ -438,8 +455,13 @@ typedef struct WASMComponentExternDesc { typedef struct WASMComponentImportName { WASMComponentImportExportTypeTag tag; union { - struct { WASMComponentCoreName *name; } simple; - struct { WASMComponentCoreName *name; WASMComponentCoreName *version; } versioned; + struct { + WASMComponentCoreName *name; + } simple; + struct { + WASMComponentCoreName *name; + WASMComponentCoreName *version; + } versioned; } imported; } WASMComponentImportName; @@ -451,20 +473,25 @@ typedef struct WASMComponentImportName { typedef struct WASMComponentExportName { WASMComponentImportExportTypeTag tag; union { - struct { WASMComponentCoreName *name; } simple; - struct { WASMComponentCoreName *name; WASMComponentCoreName *version; } versioned; + struct { + WASMComponentCoreName *name; + } simple; + struct { + WASMComponentCoreName *name; + WASMComponentCoreName *version; + } versioned; } exported; -} WASMComponentExportName; +} 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; + 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 @@ -472,8 +499,8 @@ typedef struct WASMComponentCoreCustomSection { // Module Wrapper Structure - Contains core WebAssembly module typedef struct WASMComponentCoreModuleWrapper { struct WASMModule *module; - void *module_handle; -} WASMComponentCoreModuleWrapper; + void *module_handle; +} WASMComponentCoreModuleWrapper; // ----------------------------------------------------------------------------- // Section 2: Core Instance Section Structs @@ -495,8 +522,15 @@ typedef struct WASMComponentInstArg { } 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; + 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 { @@ -517,40 +551,41 @@ typedef struct WASMComponentCoreInstSection { // 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 + 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 + 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 + 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 +// 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 + 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 @@ -564,7 +599,7 @@ typedef struct WASMComponentCoreHeapType { WASMComponentCoreHeapTypeTag tag; union { WASMCoreAbsHeapTypeTag abstract_type; - uint32_t concrete_index; // Type index for heap type (s33) + uint32_t concrete_index; // Type index for heap type (s33) } heap_type; } WASMComponentCoreHeapType; @@ -586,7 +621,7 @@ typedef struct WASMComponentCoreValType { union { WASMCoreNumTypeTag num_type; WASMCoreVectorTypeTag vector_type; - WASMComponentCoreRefType ref_type; + WASMComponentCoreRefType ref_type; } type; } WASMComponentCoreValType; @@ -608,7 +643,7 @@ typedef struct 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 + bool is_mutable; // true for var, false for const WASMComponentCoreStorageType storage_type; } WASMComponentCoreFieldType; @@ -622,8 +657,8 @@ typedef struct WASMComponentCoreResultType { // Core Function Type Structure // functype ::= rt1:resulttype rt2:resulttype => rt1 -> rt2 typedef struct WASMComponentCoreFuncType { - WASMComponentCoreResultType params; // rt1 - WASMComponentCoreResultType results; // rt2 + WASMComponentCoreResultType params; // rt1 + WASMComponentCoreResultType results; // rt2 } WASMComponentCoreFuncType; // Core Array Type Structure @@ -660,12 +695,13 @@ typedef struct WASMComponentCoreCompType { // Core SubType Structure // subtype ::= 0x50 x*:vec(typeidx) ct:comptype => sub x* ct -// | 0x4F x*:vec(typeidx) ct:comptype => sub final 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) + uint32_t *supertypes; // Vector of type indices (can be empty for final with + // no supertypes) WASMComponentCoreCompType comptype; } WASMComponentCoreSubType; @@ -679,20 +715,22 @@ typedef struct 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)) +// 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) + 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 { @@ -703,8 +741,13 @@ typedef enum WASMComponentCoreLimitsTag { typedef struct WASMComponentCoreLimits { WASMComponentCoreLimitsTag tag; union { - struct { uint32_t min; } limits; - struct { uint32_t min; uint32_t max; } limits_max; + struct { + uint32_t min; + } limits; + struct { + uint32_t min; + uint32_t max; + } limits_max; } lim; } WASMComponentCoreLimits; @@ -751,10 +794,14 @@ typedef struct WASMComponentCoreExportDecl { // | 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) + 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 { @@ -805,8 +852,8 @@ typedef struct WASMComponentCoreModuleType { // Core DefType Structure // core:deftype ::= rt: => rt (WebAssembly 3.0) -// | 0x00 0x50 x*:vec() ct: => sub x* ct (WebAssembly 3.0) -// | mt: => mt +// | 0x00 0x50 x*:vec() ct: => sub x* +// ct (WebAssembly 3.0) | mt: => mt typedef enum WASMComponentCoreDefTypeTag { WASM_CORE_DEFTYPE_RECTYPE, WASM_CORE_DEFTYPE_SUBTYPE, @@ -980,8 +1027,8 @@ typedef struct 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) + WASMComponentValueType *result_type; // Optional (can be NULL) + WASMComponentValueType *error_type; // Optional (can be NULL) } WASMComponentResultType; // Own Type Structure - Owned handle @@ -1187,60 +1234,64 @@ typedef struct WASMComponentTypeSection { // ----------------------------------------------------------------------------- // 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 + 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) + 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: +// 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) @@ -1249,14 +1300,26 @@ typedef enum WASMComponentCanonOptTag { 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 */ + 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; @@ -1370,7 +1433,8 @@ typedef struct WASMComponentCanon { struct { // No parameters } waitable_set_new; - // 0x20 cancel?: m: or 0x21 cancel?: m: + // 0x20 cancel?: m: or 0x21 cancel?: + // m: struct { bool cancellable; uint32_t mem_idx; @@ -1410,10 +1474,10 @@ typedef struct WASMComponentCanonSection { // ----------------------------------------------------------------------------- // 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 + 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; // ----------------------------------------------------------------------------- @@ -1427,7 +1491,7 @@ typedef struct WASMComponentImport { // Import Section Structure - Vector of imports typedef struct WASMComponentImportSection { - uint32_t count; + uint32_t count; WASMComponentImport *imports; } WASMComponentImportSection; @@ -1436,15 +1500,15 @@ typedef struct WASMComponentImportSection { // ----------------------------------------------------------------------------- // Export Structure - Component export typedef struct WASMComponentExport { - WASMComponentExportName *export_name; + WASMComponentExportName *export_name; WASMComponentSortIdx *sort_idx; WASMComponentExternDesc *extern_desc; } WASMComponentExport; // Export Section Structure - Vector of exports typedef struct WASMComponentExportSection { - uint32_t count; - WASMComponentExport *exports; + uint32_t count; + WASMComponentExport *exports; } WASMComponentExportSection; // ----------------------------------------------------------------------------- @@ -1452,9 +1516,9 @@ typedef struct WASMComponentExportSection { // ----------------------------------------------------------------------------- // 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:) + 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 @@ -1506,88 +1570,253 @@ typedef struct WASMComponent { #ifdef __cplusplus extern "C" { #endif -void set_error_buf_ex(char *error_buf, uint32_t error_buf_size, const char *format, ...); +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); +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 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 +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); +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 +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); +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_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); +void +wasm_component_free(WASMComponent *component); #ifdef __cplusplus } #endif // Utility functions -static inline bool is_primitive_type(uint8_t value) { +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 + // 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: @@ -1610,51 +1839,70 @@ static inline bool is_primitive_type(uint8_t value) { } // Core type utility functions -static inline bool is_core_numtype(uint8_t value) { +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) { +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 +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); + 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 +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); + return (value >= WASM_CORE_ABS_HEAP_TYPE_ARRAY + && value <= WASM_CORE_ABS_HEAP_TYPE_NOFUNC); } -static inline bool is_core_packedtype(uint8_t value) { +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); + return (value == WASM_CORE_PACKED_TYPE_I16 + || value == WASM_CORE_PACKED_TYPE_I8); } -static inline bool is_core_storagetype(uint8_t value) { +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); + 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) { +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); + return (value == WASM_CORE_COMPTYPE_ARRAY + || value == WASM_CORE_COMPTYPE_STRUCT + || value == WASM_CORE_COMPTYPE_FUNC); } // Core type parsing constants @@ -1676,51 +1924,79 @@ typedef enum WASMCoreTypeParsingTag { } 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_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) { +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) { +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) { +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) { +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); +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); +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); +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 index 706c873d4..af1b196cc 100644 --- a/core/iwasm/common/component-model/wasm_component_alias_section.c +++ b/core/iwasm/common/component-model/wasm_component_alias_section.c @@ -12,12 +12,17 @@ #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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for alias sort"); return false; } @@ -31,9 +36,11 @@ bool parse_single_alias(const uint8_t **payload, const uint8_t *end, WASMCompone // Parse alias target using switch switch (tag) { - case WASM_COMP_ALIAS_TARGET_EXPORT: { + 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)) { + if (!read_leb((uint8_t **)&p, end, 32, false, &instance_idx, + error_buf, error_buf_size)) { return false; } WASMComponentCoreName *name = NULL; @@ -45,27 +52,34 @@ bool parse_single_alias(const uint8_t **payload, const uint8_t *end, WASMCompone out->target.exported.name = name; break; } - case WASM_COMP_ALIAS_TARGET_CORE_EXPORT: { + 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)) { + 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)) { + 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.instance_idx = + (uint32_t)core_instance_idx; out->target.core_exported.name = core_name; break; } - case WASM_COMP_ALIAS_TARGET_OUTER: { + 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)) { + 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)) { + 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; @@ -78,13 +92,16 @@ bool parse_single_alias(const uint8_t **payload, const uint8_t *end, WASMCompone || (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"); + 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); + snprintf(error_buf, error_buf_size, + "Unknown alias target type: 0x%02X", tag); return false; } @@ -93,10 +110,18 @@ bool parse_single_alias(const uint8_t **payload, const uint8_t *end, WASMCompone } // 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) { +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; + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); + if (consumed_len) + *consumed_len = 0; return false; } @@ -106,8 +131,10 @@ bool wasm_component_parse_alias_section(const uint8_t **payload, uint32_t payloa // 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); + 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; } @@ -115,45 +142,55 @@ bool wasm_component_parse_alias_section(const uint8_t **payload, uint32_t payloa out->count = alias_count; if (alias_count > 0) { - out->aliases = wasm_runtime_malloc(sizeof(WASMComponentAliasDefinition) * alias_count); + out->aliases = wasm_runtime_malloc(sizeof(WASMComponentAliasDefinition) + * alias_count); if (!out->aliases) { - if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } // Zero-initialize the aliases array - memset(out->aliases, 0, sizeof(WASMComponentAliasDefinition) * alias_count); + 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); + 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 (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; - +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: @@ -180,4 +217,4 @@ void wasm_component_free_alias_section(WASMComponentSection *section) { } 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 index 0a86bf3ff..7f167956d 100644 --- a/core/iwasm/common/component-model/wasm_component_canons_section.c +++ b/core/iwasm/common/component-model/wasm_component_canons_section.c @@ -13,8 +13,11 @@ #include // Local helpers to free nested allocations safely -static void free_canon_opts_struct(WASMComponentCanonOpts *opts) { - if (!opts) return; +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; @@ -23,8 +26,11 @@ static void free_canon_opts_struct(WASMComponentCanonOpts *opts) { wasm_runtime_free(opts); } -static void free_result_list_struct(WASMComponentResultList *rl) { - if (!rl) return; +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; @@ -32,8 +38,11 @@ static void free_result_list_struct(WASMComponentResultList *rl) { wasm_runtime_free(rl); } -static void free_single_canon_allocs(WASMComponentCanon *canon) { - if (!canon) return; +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) { @@ -49,32 +58,37 @@ static void free_single_canon_allocs(WASMComponentCanon *canon) { 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); + 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); + 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); + 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); + 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); + free_canon_opts_struct( + canon->canon_data.error_context_new_debug.canon_opts); canon->canon_data.error_context_new_debug.canon_opts = NULL; } break; @@ -84,53 +98,69 @@ static void free_single_canon_allocs(WASMComponentCanon *canon) { } // 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) { +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 + 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 + 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)) { + 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 + 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)) { + 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 + 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)) { + 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 + case WASM_COMP_CANON_OPT_ASYNC: + { // async - 0x06 break; } - case WASM_COMP_CANON_OPT_CALLBACK: { // (callback f) - 0x07 + 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)) { + 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); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid canon opt tag: %02x", tag); return false; } } @@ -140,9 +170,14 @@ static bool parse_canon_opt(const uint8_t **payload, const uint8_t *end, WASMCom } // 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); return false; } @@ -150,12 +185,14 @@ static bool parse_canon_opts(const uint8_t **payload, const uint8_t *end, WASMCo *out = wasm_runtime_malloc(sizeof(WASMComponentCanonOpts)); if (!*out) { - set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for canon opts"); + 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)) { + 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; @@ -163,22 +200,26 @@ static bool parse_canon_opts(const uint8_t **payload, const uint8_t *end, WASMCo (*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); + (*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"); + 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)) { + 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 { + } + else { (*out)->canon_opts = NULL; } @@ -187,19 +228,23 @@ static bool parse_canon_opts(const uint8_t **payload, const uint8_t *end, WASMCo 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) { + || 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"); + 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 { + } + 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); + set_error_buf_ex(error_buf, error_buf_size, + "Duplicate canonopt: 0x%02x", t); free_canon_opts_struct(*out); *out = NULL; return false; @@ -213,35 +258,45 @@ static bool parse_canon_opts(const uint8_t **payload, const uint8_t *end, WASMCo } // 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) { +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: + 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); + 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"); + 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)) { + 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)) { + 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); @@ -253,31 +308,37 @@ static bool parse_single_canon(const uint8_t **payload, const uint8_t *end, WASM break; } - - case WASM_COMP_CANON_LOWER: { // 0x01 0x00 f: opts: + + 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); + 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)) { + 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)) { + 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: + 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)) { + 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; @@ -285,54 +346,70 @@ static bool parse_single_canon(const uint8_t **payload, const uint8_t *end, WASM break; } - case WASM_COMP_CANON_RESOURCE_DROP: { // 0x03 rt: + 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)) { + 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.resource_type_idx = + (uint32_t)type_idx; out->canon_data.resource_drop.async = false; break; } - case WASM_COMP_CANON_RESOURCE_DROP_ASYNC: { //0x07 rt: + 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)) { + 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.resource_type_idx = + (uint32_t)type_idx; out->canon_data.resource_drop.async = true; break; } - case WASM_COMP_CANON_RESOURCE_REP: { // 0x04 rt: + 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)) { + 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 + 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)) { + 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); + 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)) { + 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); + free_result_list_struct( + out->canon_data.task_return.result_list); out->canon_data.task_return.result_list = NULL; } return false; @@ -340,20 +417,25 @@ static bool parse_single_canon(const uint8_t **payload, const uint8_t *end, WASM break; } - case WASM_COMP_CANON_TASK_CANCEL: { // 0x05 (no parameters) + case WASM_COMP_CANON_TASK_CANCEL: + { // 0x05 (no parameters) break; } - case WASM_COMP_CANON_CONTEXT_GET: { // 0x0a 0x7f i: + 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); + 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"); + 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; @@ -361,16 +443,20 @@ static bool parse_single_canon(const uint8_t **payload, const uint8_t *end, WASM break; } - case WASM_COMP_CANON_CONTEXT_SET: { // 0x0b 0x7f i: + 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); + 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"); + 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; @@ -378,322 +464,425 @@ static bool parse_single_canon(const uint8_t **payload, const uint8_t *end, WASM break; } - case WASM_COMP_CANON_YIELD: { // 0x0c cancel?: + 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) { + } + 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); + } + 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?: + 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) { + } + 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); + } + 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 + case WASM_COMP_CANON_SUBTASK_DROP: + { // 0x0d break; } - case WASM_COMP_CANON_STREAM_NEW: { // 0x0e t: + 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)) { + 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: + 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)) { + 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; - + 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)) { + 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: + 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)) { + 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; - + 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)) { + 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?: + 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)) { + 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; + 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) { + } + 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); + } + 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?: + 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)) { + 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; + 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) { + } + 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); + } + 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: + 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)) { + 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; + out->canon_data.stream_drop_readable_writable.stream_type_idx = + (uint32_t)type_idx; break; } - case WASM_COMP_CANON_STREAM_DROP_WRITABLE: { // 0x14 t: + 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)) { + 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; + out->canon_data.stream_drop_readable_writable.stream_type_idx = + (uint32_t)type_idx; break; } - case WASM_COMP_CANON_FUTURE_NEW: { // 0x15 t: + 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)) { + 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: + 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)) { + 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)) { + 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: + 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)) { + 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)) { + 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?: + 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)) { + 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; + 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) { + } + 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); + } + 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?: + 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)) { + 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; + 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) { + } + 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); + } + 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: + 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)) { + 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; + out->canon_data.future_drop_readable_writable.future_type_idx = + (uint32_t)type_idx; break; } - case WASM_COMP_CANON_FUTURE_DROP_WRITABLE: { // 0x1b t: + 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)) { + 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; + 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)) { + 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) + case WASM_COMP_CANON_WAITABLE_SET_NEW: + { // 0x1f (no parameters) break; } - case WASM_COMP_CANON_WAITABLE_SET_WAIT: { // 0x20 cancel?: m: + 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) { + } + 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); + } + 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"); + 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; + 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: + 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) { + } + 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); + } + 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"); + 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; + 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) + 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: + 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"); + 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; + 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: + 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"); + 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; + 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"); + 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; + out->canon_data.thread_spawn_indirect.table_idx = + (uint32_t)core_table_idx; break; } - case WASM_COMP_CANON_THREAD_AVAILABLE_PAR: { // 0x42 (no parameters) + 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); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid canon tag: %02x", tag); return false; } } @@ -703,10 +892,18 @@ static bool parse_single_canon(const uint8_t **payload, const uint8_t *end, WASM } // 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) { +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; + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); + if (consumed_len) + *consumed_len = 0; return false; } @@ -714,17 +911,22 @@ bool wasm_component_parse_canons_section(const uint8_t **payload, uint32_t paylo 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); + 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); + 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); + 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; } @@ -734,13 +936,17 @@ bool wasm_component_parse_canons_section(const uint8_t **payload, uint32_t paylo 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); + 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"); + 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]); @@ -748,103 +954,124 @@ bool wasm_component_parse_canons_section(const uint8_t **payload, uint32_t paylo wasm_runtime_free(out->canons); out->canons = NULL; out->count = 0; - if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } } } - if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + 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) { +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->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->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->results); } - wasm_runtime_free(canon->canon_data.task_return.result_list); + 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->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); + 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); + 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); + 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); + 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); + 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); + 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 + // 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 index caf561d45..7019c40b9 100644 --- a/core/iwasm/common/component-model/wasm_component_component_section.c +++ b/core/iwasm/common/component-model/wasm_component_component_section.c @@ -13,37 +13,54 @@ #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; +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); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); return false; } - if (consumed_len) *consumed_len = payload_len; + // 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; - +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); 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 index 1f8ad42bd..0e494e38a 100644 --- a/core/iwasm/common/component-model/wasm_component_core_custom_section.c +++ b/core/iwasm/common/component-model/wasm_component_core_custom_section.c @@ -14,14 +14,23 @@ #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) { +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 (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"); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); return false; } @@ -32,45 +41,54 @@ bool wasm_component_parse_core_custom_section(const uint8_t **payload, uint32_t // 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); + 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); + 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); + 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); + 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); + 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); + 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; @@ -88,9 +106,12 @@ bool wasm_component_parse_core_custom_section(const uint8_t **payload, uint32_t } // Individual section free functions -void wasm_component_free_core_custom_section(WASMComponentSection *section) { - if (!section || !section->parsed.core_custom) return; - +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; 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 index 09bf4130c..61a817aaa 100644 --- a/core/iwasm/common/component-model/wasm_component_core_instance_section.c +++ b/core/iwasm/common/component-model/wasm_component_core_instance_section.c @@ -12,14 +12,23 @@ #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) { +// 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; + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); + if (consumed_len) + *consumed_len = 0; return false; } @@ -27,217 +36,313 @@ bool wasm_component_parse_core_instance_section(const uint8_t **payload, uint32_ 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); + 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); + 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); + 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); + 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); + 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: { + 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); + 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; + 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); + 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; - + 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); + 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); + 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); + 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) - + // 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); + 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); + 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; + 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); + 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"); + 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); + 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)) { + 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); + 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; + out->instances[i] + .expression.with_args.args[j] + .idx.instance_idx = (uint32_t)instance_idx; } - } else { + } + else { out->instances[i].expression.with_args.args = NULL; } break; } - case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: { + 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); + 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; + 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); + 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); + 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: + // 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); + 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); + // 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } - out->instances[i].expression.without_args.inline_expr[j].name = name; + 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); + 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)); + // 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"); + 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); + 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); + 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"); + 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } - out->instances[i].expression.without_args.inline_expr[j].sort_idx = sort_idx; + out->instances[i] + .expression.without_args.inline_expr[j] + .sort_idx = sort_idx; } - } else { - out->instances[i].expression.without_args.inline_expr = NULL; } - + 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); + 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; + 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; +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]; - + 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); @@ -249,30 +354,37 @@ void wasm_component_free_core_instance_section(WASMComponentSection *section) { 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]; - + 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); + 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); + wasm_runtime_free( + instance->expression.without_args.inline_expr); instance->expression.without_args.inline_expr = NULL; } break; @@ -283,4 +395,4 @@ void wasm_component_free_core_instance_section(WASMComponentSection *section) { } 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 index df12e9774..829bd2389 100644 --- a/core/iwasm/common/component-model/wasm_component_core_module_section.c +++ b/core/iwasm/common/component-model/wasm_component_core_module_section.c @@ -13,32 +13,48 @@ #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; +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"); + 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); + 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); + 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)); + 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(" 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)); + 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) { @@ -46,18 +62,19 @@ bool wasm_component_parse_core_module_section(const uint8_t **payload, uint32_t 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); - + 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"); + 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"); + LOG_DEBUG(" WARNING: Empty field name - this will " + "cause 'unknown import' error\n"); } } } @@ -69,32 +86,36 @@ bool wasm_component_parse_core_module_section(const uint8_t **payload, uint32_t 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); - + 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"); + 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_handle = (void *)mod; out->module = NULL; // We don't need the actual module structure for now - if (consumed_len) *consumed_len = payload_len; + 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; - +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); + 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); 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 index 83faeb1d4..662674b50 100644 --- a/core/iwasm/common/component-model/wasm_component_core_type_section.c +++ b/core/iwasm/common/component-model/wasm_component_core_type_section.c @@ -12,14 +12,20 @@ #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) { +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: { + case WASM_CORE_LIMITS_MIN: + { uint64_t min = 0; - if (!read_leb((uint8_t **)&p, end, 32, false, &min, error_buf, error_buf_size)) { + if (!read_leb((uint8_t **)&p, end, 32, false, &min, error_buf, + error_buf_size)) { return false; } @@ -27,14 +33,17 @@ bool parse_core_limits(const uint8_t **payload, const uint8_t *end, WASMComponen out->lim.limits.min = (uint32_t)min; break; } - case WASM_CORE_LIMITS_MAX: { + case WASM_CORE_LIMITS_MAX: + { uint64_t min = 0; - if (!read_leb((uint8_t **)&p, end, 32, false, &min, error_buf, error_buf_size)) { + 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)) { + if (!read_leb((uint8_t **)&p, end, 32, false, &max, error_buf, + error_buf_size)) { return false; } @@ -43,8 +52,10 @@ bool parse_core_limits(const uint8_t **payload, const uint8_t *end, WASMComponen out->lim.limits_max.max = (uint32_t)max; break; } - default: { - set_error_buf_ex(error_buf, error_buf_size, "Invalid limits tag: %02x", tag); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid limits tag: %02x", tag); return false; } } @@ -53,11 +64,15 @@ bool parse_core_limits(const uint8_t **payload, const uint8_t *end, WASMComponen 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) +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Unexpected end while parsing heaptype"); return false; } @@ -73,11 +88,14 @@ static bool parse_core_heaptype(const uint8_t **payload, const uint8_t *end, WAS // 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)) { + 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); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid heaptype index: %llu", + (unsigned long long)idx); return false; } @@ -87,7 +105,11 @@ static bool parse_core_heaptype(const uint8_t **payload, const uint8_t *end, WAS return true; } -bool parse_core_valtype(const uint8_t **payload, const uint8_t *end, WASMComponentCoreValType *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) +{ const uint8_t *p = *payload; uint8_t tag = *p++; @@ -113,29 +135,34 @@ bool parse_core_valtype(const uint8_t **payload, const uint8_t *end, WASMCompone // - 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)) { + 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) { + 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) { + 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"); + 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_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; @@ -148,22 +175,31 @@ bool parse_core_valtype(const uint8_t **payload, const uint8_t *end, WASMCompone *payload = p; return true; } - set_error_buf_ex(error_buf, error_buf_size, "Unsupported short-form absheaptype %02x for core valtype", tag); + 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); + 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) { +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: { + 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)) { + if (!read_leb((uint8_t **)&p, end, 32, false, &func_type_idx, + error_buf, error_buf_size)) { return false; } @@ -172,25 +208,33 @@ bool parse_core_import_desc(const uint8_t **payload, const uint8_t *end, WASMCom break; } - case WASM_CORE_IMPORTDESC_TABLE: { + 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) { + } + 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); + } + 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)); + WASMComponentCoreLimits *limits = + wasm_runtime_malloc(sizeof(WASMComponentCoreLimits)); if (!limits) { - set_error_buf_ex(error_buf, error_buf_size, "OOM allocating table 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)) { + if (!parse_core_limits(&p, end, limits, error_buf, + error_buf_size)) { wasm_runtime_free(limits); return false; } @@ -200,13 +244,17 @@ bool parse_core_import_desc(const uint8_t **payload, const uint8_t *end, WASMCom break; } - case WASM_CORE_IMPORTDESC_MEMORY: { - WASMComponentCoreLimits *limits = wasm_runtime_malloc(sizeof(WASMComponentCoreLimits)); + 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"); + 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)) { + if (!parse_core_limits(&p, end, limits, error_buf, + error_buf_size)) { wasm_runtime_free(limits); return false; } @@ -216,8 +264,10 @@ bool parse_core_import_desc(const uint8_t **payload, const uint8_t *end, WASMCom break; } - case WASM_CORE_IMPORTDESC_GLOBAL: { - if (!parse_core_valtype(&p, end, &out->desc.global_type.val_type, error_buf, error_buf_size)) { + case WASM_CORE_IMPORTDESC_GLOBAL: + { + if (!parse_core_valtype(&p, end, &out->desc.global_type.val_type, + error_buf, error_buf_size)) { return false; } @@ -225,17 +275,22 @@ bool parse_core_import_desc(const uint8_t **payload, const uint8_t *end, WASMCom 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) { + } + 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); + } + 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); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid import descriptor tag: %02x", tag); return false; } } @@ -244,7 +299,11 @@ bool parse_core_import_desc(const uint8_t **payload, const uint8_t *end, WASMCom return true; } -bool parse_core_import(const uint8_t **payload, const uint8_t *end, WASMComponentCoreImport *out, char *error_buf, uint32_t error_buf_size) { +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; @@ -261,12 +320,15 @@ bool parse_core_import(const uint8_t **payload, const uint8_t *end, WASMComponen out->nm = nm_name; - WASMComponentCoreImportDesc *import_desc = wasm_runtime_malloc(sizeof(WASMComponentCoreImportDesc)); + WASMComponentCoreImportDesc *import_desc = + wasm_runtime_malloc(sizeof(WASMComponentCoreImportDesc)); if (!import_desc) { - set_error_buf_ex(error_buf, error_buf_size, "OOM allocating 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)) { + if (!parse_core_import_desc(&p, end, import_desc, error_buf, + error_buf_size)) { wasm_runtime_free(import_desc); return false; } @@ -277,43 +339,57 @@ bool parse_core_import(const uint8_t **payload, const uint8_t *end, WASMComponen return true; } -bool parse_alias_target(const uint8_t **payload, const uint8_t *end, WASMComponentCoreAliasTarget *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) +{ 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)) { + 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)) { + 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); + } + 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) { +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"); + 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; } @@ -321,7 +397,11 @@ bool parse_core_alias(const uint8_t **payload, const uint8_t *end, WASMComponent 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) { +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; @@ -330,12 +410,15 @@ bool parse_core_export_decl(const uint8_t **payload, const uint8_t *end, WASMCom } out->name = mod_name; - WASMComponentCoreImportDesc *export_desc = wasm_runtime_malloc(sizeof(WASMComponentCoreImportDesc)); + WASMComponentCoreImportDesc *export_desc = + wasm_runtime_malloc(sizeof(WASMComponentCoreImportDesc)); if (!export_desc) { - set_error_buf_ex(error_buf, error_buf_size, "OOM allocating 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)) { + if (!parse_core_import_desc(&p, end, export_desc, error_buf, + error_buf_size)) { wasm_runtime_free(export_desc); return false; } @@ -346,69 +429,98 @@ bool parse_core_export_decl(const uint8_t **payload, const uint8_t *end, WASMCom 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) { +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)); + 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"); + 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)) { + 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)); + 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"); + 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)); + 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"); + 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"); + 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)); + 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"); + 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"); + 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)); + 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"); + 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"); + 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); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid module declaration tag: %02x", tag); return false; } } @@ -416,11 +528,16 @@ bool parse_core_module_decl(const uint8_t **payload, const uint8_t *end, WASMCom return true; } -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_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)) { + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, + error_buf_size)) { return false; } @@ -428,29 +545,38 @@ bool parse_core_moduletype(const uint8_t **payload, const uint8_t *end, WASMComp out->decl_count = count; if (count > 0) { - out->declarations = wasm_runtime_malloc(sizeof(WASMComponentCoreModuleDecl) * count); + 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"); + 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); + 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)) { + 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Unexpected end while parsing core:deftype"); return false; } @@ -460,12 +586,15 @@ bool parse_single_core_type(const uint8_t **payload, const uint8_t *end, WASMCom if (b0 == 0x50) { p++; // consume 0x50 out->tag = WASM_CORE_DEFTYPE_MODULETYPE; - out->type.moduletype = wasm_runtime_malloc(sizeof(WASMComponentCoreModuleType)); + 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"); + 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)) { + if (!parse_core_moduletype(&p, end, out->type.moduletype, error_buf, + error_buf_size)) { return false; } *payload = p; @@ -474,42 +603,57 @@ bool parse_single_core_type(const uint8_t **payload, const uint8_t *end, WASMCom // 2) rectype (GC): 0x4E ... if (b0 == 0x4E) { - set_error_buf_ex(error_buf, error_buf_size, "WebAssembly 3.0 core:rectype (0x4E ...) not supported"); + 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"); + 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); + 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); + 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) { +// 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; + 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)) { + if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, + error_buf_size)) { return false; } @@ -519,19 +663,23 @@ bool wasm_component_parse_core_type_section(const uint8_t **payload, uint32_t pa 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"); + 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)); + 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"); + 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)) { + if (!parse_single_core_type(&p, end, dt, error_buf, + error_buf_size)) { wasm_runtime_free(dt); return false; } @@ -539,18 +687,22 @@ bool wasm_component_parse_core_type_section(const uint8_t **payload, uint32_t pa } } - if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return true; } // Individual section free functions -void wasm_component_free_core_type_section(WASMComponentSection *section) { +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; - + + 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) { @@ -560,17 +712,19 @@ void wasm_component_free_core_type_section(WASMComponentSection *section) { } 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) { +void +free_core_import_desc(WASMComponentCoreImportDesc *import_desc) +{ if (!import_desc) { return; } - + switch (import_desc->type) { case WASM_CORE_IMPORTDESC_FUNC: break; @@ -592,48 +746,54 @@ void free_core_import_desc(WASMComponentCoreImportDesc *import_desc) { } } -void free_core_import(WASMComponentCoreImport *import) { +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) { +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) { +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) { @@ -654,18 +814,21 @@ void free_core_module_decl(WASMComponentCoreModuleDecl *module_decl) { 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); + 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) { +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]); @@ -674,11 +837,13 @@ void free_core_moduletype(WASMComponentCoreModuleType *moduletype) { } } -void free_core_deftype(WASMComponentCoreDefType *deftype) { +void +free_core_deftype(WASMComponentCoreDefType *deftype) +{ if (!deftype) { return; } - + switch (deftype->tag) { case WASM_CORE_DEFTYPE_RECTYPE: if (deftype->type.rectype) { @@ -686,12 +851,12 @@ void free_core_deftype(WASMComponentCoreDefType *deftype) { 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_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); @@ -701,22 +866,26 @@ void free_core_deftype(WASMComponentCoreDefType *deftype) { } } -void free_core_type(WASMComponentCoreType *type) { +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) { +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]); @@ -726,25 +895,29 @@ void free_core_type_section(WASMComponentCoreTypeSection *section) { } // Additional helper functions for freeing core structures -void free_core_functype(WASMComponentCoreFuncType *functype) { +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) { +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]); @@ -753,31 +926,37 @@ void free_core_rectype(WASMComponentCoreRecType *rectype) { } } -void free_core_resulttype(WASMComponentCoreResultType *resulttype) { +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) { +void +free_core_structtype(WASMComponentCoreStructType *structtype) +{ if (!structtype) { return; } - + if (structtype->fields) { wasm_runtime_free(structtype->fields); } } -void free_core_comptype(WASMComponentCoreCompType *comptype) { +void +free_core_comptype(WASMComponentCoreCompType *comptype) +{ if (!comptype) { return; } - + switch (comptype->tag) { case WASM_CORE_COMPTYPE_FUNC: free_core_functype(&comptype->type.func_type); @@ -793,28 +972,32 @@ void free_core_comptype(WASMComponentCoreCompType *comptype) { } } -void free_core_subtype(WASMComponentCoreSubType *subtype) { +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) { +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 index ad01b0501..8d8d931ce 100644 --- a/core/iwasm/common/component-model/wasm_component_export.c +++ b/core/iwasm/common/component-model/wasm_component_export.c @@ -8,10 +8,14 @@ static bool is_component = false; -bool is_component_runtime() { +bool +is_component_runtime() +{ return is_component; } -void set_component_runtime(bool type) { +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 index e43a62848..c2798ac50 100644 --- a/core/iwasm/common/component-model/wasm_component_export.h +++ b/core/iwasm/common/component-model/wasm_component_export.h @@ -8,7 +8,9 @@ #include "stdbool.h" -bool is_component_runtime(); -void set_component_runtime(bool type); +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 index a5c7bbff9..4ac58680e 100644 --- a/core/iwasm/common/component-model/wasm_component_exports_section.c +++ b/core/iwasm/common/component-model/wasm_component_exports_section.c @@ -13,10 +13,18 @@ #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){ +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; + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); + if (consumed_len) + *consumed_len = 0; return false; } @@ -24,14 +32,19 @@ bool wasm_component_parse_exports_section(const uint8_t **payload, uint32_t payl 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); + 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); + 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; } @@ -39,124 +52,169 @@ bool wasm_component_parse_exports_section(const uint8_t **payload, uint32_t payl out->count = export_count; if (export_count > 0) { - out->exports = wasm_runtime_malloc(sizeof(WASMComponentExport) * export_count); + 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); + 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 + // 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); + 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)); + 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); + 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); + 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); + 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); + 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)); + 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"); + 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); + 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); + + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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) { + } + 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); + } + 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); + 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; - +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) { @@ -166,7 +224,7 @@ void wasm_component_free_exports_section(WASMComponentSection *section) { wasm_runtime_free(export->sort_idx); export->sort_idx = NULL; } - + // Free extern desc (optional) if (export->extern_desc) { free_extern_desc(export->extern_desc); diff --git a/core/iwasm/common/component-model/wasm_component_helpers.c b/core/iwasm/common/component-model/wasm_component_helpers.c index c8a28a0e1..8668eca45 100644 --- a/core/iwasm/common/component-model/wasm_component_helpers.c +++ b/core/iwasm/common/component-model/wasm_component_helpers.c @@ -13,8 +13,12 @@ #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, ...) { +// 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; @@ -25,13 +29,17 @@ void set_error_buf_ex(char *error_buf, uint32_t error_buf_size, const char *form } bool -parse_result_list(const uint8_t **payload, const uint8_t *end, WASMComponentResultList **out, char *error_buf, uint32_t error_buf_size) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for result list"); return false; } memset(*out, 0, sizeof(WASMComponentResultList)); @@ -41,33 +49,44 @@ parse_result_list(const uint8_t **payload, const uint8_t *end, WASMComponentResu p++; switch (tag) { - case WASM_COMP_RESULT_LIST_WITH_TYPE: { + case WASM_COMP_RESULT_LIST_WITH_TYPE: + { // Allocate memory for the single result value type - (*out)->results = wasm_runtime_malloc(sizeof(WASMComponentValueType)); + (*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"); + 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"); + + 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: { + 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); + 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); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid result list tag: 0x%02x", tag); return false; } } @@ -77,29 +96,32 @@ parse_result_list(const uint8_t **payload, const uint8_t *end, WASMComponentResu } bool -parse_sort(const uint8_t **payload, const uint8_t *end, WASMComponentSort *out, char *error_buf, uint32_t error_buf_size, bool is_core) +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"); + 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 + 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); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid sort value: 0x%02x", out->sort); *payload = p; return false; } @@ -109,38 +131,42 @@ parse_sort(const uint8_t **payload, const uint8_t *end, WASMComponentSort *out, 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"); + 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){ + 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 + 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); + 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. + // For any other value of s->sort, the s->core_sort field remains 0 and is + // ignored. // Update the original pointer *payload = p; @@ -148,51 +174,62 @@ parse_sort(const uint8_t **payload, const uint8_t *end, WASMComponentSort *out, } 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) +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"); + 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"); + 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); + 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)) { + 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){ +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"); + 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: { + 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++; @@ -202,7 +239,8 @@ parse_extern_desc(const uint8_t **payload, const uint8_t *end, WASMComponentExte } // 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)) { + 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; } @@ -210,65 +248,84 @@ parse_extern_desc(const uint8_t **payload, const uint8_t *end, WASMComponentExte out->extern_desc.core_module.type_idx = (uint32_t)type_idx; break; } - case WASM_COMP_EXTERN_FUNC: { + 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)) { + 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: { + 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)); + 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"); + 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: { + 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)) { + 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; + out->extern_desc.value.value_bound->bound.value_idx = + (uint32_t)value_idx; break; } - case WASM_COMP_VALUEBOUND_TYPE: { + 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)); + 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"); + 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); + 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); + 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; @@ -276,69 +333,82 @@ parse_extern_desc(const uint8_t **payload, const uint8_t *end, WASMComponentExte } break; } - case WASM_COMP_EXTERN_TYPE: { + 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)); + 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"); + 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)) { + 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) { + } + 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); + 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: { + 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)) { + 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: { + 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)) { + 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); + 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; @@ -352,10 +422,12 @@ free_extern_desc(WASMComponentExternDesc *desc) } switch (desc->type) { - case WASM_COMP_EXTERN_VALUE: { + 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) { + if (vb->tag == WASM_COMP_VALUEBOUND_TYPE + && vb->bound.value_type) { wasm_runtime_free(vb->bound.value_type); vb->bound.value_type = NULL; } @@ -364,7 +436,8 @@ free_extern_desc(WASMComponentExternDesc *desc) } break; } - case WASM_COMP_EXTERN_TYPE: { + 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; @@ -382,80 +455,95 @@ free_extern_desc(WASMComponentExternDesc *desc) // 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) +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"); + 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"); + + 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)); + 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"); + 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 + 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"); + 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"); + 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"); + 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)); + + 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"); + 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"); + 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; @@ -473,18 +561,22 @@ 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) +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"); + 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: { + 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)) { @@ -494,7 +586,8 @@ parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMCom out->imported.simple.name = name; break; } - case WASM_COMP_IMPORTNAME_VERSIONED: { + 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)) { @@ -503,8 +596,10 @@ parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMCom } 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"); + 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 @@ -512,12 +607,14 @@ parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMCom } // Merge into "name@version", check first char for @ - bool version_has_at = (version->name_len > 0 && version->name[0] == '@'); + 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"); + 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); @@ -526,8 +623,10 @@ parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMCom 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); + 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); @@ -542,7 +641,8 @@ parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMCom break; } default: - set_error_buf_ex(error_buf, error_buf_size, "Unknown import/export name tag: 0x%02X", tag); + 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; } @@ -553,18 +653,22 @@ parse_component_import_name(const uint8_t **payload, const uint8_t *end, WASMCom } bool -parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMComponentExportName *out, char *error_buf, uint32_t error_buf_size) +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"); + 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: { + 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)) { @@ -574,7 +678,8 @@ parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMCom out->exported.simple.name = name; break; } - case WASM_COMP_IMPORTNAME_VERSIONED: { + 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)) { @@ -583,8 +688,10 @@ parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMCom } 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"); + 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 @@ -592,12 +699,14 @@ parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMCom } // Merge into "name@version", check first char for @ - bool version_has_at = (version->name_len > 0 && version->name[0] == '@'); + 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"); + 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); @@ -606,8 +715,10 @@ parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMCom 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); + 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); @@ -622,7 +733,8 @@ parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMCom break; } default: - set_error_buf_ex(error_buf, error_buf_size, "Unknown import/export name tag: 0x%02X", tag); + 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; } @@ -632,7 +744,6 @@ parse_component_export_name(const uint8_t **payload, const uint8_t *end, WASMCom return true; } - void free_component_import_name(WASMComponentImportName *name_struct) { @@ -703,12 +814,14 @@ free_component_export_name(WASMComponentExportName *name_struct) // Type Section Helper Functions // ----------------------------------------------------------------------------- -bool is_defvaltype_tag(uint8_t byte) { +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 @@ -730,12 +843,14 @@ bool is_defvaltype_tag(uint8_t byte) { } } -WASMComponentTypesTag get_type_tag(uint8_t first_byte) { +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 @@ -754,24 +869,31 @@ WASMComponentTypesTag get_type_tag(uint8_t first_byte) { } } -bool parse_valtype(const uint8_t **payload, const uint8_t *end, WASMComponentValueType *out, char *error_buf, uint32_t error_buf_size) { +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"); + 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 { + } + 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)) { + 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 @@ -780,27 +902,35 @@ bool parse_valtype(const uint8_t **payload, const uint8_t *end, WASMComponentVal } } -bool parse_labelvaltype(const uint8_t **payload, const uint8_t *end, WASMComponentLabelValType *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) +{ if (!payload || !*payload || !out || !end) { - set_error_buf_ex(error_buf, error_buf_size, "Invalid payload or output pointer"); + 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)) { + 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"); + 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)) { + 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); @@ -808,21 +938,27 @@ bool parse_labelvaltype(const uint8_t **payload, const uint8_t *end, WASMCompone 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) { +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"); + 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)) { + if (!parse_core_name(payload, end, &out->label, error_buf, + error_buf_size)) { return false; } - + // Parse optional valtype uint8_t optional_tag = *(*payload)++; @@ -830,132 +966,161 @@ bool parse_case(const uint8_t **payload, const uint8_t *end, WASMComponentCaseVa // 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"); + 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)) { + + 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) { + } + 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); + } + 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); + 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) { +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"); + 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)) { + 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)); + 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"); + 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"); + 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] = '\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) { +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"); + 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)) { + 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)); + 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"); + 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] = '\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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); return false; } @@ -963,16 +1128,19 @@ bool parse_label_prime_vector(const uint8_t **payload, const uint8_t *end, WASMC // 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)) { + 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); + *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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for labels array"); return false; } @@ -981,7 +1149,8 @@ bool parse_label_prime_vector(const uint8_t **payload, const uint8_t *end, WASMC // 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)) { + 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) { @@ -993,7 +1162,8 @@ bool parse_label_prime_vector(const uint8_t **payload, const uint8_t *end, WASMC return false; } } - } else { + } + else { *out_labels = NULL; } @@ -1003,7 +1173,9 @@ bool parse_label_prime_vector(const uint8_t **payload, const uint8_t *end, WASMC } // Free a label_prime (single label') -void free_label_prime(WASMComponentCoreName *label) { +void +free_label_prime(WASMComponentCoreName *label) +{ if (label) { if (label->name) { wasm_runtime_free(label->name); @@ -1013,7 +1185,9 @@ void free_label_prime(WASMComponentCoreName *label) { } // Free a label_prime_vector (array of labels) -void free_label_prime_vector(WASMComponentCoreName *labels, uint32_t count) { +void +free_label_prime_vector(WASMComponentCoreName *labels, uint32_t count) +{ if (labels) { for (uint32_t i = 0; i < count; i++) { if (labels[i].name) { @@ -1024,7 +1198,9 @@ void free_label_prime_vector(WASMComponentCoreName *labels, uint32_t count) { } } -void free_labelvaltype(WASMComponentLabelValType *labelvaltype) { +void +free_labelvaltype(WASMComponentLabelValType *labelvaltype) +{ if (labelvaltype) { if (labelvaltype->label) { free_core_name(labelvaltype->label); @@ -1038,7 +1214,9 @@ void free_labelvaltype(WASMComponentLabelValType *labelvaltype) { } } -void free_case(WASMComponentCaseValType *case_valtype) { +void +free_case(WASMComponentCaseValType *case_valtype) +{ if (case_valtype) { if (case_valtype->label) { free_core_name(case_valtype->label); @@ -1052,8 +1230,11 @@ void free_case(WASMComponentCaseValType *case_valtype) { } } -// 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) { +// 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; } @@ -1061,7 +1242,9 @@ bool wasm_component_validate_utf8(const uint8_t *bytes, uint32_t 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) { +bool +wasm_component_validate_single_utf8_scalar(const uint8_t *bytes, uint32_t len) +{ if (!bytes || len < 1 || len > 4) { return false; } @@ -1075,50 +1258,64 @@ bool wasm_component_validate_single_utf8_scalar(const uint8_t *bytes, uint32_t l if (b0 >= 0xC2 && b0 <= 0xDF) { // 2-byte non-overlong - if (len != 2) return false; + 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; + 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; + 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; + // 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); + return (b1 >= 0x80 && b1 <= 0x9F) + ? false + : (b1 >= 0xA0 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF); } if (b0 >= 0xEE && b0 <= 0xEF) { - if (len != 3) return false; + 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; + 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); + return (b1 >= 0x90 && b1 <= 0xBF) && (b2 >= 0x80 && b2 <= 0xBF) + && (b3 >= 0x80 && b3 <= 0xBF); } if (b0 >= 0xF1 && b0 <= 0xF3) { - if (len != 4) return false; + 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); + 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; + 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); + return (b1 >= 0x80 && b1 <= 0x8F) && (b2 >= 0x80 && b2 <= 0xBF) + && (b3 >= 0x80 && b3 <= 0xBF); } // Invalid leading byte or overlong prefix (0xC0, 0xC1) or > 0xF4 diff --git a/core/iwasm/common/component-model/wasm_component_imports_section.c b/core/iwasm/common/component-model/wasm_component_imports_section.c index 1e41489c8..0027ac8c8 100644 --- a/core/iwasm/common/component-model/wasm_component_imports_section.c +++ b/core/iwasm/common/component-model/wasm_component_imports_section.c @@ -13,111 +13,146 @@ #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) { +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; + 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); + 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); + 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); + 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|) + // 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)); + 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); + 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); + 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); + 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } - - // externdesc ::= 0x00 0x11 i: => (core module (type i)) + + // 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)); + // 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"); + 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); + 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); + 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); + 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); + 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); + + 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; - +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); @@ -130,4 +165,4 @@ void wasm_component_free_imports_section(WASMComponentSection *section) { } 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 index 7279b2597..dc7f2ed68 100644 --- a/core/iwasm/common/component-model/wasm_component_instances_section.c +++ b/core/iwasm/common/component-model/wasm_component_instances_section.c @@ -14,12 +14,20 @@ // 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) { +// 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; + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); + if (consumed_len) + *consumed_len = 0; return false; } @@ -27,17 +35,22 @@ bool wasm_component_parse_instances_section(const uint8_t **payload, uint32_t pa 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); + 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); + 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); + 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; } @@ -47,181 +60,269 @@ bool wasm_component_parse_instances_section(const uint8_t **payload, uint32_t pa 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); + 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: { + 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); + 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; + 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); + 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; - + 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); + 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); + 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); + 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); + 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"); + // 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); + 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)); - + 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); + 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"); + 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } } - } else { + } + else { out->instances[i].expression.with_args.args = NULL; } break; } - case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: { + 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); + 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; + 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); + 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); + 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)); + 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); + 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); + 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } - out->instances[i].expression.without_args.inline_expr[j].name = name; + out->instances[i] + .expression.without_args.inline_expr[j] + .name = name; // Parse component sort index - WASMComponentSortIdx *sort_idx = wasm_runtime_malloc(sizeof(WASMComponentSortIdx)); + 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); + 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); + 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"); + 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } - out->instances[i].expression.without_args.inline_expr[j].sort_idx = sort_idx; + out->instances[i] + .expression.without_args.inline_expr[j] + .sort_idx = sort_idx; } - } else { - out->instances[i].expression.without_args.inline_expr = NULL; + } + 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); + 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; + 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; - +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]; - + 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) { @@ -236,30 +337,37 @@ void wasm_component_free_instances_section(WASMComponentSection *section) { 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]; - + 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); + 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); + wasm_runtime_free( + instance->expression.without_args.inline_expr); instance->expression.without_args.inline_expr = NULL; } break; @@ -270,4 +378,4 @@ void wasm_component_free_instances_section(WASMComponentSection *section) { } 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 index b954c6d05..89488f0c2 100644 --- a/core/iwasm/common/component-model/wasm_component_start_section.c +++ b/core/iwasm/common/component-model/wasm_component_start_section.c @@ -13,8 +13,15 @@ #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; +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; } @@ -29,15 +36,18 @@ bool wasm_component_parse_start_section(const uint8_t **payload, uint32_t payloa out->result = 0; uint64_t func_idx = 0; - if (!read_leb((uint8_t **)&p, end, 32, false, &func_idx, error_buf, error_buf_size)) { + 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"); + 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; @@ -45,14 +55,17 @@ bool wasm_component_parse_start_section(const uint8_t **payload, uint32_t payloa 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"); + 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"); + 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; @@ -64,8 +77,10 @@ bool wasm_component_parse_start_section(const uint8_t **payload, uint32_t payloa } 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 (!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; @@ -75,12 +90,15 @@ bool wasm_component_parse_start_section(const uint8_t **payload, uint32_t payloa } out->result = (uint32_t)result_leb; - if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return true; } // Individual section free functions -void wasm_component_free_start_section(WASMComponentSection *section) { +void +wasm_component_free_start_section(WASMComponentSection *section) +{ if (!section || !section->parsed.start_section) { return; } diff --git a/core/iwasm/common/component-model/wasm_component_types_section.c b/core/iwasm/common/component-model/wasm_component_types_section.c index a40695742..e4dfbacc7 100644 --- a/core/iwasm/common/component-model/wasm_component_types_section.c +++ b/core/iwasm/common/component-model/wasm_component_types_section.c @@ -12,53 +12,68 @@ #include "wasm_export.h" #include -static void free_component_instance_decl(WASMComponentInstDecl *decl); +static void +free_component_instance_decl(WASMComponentInstDecl *decl); // Free helpers for nested component/instance/resource types -static void free_component_types_entry(WASMComponentTypes *type); +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) { +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"); + 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"); + 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)); + (*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"); + 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); + (*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"); + 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); - + 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)) { + 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]); @@ -66,60 +81,75 @@ static bool parse_record_type(const uint8_t **payload, const uint8_t *end, WASMC 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"); + 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"); + } + 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) { +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"); + 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)) { + 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)); + (*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"); + 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); + (*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"); + 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); - + 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)) { + 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]); @@ -127,80 +157,105 @@ static bool parse_variant_type(const uint8_t **payload, const uint8_t *end, WASM 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"); + 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"); + } + 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) { +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"); + 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)) { + 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)); + (*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"); + 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); + (*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"); + 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); - + 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)) { + 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); + 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"); + } + 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); return false; } @@ -208,37 +263,44 @@ static bool parse_flags_type(const uint8_t **payload, const uint8_t *end, WASMCo // Parse vec uint64_t count_leb = 0; - if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + 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)); + (*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"); + 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); + (*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"); + 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); - + 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)) { + 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]); @@ -246,12 +308,15 @@ static bool parse_flags_type(const uint8_t **payload, const uint8_t *end, WASMCo 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); + 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); + } + else { + set_error_buf_ex(error_buf, error_buf_size, + "Flags type must have 0 < count <= 32, got %u", count); return false; } @@ -260,9 +325,14 @@ static bool parse_flags_type(const uint8_t **payload, const uint8_t *end, WASMCo } // 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); return false; } @@ -270,37 +340,45 @@ static bool parse_enum_type(const uint8_t **payload, const uint8_t *end, WASMCom // Parse vec uint64_t count_leb = 0; - if (!read_leb((uint8_t **)&p, end, 32, false, &count_leb, error_buf, error_buf_size)) { + 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)); + (*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"); + 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); + (*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"); + 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); - + 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)) { + 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]); @@ -308,12 +386,15 @@ static bool parse_enum_type(const uint8_t **payload, const uint8_t *end, WASMCom 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); + 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"); + } + else { + set_error_buf_ex(error_buf, error_buf_size, + "enum type must have at least one field"); return false; } @@ -322,39 +403,51 @@ static bool parse_enum_type(const uint8_t **payload, const uint8_t *end, WASMCom } // 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) { +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"); + 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)); + (*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"); + 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)); + (*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"); + 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)); + 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)) { + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to parse option type"); return false; } @@ -363,21 +456,28 @@ static bool parse_option_type(const uint8_t **payload, const uint8_t *end, WASMC } // 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) { +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"); + 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)); + (*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"); + 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; @@ -386,52 +486,69 @@ static bool parse_result_type(const uint8_t **payload, const uint8_t *end, WASMC // 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)); + (*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"); + 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)) { + 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"); + 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); + } + 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)); + (*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"); + 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)) { + 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"); + 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); + } + 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; } @@ -440,9 +557,14 @@ static bool parse_result_type(const uint8_t **payload, const uint8_t *end, WASMC } // 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); return false; } @@ -450,13 +572,15 @@ static bool parse_own_type(const uint8_t **payload, const uint8_t *end, WASMComp (*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"); + 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)) { + 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"); @@ -470,26 +594,35 @@ static bool parse_own_type(const uint8_t **payload, const uint8_t *end, WASMComp // 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) { +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"); + 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)); + (*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"); + 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)) { + 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"); + 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; @@ -499,21 +632,28 @@ static bool parse_borrow_type(const uint8_t **payload, const uint8_t *end, WASMC } // 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) { +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"); + 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)); + (*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"); + 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; @@ -521,26 +661,35 @@ static bool parse_stream_type(const uint8_t **payload, const uint8_t *end, WASMC 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)); + (*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"); + 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)) { + 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"); + 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); + } + 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; } @@ -549,21 +698,28 @@ static bool parse_stream_type(const uint8_t **payload, const uint8_t *end, WASMC } // 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) { +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"); + 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)); + (*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"); + 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; @@ -571,26 +727,35 @@ static bool parse_future_type(const uint8_t **payload, const uint8_t *end, WASMC 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)); + (*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"); + 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)) { + 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"); + 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); + } + 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; } @@ -599,55 +764,67 @@ static bool parse_future_type(const uint8_t **payload, const uint8_t *end, WASMC } // 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) { +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"); + 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)); + (*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"); + 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)); + (*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"); + 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)) { + 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"); + 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)) { + + 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; @@ -655,30 +832,39 @@ static bool parse_list_type_with_len(const uint8_t **payload, const uint8_t *end } // 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) { +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"); + 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"); + 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)); + (*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"); + 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)) { + + 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; @@ -690,17 +876,22 @@ static bool parse_list_type(const uint8_t **payload, const uint8_t *end, WASMCom } // Helper function to free a defvaltype structure -static void free_defvaltype(WASMComponentDefValType *def_val_type) { +static void +free_defvaltype(WASMComponentDefValType *def_val_type) +{ if (!def_val_type) { return; } - + switch (def_val_type->tag) { - case WASM_COMP_DEF_VAL_RECORD: { + 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]); + 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); } @@ -709,10 +900,12 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_VARIANT: { + 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++) { + 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); @@ -722,7 +915,8 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_LIST: { + 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); @@ -733,10 +927,12 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_LIST_LEN: { + 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); + 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); @@ -744,10 +940,12 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_TUPLE: { + 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); + 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); @@ -755,10 +953,12 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_FLAGS: { + 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++) { + 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); @@ -768,11 +968,14 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_ENUM: { + 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]); + 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); } @@ -781,10 +984,12 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_OPTION: { + 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); + 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); @@ -792,10 +997,12 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_RESULT: { + 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); + 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) { @@ -807,24 +1014,28 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_OWN: { + 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: { + 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: { + 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); + 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); @@ -832,10 +1043,12 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } break; } - case WASM_COMP_DEF_VAL_FUTURE: { + 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); + 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); @@ -850,22 +1063,27 @@ static void free_defvaltype(WASMComponentDefValType *def_val_type) { } // 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) { +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"); + 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; @@ -893,7 +1111,7 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo 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); @@ -903,14 +1121,16 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; case WASM_COMP_DEF_VAL_LIST_LEN: - if (!parse_list_type_with_len(&p, end, out, error_buf, error_buf_size)) { + 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: { + + case WASM_COMP_DEF_VAL_TUPLE: + { if (!parse_tuple_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -918,7 +1138,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo } break; } - case WASM_COMP_DEF_VAL_FLAGS: { + case WASM_COMP_DEF_VAL_FLAGS: + { if (!parse_flags_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -927,7 +1148,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - case WASM_COMP_DEF_VAL_ENUM: { + case WASM_COMP_DEF_VAL_ENUM: + { if (!parse_enum_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -936,7 +1158,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - case WASM_COMP_DEF_VAL_OPTION: { + case WASM_COMP_DEF_VAL_OPTION: + { if (!parse_option_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -945,7 +1168,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - case WASM_COMP_DEF_VAL_RESULT: { + case WASM_COMP_DEF_VAL_RESULT: + { if (!parse_result_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -954,7 +1178,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - case WASM_COMP_DEF_VAL_OWN: { + case WASM_COMP_DEF_VAL_OWN: + { if (!parse_own_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -963,7 +1188,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - case WASM_COMP_DEF_VAL_BORROW: { + case WASM_COMP_DEF_VAL_BORROW: + { if (!parse_borrow_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -972,7 +1198,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - case WASM_COMP_DEF_VAL_STREAM: { + case WASM_COMP_DEF_VAL_STREAM: + { if (!parse_stream_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -981,7 +1208,8 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - case WASM_COMP_DEF_VAL_FUTURE: { + case WASM_COMP_DEF_VAL_FUTURE: + { if (!parse_future_type(&p, end, out, error_buf, error_buf_size)) { wasm_runtime_free(*out); *out = NULL; @@ -990,8 +1218,10 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo break; } - default: { - set_error_buf_ex(error_buf, error_buf_size, "Invalid defvaltype tag: 0x%02x", tag); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid defvaltype tag: 0x%02x", tag); wasm_runtime_free(*out); *out = NULL; return false; @@ -1002,21 +1232,28 @@ static bool parse_defvaltype(const uint8_t **payload, const uint8_t *end, WASMCo 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) { +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"); + 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"); + 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; } @@ -1025,20 +1262,25 @@ static bool parse_param_list(const uint8_t **payload, const uint8_t *end, WASMCo // Allocate memory for the param list if (param_count > 0) { - (*out)->params = wasm_runtime_malloc(sizeof(WASMComponentLabelValType) * param_count); + (*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"); + 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); + 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 { + } + else { (*out)->params = NULL; } @@ -1046,30 +1288,39 @@ static bool parse_param_list(const uint8_t **payload, const uint8_t *end, WASMCo return true; } -bool parse_func_type(const uint8_t **payload, const uint8_t *end, WASMComponentFuncType **out, char *error_buf, uint32_t error_buf_size) { +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"); + 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"); + 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"); + 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; } @@ -1077,38 +1328,49 @@ bool parse_func_type(const uint8_t **payload, const uint8_t *end, WASMComponentF 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) { +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"); + 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)); + 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"); + 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); + 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"); + 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)); + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for extern desc"); wasm_runtime_free(import_name); return false; } @@ -1116,7 +1378,8 @@ bool parse_component_decl_import_decl(const uint8_t **payload, const uint8_t *en // 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"); + 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; @@ -1128,21 +1391,28 @@ bool parse_component_decl_import_decl(const uint8_t **payload, const uint8_t *en 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) { +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"); + 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)); + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for core def type"); return false; } memset(deftype, 0, sizeof(WASMComponentCoreDefType)); @@ -1154,19 +1424,23 @@ bool parse_component_decl_core_type(const uint8_t **payload, const uint8_t *end, // 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)); + 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)) { + 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; @@ -1175,18 +1449,21 @@ bool parse_component_decl_core_type(const uint8_t **payload, const uint8_t *end, } // Store as unresolved reference by leaving deftype NULL for now. - // The index %llu will need to be resolved later against the core type section + // 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. + + // 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:) + // 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); @@ -1201,13 +1478,18 @@ bool parse_component_decl_core_type(const uint8_t **payload, const uint8_t *end, 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for types"); return false; } memset(*out, 0, sizeof(WASMComponentTypes)); @@ -1222,13 +1504,18 @@ bool parse_component_decl_type(const uint8_t **payload, const uint8_t *end, WASM 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for alias definition"); return false; } memset(*out, 0, sizeof(WASMComponentAliasDefinition)); @@ -1243,38 +1530,49 @@ bool parse_component_decl_alias(const uint8_t **payload, const uint8_t *end, WAS 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) { +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"); + 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)); + 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"); + 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); + 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"); + 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)); + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for extern desc"); wasm_runtime_free(export_name); return false; } @@ -1282,7 +1580,8 @@ bool parse_component_decl_export(const uint8_t **payload, const uint8_t *end, WA // 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"); + 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; @@ -1294,13 +1593,18 @@ bool parse_component_decl_export(const uint8_t **payload, const uint8_t *end, WA 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for instance decl"); return false; } memset(*out, 0, sizeof(WASMComponentInstDecl)); @@ -1309,34 +1613,45 @@ bool parse_component_instance_decl(const uint8_t **payload, const uint8_t *end, (*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)) { + 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)) { + 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)) { + 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)) { + 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); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid instance decl tag: 0x%02x", tag); return false; } } @@ -1345,18 +1660,26 @@ bool parse_component_instance_decl(const uint8_t **payload, const uint8_t *end, return true; } -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_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)) { + 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)) { + } + else { + if (!parse_component_instance_decl(&p, end, &(*out)->decl.instance_decl, + error_buf, error_buf_size)) { return false; } } @@ -1365,46 +1688,60 @@ bool parse_component_decl(const uint8_t **payload, const uint8_t *end, WASMCompo return true; } -bool parse_component_type(const uint8_t **payload, const uint8_t *end, WASMComponentComponentType **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) +{ 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"); + 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"); + 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); + (*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"); + 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)); + 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"); + 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); + 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; } @@ -1412,14 +1749,19 @@ bool parse_component_type(const uint8_t **payload, const uint8_t *end, WASMCompo (*out)->component_decls[i] = *component_decl; wasm_runtime_free(component_decl); // free shell } - } else { + } + 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) { +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; } @@ -1434,14 +1776,17 @@ bool parse_component_instance_type(const uint8_t **payload, const uint8_t *end, *out = wasm_runtime_malloc(sizeof(WASMComponentInstType)); if (!*out) { - set_error_buf_ex(error_buf, error_buf_size, "Failed to allocate memory for instance type"); + 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"); + 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; } @@ -1450,21 +1795,26 @@ bool parse_component_instance_type(const uint8_t **payload, const uint8_t *end, // Allocate memory for the instance list if (instance_count > 0) { - instance_decls = wasm_runtime_malloc(sizeof(WASMComponentInstDecl) * instance_count); + 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"); + 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); + 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)) { + if (!parse_component_instance_decl(&p, end, &instance_decl, + error_buf, error_buf_size)) { goto fail; } @@ -1495,13 +1845,18 @@ 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) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for resource type sync"); return false; } memset(*out, 0, sizeof(WASMComponentResourceTypeSync)); @@ -1511,37 +1866,49 @@ bool parse_resource_type_sync(const uint8_t **payload, const uint8_t *end, WASMC 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"); + 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); + } + 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) { +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"); + 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"); + 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; @@ -1551,13 +1918,18 @@ bool parse_resource_type_async(const uint8_t **payload, const uint8_t *end, WASM 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"); + 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); + } + 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; } @@ -1565,13 +1937,18 @@ bool parse_resource_type_async(const uint8_t **payload, const uint8_t *end, WASM return true; } -bool parse_resource_type(const uint8_t **payload, const uint8_t *end, WASMComponentResourceType **out, char *error_buf, uint32_t error_buf_size) { +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"); + set_error_buf_ex(error_buf, error_buf_size, + "Failed to allocate memory for resource type"); return false; } memset(*out, 0, sizeof(WASMComponentResourceType)); @@ -1582,27 +1959,34 @@ bool parse_resource_type(const uint8_t **payload, const uint8_t *end, WASMCompon // 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); + 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)) { + 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)) { + 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); + + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid resource type tag: 0x%02x", tag); return false; } } @@ -1612,7 +1996,11 @@ bool parse_resource_type(const uint8_t **payload, const uint8_t *end, WASMCompon } // 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) { +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); @@ -1625,51 +2013,67 @@ bool parse_single_type(const uint8_t **payload, const uint8_t *end, WASMComponen } switch (type_tag) { - case WASM_COMP_DEF_TYPE: { - if (!parse_defvaltype(&p, end, &out->type.def_val_type, error_buf, error_buf_size)) { + 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)) { + + 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: { + + case WASM_COMP_COMPONENT_TYPE: + { // componenttype ::= 0x41 cd*:vec() - if (!parse_component_type(&p, end, &out->type.component_type, error_buf, error_buf_size)) { + if (!parse_component_type(&p, end, &out->type.component_type, + error_buf, error_buf_size)) { return false; } break; } - - case WASM_COMP_INSTANCE_TYPE: { + + 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)) { + 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. + 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)) { + 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); + + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "Invalid type tag: 0x%02x", tag); return false; } } @@ -1679,9 +2083,16 @@ bool parse_single_type(const uint8_t **payload, const uint8_t *end, WASMComponen } // 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) { +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; + if (consumed_len) + *consumed_len = 0; return false; } @@ -1691,43 +2102,55 @@ bool wasm_component_parse_types_section(const uint8_t **payload, uint32_t payloa // 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); + 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); + 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); + 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)) { + 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return false; } } - } else { + } + else { out->types = NULL; } - if (consumed_len) *consumed_len = (uint32_t)(p - *payload); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return true; } -static void free_component_instance_decl(WASMComponentInstDecl *decl) { - if (!decl) return; +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) { @@ -1757,15 +2180,19 @@ static void free_component_instance_decl(WASMComponentInstDecl *decl) { 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); + 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); + 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; @@ -1779,7 +2206,8 @@ static void free_component_instance_decl(WASMComponentInstDecl *decl) { 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); + 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; } @@ -1795,13 +2223,17 @@ static void free_component_instance_decl(WASMComponentInstDecl *decl) { } } -static void free_component_decl(WASMComponentComponentDecl *decl) { - if (!decl) return; +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); + 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; } @@ -1815,7 +2247,8 @@ static void free_component_decl(WASMComponentComponentDecl *decl) { } break; default: - // Instance decl branch handles tags 0x00/0x01/0x02/0x04 inside nested decl + // 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); @@ -1825,8 +2258,11 @@ static void free_component_decl(WASMComponentComponentDecl *decl) { } } -static void free_resource_type(WASMComponentResourceType *rt) { - if (!rt) return; +static void +free_resource_type(WASMComponentResourceType *rt) +{ + if (!rt) + return; switch (rt->tag) { case WASM_COMP_RESOURCE_TYPE_SYNC: if (rt->resource.sync) { @@ -1845,8 +2281,11 @@ static void free_resource_type(WASMComponentResourceType *rt) { } } -static void free_component_types_entry(WASMComponentTypes *type) { - if (!type) return; +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) { @@ -1859,13 +2298,21 @@ static void free_component_types_entry(WASMComponentTypes *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++) { + 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); + 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); + 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); @@ -1875,7 +2322,8 @@ static void free_component_types_entry(WASMComponentTypes *type) { } 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->results); } wasm_runtime_free(type->type.func_type->results); type->type.func_type->results = NULL; @@ -1887,10 +2335,13 @@ static void free_component_types_entry(WASMComponentTypes *type) { 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]); + 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); + wasm_runtime_free( + type->type.component_type->component_decls); type->type.component_type->component_decls = NULL; } wasm_runtime_free(type->type.component_type); @@ -1900,8 +2351,10 @@ static void free_component_types_entry(WASMComponentTypes *type) { 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]); + 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; @@ -1924,24 +2377,26 @@ static void free_component_types_entry(WASMComponentTypes *type) { } // Individual section free functions -void wasm_component_free_types_section(WASMComponentSection *section) { +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 index 1a9beb832..e82b3d202 100644 --- a/core/iwasm/common/component-model/wasm_component_validate.c +++ b/core/iwasm/common/component-model/wasm_component_validate.c @@ -12,14 +12,25 @@ #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); +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) { +// 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 *)); + 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) @@ -28,14 +39,17 @@ static bool ctx_push_type(WASMComponentValidationContext *ctx, WASMComponentType 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"); + 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)); + 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); } @@ -51,17 +65,25 @@ static bool ctx_push_type(WASMComponentValidationContext *ctx, WASMComponentType 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) { +// 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; + 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"); + 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)); + memcpy(new_consumed, ctx->value_consumed, + ctx->value_count * sizeof(bool)); wasm_runtime_free(ctx->value_consumed); } ctx->value_consumed = new_consumed; @@ -71,17 +93,26 @@ static bool ctx_push_value(WASMComponentValidationContext *ctx, char *error_buf, 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) { +// 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_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"); + 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)); + 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; @@ -92,13 +123,18 @@ static bool ctx_push_func_type(WASMComponentValidationContext *ctx, uint32_t typ } // 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) { +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); + 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); + set_error_buf_ex(error_buf, error_buf_size, + "value %u consumed more than once", idx); return false; } ctx->value_consumed[idx] = true; @@ -106,16 +142,23 @@ static bool ctx_consume_value(WASMComponentValidationContext *ctx, uint32_t idx, } // 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; +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) + 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 == 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; @@ -133,7 +176,8 @@ static bool valtype_equal(WASMComponentValueType *a, WASMComponentValueType *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); + return defvaltype_equal(ta->type.def_val_type, tb->type.def_val_type, + ctx); } // Mixed (eg one primval, one idx) - not equal @@ -141,90 +185,124 @@ static bool valtype_equal(WASMComponentValueType *a, WASMComponentValueType *b, } // 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; +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; + 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) + 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)) + 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; + 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; +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: { + 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; + 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) + 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)) + if (!valtype_equal(ra->fields[i].value_type, + rb->fields[i].value_type, ctx)) return false; } return true; } - case WASM_COMP_DEF_VAL_VARIANT: { + 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; + 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) + 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)) + 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); + 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); + return valtype_equal(a->def_val.list_len->element_type, + b->def_val.list_len->element_type, ctx); - case WASM_COMP_DEF_VAL_TUPLE: { + 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; + 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)) + if (!valtype_equal(&ta->element_types[i], &tb->element_types[i], + ctx)) return false; } return true; } - case WASM_COMP_DEF_VAL_FLAGS: { + 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; + 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; @@ -232,10 +310,12 @@ static bool defvaltype_equal(WASMComponentDefValType *a, WASMComponentDefValType return true; } - case WASM_COMP_DEF_VAL_ENUM: { + 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; + 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; @@ -244,10 +324,14 @@ static bool defvaltype_equal(WASMComponentDefValType *a, WASMComponentDefValType } case WASM_COMP_DEF_VAL_OPTION: - return valtype_equal(a->def_val.option->element_type, b->def_val.option->element_type, ctx); + 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); + 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; @@ -256,10 +340,12 @@ static bool defvaltype_equal(WASMComponentDefValType *a, WASMComponentDefValType 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); + 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); + return valtype_equal(a->def_val.future->element_type, + b->def_val.future->element_type, ctx); default: return false; @@ -267,35 +353,51 @@ static bool defvaltype_equal(WASMComponentDefValType *a, WASMComponentDefValType } // 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; +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); + 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 + 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. + // 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; +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) + 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 == 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; @@ -303,7 +405,8 @@ static bool valtype_subtype(WASMComponentValueType *a, WASMComponentValueType *b 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 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; @@ -312,7 +415,8 @@ static bool valtype_subtype(WASMComponentValueType *a, WASMComponentValueType *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 defvaltype_subtype(ta->type.def_val_type, tb->type.def_val_type, + ctx); } return false; @@ -321,17 +425,24 @@ static bool valtype_subtype(WASMComponentValueType *a, WASMComponentValueType *b // 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; +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; + 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) + 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, @@ -339,28 +450,39 @@ static bool functype_subtype(WASMComponentFuncType *a, WASMComponentFuncType *b, 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; + 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) { +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; + 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: { + 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; @@ -368,57 +490,72 @@ static bool defvaltype_subtype(WASMComponentDefValType *a, WASMComponentDefValTy 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)) + 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; + if (!found) + return false; } return true; } - case WASM_COMP_DEF_VAL_VARIANT: { + 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)) + 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)) + if (!found) return false; } return true; } - case WASM_COMP_DEF_VAL_FLAGS: { + 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; @@ -430,12 +567,14 @@ static bool defvaltype_subtype(WASMComponentDefValType *a, WASMComponentDefValTy break; } } - if (!found) return false; + if (!found) + return false; } return true; } - case WASM_COMP_DEF_VAL_ENUM: { + 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; @@ -447,42 +586,57 @@ static bool defvaltype_subtype(WASMComponentDefValType *a, WASMComponentDefValTy break; } } - if (!found) return false; + 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); + 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); + 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: { + 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; + 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 (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; + if (!ctx->types[ia] || !ctx->types[ib]) + return true; return ctx->types[ia] == ctx->types[ib]; } - case WASM_COMP_DEF_VAL_BORROW: { + 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; + 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); + 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); + return valtype_subtype(a->def_val.future->element_type, + b->def_val.future->element_type, ctx); default: return false; @@ -490,14 +644,21 @@ static bool defvaltype_subtype(WASMComponentDefValType *a, WASMComponentDefValTy } // 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; +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); + 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: @@ -507,8 +668,12 @@ static bool component_type_subtype(WASMComponentTypes *a, WASMComponentTypes *b, } } -// 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) { +// 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; @@ -526,8 +691,12 @@ static uint32_t valtype_get_own_resource(WASMComponentValueType *vt, WASMCompone 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) { +// 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; @@ -546,11 +715,15 @@ static uint32_t valtype_get_borrow_resource(WASMComponentValueType *vt, WASMComp } // Check if result type is (own $R) or (result (own $R) E?) -static bool result_is_own_or_result_own(WASMComponentFuncType *ft, WASMComponentValidationContext *ctx) { +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) + if (ft->results->tag != WASM_COMP_RESULT_LIST_WITH_TYPE + || !ft->results->results) return false; WASMComponentValueType *rv = ft->results->results; @@ -562,8 +735,12 @@ static bool result_is_own_or_result_own(WASMComponentFuncType *ft, WASMComponent // 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 (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; } @@ -572,65 +749,89 @@ static bool result_is_own_or_result_own(WASMComponentFuncType *ft, WASMComponent 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) { +// 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) { + 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"); + 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?)"); + 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) { + } + 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"); + 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"); + 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\""); + 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"); + 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) { + } + 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"); + 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"); + 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); + set_error_buf_ex(error_buf, error_buf_size, + "[static] resource name \"%s\" not found in scope", + r_name); return false; } } @@ -638,18 +839,27 @@ static bool validate_func_name_annotation(WASMComponentValidationContext *ctx, c 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; +// 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; + if (idx >= ctx->type_count || !ctx->types[idx]) + return false; WASMComponentTypes *t = ctx->types[idx]; - if (t->tag != WASM_COMP_DEF_TYPE) return false; + if (t->tag != WASM_COMP_DEF_TYPE) + return false; // Walk the structure recursively WASMComponentDefValType *dvt = t->type.def_val_type; @@ -658,7 +868,8 @@ static bool valtype_has_borrow(WASMComponentValueType *vt, WASMComponentValidati return true; case WASM_COMP_DEF_VAL_OWN: return false; - case WASM_COMP_DEF_VAL_RECORD: { + 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++) @@ -666,15 +877,18 @@ static bool valtype_has_borrow(WASMComponentValueType *vt, WASMComponentValidati return true; return false; } - case WASM_COMP_DEF_VAL_VARIANT: { - // A borrow in any variant case is enough to reject it in result position + 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: { + 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)) @@ -685,7 +899,8 @@ static bool valtype_has_borrow(WASMComponentValueType *vt, WASMComponentValidati 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); + 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: @@ -698,38 +913,47 @@ static bool valtype_has_borrow(WASMComponentValueType *vt, WASMComponentValidati } } -static bool valtype_has_list_or_string(WASMComponentValueType *vt, WASMComponentValidationContext *ctx) { - if (!vt) 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; + if (idx >= ctx->type_count || !ctx->types[idx]) + return false; WASMComponentTypes *t = ctx->types[idx]; - if (t->tag != WASM_COMP_DEF_TYPE) return false; + 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: { + 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: { + 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: { + 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)) @@ -737,16 +961,24 @@ static bool valtype_has_list_or_string(WASMComponentValueType *vt, WASMComponent return false; } case WASM_COMP_DEF_VAL_OPTION: - return valtype_has_list_or_string(dvt->def_val.option->element_type, ctx); + 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); + 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; +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)) @@ -755,10 +987,15 @@ static bool functype_params_has_list_or_string(WASMComponentFuncType *ft, WASMCo return false; } -static bool functype_results_has_list_or_string(WASMComponentFuncType *ft, WASMComponentValidationContext *ctx) { - if (!ft) 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 (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; } @@ -766,35 +1003,61 @@ static bool functype_results_has_list_or_string(WASMComponentFuncType *ft, WASMC 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); +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) { +// 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++) { + 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"); + 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"); + // 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"); + 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; } } @@ -803,10 +1066,14 @@ static bool validate_core_instance_section(WASMComponentValidationContext *ctx, break; } - case WASM_COMP_INSTANCE_EXPRESSION_WITHOUT_ARGS: { + 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]; + 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; @@ -834,18 +1101,34 @@ static bool validate_core_instance_section(WASMComponentValidationContext *ctx, 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); + 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); + 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"); + 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; } } @@ -853,88 +1136,137 @@ static bool validate_core_instance_section(WASMComponentValidationContext *ctx, break; } - default: { - set_error_buf_ex(error_buf, error_buf_size, "failed to validate core instance section"); + 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 + // 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) { +// 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"); + 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; + 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 + 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) + 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"); + 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"); + 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"); + 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; + 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) + 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"); + 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"); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "invalid moduletype tag"); return false; } } @@ -943,8 +1275,10 @@ static bool validate_core_type_section(WASMComponentValidationContext *ctx, WASM break; } - default: { - set_error_buf_ex(error_buf, error_buf_size, "invalid deftype tag"); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "invalid deftype tag"); return false; } } @@ -956,33 +1290,53 @@ static bool validate_core_type_section(WASMComponentValidationContext *ctx, WASM } // 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++; +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) { +// 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: { + 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"); + 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; + // 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"); + 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; @@ -1003,23 +1357,36 @@ static bool validate_instances_section(WASMComponentValidationContext *ctx, WASM 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); + 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); + 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)) + 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"); + 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; } } @@ -1028,9 +1395,12 @@ static bool validate_instances_section(WASMComponentValidationContext *ctx, WASM 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]; + 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; @@ -1038,7 +1408,10 @@ static bool validate_instances_section(WASMComponentValidationContext *ctx, WASM 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"); + 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; @@ -1059,24 +1432,39 @@ static bool validate_instances_section(WASMComponentValidationContext *ctx, WASM 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); + 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); + 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)) + 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"); + 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; } } @@ -1084,8 +1472,10 @@ static bool validate_instances_section(WASMComponentValidationContext *ctx, WASM break; } - default: { - set_error_buf_ex(error_buf, error_buf_size, "failed to validate instance section"); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "failed to validate instance section"); return false; } } @@ -1096,57 +1486,84 @@ static bool validate_instances_section(WASMComponentValidationContext *ctx, WASM return true; } -static bool validate_aliases_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { +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"); + 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"); + 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 + 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 + // 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"); + 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 { + } + 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"); + 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 + // 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"); + set_error_buf_ex( + error_buf, error_buf_size, + "outer alias ct exceeds component nesting depth"); return false; } } @@ -1154,45 +1571,61 @@ static bool validate_aliases_section(WASMComponentValidationContext *ctx, WASMCo 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: + 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"); + set_error_buf_ex( + error_buf, error_buf_size, + "invalid core sort in outer alias"); return false; } - } else { + } + 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 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"); + 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; + 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"); + 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); + 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"); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "unknown alias target type"); return false; } } @@ -1221,15 +1654,19 @@ static bool validate_aliases_section(WASMComponentValidationContext *ctx, WASMCo 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"); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "invalid core sort in alias"); return false; } } - } else { + } + else { switch (alias_def->sort->sort) { case WASM_COMP_SORT_FUNC: - if (!ctx_push_func_type(ctx, UINT32_MAX, error_buf, error_buf_size)) + if (!ctx_push_func_type(ctx, UINT32_MAX, error_buf, + error_buf_size)) return false; ctx->func_count++; break; @@ -1239,9 +1676,11 @@ static bool validate_aliases_section(WASMComponentValidationContext *ctx, WASMCo 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)) + // 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; @@ -1251,8 +1690,11 @@ static bool validate_aliases_section(WASMComponentValidationContext *ctx, WASMCo 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); + default: + { + set_error_buf_ex(error_buf, error_buf_size, + "invalid sort in alias: 0x%02x", + alias_def->sort->sort); return false; } } @@ -1262,113 +1704,181 @@ static bool validate_aliases_section(WASMComponentValidationContext *ctx, WASMCo 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) { +// 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: { + 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: { + 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); + 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"); + 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: { + 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); + 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"); + 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 + 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"); + 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"); + 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: { + 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"); + 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"); + 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: { + case WASM_COMP_DEF_VAL_RECORD: + { // Record field names must all be unique - const WASMComponentRecordType *rec = dvt->def_val.record; + 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"); + 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: { + case WASM_COMP_DEF_VAL_VARIANT: + { // Variant case names must be unique - const WASMComponentVariantType *var = dvt->def_val.variant; + 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"); + 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 + 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"); + 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; + 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"); + 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; } } @@ -1381,38 +1891,55 @@ static bool validate_type_section(WASMComponentValidationContext *ctx, WASMCompo break; } - case WASM_COMP_FUNC_TYPE: { + 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"); + 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"); + // 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; + 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"); + 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; } } @@ -1421,23 +1948,32 @@ static bool validate_type_section(WASMComponentValidationContext *ctx, WASMCompo 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; + 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"); + 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"); + 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; } } @@ -1445,38 +1981,54 @@ static bool validate_type_section(WASMComponentValidationContext *ctx, WASMCompo 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; + 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"); + 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; + 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"); + 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"); + 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"); + 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 + // 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++; @@ -1485,11 +2037,19 @@ static bool validate_type_section(WASMComponentValidationContext *ctx, WASMCompo 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; +// 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 + // 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; @@ -1502,74 +2062,99 @@ static bool validate_canon_opts(WASMComponentValidationContext *ctx, WASMCompone 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"); + 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"); + 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"); + 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"); + 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"); + 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 + // 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"); + 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"); + 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"); + 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"); + 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); + 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"); + 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"); + 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); + // 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"); + 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; } } @@ -1577,102 +2162,161 @@ static bool validate_canon_opts(WASMComponentValidationContext *ctx, WASMCompone 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) { +// 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"); + 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; + 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"); + 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"); + 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)) + 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)) + // 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; + 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"); + 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) { + 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)) + 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; + 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"); + 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"); + 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"); + 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: { + 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; + 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"); + 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"); + 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; + 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"); + 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"); + 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"); + 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++; @@ -1680,7 +2324,9 @@ static bool validate_canons_section(WASMComponentValidationContext *ctx, WASMCom } default: - set_error_buf_ex(error_buf, error_buf_size, "unsupported canon opcode: 0x%02x", (unsigned)canon_section->tag); + set_error_buf_ex(error_buf, error_buf_size, + "unsupported canon opcode: 0x%02x", + (unsigned)canon_section->tag); return false; } } @@ -1688,29 +2334,44 @@ static bool validate_canons_section(WASMComponentValidationContext *ctx, WASMCom return true; } -static bool validate_start_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { +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"); + 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 + // 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; + 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) + 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", + 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", + 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; } @@ -1719,13 +2380,17 @@ static bool validate_start_section(WASMComponentValidationContext *ctx, WASMComp // 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]); + 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)) + 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 + // 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; @@ -1736,63 +2401,87 @@ static bool validate_start_section(WASMComponentValidationContext *ctx, WASMComp } // The name must be unique -static bool validate_imports_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { +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 + // 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 { + } + 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"); + 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); + 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"); + 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: { + 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"); + 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"); + 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)) + 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)) + 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; + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "import value eq idx out of bounds"); return false; } - } else { + } + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "import value type idx out of bounds"); return false; } } @@ -1801,86 +2490,119 @@ static bool validate_imports_section(WASMComponentValidationContext *ctx, WASMCo 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; + 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"); + 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 + // 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); + 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: { + 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"); + 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"); + 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: { + 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"); + 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"); + 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"); + 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) { +// 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 { + } + 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"); + 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); + 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"); + 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 { + } + else { switch (exp->sort_idx->sort->sort) { case WASM_COMP_SORT_FUNC: in_bounds = idx < ctx->func_count; @@ -1898,19 +2620,26 @@ static bool validate_exports_section(WASMComponentValidationContext *ctx, WASMCo 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); + 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); + 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)) + 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; } @@ -1920,114 +2649,176 @@ static bool validate_exports_section(WASMComponentValidationContext *ctx, WASMCo 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"); + 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"); + 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"); + 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"); + 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; + 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"); + 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"); + 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); + 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 (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"); + 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 + // 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; + 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"); + 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"); + 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 + // 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; + 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"); + 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"); + 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); + 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 + // 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 + // 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 { + } + 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)) + 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 + // 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)) + if (!ctx_push_type(ctx, NULL, false, error_buf, + error_buf_size)) return false; ctx->type_count++; break; @@ -2046,23 +2837,31 @@ static bool validate_exports_section(WASMComponentValidationContext *ctx, WASMCo return true; } -static bool validate_values_section(WASMComponentValidationContext *ctx, WASMComponentSection *section, char *error_buf, uint32_t error_buf_size) { +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"); + 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"); + 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"); + 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)) @@ -2073,7 +2872,11 @@ static bool validate_values_section(WASMComponentValidationContext *ctx, WASMCom return true; } -bool wasm_component_validate(WASMComponent *comp, WASMComponentValidationContext *parent, char *error_buf, uint32_t error_buf_size) { +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; @@ -2083,24 +2886,33 @@ bool wasm_component_validate(WASMComponent *comp, WASMComponentValidationContext 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); + 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"); + 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); + 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"); + 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); + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "could not allocate hashmap for resource type names"); return false; } @@ -2112,44 +2924,57 @@ bool wasm_component_validate(WASMComponent *comp, WASMComponentValidationContext 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 + // 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + set_error_buf_ex(error_buf, error_buf_size, + "invalid section id: %d", section->id); ok = false; break; } @@ -2159,7 +2984,8 @@ bool wasm_component_validate(WASMComponent *comp, WASMComponentValidationContext 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); + set_error_buf_ex(error_buf, error_buf_size, + "value %u is never consumed", i); ok = false; break; } diff --git a/core/iwasm/common/component-model/wasm_component_validate.h b/core/iwasm/common/component-model/wasm_component_validate.h index 89d1207d5..c8a3be5f3 100644 --- a/core/iwasm/common/component-model/wasm_component_validate.h +++ b/core/iwasm/common/component-model/wasm_component_validate.h @@ -20,9 +20,9 @@ typedef struct WASMComponentValidationContext { 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_memory_count; // needed for canon memory opts uint32_t core_global_count; - uint32_t core_func_count; // needed for canon realloc/post-return checks + uint32_t core_func_count; // needed for canon realloc/post-return checks struct WASMComponentValidationContext *parent; @@ -30,27 +30,31 @@ typedef struct WASMComponentValidationContext { 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 + // 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 + // 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) + // 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 + // 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); +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 index f6abdc429..dd4fb1131 100644 --- a/core/iwasm/common/component-model/wasm_component_values_section.c +++ b/core/iwasm/common/component-model/wasm_component_values_section.c @@ -14,26 +14,33 @@ // 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; +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 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) { +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 { + } + else { // Check f32 NaN pattern (exponent all 1s, mantissa non-zero) uint32_t bits = 0; memcpy(&bits, bytes, 4); @@ -41,15 +48,20 @@ static bool is_any_nan(const uint8_t *bytes, bool is_f64) { } } -// 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) { +// 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"); + 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)) { @@ -60,7 +72,8 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone 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)) { + 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; } @@ -70,7 +83,10 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone // 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)); + 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; } @@ -79,25 +95,19 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone if (val_type->type == WASM_COMP_VAL_TYPE_PRIMVAL) { switch (val_type->type_specific.primval_type) { - case WASM_COMP_PRIMVAL_BOOL: { + 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); + 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); + set_error_buf_ex(error_buf, error_buf_size, + "Invalid bool value byte: 0x%02x", b); wasm_runtime_free(val_type); return false; } @@ -105,9 +115,12 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_S8: { + case WASM_COMP_PRIMVAL_U8: + { 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); + 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; } @@ -115,22 +128,43 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_S16: { + 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); + 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)) { + 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)); + 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; } @@ -138,22 +172,30 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_U16: { + 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); + 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)) { + 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)); + 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; } @@ -161,22 +203,30 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_S32: { + 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); + 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)) { + 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)); + 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; } @@ -184,22 +234,30 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_U32: { + 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); + 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)) { + 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)); + 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; } @@ -207,22 +265,30 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_S64: { + 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); + 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)) { + 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)); + 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; } @@ -230,22 +296,30 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_U64: { + 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); + 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)) { + 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)); + 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; } @@ -253,18 +327,23 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_F32: { + 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); + 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)) { + } + 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"); + set_error_buf_ex(error_buf, error_buf_size, + "Non-canonical NaN not allowed"); wasm_runtime_free(val_type); return false; } @@ -272,36 +351,46 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_F64: { + 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); + 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)) { + } + 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"); + 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: { + 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); + 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"); + 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; } @@ -309,49 +398,63 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone break; } - case WASM_COMP_PRIMVAL_STRING: { + case WASM_COMP_PRIMVAL_STRING: + { // val(string) ::= v: => v - // core:name = name_len_leb + name_bytes; require outer len == leb_len + name_len + // 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)) { + 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)); + 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); + 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"); + 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: { + default: + { set_error_buf_ex(error_buf, error_buf_size, - "Unknown primitive value type 0x%02x", - val_type->type_specific.primval_type); + "Unknown primitive value type 0x%02x", + val_type->type_specific.primval_type); wasm_runtime_free(val_type); return false; } } - } else { + } + 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); + "Unsupported valtype tag %u in values section " + "(expected typeidx)", + (unsigned)val_type->type); wasm_runtime_free(val_type); return false; } @@ -361,8 +464,9 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone // - 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)); + "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; } @@ -377,10 +481,18 @@ static bool parse_value(const uint8_t **payload, const uint8_t *end, WASMCompone } // 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) { +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; + set_error_buf_ex(error_buf, error_buf_size, + "Invalid payload or output pointer"); + if (consumed_len) + *consumed_len = 0; return false; } @@ -390,8 +502,10 @@ bool wasm_component_parse_values_section(const uint8_t **payload, uint32_t paylo // 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); + 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; } @@ -399,10 +513,13 @@ bool wasm_component_parse_values_section(const uint8_t **payload, uint32_t paylo out->count = value_count; if (value_count > 0) { - out->values = wasm_runtime_malloc(sizeof(WASMComponentValue) * value_count); + 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); + 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; } @@ -410,20 +527,26 @@ bool wasm_component_parse_values_section(const uint8_t **payload, uint32_t paylo 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); + 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); + if (consumed_len) + *consumed_len = (uint32_t)(p - *payload); return true; } // Individual section free functions -void wasm_component_free_values_section(WASMComponentSection *section) { +void +wasm_component_free_values_section(WASMComponentSection *section) +{ if (!section || !section->parsed.value_section) { return; } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index c78e55d8c..b381c2b6a 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -652,17 +652,20 @@ wasm_runtime_init_internal(void) return true; } -bool wasm_decode_header(const uint8_t *buf, uint32_t size, WASMHeader *out_header) { +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); + 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 + // 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); @@ -673,13 +676,16 @@ bool wasm_decode_header(const uint8_t *buf, uint32_t size, WASMHeader *out_heade return true; } -bool is_wasm_module(WASMHeader header) { +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; + uint32_t combined_version = + ((uint32_t)header.layer << 16) | (uint32_t)header.version; if (combined_version != WASM_CURRENT_VERSION) { return false; } @@ -4556,7 +4562,6 @@ wasm_runtime_get_function_count(WASMModuleCommon *const module) return -1; } - if (module->module_type == Wasm_Module_Bytecode) { const WASMModule *wasm_module = (const WASMModule *)module; return (int32)wasm_module->function_count; @@ -4573,7 +4578,6 @@ wasm_runtime_get_table_count(WASMModuleCommon *const module) return -1; } - if (module->module_type == Wasm_Module_Bytecode) { const WASMModule *wasm_module = (const WASMModule *)module; return (int32)wasm_module->table_count; @@ -4590,7 +4594,6 @@ wasm_runtime_get_memories_count(WASMModuleCommon *const module) return -1; } - if (module->module_type == Wasm_Module_Bytecode) { const WASMModule *wasm_module = (const WASMModule *)module; return (int32)wasm_module->memory_count; @@ -4607,7 +4610,6 @@ wasm_runtime_get_globals_count(WASMModuleCommon *const module) return -1; } - if (module->module_type == Wasm_Module_Bytecode) { const WASMModule *wasm_module = (const WASMModule *)module; return (int32)wasm_module->global_count; diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 772e60703..3bb40991e 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -92,9 +92,9 @@ 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 + uint32_t magic; // Magic number (0x6d736100 for both) + uint16_t version; // Version field + uint16_t layer; // Layer field } WASMHeader; typedef struct wasm_import_t { @@ -374,14 +374,16 @@ typedef struct SharedHeapInitArgs { * * @return true if success, false otherwise */ -bool wasm_decode_header(const uint8_t *buf, uint32_t size, WASMHeader *out_header); +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); +bool +is_wasm_module(WASMHeader header); /** * Initialize the WASM runtime environment, and also initialize diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index f3a88330b..bceb778c0 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -154,8 +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 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 079975e35..031a78aed 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -7108,8 +7108,9 @@ 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, false, wasm_binary_freeable, - no_resolve, error_buf, error_buf_size)) { + || !load_from_sections(module, section_list, false, + wasm_binary_freeable, no_resolve, error_buf, + error_buf_size)) { destroy_sections(section_list); return false; } @@ -7131,9 +7132,9 @@ check_wasi_abi_compatibility(const WASMModule *module, bool main_module, #endif #if WASM_ENABLE_COMPONENT_MODEL != 0 - bool is_component, + bool is_component, #endif - char *error_buf, uint32 error_buf_size) + char *error_buf, uint32 error_buf_size) { /** * be careful with: @@ -7222,8 +7223,8 @@ check_wasi_abi_compatibility(const WASMModule *module, /* 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"); + LOG_WARNING("warning: a module with WASI apis should be either " + "a command or a reactor"); } #endif /* @@ -7301,9 +7302,9 @@ wasm_loader_load(uint8 *buf, uint32 size, main_module, #endif #if WASM_ENABLE_COMPONENT_MODEL != 0 - args->is_component, + args->is_component, #endif - error_buf, error_buf_size)) { + 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 4cccd9776..318ed0a8f 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1507,9 +1507,9 @@ export_functions_instantiate(const WASMModule *module, */ static WASMExportTabInstance * export_tables_instantiate(const WASMModule *module, - WASMModuleInstance *module_inst, - uint32 export_table_count, char *error_buf, - uint32 error_buf_size) + WASMModuleInstance *module_inst, + uint32 export_table_count, char *error_buf, + uint32 error_buf_size) { WASMExportTabInstance *export_tables, *export_table; WASMExport *export = module->exports; @@ -1533,7 +1533,6 @@ export_tables_instantiate(const WASMModule *module, return export_tables; } - #if WASM_ENABLE_TAGS != 0 /** * Destroy export function instances. diff --git a/tests/unit/component/helpers.h b/tests/unit/component/helpers.h index 01403da55..3480aedaf 100644 --- a/tests/unit/component/helpers.h +++ b/tests/unit/component/helpers.h @@ -17,15 +17,16 @@ #define HEAP_SIZE (100 * 1024 * 1024) // 100 MB -class ComponentHelper { -public: +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 + uint32_t heap_size = HEAP_SIZE; // 100 MB char error_buf[128]; char global_heap_buf[HEAP_SIZE]; // 100 MB @@ -49,9 +50,13 @@ public: void do_setup(); void do_teardown(); - std::vector get_section(WASMComponentSectionType section_id) const; + 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 + 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 index 2eb8d66d6..ea18be78d 100644 --- a/tests/unit/component/test_binary_parser.cc +++ b/tests/unit/component/test_binary_parser.cc @@ -15,9 +15,9 @@ static std::vector component_files = { "add.wasm", "complex_with_host.wasm", "complex.wasm", - "logging-service.component.wasm", + "logging_service.component.wasm", "processor_and_logging_merged_wac_plug.wasm", - "processor-service.component.wasm", + "processor_service.component.wasm", "sampletypes.wasm" }; @@ -78,7 +78,7 @@ TEST_F(BinaryParserTest, TestLoadCorruptComponent) TEST_F(BinaryParserTest, TestDecodeHeaderValid) { helper->reset_component(); - bool ret = helper->read_wasm_file("logging-service.component.wasm"); + bool ret = helper->read_wasm_file("logging_service.component.wasm"); ASSERT_TRUE(ret); ASSERT_TRUE(helper->component_raw != NULL); @@ -95,7 +95,7 @@ TEST_F(BinaryParserTest, TestDecodeHeaderValid) TEST_F(BinaryParserTest, TestDecodeHeaderInvalid) { helper->reset_component(); - bool ret = helper->read_wasm_file("logging-service.component.wasm"); + bool ret = helper->read_wasm_file("logging_service.component.wasm"); ASSERT_TRUE(ret); ASSERT_TRUE(helper->component_raw != NULL); diff --git a/tests/unit/component/wasm-apps/logging-service.component.wasm b/tests/unit/component/wasm-apps/logging_service.component.wasm similarity index 100% rename from tests/unit/component/wasm-apps/logging-service.component.wasm rename to tests/unit/component/wasm-apps/logging_service.component.wasm diff --git a/tests/unit/component/wasm-apps/processor-service.component.wasm b/tests/unit/component/wasm-apps/processor_service.component.wasm similarity index 100% rename from tests/unit/component/wasm-apps/processor-service.component.wasm rename to tests/unit/component/wasm-apps/processor_service.component.wasm