summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/c-writer.cc453
-rwxr-xr-xtest/run-spec-wasm2c.py30
-rw-r--r--test/spec-wasm2c-prefix.c40
-rw-r--r--test/wasm2c/add.txt30
-rw-r--r--test/wasm2c/hello.txt78
-rw-r--r--test/wasm2c/minimal.txt16
-rw-r--r--wasm2c/README.md142
-rw-r--r--wasm2c/examples/callback/callback.wat2
-rw-r--r--wasm2c/examples/callback/main.c17
-rw-r--r--wasm2c/examples/fac/fac.c20
-rw-r--r--wasm2c/examples/fac/fac.h12
-rw-r--r--wasm2c/examples/fac/main.c8
-rw-r--r--wasm2c/examples/rot13/main.c48
13 files changed, 528 insertions, 368 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());
diff --git a/test/run-spec-wasm2c.py b/test/run-spec-wasm2c.py
index e2a0cc91..4c3c1f1d 100755
--- a/test/run-spec-wasm2c.py
+++ b/test/run-spec-wasm2c.py
@@ -101,11 +101,19 @@ def MangleTypes(types):
def MangleName(s):
def Mangle(match):
s = match.group(0)
- return b'Z%02X' % s[0]
+ return b'0x%02X' % s[0]
- # NOTE(binji): Z is not allowed.
- pattern = b'([^_a-zA-Y0-9])'
- return 'Z_' + re.sub(pattern, Mangle, s.encode('utf-8')).decode('utf-8')
+ # escape underscores at beginning and end
+ s = re.sub(b'((^_)|(_$))', Mangle, s.encode('utf-8'))
+
+ # NOTE(keithw): forced escapes for '0x[hexdigit]' not implemented here
+ pattern = b'([^_a-zA-Z0-9])'
+ return re.sub(pattern, Mangle, s).decode('utf-8')
+
+
+def MangleModuleName(s):
+ # double underscores
+ return MangleName(re.sub('(_)', '__', s))
def IsModuleCommand(command):
@@ -169,7 +177,7 @@ class CWriter(object):
name = re.sub(r'[^a-zA-Z0-9_]', '_', name)
name = os.path.splitext(name)[0]
self.unmangled_names[idx] = name
- name = MangleName(name)
+ name = MangleModuleName(name)
self.module_prefix_map[idx] = name
@@ -180,7 +188,7 @@ class CWriter(object):
idx += 1
elif command['type'] == 'register':
- name = MangleName(command['as'])
+ name = MangleModuleName(command['as'])
if 'name' in command:
self.module_prefix_map[command['name']] = name
name_idx = self.module_name_to_idx[command['name']]
@@ -199,13 +207,13 @@ class CWriter(object):
for line in f:
if 'import: ' in line:
line_split = line.split()
- import_module_name = MangleName(line_split[2][1:-1])
+ import_module_name = MangleModuleName(line_split[2][1:-1])
imported_modules.add(import_module_name)
if uninstantiable:
self.out_file.write('ASSERT_TRAP(')
- self.out_file.write('%s_instantiate(&%s_instance' % (self.GetModulePrefix(), self.GetModulePrefix()))
+ self.out_file.write('wasm2c_%s_instantiate(&%s_instance' % (self.GetModulePrefix(), self.GetModulePrefix()))
for imported_module in sorted(imported_modules):
self.out_file.write(', &%s_instance' % imported_module)
self.out_file.write(')')
@@ -260,12 +268,12 @@ class CWriter(object):
idx = 0
for command in self.commands:
if IsModuleCommand(command):
- self.out_file.write('%s_instance_t %s;\n' % (self.GetModulePrefix(idx), self.GetModuleInstanceName(idx)))
+ self.out_file.write('w2c_%s %s;\n' % (self.GetModulePrefix(idx), self.GetModuleInstanceName(idx)))
idx += 1
def _WriteModuleCleanUps(self):
for idx in range(self.module_idx):
- self.out_file.write("%s_free(&%s_instance);\n" % (self.GetModulePrefix(idx), self.GetModulePrefix(idx)))
+ self.out_file.write("wasm2c_%s_free(&%s);\n" % (self.GetModulePrefix(idx), self.GetModuleInstanceName(idx)))
def _WriteAssertUninstantiableCommand(self, command):
self.module_idx += 1
@@ -422,7 +430,7 @@ class CWriter(object):
action = command['action']
type_ = action['type']
mangled_module_name = self.GetModulePrefix(action.get('module'))
- field = mangled_module_name + MangleName(action['field'])
+ field = "w2c_" + mangled_module_name + '_' + MangleName(action['field'])
if type_ == 'invoke':
args = self._ConstantList(action.get('args', []))
if len(args) == 0:
diff --git a/test/spec-wasm2c-prefix.c b/test/spec-wasm2c-prefix.c
index 99af49ab..c82a882d 100644
--- a/test/spec-wasm2c-prefix.c
+++ b/test/spec-wasm2c-prefix.c
@@ -277,77 +277,73 @@ static bool is_arithmetic_nan_f64(u64 x) {
return (x & 0x7ff8000000000000) == 0x7ff8000000000000;
}
-typedef struct Z_spectest_instance_t {
+typedef struct w2c_spectest {
wasm_rt_funcref_table_t spectest_table;
wasm_rt_memory_t spectest_memory;
uint32_t spectest_global_i32;
uint64_t spectest_global_i64;
float spectest_global_f32;
double spectest_global_f64;
-} Z_spectest_instance_t;
+} w2c_spectest;
-static Z_spectest_instance_t Z_spectest_instance;
+static w2c_spectest spectest_instance;
/*
* spectest implementations
*/
-void Z_spectestZ_print(Z_spectest_instance_t* instance) {
+void w2c_spectest_print(w2c_spectest* instance) {
printf("spectest.print()\n");
}
-void Z_spectestZ_print_i32(Z_spectest_instance_t* instance, uint32_t i) {
+void w2c_spectest_print_i32(w2c_spectest* instance, uint32_t i) {
printf("spectest.print_i32(%d)\n", i);
}
-void Z_spectestZ_print_i64(Z_spectest_instance_t* instance, uint64_t i) {
+void w2c_spectest_print_i64(w2c_spectest* instance, uint64_t i) {
printf("spectest.print_i64(%" PRIu64 ")\n", i);
}
-void Z_spectestZ_print_f32(Z_spectest_instance_t* instance, float f) {
+void w2c_spectest_print_f32(w2c_spectest* instance, float f) {
printf("spectest.print_f32(%g)\n", f);
}
-void Z_spectestZ_print_i32_f32(Z_spectest_instance_t* instance,
- uint32_t i,
- float f) {
+void w2c_spectest_print_i32_f32(w2c_spectest* instance, uint32_t i, float f) {
printf("spectest.print_i32_f32(%d %g)\n", i, f);
}
-void Z_spectestZ_print_f64(Z_spectest_instance_t* instance, double d) {
+void w2c_spectest_print_f64(w2c_spectest* instance, double d) {
printf("spectest.print_f64(%g)\n", d);
}
-void Z_spectestZ_print_f64_f64(Z_spectest_instance_t* instance,
- double d1,
- double d2) {
+void w2c_spectest_print_f64_f64(w2c_spectest* instance, double d1, double d2) {
printf("spectest.print_f64_f64(%g %g)\n", d1, d2);
}
-wasm_rt_funcref_table_t* Z_spectestZ_table(Z_spectest_instance_t* instance) {
+wasm_rt_funcref_table_t* w2c_spectest_table(w2c_spectest* instance) {
return &instance->spectest_table;
}
-wasm_rt_memory_t* Z_spectestZ_memory(Z_spectest_instance_t* instance) {
+wasm_rt_memory_t* w2c_spectest_memory(w2c_spectest* instance) {
return &instance->spectest_memory;
}
-uint32_t* Z_spectestZ_global_i32(Z_spectest_instance_t* instance) {
+uint32_t* w2c_spectest_global_i32(w2c_spectest* instance) {
return &instance->spectest_global_i32;
}
-uint64_t* Z_spectestZ_global_i64(Z_spectest_instance_t* instance) {
+uint64_t* w2c_spectest_global_i64(w2c_spectest* instance) {
return &instance->spectest_global_i64;
}
-float* Z_spectestZ_global_f32(Z_spectest_instance_t* instance) {
+float* w2c_spectest_global_f32(w2c_spectest* instance) {
return &instance->spectest_global_f32;
}
-double* Z_spectestZ_global_f64(Z_spectest_instance_t* instance) {
+double* w2c_spectest_global_f64(w2c_spectest* instance) {
return &instance->spectest_global_f64;
}
-static void init_spectest_module(Z_spectest_instance_t* instance) {
+static void init_spectest_module(w2c_spectest* instance) {
instance->spectest_global_i32 = 666;
instance->spectest_global_i64 = 666l;
wasm_rt_allocate_memory(&instance->spectest_memory, 1, 2, false);
@@ -356,7 +352,7 @@ static void init_spectest_module(Z_spectest_instance_t* instance) {
int main(int argc, char** argv) {
wasm_rt_init();
- init_spectest_module(&Z_spectest_instance);
+ init_spectest_module(&spectest_instance);
run_spec_tests();
printf("%u/%u tests passed.\n", g_tests_passed, g_tests_run);
wasm_rt_free();
diff --git a/test/wasm2c/add.txt b/test/wasm2c/add.txt
index 4cd3c835..125f3152 100644
--- a/test/wasm2c/add.txt
+++ b/test/wasm2c/add.txt
@@ -40,16 +40,16 @@ typedef simde_v128_t v128;
extern "C" {
#endif
-typedef struct Z_test_instance_t {
+typedef struct w2c_test {
char dummy_member;
-} Z_test_instance_t;
+} w2c_test;
-void Z_test_instantiate(Z_test_instance_t*);
-void Z_test_free(Z_test_instance_t*);
-wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_count, ...);
+void wasm2c_test_instantiate(w2c_test*);
+void wasm2c_test_free(w2c_test*);
+wasm_rt_func_type_t wasm2c_test_get_func_type(uint32_t param_count, uint32_t result_count, ...);
/* export: 'add' */
-u32 Z_testZ_add(Z_test_instance_t*, u32, u32);
+u32 w2c_test_add(w2c_test*, u32, u32);
#ifdef __cplusplus
}
@@ -782,11 +782,11 @@ DEFINE_TABLE_FILL(externref)
#define FUNC_TYPE_T(x) static const char x[]
#endif
-FUNC_TYPE_T(w2c_t0) = "\x92\xfb\x6a\xdf\x49\x07\x0a\x83\xbe\x08\x02\x68\xcd\xf6\x95\x27\x4a\xc2\xf3\xe5\xe4\x7d\x29\x49\xe8\xed\x42\x92\x6a\x9d\xda\xf0";
+FUNC_TYPE_T(w2c_test_t0) = "\x92\xfb\x6a\xdf\x49\x07\x0a\x83\xbe\x08\x02\x68\xcd\xf6\x95\x27\x4a\xc2\xf3\xe5\xe4\x7d\x29\x49\xe8\xed\x42\x92\x6a\x9d\xda\xf0";
-static u32 w2c_add(Z_test_instance_t*, u32, u32);
+static u32 w2c_test_add_0(w2c_test*, u32, u32);
-static u32 w2c_add(Z_test_instance_t* instance, u32 w2c_p0, u32 w2c_p1) {
+static u32 w2c_test_add_0(w2c_test* instance, u32 w2c_p0, u32 w2c_p1) {
FUNC_PROLOGUE;
u32 w2c_i0, w2c_i1;
w2c_i0 = w2c_p0;
@@ -797,25 +797,25 @@ static u32 w2c_add(Z_test_instance_t* instance, u32 w2c_p0, u32 w2c_p1) {
}
/* export: 'add' */
-u32 Z_testZ_add(Z_test_instance_t* instance, u32 w2c_p0, u32 w2c_p1) {
- return w2c_add(instance, w2c_p0, w2c_p1);
+u32 w2c_test_add(w2c_test* instance, u32 w2c_p0, u32 w2c_p1) {
+ return w2c_test_add_0(instance, w2c_p0, w2c_p1);
}
-void Z_test_instantiate(Z_test_instance_t* instance) {
+void wasm2c_test_instantiate(w2c_test* instance) {
assert(wasm_rt_is_initialized());
}
-void Z_test_free(Z_test_instance_t* instance) {
+void wasm2c_test_free(w2c_test* instance) {
}
-wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
+wasm_rt_func_type_t wasm2c_test_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
va_list args;
if (param_count == 2 && result_count == 1) {
va_start(args, result_count);
if (true && va_arg(args, wasm_rt_type_t) == WASM_RT_I32 && va_arg(args, wasm_rt_type_t) == WASM_RT_I32 && va_arg(args, wasm_rt_type_t) == WASM_RT_I32) {
va_end(args);
- return w2c_t0;
+ return w2c_test_t0;
}
va_end(args);
}
diff --git a/test/wasm2c/hello.txt b/test/wasm2c/hello.txt
index 4e756743..3eef2cc4 100644
--- a/test/wasm2c/hello.txt
+++ b/test/wasm2c/hello.txt
@@ -58,28 +58,28 @@ typedef simde_v128_t v128;
extern "C" {
#endif
-struct Z_wasi_snapshot_preview1_instance_t;
+struct w2c_wasi__snapshot__preview1;
-typedef struct Z_test_instance_t {
- struct Z_wasi_snapshot_preview1_instance_t* Z_wasi_snapshot_preview1_instance;
+typedef struct w2c_test {
+ struct w2c_wasi__snapshot__preview1* w2c_wasi__snapshot__preview1_instance;
wasm_rt_memory_t w2c_memory;
wasm_rt_funcref_table_t w2c_T0;
-} Z_test_instance_t;
+} w2c_test;
-void Z_test_instantiate(Z_test_instance_t*, struct Z_wasi_snapshot_preview1_instance_t*);
-void Z_test_free(Z_test_instance_t*);
-wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_count, ...);
+void wasm2c_test_instantiate(w2c_test*, struct w2c_wasi__snapshot__preview1*);
+void wasm2c_test_free(w2c_test*);
+wasm_rt_func_type_t wasm2c_test_get_func_type(uint32_t param_count, uint32_t result_count, ...);
/* import: 'wasi_snapshot_preview1' 'fd_write' */
-u32 Z_wasi_snapshot_preview1Z_fd_write(struct Z_wasi_snapshot_preview1_instance_t*, u32, u32, u32, u32);
+u32 w2c_wasi__snapshot__preview1_fd_write(struct w2c_wasi__snapshot__preview1*, u32, u32, u32, u32);
/* import: 'wasi_snapshot_preview1' 'proc_exit' */
-void Z_wasi_snapshot_preview1Z_proc_exit(struct Z_wasi_snapshot_preview1_instance_t*, u32);
+void w2c_wasi__snapshot__preview1_proc_exit(struct w2c_wasi__snapshot__preview1*, u32);
/* export: 'memory' */
-wasm_rt_memory_t* Z_testZ_memory(Z_test_instance_t* instance);
+wasm_rt_memory_t* w2c_test_memory(w2c_test* instance);
/* export: '_start' */
-void Z_testZ__start(Z_test_instance_t*);
+void w2c_test_0x5Fstart(w2c_test*);
#ifdef __cplusplus
}
@@ -812,37 +812,37 @@ DEFINE_TABLE_FILL(externref)
#define FUNC_TYPE_T(x) static const char x[]
#endif
-FUNC_TYPE_T(w2c_t0) = "\xf6\x98\x1b\xc6\x10\xda\xb7\xb2\x63\x37\xcd\xdc\x72\xca\xe9\x50\x00\x13\xba\x10\x6c\xde\x87\x27\x10\xf8\x86\x2f\xe3\xdb\x94\xe4";
-FUNC_TYPE_T(w2c_t1) = "\x89\x3a\x3d\x2c\x8f\x4d\x7f\x6d\x6c\x9d\x62\x67\x29\xaf\x3d\x44\x39\x8e\xc3\xf3\xe8\x51\xc1\x99\xb9\xdd\x9f\xd5\x3d\x1f\xd3\xe4";
-FUNC_TYPE_T(w2c_t2) = "\x36\xa9\xe7\xf1\xc9\x5b\x82\xff\xb9\x97\x43\xe0\xc5\xc4\xce\x95\xd8\x3c\x9a\x43\x0a\xac\x59\xf8\x4e\xf3\xcb\xfa\xb6\x14\x50\x68";
+FUNC_TYPE_T(w2c_test_t0) = "\xf6\x98\x1b\xc6\x10\xda\xb7\xb2\x63\x37\xcd\xdc\x72\xca\xe9\x50\x00\x13\xba\x10\x6c\xde\x87\x27\x10\xf8\x86\x2f\xe3\xdb\x94\xe4";
+FUNC_TYPE_T(w2c_test_t1) = "\x89\x3a\x3d\x2c\x8f\x4d\x7f\x6d\x6c\x9d\x62\x67\x29\xaf\x3d\x44\x39\x8e\xc3\xf3\xe8\x51\xc1\x99\xb9\xdd\x9f\xd5\x3d\x1f\xd3\xe4";
+FUNC_TYPE_T(w2c_test_t2) = "\x36\xa9\xe7\xf1\xc9\x5b\x82\xff\xb9\x97\x43\xe0\xc5\xc4\xce\x95\xd8\x3c\x9a\x43\x0a\xac\x59\xf8\x4e\xf3\xcb\xfa\xb6\x14\x50\x68";
-static void w2c__start(Z_test_instance_t*);
+static void w2c_test_0x5Fstart_0(w2c_test*);
-static const u8 data_segment_data_w2c_d0[] = {
+static const u8 data_segment_data_w2c_test_d0[] = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
0x2e, 0x0a,
};
-static void init_memories(Z_test_instance_t* instance) {
+static void init_memories(w2c_test* instance) {
wasm_rt_allocate_memory(&instance->w2c_memory, 1, 65536, 0);
- LOAD_DATA(instance->w2c_memory, 8u, data_segment_data_w2c_d0, 14);
+ LOAD_DATA(instance->w2c_memory, 8u, data_segment_data_w2c_test_d0, 14);
}
-static void init_data_instances(Z_test_instance_t *instance) {
+static void init_data_instances(w2c_test *instance) {
}
-static const wasm_elem_segment_expr_t elem_segment_exprs_w2c_e0[] = {
- {w2c_t0, (wasm_rt_function_ptr_t)Z_wasi_snapshot_preview1Z_fd_write, offsetof(Z_test_instance_t, Z_wasi_snapshot_preview1_instance)},
+static const wasm_elem_segment_expr_t elem_segment_exprs_w2c_test_e0[] = {
+ {w2c_test_t0, (wasm_rt_function_ptr_t)w2c_wasi__snapshot__preview1_fd_write, offsetof(w2c_test, w2c_wasi__snapshot__preview1_instance)},
};
-static void init_tables(Z_test_instance_t* instance) {
+static void init_tables(w2c_test* instance) {
wasm_rt_allocate_funcref_table(&instance->w2c_T0, 1, 1);
- funcref_table_init(&instance->w2c_T0, elem_segment_exprs_w2c_e0, 1, 0u, 0, 1, instance);
+ funcref_table_init(&instance->w2c_T0, elem_segment_exprs_w2c_test_e0, 1, 0u, 0, 1, instance);
}
-static void init_elem_instances(Z_test_instance_t *instance) {
+static void init_elem_instances(w2c_test *instance) {
}
-static void w2c__start(Z_test_instance_t* instance) {
+static void w2c_test_0x5Fstart_0(w2c_test* instance) {
FUNC_PROLOGUE;
u32 w2c_i0, w2c_i1, w2c_i2, w2c_i3, w2c_i4;
w2c_i0 = 0u;
@@ -856,47 +856,47 @@ static void w2c__start(Z_test_instance_t* instance) {
w2c_i2 = 1u;
w2c_i3 = 0u;
w2c_i4 = 0u;
- w2c_i0 = CALL_INDIRECT(instance->w2c_T0, u32 (*)(void*, u32, u32, u32, u32), w2c_t0, w2c_i4, instance->w2c_T0.data[w2c_i4].module_instance, w2c_i0, w2c_i1, w2c_i2, w2c_i3);
- (*Z_wasi_snapshot_preview1Z_proc_exit)(instance->Z_wasi_snapshot_preview1_instance, w2c_i0);
+ w2c_i0 = CALL_INDIRECT(instance->w2c_T0, u32 (*)(void*, u32, u32, u32, u32), w2c_test_t0, w2c_i4, instance->w2c_T0.data[w2c_i4].module_instance, w2c_i0, w2c_i1, w2c_i2, w2c_i3);
+ (*w2c_wasi__snapshot__preview1_proc_exit)(instance->w2c_wasi__snapshot__preview1_instance, w2c_i0);
FUNC_EPILOGUE;
}
/* export: 'memory' */
-wasm_rt_memory_t* Z_testZ_memory(Z_test_instance_t* instance) {
+wasm_rt_memory_t* w2c_test_memory(w2c_test* instance) {
return &instance->w2c_memory;
}
/* export: '_start' */
-void Z_testZ__start(Z_test_instance_t* instance) {
- return w2c__start(instance);
+void w2c_test_0x5Fstart(w2c_test* instance) {
+ return w2c_test_0x5Fstart_0(instance);
}
-static void init_instance_import(Z_test_instance_t* instance, struct Z_wasi_snapshot_preview1_instance_t* Z_wasi_snapshot_preview1_instance){
- instance->Z_wasi_snapshot_preview1_instance = Z_wasi_snapshot_preview1_instance;
+static void init_instance_import(w2c_test* instance, struct w2c_wasi__snapshot__preview1* w2c_wasi__snapshot__preview1_instance){
+ instance->w2c_wasi__snapshot__preview1_instance = w2c_wasi__snapshot__preview1_instance;
}
-void Z_test_instantiate(Z_test_instance_t* instance, struct Z_wasi_snapshot_preview1_instance_t* Z_wasi_snapshot_preview1_instance) {
+void wasm2c_test_instantiate(w2c_test* instance, struct w2c_wasi__snapshot__preview1* w2c_wasi__snapshot__preview1_instance) {
assert(wasm_rt_is_initialized());
- init_instance_import(instance, Z_wasi_snapshot_preview1_instance);
+ init_instance_import(instance, w2c_wasi__snapshot__preview1_instance);
init_memories(instance);
init_tables(instance);
init_data_instances(instance);
init_elem_instances(instance);
}
-void Z_test_free(Z_test_instance_t* instance) {
+void wasm2c_test_free(w2c_test* instance) {
wasm_rt_free_funcref_table(&instance->w2c_T0);
wasm_rt_free_memory(&instance->w2c_memory);
}
-wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
+wasm_rt_func_type_t wasm2c_test_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
va_list args;
if (param_count == 4 && result_count == 1) {
va_start(args, result_count);
if (true && va_arg(args, wasm_rt_type_t) == WASM_RT_I32 && va_arg(args, wasm_rt_type_t) == WASM_RT_I32 && va_arg(args, wasm_rt_type_t) == WASM_RT_I32 && va_arg(args, wasm_rt_type_t) == WASM_RT_I32 && va_arg(args, wasm_rt_type_t) == WASM_RT_I32) {
va_end(args);
- return w2c_t0;
+ return w2c_test_t0;
}
va_end(args);
}
@@ -905,7 +905,7 @@ wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_c
va_start(args, result_count);
if (true && va_arg(args, wasm_rt_type_t) == WASM_RT_I32) {
va_end(args);
- return w2c_t1;
+ return w2c_test_t1;
}
va_end(args);
}
@@ -914,7 +914,7 @@ wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_c
va_start(args, result_count);
if (true) {
va_end(args);
- return w2c_t2;
+ return w2c_test_t2;
}
va_end(args);
}
diff --git a/test/wasm2c/minimal.txt b/test/wasm2c/minimal.txt
index bfee1a53..e56187f2 100644
--- a/test/wasm2c/minimal.txt
+++ b/test/wasm2c/minimal.txt
@@ -37,13 +37,13 @@ typedef simde_v128_t v128;
extern "C" {
#endif
-typedef struct Z_test_instance_t {
+typedef struct w2c_test {
char dummy_member;
-} Z_test_instance_t;
+} w2c_test;
-void Z_test_instantiate(Z_test_instance_t*);
-void Z_test_free(Z_test_instance_t*);
-wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_count, ...);
+void wasm2c_test_instantiate(w2c_test*);
+void wasm2c_test_free(w2c_test*);
+wasm_rt_func_type_t wasm2c_test_get_func_type(uint32_t param_count, uint32_t result_count, ...);
#ifdef __cplusplus
}
@@ -776,14 +776,14 @@ DEFINE_TABLE_FILL(externref)
#define FUNC_TYPE_T(x) static const char x[]
#endif
-void Z_test_instantiate(Z_test_instance_t* instance) {
+void wasm2c_test_instantiate(w2c_test* instance) {
assert(wasm_rt_is_initialized());
}
-void Z_test_free(Z_test_instance_t* instance) {
+void wasm2c_test_free(w2c_test* instance) {
}
-wasm_rt_func_type_t Z_test_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
+wasm_rt_func_type_t wasm2c_test_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
va_list args;
return NULL;
diff --git a/wasm2c/README.md b/wasm2c/README.md
index 80a86952..cdc4f09e 100644
--- a/wasm2c/README.md
+++ b/wasm2c/README.md
@@ -49,19 +49,17 @@ files.
To actually use our `fac` module, we'll use create a new file, `main.c`, that
include `fac.h`, initializes the module, and calls `fac`.
-`wasm2c` generates a few C symbols based on the `fac.wasm` module: `Z_fac_instantiate`
-and `Z_facZ_fac`. The first constructs an instance of the module, and the second is the
-exported `fac` function.
-
-All the exported symbols shared a common prefix (`Z_fac`) which, by default, is
+`wasm2c` generates a few C symbols based on the `fac.wasm` module.
+The first is `w2c_fac`, a type that represents an instance of the
+`fac` module. `wasm2c` generates functions that construct and free a
+`w2c_fac` instance: `wasm2c_fac_instantiate` and
+`wasm2c_fac_free`. Finally, `wasm2c` generates the exported `fac`
+function itself (`w2c_fac_fac`), which acts on a `w2c_fac` instance.
+
+All the exported symbols shared a common module ID (`fac`) which, by default, is
based on the name section in the module or the name of input file. This prefix
can be overridden using the `-n/--module-name` command line flag.
-In addition to parameters defined in `fac.wat`, `Z_fac_instantiate` and `Z_facZ_fac`
-take in a pointer to a `Z_fac_instance_t`. The structure is used to
-store the context information of the module instance, and `main.c` is responsible
-for providing it.
-
```c
#include <stdio.h>
#include <stdlib.h>
@@ -70,8 +68,10 @@ for providing it.
int main(int argc, char** argv) {
/* Make sure there is at least one command-line argument. */
- if (argc < 2)
+ if (argc < 2) {
+ printf("Invalid argument. Expected '%s NUMBER'\n", argv[0]);
return 1;
+ }
/* Convert the argument from a string to an int. We'll implicitly cast the int
to a `u32`, which is what `fac` expects. */
@@ -81,19 +81,19 @@ int main(int argc, char** argv) {
wasm_rt_init();
/* Declare an instance of the `fac` module. */
- Z_fac_instance_t instance;
+ w2c_fac fac;
/* Construct the module instance. */
- Z_fac_instantiate(&instance);
+ wasm2c_fac_instantiate(&fac);
/* Call `fac`, using the mangled name. */
- u32 result = Z_facZ_fac(&instance, x);
+ u32 result = w2c_fac_fac(&fac, x);
/* Print the result. */
printf("fac(%u) -> %u\n", x, result);
/* Free the fac module. */
- Z_fac_free(&instance);
+ wasm2c_fac_free(&fac);
/* Free the Wasm runtime state. */
wasm_rt_free();
@@ -143,6 +143,7 @@ You can take a look at the all of these files in
The generated header file looks something like this:
```c
+/* Automatically generated by wasm2c */
#ifndef FAC_H_GENERATED_
#define FAC_H_GENERATED_
@@ -162,15 +163,16 @@ The generated header file looks something like this:
extern "C" {
#endif
-typedef struct Z_fac_instance_t {
+typedef struct w2c_fac {
char dummy_member;
-} Z_fac_instance_t;
+} w2c_fac;
-void Z_fac_instantiate(Z_fac_instance_t*);
-void Z_fac_free(Z_fac_instance_t*);
+void wasm2c_fac_instantiate(w2c_fac*);
+void wasm2c_fac_free(w2c_fac*);
+wasm_rt_func_type_t wasm2c_fac_get_func_type(uint32_t param_count, uint32_t result_count, ...);
/* export: 'fac' */
-u32 Z_facZ_fac(Z_fac_instance_t*, u32);
+u32 w2c_fac_fac(w2c_fac*, u32);
#ifdef __cplusplus
}
@@ -382,10 +384,10 @@ of `fac` is essentially empty), and the exported symbols provided by
the module. In our example, the only function we exported was
`fac`.
-`Z_fac_instantiate(Z_fac_instance_t*)` creates an instance of
+`wasm2c_fac_instantiate(w2c_fac*)` creates an instance of
the module and must be called before the module instance can be
-used. `Z_fac_free(Z_fac_instance_t*)` frees the instance.
-`Z_fac_get_func_type` can be used to look up a function type ID
+used. `wasm2c_fac_free(w2c_fac*)` frees the instance.
+`wasm2c_fac_get_func_type` can be used to look up a function type ID
at runtime. It is a variadic function where the first two arguments
give the number of parameters and results, and the following arguments
are the types from the wasm_rt_type_t enum described above. The
@@ -393,16 +395,16 @@ are the types from the wasm_rt_type_t enum described above. The
a WebAssembly module dynamically at runtime.
```c
-typedef struct Z_fac_instance_t {
+typedef struct w2c_fac {
char dummy_member;
-} Z_fac_instance_t;
+} w2c_fac;
-void Z_fac_instantiate(Z_fac_instance_t*);
-void Z_fac_free(Z_fac_instance_t*);
-wasm_rt_func_type_t Z_fac_get_func_type(uint32_t param_count, uint32_t result_count, ...);
+void wasm2c_fac_instantiate(w2c_fac*);
+void wasm2c_fac_free(w2c_fac*);
+wasm_rt_func_type_t wasm2c_fac_get_func_type(uint32_t param_count, uint32_t result_count, ...);
/* export: 'fac' */
-u32 Z_facZ_fac(Z_fac_instance_t*, u32);
+u32 w2c_fac_fac(w2c_fac*, u32);
```
## Handling other kinds of imports and exports of modules
@@ -427,14 +429,15 @@ then `wasm2c` would declare the following function in the header:
```c
/* export: 'mem' */
-extern wasm_rt_memory_t* Z_facZ_mem(Z_fac_instance_t*);
+wasm_rt_memory_t* w2c_fac_mem(w2c_fac* instance);
+
```
which would be defined as:
```c
/* export: 'mem' */
-wasm_rt_memory_t* Z_fac_Z_mem(Z_fac_instance_t* instance) {
- return &instance->w2c_M0;
+wasm_rt_memory_t* w2c_fac_mem(w2c_fac* instance) {
+ return &instance->w2c_mem;
}
```
@@ -455,7 +458,7 @@ module doesn't use any globals, memory or tables.
The most interesting part is the definition of the function `fac`:
```c
-static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) {
+static u32 w2c_fac_fac_0(w2c_fac* instance, u32 w2c_p0) {
FUNC_PROLOGUE;
u32 w2c_i0, w2c_i1, w2c_i2;
w2c_i0 = w2c_p0;
@@ -468,7 +471,7 @@ static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) {
w2c_i1 = w2c_p0;
w2c_i2 = 1u;
w2c_i1 -= w2c_i2;
- w2c_i1 = w2c_fac(instance, w2c_i1);
+ w2c_i1 = w2c_fac_fac_0(instance, w2c_i1);
w2c_i0 *= w2c_i1;
}
FUNC_EPILOGUE;
@@ -546,62 +549,45 @@ in the same address space.
#include "rot13.h"
/* Define structure to hold the imports */
-struct Z_host_instance_t {
+typedef struct w2c_host {
wasm_rt_memory_t memory;
char* input;
-};
+} w2c_host;
/* Accessor to access the memory member of the host */
-wasm_rt_memory_t* Z_hostZ_mem(struct Z_host_instance_t* instance) {
+wasm_rt_memory_t* w2c_host_mem(w2c_host* instance) {
return &instance->memory;
}
-/* Declare the implementations of the imports. */
-static u32 fill_buf(struct Z_host_instance_t* instance, u32 ptr, u32 size);
-static void buf_done(struct Z_host_instance_t* instance, u32 ptr, u32 size);
-
-/* Define host-provided functions under the names imported by the `rot13` instance */
-u32 Z_hostZ_fill_buf(struct Z_host_instance_t* instance,
- u32 ptr,
- u32 size) {
- return fill_buf(instance, ptr, size);
-}
-
-void Z_hostZ_buf_done(struct Z_host_instance_t* instance,
- u32 ptr,
- u32 size) {
- return buf_done(instance, ptr, size);
-}
-
int main(int argc, char** argv) {
+ /* Make sure there is at least one command-line argument. */
+ if (argc < 2) {
+ printf("Invalid argument. Expected '%s WORD...'\n", argv[0]);
+ return 1;
+ }
/* Initialize the Wasm runtime. */
wasm_rt_init();
- /* Declare two instances of the `rot13` module. */
- Z_rot13_instance_t rot13_instance_1;
- Z_rot13_instance_t rot13_instance_2;
-
- /* Create two `host` module instances to store the memory and current string */
- struct Z_host_instance_t host_instance_1;
- struct Z_host_instance_t host_instance_2;
- /* Allocate 1 page of wasm memory (64KiB). */
- wasm_rt_allocate_memory(&host_instance_1.memory, 1, 1, false);
- wasm_rt_allocate_memory(&host_instance_2.memory, 1, 1, false);
+ /* Create two `host` instances to store the memory and current string */
+ w2c_host host_1, host_2;
+ wasm_rt_allocate_memory(&host_1.memory, 1, 1, false);
+ wasm_rt_allocate_memory(&host_2.memory, 1, 1, false);
- /* Construct the module instances */
- Z_rot13_instantiate(&rot13_instance_1, &host_instance_1);
- Z_rot13_instantiate(&rot13_instance_2, &host_instance_2);
+ /* Construct the `rot13` module instances */
+ w2c_rot13 rot13_1, rot13_2;
+ wasm2c_rot13_instantiate(&rot13_1, &host_1);
+ wasm2c_rot13_instantiate(&rot13_2, &host_2);
- /* Call `rot13` on first two argument, using the mangled name. */
+ /* Call `rot13` on the first two arguments. */
assert(argc > 2);
- host_instance_1.input = argv[1];
- Z_rot13Z_rot13(&rot13_instance_1);
- host_instance_2.input = argv[2];
- Z_rot13Z_rot13(&rot13_instance_2);
+ host_1.input = argv[1];
+ w2c_rot13_rot13(&rot13_1);
+ host_2.input = argv[2];
+ w2c_rot13_rot13(&rot13_2);
- /* Free the rot13 modules. */
- Z_rot13_free(&rot13_instance_1);
- Z_rot13_free(&rot13_instance_2);
+ /* Free the rot13 instances. */
+ wasm2c_rot13_free(&rot13_1);
+ wasm2c_rot13_free(&rot13_2);
/* Free the Wasm runtime state. */
wasm_rt_free();
@@ -612,12 +598,13 @@ int main(int argc, char** argv) {
/* Fill the wasm buffer with the input to be rot13'd.
*
* params:
+ * instance: An instance of the w2c_host structure
* ptr: The wasm memory address of the buffer to fill data.
* size: The size of the buffer in wasm memory.
* result:
* The number of bytes filled into the buffer. (Must be <= size).
*/
-u32 fill_buf(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
+u32 w2c_host_fill_buf(w2c_host* instance, u32 ptr, u32 size) {
for (size_t i = 0; i < size; ++i) {
if (instance->input[i] == 0) {
return i;
@@ -630,10 +617,11 @@ u32 fill_buf(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
/* Called when the wasm buffer has been rot13'd.
*
* params:
+ * w2c_host: An instance of the w2c_host structure
* ptr: The wasm memory address of the buffer.
* size: The size of the buffer in wasm memory.
*/
-void buf_done(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
+void w2c_host_buf_done(w2c_host* instance, u32 ptr, u32 size) {
/* The output buffer is not necessarily null-terminated, so use the %*.s
* printf format to limit the number of characters printed. */
printf("%s -> %.*s\n", instance->input, (int)size, &instance->memory.data[ptr]);
diff --git a/wasm2c/examples/callback/callback.wat b/wasm2c/examples/callback/callback.wat
index 6a8ab233..9786209a 100644
--- a/wasm2c/examples/callback/callback.wat
+++ b/wasm2c/examples/callback/callback.wat
@@ -1,7 +1,7 @@
;; Module demonstrating use of a host-installed callback function.
;; The type of the callback function. The type ID can be looked up outside the module by calling
-;; Z_[modname]_get_func_type(1, 0, WASM_RT_I32) (indicating 1 param, 0 results, param type is i32).
+;; wasm2c_[modname]_get_func_type(1, 0, WASM_RT_I32) (indicating 1 param, 0 results, param type is i32).
(type $print_type (func (param i32)))
;; An indirect function table to hold the callback function
diff --git a/wasm2c/examples/callback/main.c b/wasm2c/examples/callback/main.c
index b0b37d46..8c6f9db0 100644
--- a/wasm2c/examples/callback/main.c
+++ b/wasm2c/examples/callback/main.c
@@ -6,8 +6,8 @@
* The callback function. Prints the null-terminated string at the given
* location in the instance's exported memory.
*/
-void print(Z_callback_instance_t* instance, uint32_t ptr) {
- puts(Z_callbackZ_memory(instance)->data + ptr);
+void print(w2c_callback* instance, uint32_t ptr) {
+ puts(w2c_callback_memory(instance)->data + ptr);
}
int main(int argc, char** argv) {
@@ -15,8 +15,8 @@ int main(int argc, char** argv) {
wasm_rt_init();
/* Instantiate the callback module. */
- Z_callback_instance_t inst;
- Z_callback_instantiate(&inst);
+ w2c_callback inst;
+ wasm2c_callback_instantiate(&inst);
/*
* Call the module's "set_print_function" function, which takes a funcref to
@@ -24,15 +24,16 @@ int main(int argc, char** argv) {
* looked up with "Z_callback_get_func_type"), a pointer to the function, and
* a module instance pointer that will be passed to the function when called.
*/
- wasm_rt_func_type_t fn_type = Z_callback_get_func_type(1, 0, WASM_RT_I32);
+ wasm_rt_func_type_t fn_type =
+ wasm2c_callback_get_func_type(1, 0, WASM_RT_I32);
wasm_rt_funcref_t fn_ref = {fn_type, (wasm_rt_function_ptr_t)print, &inst};
- Z_callbackZ_set_print_function(&inst, fn_ref);
+ w2c_callback_set_print_function(&inst, fn_ref);
/* "say_hello" uses the previously installed callback. */
- Z_callbackZ_say_hello(&inst);
+ w2c_callback_say_hello(&inst);
/* Free the module instance and the Wasm runtime state. */
- Z_callback_free(&inst);
+ wasm2c_callback_free(&inst);
wasm_rt_free();
return 0;
diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c
index c00a60d0..40cb43b2 100644
--- a/wasm2c/examples/fac/fac.c
+++ b/wasm2c/examples/fac/fac.c
@@ -724,11 +724,11 @@ DEFINE_TABLE_FILL(externref)
#define FUNC_TYPE_T(x) static const char x[]
#endif
-FUNC_TYPE_T(w2c_t0) = "\x07\x80\x96\x7a\x42\xf7\x3e\xe6\x70\x5c\x2f\xac\x83\xf5\x67\xd2\xa2\xa0\x69\x41\x5f\xf8\xe7\x96\x7f\x23\xab\x00\x03\x5f\x4a\x3c";
+FUNC_TYPE_T(w2c_fac_t0) = "\x07\x80\x96\x7a\x42\xf7\x3e\xe6\x70\x5c\x2f\xac\x83\xf5\x67\xd2\xa2\xa0\x69\x41\x5f\xf8\xe7\x96\x7f\x23\xab\x00\x03\x5f\x4a\x3c";
-static u32 w2c_fac(Z_fac_instance_t*, u32);
+static u32 w2c_fac_fac_0(w2c_fac*, u32);
-static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) {
+static u32 w2c_fac_fac_0(w2c_fac* instance, u32 w2c_p0) {
FUNC_PROLOGUE;
u32 w2c_i0, w2c_i1, w2c_i2;
w2c_i0 = w2c_p0;
@@ -741,7 +741,7 @@ static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) {
w2c_i1 = w2c_p0;
w2c_i2 = 1u;
w2c_i1 -= w2c_i2;
- w2c_i1 = w2c_fac(instance, w2c_i1);
+ w2c_i1 = w2c_fac_fac_0(instance, w2c_i1);
w2c_i0 *= w2c_i1;
}
FUNC_EPILOGUE;
@@ -749,25 +749,25 @@ static u32 w2c_fac(Z_fac_instance_t* instance, u32 w2c_p0) {
}
/* export: 'fac' */
-u32 Z_facZ_fac(Z_fac_instance_t* instance, u32 w2c_p0) {
- return w2c_fac(instance, w2c_p0);
+u32 w2c_fac_fac(w2c_fac* instance, u32 w2c_p0) {
+ return w2c_fac_fac_0(instance, w2c_p0);
}
-void Z_fac_instantiate(Z_fac_instance_t* instance) {
+void wasm2c_fac_instantiate(w2c_fac* instance) {
assert(wasm_rt_is_initialized());
}
-void Z_fac_free(Z_fac_instance_t* instance) {
+void wasm2c_fac_free(w2c_fac* instance) {
}
-wasm_rt_func_type_t Z_fac_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
+wasm_rt_func_type_t wasm2c_fac_get_func_type(uint32_t param_count, uint32_t result_count, ...) {
va_list args;
if (param_count == 1 && result_count == 1) {
va_start(args, result_count);
if (true && va_arg(args, wasm_rt_type_t) == WASM_RT_I32 && va_arg(args, wasm_rt_type_t) == WASM_RT_I32) {
va_end(args);
- return w2c_t0;
+ return w2c_fac_t0;
}
va_end(args);
}
diff --git a/wasm2c/examples/fac/fac.h b/wasm2c/examples/fac/fac.h
index 1354411a..5450fe42 100644
--- a/wasm2c/examples/fac/fac.h
+++ b/wasm2c/examples/fac/fac.h
@@ -34,16 +34,16 @@ typedef simde_v128_t v128;
extern "C" {
#endif
-typedef struct Z_fac_instance_t {
+typedef struct w2c_fac {
char dummy_member;
-} Z_fac_instance_t;
+} w2c_fac;
-void Z_fac_instantiate(Z_fac_instance_t*);
-void Z_fac_free(Z_fac_instance_t*);
-wasm_rt_func_type_t Z_fac_get_func_type(uint32_t param_count, uint32_t result_count, ...);
+void wasm2c_fac_instantiate(w2c_fac*);
+void wasm2c_fac_free(w2c_fac*);
+wasm_rt_func_type_t wasm2c_fac_get_func_type(uint32_t param_count, uint32_t result_count, ...);
/* export: 'fac' */
-u32 Z_facZ_fac(Z_fac_instance_t*, u32);
+u32 w2c_fac_fac(w2c_fac*, u32);
#ifdef __cplusplus
}
diff --git a/wasm2c/examples/fac/main.c b/wasm2c/examples/fac/main.c
index 37593f6e..eb85376e 100644
--- a/wasm2c/examples/fac/main.c
+++ b/wasm2c/examples/fac/main.c
@@ -18,19 +18,19 @@ int main(int argc, char** argv) {
wasm_rt_init();
/* Declare an instance of the `fac` module. */
- Z_fac_instance_t instance;
+ w2c_fac fac;
/* Construct the module instance. */
- Z_fac_instantiate(&instance);
+ wasm2c_fac_instantiate(&fac);
/* Call `fac`, using the mangled name. */
- u32 result = Z_facZ_fac(&instance, x);
+ u32 result = w2c_fac_fac(&fac, x);
/* Print the result. */
printf("fac(%u) -> %u\n", x, result);
/* Free the fac module. */
- Z_fac_free(&instance);
+ wasm2c_fac_free(&fac);
/* Free the Wasm runtime state. */
wasm_rt_free();
diff --git a/wasm2c/examples/rot13/main.c b/wasm2c/examples/rot13/main.c
index d6517f39..f0164fba 100644
--- a/wasm2c/examples/rot13/main.c
+++ b/wasm2c/examples/rot13/main.c
@@ -20,49 +20,33 @@
#include "rot13.h"
/* Define structure to hold the imports */
-struct Z_host_instance_t {
+struct w2c_host {
wasm_rt_memory_t memory;
char* input;
};
/* Accessor to access the memory member of the host */
-wasm_rt_memory_t* Z_hostZ_mem(struct Z_host_instance_t* instance) {
+wasm_rt_memory_t* w2c_host_mem(struct w2c_host* instance) {
return &instance->memory;
}
-/* Declare the implementations of the imports. */
-static u32 fill_buf(struct Z_host_instance_t* instance, u32 ptr, u32 size);
-static void buf_done(struct Z_host_instance_t* instance, u32 ptr, u32 size);
-
-/* Define host-provided functions under the names imported by the `rot13`
- * instance */
-u32 Z_hostZ_fill_buf(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
- return fill_buf(instance, ptr, size);
-}
-
-void Z_hostZ_buf_done(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
- return buf_done(instance, ptr, size);
-}
-
int main(int argc, char** argv) {
/* Make sure there is at least one command-line argument. */
if (argc < 2) {
- printf("Invalid argument. Expected '%s WORD'\n", argv[0]);
+ printf("Invalid argument. Expected '%s WORD...'\n", argv[0]);
return 1;
}
/* Initialize the Wasm runtime. */
wasm_rt_init();
- /* Declare an instance of the `rot13` module. */
- Z_rot13_instance_t rot13_instance;
-
- /* Create a `host` module instance to store the memory and current string */
- struct Z_host_instance_t host_instance;
- /* Allocate 1 page of wasm memory (64KiB). */
- wasm_rt_allocate_memory(&host_instance.memory, 1, 1, false);
+ /* Create a structure to store the memory and current string, allocating 1
+ page of Wasm memory (64 KiB) that the rot13 module instance will import. */
+ struct w2c_host host;
+ wasm_rt_allocate_memory(&host.memory, 1, 1, false);
- /* Construct the module instance */
- Z_rot13_instantiate(&rot13_instance, &host_instance);
+ // Construct an instance of the `rot13` module, which imports from the host.
+ w2c_rot13 rot13;
+ wasm2c_rot13_instantiate(&rot13, &host);
/* Call `rot13` on each argument. */
while (argc > 1) {
@@ -70,12 +54,12 @@ int main(int argc, char** argv) {
argc--;
argv++;
- host_instance.input = argv[0];
- Z_rot13Z_rot13(&rot13_instance);
+ host.input = argv[0];
+ w2c_rot13_rot13(&rot13);
}
/* Free the rot13 module. */
- Z_rot13_free(&rot13_instance);
+ wasm2c_rot13_free(&rot13);
/* Free the Wasm runtime state. */
wasm_rt_free();
@@ -86,12 +70,13 @@ int main(int argc, char** argv) {
/* Fill the wasm buffer with the input to be rot13'd.
*
* params:
+ * instance: An instance of the w2c_host structure
* ptr: The wasm memory address of the buffer to fill data.
* size: The size of the buffer in wasm memory.
* result:
* The number of bytes filled into the buffer. (Must be <= size).
*/
-u32 fill_buf(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
+u32 w2c_host_fill_buf(struct w2c_host* instance, u32 ptr, u32 size) {
for (size_t i = 0; i < size; ++i) {
if (instance->input[i] == 0) {
return i;
@@ -104,10 +89,11 @@ u32 fill_buf(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
/* Called when the wasm buffer has been rot13'd.
*
* params:
+ * w2c_host: An instance of the w2c_host structure
* ptr: The wasm memory address of the buffer.
* size: The size of the buffer in wasm memory.
*/
-void buf_done(struct Z_host_instance_t* instance, u32 ptr, u32 size) {
+void w2c_host_buf_done(struct w2c_host* instance, u32 ptr, u32 size) {
/* The output buffer is not necessarily null-terminated, so use the %*.s
* printf format to limit the number of characters printed. */
printf("%s -> %.*s\n", instance->input, (int)size,