diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/c-writer.cc | 453 |
1 files changed, 317 insertions, 136 deletions
diff --git a/src/c-writer.cc b/src/c-writer.cc index 9d637ee5..67b3db3c 100644 --- a/src/c-writer.cc +++ b/src/c-writer.cc @@ -180,7 +180,7 @@ class CWriter { c_stream_(c_stream), h_stream_(h_stream), header_name_(header_name) { - module_prefix_ = MangleName(options_.module_name); + module_prefix_ = MangleModuleName(options_.module_name); } Result WriteModule(const Module&); @@ -213,16 +213,32 @@ class CWriter { static constexpr char MangleField(ModuleFieldType); static std::string MangleMultivalueTypes(const TypeVector&); static std::string MangleTagTypes(const TypeVector&); + static std::string Mangle(std::string_view name, bool double_underscores); static std::string MangleName(std::string_view); - static std::string LegalizeName(std::string_view); - std::string ExportName(std::string_view mangled_name); + static std::string MangleModuleName(std::string_view); + std::string ExportName(std::string_view module_name, + std::string_view export_name); + std::string ExportName(std::string_view export_name); std::string ModuleInstanceTypeName() const; - static std::string MangleModuleInstanceName(std::string_view module_name); - static std::string MangleModuleInstanceTypeName(std::string_view module_name); - std::string DefineName(SymbolSet*, std::string_view); + static std::string ModuleInstanceTypeName(std::string_view module_name); + void ClaimName(SymbolSet& set, + SymbolMap& map, + char type_suffix, + std::string_view wasm_name, + const std::string& c_name); + std::string FindUniqueName(SymbolSet& set, std::string_view proposed_name); + std::string ClaimUniqueName(SymbolSet& set, + SymbolMap& map, + char type_suffix, + std::string_view wasm_name, + const std::string& proposed_c_name); void DefineImportName(const Import* import, std::string_view module_name, std::string_view field_name); + void ReserveExportNames(); + void ReserveExportName(std::string_view); + std::string DefineImportedModuleInstanceName(std::string_view name); + std::string DefineInstanceMemberName(ModuleFieldType, std::string_view); std::string DefineGlobalScopeName(ModuleFieldType, std::string_view); std::string DefineLocalScopeName(std::string_view name, bool is_label); std::string DefineParamName(std::string_view); @@ -408,6 +424,9 @@ static constexpr char kParamSuffix = 'a' + static_cast<char>(ModuleFieldType::Tag) + 1; static constexpr char kLabelSuffix = kParamSuffix + 1; +static constexpr char kSymbolPrefix[] = "w2c_"; +static constexpr char kAdminSymbolPrefix[] = "wasm2c_"; + size_t CWriter::MarkTypeStack() const { return type_stack_.size(); } @@ -527,87 +546,212 @@ std::string CWriter::MangleTagTypes(const TypeVector& types) { return result; } +/* The C symbol for an export from this module. */ +std::string CWriter::ExportName(std::string_view export_name) { + return kSymbolPrefix + module_prefix_ + '_' + MangleName(export_name); +} + +/* The C symbol for an export from an arbitrary module. */ // static -std::string CWriter::MangleName(std::string_view name) { - const char kPrefix = 'Z'; - std::string result = "Z_"; +std::string CWriter::ExportName(std::string_view module_name, + std::string_view export_name) { + return kSymbolPrefix + MangleModuleName(module_name) + '_' + + MangleName(export_name); +} - if (!name.empty()) { - for (unsigned char c : name) { - if ((isalnum(c) && c != kPrefix) || c == '_') { - result += c; - } else { - result += kPrefix; - result += StringPrintf("%02X", static_cast<uint8_t>(c)); - } - } - } +/* The type name of an instance of this module. */ +std::string CWriter::ModuleInstanceTypeName() const { + return kSymbolPrefix + module_prefix_; +} - return result; +/* The type name of an instance of an arbitrary module. */ +// static +std::string CWriter::ModuleInstanceTypeName(std::string_view module_name) { + return kSymbolPrefix + MangleModuleName(module_name); } -std::string CWriter::ExportName(std::string_view mangled_name) { - return module_prefix_ + std::string(mangled_name); +/* + * Hardcoded "C"-locale versions of isalpha/isdigit/isalnum/isxdigit for use + * in CWriter::Mangle(). We don't use the standard isalpha/isdigit/isalnum + * because the caller might have changed the current locale. + */ +static bool internal_isalpha(uint8_t ch) { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } -std::string CWriter::ModuleInstanceTypeName() const { - return module_prefix_ + "_instance_t"; +static bool internal_isdigit(uint8_t ch) { + return (ch >= '0' && ch <= '9'); } -// static -std::string CWriter::MangleModuleInstanceName(std::string_view module_name) { - return MangleName(module_name) + "_instance"; +static bool internal_isalnum(uint8_t ch) { + return internal_isalpha(ch) || internal_isdigit(ch); } -// static -std::string CWriter::MangleModuleInstanceTypeName( - std::string_view module_name) { - return MangleName(module_name) + "_instance_t"; +static bool internal_ishexdigit(uint8_t ch) { + return internal_isdigit(ch) || (ch >= 'A' && ch <= 'F'); // capitals only } // static -std::string CWriter::LegalizeName(std::string_view name) { - if (name.empty()) - return "_"; +std::string CWriter::Mangle(std::string_view name, bool double_underscores) { + /* + * Name mangling transforms arbitrary Wasm names into "safe" C names + * in a deterministic way. To avoid collisions, distinct Wasm names must be + * transformed into distinct C names. + * + * The rules implemented here are: + * 1) any hex digit ('A' through 'F') that follows the sequence "0x" + * is escaped + * 2) any underscore at the beginning, at the end, or following another + * underscore, is escaped + * 3) if double_underscores is set, underscores are replaced with + * two underscores. + * 4) otherwise, any alphanumeric character is kept as-is, + * and any other character is escaped + * + * "Escaped" means the character is represented with the sequence "0xAB", + * where A B are hex digits ('0'-'9' or 'A'-'F') representing the character's + * numeric value. + * + * Module names are mangled with double_underscores=true to prevent + * collisions between, e.g., a module "alfa" with export + * "bravo_charlie" vs. a module "alfa_bravo" with export "charlie". + */ + + enum State { Any, Zero, ZeroX, ZeroXHexDigit } state{Any}; + bool last_was_underscore = false; std::string result; - result = isalpha(static_cast<unsigned char>(name[0])) ? name[0] : '_'; - for (size_t i = 1; i < name.size(); ++i) - result += isalnum(static_cast<unsigned char>(name[i])) ? name[i] : '_'; + auto append_escaped = [&](const uint8_t ch) { + result += "0x" + StringPrintf("%02X", ch); + last_was_underscore = false; + state = Any; + }; + + auto append_verbatim = [&](const uint8_t ch) { + result += ch; + last_was_underscore = (ch == '_'); + }; + + for (auto it = name.begin(); it != name.end(); ++it) { + const uint8_t ch = *it; + switch (state) { + case Any: + state = (ch == '0') ? Zero : Any; + break; + case Zero: + state = (ch == 'x') ? ZeroX : Any; + break; + case ZeroX: + state = internal_ishexdigit(ch) ? ZeroXHexDigit : Any; + break; + case ZeroXHexDigit: + WABT_UNREACHABLE; + break; + } - // In addition to containing valid characters for C, we must also avoid - // colliding with things C cares about, such as reserved words (e.g. "void") - // or a function name like main() (which a compiler will complain about if we - // define it with another type). To avoid such problems, prefix. - result = "w2c_" + result; + /* rule 1 */ + if (state == ZeroXHexDigit) { + append_escaped(ch); + continue; + } + + /* rule 2 */ + if ((ch == '_') && ((it == name.begin()) || (std::next(it) == name.end()) || + last_was_underscore)) { + append_escaped(ch); + continue; + } + + /* rule 3 */ + if (double_underscores && ch == '_') { + append_verbatim(ch); + append_verbatim(ch); + continue; + } + + /* rule 4 */ + if (internal_isalnum(ch) || (ch == '_')) { + append_verbatim(ch); + } else { + append_escaped(ch); + } + } return result; } -std::string CWriter::DefineName(SymbolSet* set, std::string_view name) { - std::string legal = LegalizeName(name); - if (set->find(legal) != set->end()) { - std::string base = legal + "_"; +// static +std::string CWriter::MangleName(std::string_view name) { + return Mangle(name, false); +} + +// static +std::string CWriter::MangleModuleName(std::string_view name) { + return Mangle(name, true); +} + +/* + * Allocate a C symbol (must be unused) in the SymbolSet, + * and a mapping from the Wasm name (tagged with + * the index space of the name) to that C symbol. + */ +void CWriter::ClaimName(SymbolSet& set, + SymbolMap& map, + char type_suffix, + std::string_view wasm_name, + const std::string& c_name) { + const std::string type_tagged_wasm_name = + std::string(wasm_name) + type_suffix; + + [[maybe_unused]] bool success; + success = set.insert(c_name).second; + assert(success); + + success = map.emplace(type_tagged_wasm_name, c_name).second; + assert(success); +} + +/* + * Make a proposed C symbol unique in a given symbol set by appending + * an integer to the symbol if necessary. + */ +std::string CWriter::FindUniqueName(SymbolSet& set, + std::string_view proposed_name) { + std::string unique{proposed_name}; + if (set.find(unique) != set.end()) { + std::string base = unique + "_"; size_t count = 0; do { - legal = base + std::to_string(count++); - } while (set->find(legal) != set->end()); + unique = base + std::to_string(count++); + } while (set.find(unique) != set.end()); } - set->insert(legal); - return legal; + return unique; +} + +/* + * Find a unique C symbol in the symbol set and claim it (mapping the + * type-tagged Wasm name to it). + */ +std::string CWriter::ClaimUniqueName(SymbolSet& set, + SymbolMap& map, + char type_suffix, + std::string_view wasm_name, + const std::string& proposed_c_name) { + const std::string unique = FindUniqueName(set, proposed_c_name); + ClaimName(set, map, type_suffix, wasm_name, unique); + return unique; } std::string_view StripLeadingDollar(std::string_view name) { - if (!name.empty() && name[0] == '$') { - name.remove_prefix(1); - } + assert(!name.empty()); + assert(name.front() == '$'); + name.remove_prefix(1); return name; } void CWriter::DefineImportName(const Import* import, std::string_view module, std::string_view field_name) { - std::string mangled = MangleName(module) + MangleName(field_name); std::string name; ModuleFieldType type; @@ -636,31 +780,40 @@ void CWriter::DefineImportName(const Import* import, import_syms_.insert(name); import_module_sym_map_.emplace(name, import->module_name); - global_syms_.insert(mangled); - [[maybe_unused]] bool success = - global_sym_map_.emplace(name + MangleField(type), mangled).second; - assert(success); + + const std::string mangled = ExportName(module, field_name); + global_syms_.erase(mangled); // duplicate imports are allowed + ClaimName(global_syms_, global_sym_map_, MangleField(type), name, mangled); +} + +/* + * Reserve a C symbol for the public name of a module's export. The + * format of these is "w2c_" + the module prefix + "_" + the mangled + * export name. Reserving the symbol prevents internal functions and + * other names from shadowing/overlapping the exports. + */ +void CWriter::ReserveExportName(std::string_view name) { + ClaimName(global_syms_, global_sym_map_, MangleField(ModuleFieldType::Export), + name, ExportName(name)); } +/* + * Names for functions, function types, tags, and segments are globally unique + * across modules (formatted the same as an export, as "w2c_" + module prefix + + * "_" + the name, made unique if necessary). + */ std::string CWriter::DefineGlobalScopeName(ModuleFieldType type, std::string_view name) { - std::string mangled = std::string(name) + MangleField(type); - std::string unique = DefineName(&global_syms_, StripLeadingDollar(name)); - [[maybe_unused]] bool success = - global_sym_map_.emplace(mangled, unique).second; - assert(success); - return unique; + return ClaimUniqueName(global_syms_, global_sym_map_, MangleField(type), name, + ExportName(StripLeadingDollar(name))); } +/* Names for params, locals, and stack vars are formatted as "w2c_" + name. */ std::string CWriter::DefineLocalScopeName(std::string_view name, bool is_label) { - std::string mangled = - std::string(name) + (is_label ? kLabelSuffix : kParamSuffix); - std::string unique = DefineName(&local_syms_, StripLeadingDollar(name)); - [[maybe_unused]] bool success = - local_sym_map_.emplace(mangled, unique).second; - assert(success); - return unique; + return ClaimUniqueName(local_syms_, local_sym_map_, + is_label ? kLabelSuffix : kParamSuffix, name, + kSymbolPrefix + MangleName(StripLeadingDollar(name))); } std::string CWriter::DefineParamName(std::string_view name) { @@ -674,7 +827,8 @@ std::string CWriter::DefineLabelName(std::string_view name) { std::string CWriter::DefineStackVarName(Index index, Type type, std::string_view name) { - std::string unique = DefineName(&local_syms_, name); + std::string unique = + FindUniqueName(local_syms_, kSymbolPrefix + MangleName(name)); StackTypePair stp = {index, type}; [[maybe_unused]] bool success = stack_var_sym_map_.emplace(stp, unique).second; @@ -682,6 +836,27 @@ std::string CWriter::DefineStackVarName(Index index, return unique; } +/* + * Members of the module instance (globals, tables, and memories) are formatted + * as "w2c_" + the mangled name of the element (made unique if necessary). + */ +std::string CWriter::DefineInstanceMemberName(ModuleFieldType type, + std::string_view name) { + return ClaimUniqueName(global_syms_, global_sym_map_, MangleField(type), name, + kSymbolPrefix + MangleName(StripLeadingDollar(name))); +} + +/* + * The name of a module-instance member that points to the originating + * instance of an imported function is formatted as "w2c_" + originating + * module prefix + "_instance". + */ +std::string CWriter::DefineImportedModuleInstanceName(std::string_view name) { + return ClaimUniqueName(global_syms_, global_sym_map_, + MangleField(ModuleFieldType::Import), name, + ExportName(name, "instance")); +} + void CWriter::Indent(int size) { indent_ += size; } @@ -980,21 +1155,21 @@ void CWriter::Write(const Const& const_) { } void CWriter::WriteInitDecl() { - Write("void " + module_prefix_ + "_instantiate(", ModuleInstanceTypeName(), - "*"); + Write("void ", kAdminSymbolPrefix, module_prefix_, "_instantiate(", + ModuleInstanceTypeName(), "*"); for (const auto& import_module_name : import_module_set_) { - Write(", struct ", MangleModuleInstanceTypeName(import_module_name), "*"); + Write(", struct ", ModuleInstanceTypeName(import_module_name), "*"); } Write(");", Newline()); } void CWriter::WriteFreeDecl() { - Write("void " + module_prefix_ + "_free(", ModuleInstanceTypeName(), "*);", - Newline()); + Write("void ", kAdminSymbolPrefix, module_prefix_, "_free(", + ModuleInstanceTypeName(), "*);", Newline()); } void CWriter::WriteGetFuncTypeDecl() { - Write("wasm_rt_func_type_t ", module_prefix_, + Write("wasm_rt_func_type_t ", kAdminSymbolPrefix, module_prefix_, "_get_func_type(uint32_t param_count, uint32_t result_count, ...);", Newline()); } @@ -1027,8 +1202,8 @@ void CWriter::WriteInitExpr(const ExprList& expr_list) { bool is_import = import_module_sym_map_.count(func->name) != 0; if (is_import) { - Write("instance->", - MangleModuleInstanceName(import_module_sym_map_[func->name])); + Write("instance->", GlobalName(ModuleFieldType::Import, + import_module_sym_map_[func->name])); } else { Write("instance"); } @@ -1234,8 +1409,8 @@ void CWriter::BeginInstance() { // Forward declaring module instance types for (const auto& import_module : import_module_set_) { - Write("struct ", MangleModuleInstanceTypeName(import_module), ";", - Newline()); + DefineImportedModuleInstanceName(import_module); + Write("struct ", ModuleInstanceTypeName(import_module), ";", Newline()); } // Forward declaring module imports @@ -1265,9 +1440,8 @@ void CWriter::BeginInstance() { default: WABT_UNREACHABLE; } - Write("* ", MangleName(import->module_name), MangleName(import->field_name), - "(struct ", MangleModuleInstanceTypeName(import->module_name), "*);", - Newline()); + Write("* ", ExportName(import->module_name, import->field_name), "(struct ", + ModuleInstanceTypeName(import->module_name), "*);", Newline()); } Write(Newline()); @@ -1276,8 +1450,8 @@ void CWriter::BeginInstance() { // when invoked Write("typedef struct ", ModuleInstanceTypeName(), " ", OpenBrace()); for (const auto& import_module : import_func_module_set_) { - Write("struct ", MangleModuleInstanceTypeName(import_module), "* ", - MangleModuleInstanceName(import_module) + ";", Newline()); + Write("struct ", ModuleInstanceTypeName(import_module), "* ", + GlobalName(ModuleFieldType::Import, import_module), ";", Newline()); } for (const Import* import : unique_imports_) { @@ -1292,19 +1466,19 @@ void CWriter::BeginInstance() { switch (import->kind()) { case ExternalKind::Global: WriteGlobal(cast<GlobalImport>(import)->global, - "*" + MangleName(import->module_name) + - MangleName(import->field_name)); + std::string("*") + + ExportName(import->module_name, import->field_name)); break; case ExternalKind::Memory: - WriteMemory("*" + MangleName(import->module_name) + - MangleName(import->field_name)); + WriteMemory(std::string("*") + + ExportName(import->module_name, import->field_name)); break; case ExternalKind::Table: { const Table& table = cast<TableImport>(import)->table; - WriteTable("*" + MangleName(import->module_name) + - MangleName(import->field_name), + WriteTable(std::string("*") + + ExportName(import->module_name, import->field_name), table.elem_type); } break; @@ -1330,14 +1504,15 @@ void CWriter::WriteImports() { const Func& func = cast<FuncImport>(import)->func; WriteImportFuncDeclaration( func.decl, import->module_name, - MangleName(import->module_name) + MangleName(import->field_name)); + ExportName(import->module_name, import->field_name)); Write(";"); Write(Newline()); } else if (import->kind() == ExternalKind::Tag) { Write("/* import: '", import->module_name, "' '", import->field_name, "' */", Newline()); - Write("extern const wasm_rt_tag_t ", MangleName(import->module_name), - MangleName(import->field_name), ";", Newline()); + Write("extern const wasm_rt_tag_t ", + ExportName(import->module_name, import->field_name), ";", + Newline()); } } } @@ -1373,7 +1548,7 @@ void CWriter::WriteImportFuncDeclaration(const FuncDeclaration& decl, const std::string& module_name, const std::string& name) { Write(ResultType(decl.sig.result_types), " ", name, "("); - Write("struct ", MangleModuleInstanceTypeName(module_name), "*"); + Write("struct ", ModuleInstanceTypeName(module_name), "*"); WriteParamTypes(decl); Write(")"); } @@ -1409,8 +1584,8 @@ void CWriter::WriteGlobals() { for (const Global* global : module_->globals) { bool is_import = global_index < module_->num_global_imports; if (!is_import) { - WriteGlobal(*global, DefineGlobalScopeName(ModuleFieldType::Global, - global->name)); + WriteGlobal(*global, DefineInstanceMemberName(ModuleFieldType::Global, + global->name)); Write(Newline()); } ++global_index; @@ -1434,7 +1609,8 @@ void CWriter::WriteMemories() { for (const Memory* memory : module_->memories) { bool is_import = memory_index < module_->num_memory_imports; if (!is_import) { - WriteMemory(DefineGlobalScopeName(ModuleFieldType::Memory, memory->name)); + WriteMemory( + DefineInstanceMemberName(ModuleFieldType::Memory, memory->name)); Write(Newline()); } ++memory_index; @@ -1459,7 +1635,7 @@ void CWriter::WriteTables() { for (const Table* table : module_->tables) { bool is_import = table_index < module_->num_table_imports; if (!is_import) { - WriteTable(DefineGlobalScopeName(ModuleFieldType::Table, table->name), + WriteTable(DefineInstanceMemberName(ModuleFieldType::Table, table->name), table->elem_type); Write(Newline()); } @@ -1638,7 +1814,8 @@ void CWriter::WriteElemInitializers() { const bool is_import = import_module_sym_map_.count(func->name) != 0; if (is_import) { Write("offsetof(", ModuleInstanceTypeName(), ", ", - MangleModuleInstanceName(import_module_sym_map_[func->name]), + GlobalName(ModuleFieldType::Import, + import_module_sym_map_[func->name]), ")"); } else { Write("0"); @@ -1749,14 +1926,13 @@ void CWriter::WriteExports(CWriterPhase kind) { for (const Export* export_ : module_->exports) { Write(Newline(), "/* export: '", export_->name, "' */", Newline()); - std::string mangled_name; + const std::string mangled_name = ExportName(export_->name); std::string internal_name; std::vector<std::string> index_to_name; switch (export_->kind) { case ExternalKind::Func: { const Func* func = module_->GetFunc(export_->var); - mangled_name = ExportName(MangleName(export_->name)); internal_name = func->name; if (kind == CWriterPhase::Declarations) { WriteFuncDeclaration(func->decl, mangled_name); @@ -1776,7 +1952,6 @@ void CWriter::WriteExports(CWriterPhase kind) { case ExternalKind::Global: { const Global* global = module_->GetGlobal(export_->var); - mangled_name = ExportName(MangleName(export_->name)); internal_name = global->name; WriteGlobalPtr(*global, mangled_name); break; @@ -1784,7 +1959,6 @@ void CWriter::WriteExports(CWriterPhase kind) { case ExternalKind::Memory: { const Memory* memory = module_->GetMemory(export_->var); - mangled_name = ExportName(MangleName(export_->name)); internal_name = memory->name; WriteMemoryPtr(mangled_name); break; @@ -1792,7 +1966,6 @@ void CWriter::WriteExports(CWriterPhase kind) { case ExternalKind::Table: { const Table* table = module_->GetTable(export_->var); - mangled_name = ExportName(MangleName(export_->name)); internal_name = table->name; WriteTablePtr(mangled_name, *table); break; @@ -1800,7 +1973,6 @@ void CWriter::WriteExports(CWriterPhase kind) { case ExternalKind::Tag: { const Tag* tag = module_->GetTag(export_->var); - mangled_name = ExportName(MangleName(export_->name)); internal_name = tag->name; if (kind == CWriterPhase::Declarations) { Write("extern "); @@ -1827,8 +1999,9 @@ void CWriter::WriteExports(CWriterPhase kind) { bool is_import = import_module_sym_map_.count(internal_name) != 0; if (is_import) { - Write("instance->", MangleModuleInstanceName( - import_module_sym_map_[internal_name])); + Write("instance->", + GlobalName(ModuleFieldType::Import, + import_module_sym_map_[internal_name])); } else { Write("instance"); } @@ -1877,11 +2050,11 @@ void CWriter::WriteExports(CWriterPhase kind) { } void CWriter::WriteInit() { - Write(Newline(), "void " + module_prefix_ + "_instantiate(", + Write(Newline(), "void ", kAdminSymbolPrefix, module_prefix_, "_instantiate(", ModuleInstanceTypeName(), "* instance"); for (const auto& import_module_name : import_module_set_) { - Write(", struct ", MangleModuleInstanceTypeName(import_module_name), "* ", - MangleModuleInstanceName(import_module_name)); + Write(", struct ", ModuleInstanceTypeName(import_module_name), "* ", + GlobalName(ModuleFieldType::Import, import_module_name)); } Write(") ", OpenBrace()); @@ -1890,7 +2063,7 @@ void CWriter::WriteInit() { if (!import_module_set_.empty()) { Write("init_instance_import(instance"); for (const auto& import_module_name : import_module_set_) { - Write(", ", MangleModuleInstanceName(import_module_name)); + Write(", ", GlobalName(ModuleFieldType::Import, import_module_name)); } Write(");", Newline()); } @@ -1917,9 +2090,9 @@ void CWriter::WriteInit() { import_module_sym_map_.count(module_->GetFunc(*var)->name) != 0; if (is_import) { Write("(instance->", - MangleModuleInstanceName( - import_module_sym_map_[module_->GetFunc(*var)->name]) + - ");"); + GlobalName(ModuleFieldType::Import, + import_module_sym_map_[module_->GetFunc(*var)->name]), + ");"); } else { Write("(instance);"); } @@ -1929,8 +2102,9 @@ void CWriter::WriteInit() { } void CWriter::WriteGetFuncType() { - Write(Newline(), "wasm_rt_func_type_t ", module_prefix_, - "_get_func_type(uint32_t param_count, uint32_t result_count, ...) ", + Write(Newline(), "wasm_rt_func_type_t ", kAdminSymbolPrefix, module_prefix_, + "_get_func_type(uint32_t param_count, uint32_t result_count, " + "...) ", OpenBrace()); Write("va_list args;", Newline()); @@ -1968,14 +2142,15 @@ void CWriter::WriteInitInstanceImport() { Write(Newline(), "static void init_instance_import(", ModuleInstanceTypeName(), "* instance"); for (const auto& import_module_name : import_module_set_) { - Write(", struct ", MangleModuleInstanceTypeName(import_module_name), "* ", - MangleModuleInstanceName(import_module_name)); + Write(", struct ", ModuleInstanceTypeName(import_module_name), "* ", + GlobalName(ModuleFieldType::Import, import_module_name)); } Write(")", OpenBrace()); for (const auto& import_module : import_func_module_set_) { - Write("instance->", MangleModuleInstanceName(import_module), " = ", - MangleModuleInstanceName(import_module), ";", Newline()); + Write("instance->", GlobalName(ModuleFieldType::Import, import_module), + " = ", GlobalName(ModuleFieldType::Import, import_module), ";", + Newline()); } for (const Import* import : unique_imports_) { @@ -1987,11 +2162,9 @@ void CWriter::WriteInitInstanceImport() { case ExternalKind::Global: case ExternalKind::Memory: case ExternalKind::Table: { - Write("instance->", - MangleName(import->module_name) + MangleName(import->field_name), - " = ", - MangleName(import->module_name) + MangleName(import->field_name), - "(", MangleModuleInstanceName(import->module_name), ");", + Write("instance->", ExportName(import->module_name, import->field_name), + " = ", ExportName(import->module_name, import->field_name), "(", + GlobalName(ModuleFieldType::Import, import->module_name), ");", Newline()); break; } @@ -2013,9 +2186,9 @@ void CWriter::WriteImportProperties(CWriterPhase kind) { if (kind == CWriterPhase::Declarations) { Write("extern "); } - Write("const u32 " + module_prefix_ + "_", - prop + "_" + MangleName(import->module_name) + - MangleName(import->field_name)); + Write("const u32 ", kAdminSymbolPrefix, module_prefix_, "_", prop, "_", + MangleModuleName(import->module_name), "_", + MangleName(import->field_name)); if (kind == CWriterPhase::Definitions) { Write(" = ", value); } @@ -2037,7 +2210,7 @@ void CWriter::WriteImportProperties(CWriterPhase kind) { } void CWriter::WriteFree() { - Write(Newline(), "void " + module_prefix_ + "_free(", + Write(Newline(), "void ", kAdminSymbolPrefix, module_prefix_, "_free(", ModuleInstanceTypeName(), "* instance) ", OpenBrace()); { @@ -2505,8 +2678,8 @@ void CWriter::Write(const ExprList& exprs) { Write(ExternalRef(ModuleFieldType::Func, var.name()), "("); bool is_import = import_module_sym_map_.count(func.name) != 0; if (is_import) { - Write("instance->", - MangleModuleInstanceName(import_module_sym_map_[func.name])); + Write("instance->", GlobalName(ModuleFieldType::Import, + import_module_sym_map_[func.name])); } else { Write("instance"); } @@ -2836,8 +3009,8 @@ void CWriter::Write(const ExprList& exprs) { bool is_import = import_module_sym_map_.count(func->name) != 0; if (is_import) { - Write("instance->", - MangleModuleInstanceName(import_module_sym_map_[func->name])); + Write("instance->", GlobalName(ModuleFieldType::Import, + import_module_sym_map_[func->name])); } else { Write("instance"); } @@ -4623,7 +4796,15 @@ void CWriter::Write(const LoadZeroExpr& expr) { PushType(result_type); } +void CWriter::ReserveExportNames() { + for (const Export* export_ : module_->exports) { + ReserveExportName(export_->name); + } +} + void CWriter::WriteCHeader() { + ReserveExportNames(); + stream_ = h_stream_; std::string guard = GenerateHeaderGuard(); Write("/* Automatically generated by wasm2c */", Newline()); |