diff --git a/src/c-writer.cc b/src/c-writer.cc index 0a267e397..5bb7f6a09 100644 --- a/src/c-writer.cc +++ b/src/c-writer.cc @@ -1,5 +1,5 @@ /* - / Copyright 2017 WebAssembly Community Group participants + * Copyright 2017 WebAssembly Community Group participants * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -135,7 +135,12 @@ class CWriter { c_stream_(c_stream), h_stream_(h_stream), header_name_(header_name), - module_name_(header_name_.substr(0, header_name_.size() - 2)) {} + module_name_(header_name_) { + if ((module_name_.size() > 2) && + (module_name_.substr(module_name_.size() - 2) == ".h")) { + module_name_.erase(module_name_.size() - 2); + } + } Result WriteModule(const Module&); @@ -237,7 +242,7 @@ class CWriter { void WriteMultivalueTypes(); void WriteFuncTypes(); void ComputeUniqueImports(); - void WriteInstanceImports(); + void BeginInstance(); void WriteImports(); void WriteFuncDeclarations(); void WriteFuncDeclaration(const FuncDeclaration&, const std::string&); @@ -473,8 +478,7 @@ std::string CWriter::MangleModuleInstanceTypeName( // static std::string CWriter::ExternalName(std::string_view module_name, std::string_view name) { - return MangleName(std::string(module_name)) + "_" + - MangleName(std::string(name)); + return MangleName(module_name) + "_" + MangleName(name); } // static @@ -834,7 +838,7 @@ void CWriter::Write(const Const& const_) { } void CWriter::WriteInitDecl() { - Write("extern void " + MangleName(module_name_) + "_init_module();", + Write("extern void " + MangleName(module_name_) + "_init_module(void);", Newline()); Write("extern void " + MangleName(module_name_) + "_init(", MangleModuleInstanceTypeName(module_name_), "*"); @@ -946,7 +950,16 @@ void CWriter::WriteFuncTypes() { void CWriter::ComputeUniqueImports() { std::map, const Import*> import_map; for (const Import* import : module_->imports) { - import_map.try_emplace({import->module_name, import->field_name}, import); + auto key = make_pair(import->module_name, import->field_name); + auto insertion_result = import_map.emplace(key, import); + if (!insertion_result.second) { + if (insertion_result.first->second->kind() != import->kind()) { + UNIMPLEMENTED("contradictory import declaration"); + } else { + fprintf(stderr, "warning: duplicate import declaration \"%s\" \"%s\"\n", + import->module_name.c_str(), import->field_name.c_str()); + } + } import_module_set_.insert(import->module_name); if (import->kind() == ExternalKind::Func) { import_func_module_set_.insert(import->module_name); @@ -958,7 +971,7 @@ void CWriter::ComputeUniqueImports() { } } -void CWriter::WriteInstanceImports() { +void CWriter::BeginInstance() { if (module_->imports.empty()) { Write("typedef struct ", MangleModuleInstanceTypeName(module_name_), " ", OpenBrace()); @@ -1122,6 +1135,7 @@ void CWriter::WriteFuncDeclaration(const FuncDeclaration& decl, Write(ResultType(decl.sig.result_types), " ", name, "("); Write(MangleModuleInstanceTypeName(module_name_), "*"); WriteParamTypes(decl); + Write(")"); } void CWriter::WriteImportFuncDeclaration(const FuncDeclaration& decl, @@ -1130,16 +1144,18 @@ void CWriter::WriteImportFuncDeclaration(const FuncDeclaration& decl, Write(ResultType(decl.sig.result_types), " ", name, "("); Write("struct ", MangleModuleInstanceTypeName(module_name), "*"); WriteParamTypes(decl); + Write(")"); } void CWriter::WriteCallIndirectFuncDeclaration(const FuncDeclaration& decl, const std::string& name) { Write(ResultType(decl.sig.result_types), " ", name, "(void*"); WriteParamTypes(decl); + Write(")"); } void CWriter::WriteModuleInstance() { - WriteInstanceImports(); + BeginInstance(); WriteGlobals(); WriteMemories(); WriteTables(); @@ -1474,7 +1490,7 @@ void CWriter::WriteExports(WriteExportsKind kind) { } void CWriter::WriteInit() { - Write(Newline(), "void " + MangleName(module_name_) + "_init_module()", + Write(Newline(), "void " + MangleName(module_name_) + "_init_module(void)", OpenBrace()); Write("wasm_rt_init();", Newline()); Write("init_func_types();", Newline()); @@ -1701,7 +1717,6 @@ void CWriter::WriteParamTypes(const FuncDeclaration& decl) { Write(decl.GetParamType(i)); } } - Write(")"); } void CWriter::WriteLocals(const std::vector& index_to_name) { diff --git a/src/prebuilt/wasm2c.include.c b/src/prebuilt/wasm2c.include.c index 075e19821..68dd0efad 100644 --- a/src/prebuilt/wasm2c.include.c +++ b/src/prebuilt/wasm2c.include.c @@ -31,7 +31,7 @@ const char SECTION_NAME(declarations)[] = " , ((t)table.data[x].func)(__VA_ARGS__))\n" "\n" "#define RANGE_CHECK(mem, offset, len) \\\n" -" if (UNLIKELY(offset + (uint64_t)len > mem->size)) TRAP(OOB)\n" +" if (UNLIKELY(offset + (u64)len > mem->size)) TRAP(OOB)\n" "\n" "#if WASM_RT_MEMCHECK_SIGNAL_HANDLER\n" "#define MEMCHECK(mem, a, t)\n" diff --git a/src/wasm2c.c.tmpl b/src/wasm2c.c.tmpl index 8bfc85c9b..278c7cb5c 100644 --- a/src/wasm2c.c.tmpl +++ b/src/wasm2c.c.tmpl @@ -28,7 +28,7 @@ , ((t)table.data[x].func)(__VA_ARGS__)) #define RANGE_CHECK(mem, offset, len) \ - if (UNLIKELY(offset + (uint64_t)len > mem->size)) TRAP(OOB) + if (UNLIKELY(offset + (u64)len > mem->size)) TRAP(OOB) #if WASM_RT_MEMCHECK_SIGNAL_HANDLER #define MEMCHECK(mem, a, t) diff --git a/test/run-spec-wasm2c.py b/test/run-spec-wasm2c.py index f7178c6a1..724c2a39b 100755 --- a/test/run-spec-wasm2c.py +++ b/test/run-spec-wasm2c.py @@ -193,10 +193,8 @@ def _WriteModuleInstanceImports(self, command, uninstantiable): c_filename = os.path.join(self.out_dir, self.idx_to_c_name[self.module_idx - 1]) header_filename = utils.ChangeExt(c_filename, '.h') with open(header_filename, encoding='utf-8') as f: - headerfile = f.readlines() imported_modules = set() - for i in range(0, len(headerfile)): - line = headerfile[i] + for line in f: if "import: " in line: line_split = line.split() import_module_name = MangleName(line_split[2][1:-1]) @@ -205,7 +203,7 @@ def _WriteModuleInstanceImports(self, command, uninstantiable): if (uninstantiable): self.out_file.write("ASSERT_TRAP(") - if (len(imported_modules) > 0): + if len(imported_modules) > 0: self.out_file.write("%s_init(&%s_module_instance" % (self.GetModulePrefix(), self.GetModulePrefix())) for imported_module in sorted(imported_modules): self.out_file.write(", &%s_module_instance" % imported_module) @@ -222,16 +220,19 @@ def _WriteModuleImports(self): header_filename = utils.ChangeExt(os.path.join(self.out_dir, c_filename), '.h') with open(header_filename, encoding='utf-8') as f: + # read the whole file at once, because we want to + # look ahead to detect a function import (via "extern") headerfile = f.readlines() imported_functions = {} for i in range(0, len(headerfile)): line = headerfile[i] if "import: " in line: next_line = headerfile[i + 1] - if "extern" in next_line: + if next_line.startswith("extern "): line_split = line.split() import_module_name = MangleName(line_split[2][1:-1]) import_field_name = MangleName(line_split[3][1:-1]) + # extract function declaration between "extern" and final semicolon imported_functions[import_module_name + "_" + import_field_name] = next_line[7:-2] for imported_function, internal_name in imported_functions.items(): internal_name_split = internal_name[:-1].split(',') @@ -414,7 +415,7 @@ def _Action(self, command): field = mangled_module_name + "_" + MangleName(action['field']) if type_ == 'invoke': args = self._ConstantList(action.get('args', [])) - if (len(args) == 0): + if len(args) == 0: args = '&' + mangled_module_name + "_module_instance" else: args = '&' + mangled_module_name + "_module_instance" + ', ' + args diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c index 16848b653..9919cc18b 100644 --- a/wasm2c/examples/fac/fac.c +++ b/wasm2c/examples/fac/fac.c @@ -28,7 +28,7 @@ , ((t)table.data[x].func)(__VA_ARGS__)) #define RANGE_CHECK(mem, offset, len) \ - if (UNLIKELY(offset + (uint64_t)len > mem->size)) TRAP(OOB) + if (UNLIKELY(offset + (u64)len > mem->size)) TRAP(OOB) #if WASM_RT_MEMCHECK_SIGNAL_HANDLER #define MEMCHECK(mem, a, t) @@ -324,9 +324,7 @@ static u32 w2c_fac(Z_fac_module_instance_t* module_instance, u32 w2c_p0) { static void init_globals(Z_fac_module_instance_t* module_instance) { } - static void init_memory(Z_fac_module_instance_t* module_instance) { - wasm_rt_allocate_memory(&module_instance->w2c_M0, 1, 65536); } static void init_table(Z_fac_module_instance_t* module_instance) { @@ -338,7 +336,8 @@ u32 Z_fac_Z_fac(Z_fac_module_instance_t* module_instance, u32 w2c_p0) { return w2c_fac(module_instance, w2c_p0); } -void Z_fac_init_module(){ +void Z_fac_init_module(void){ + wasm_rt_init(); init_func_types(); } @@ -349,5 +348,4 @@ void Z_fac_init(Z_fac_module_instance_t* module_instance) { } void Z_fac_free(Z_fac_module_instance_t* module_instance) { - wasm_rt_free_memory(&module_instance->w2c_M0); } diff --git a/wasm2c/examples/fac/fac.h b/wasm2c/examples/fac/fac.h index 2f00ea9eb..adb5de541 100644 --- a/wasm2c/examples/fac/fac.h +++ b/wasm2c/examples/fac/fac.h @@ -25,10 +25,10 @@ typedef double f64; #endif typedef struct Z_fac_module_instance_t { - wasm_rt_memory_t w2c_M0; + char dummy_member; } Z_fac_module_instance_t; -extern void Z_fac_init_module(); +extern void Z_fac_init_module(void); extern void Z_fac_init(Z_fac_module_instance_t*); extern void Z_fac_free(Z_fac_module_instance_t*); diff --git a/wasm2c/examples/fac/fac.wasm b/wasm2c/examples/fac/fac.wasm index e2d148722..711421b60 100644 Binary files a/wasm2c/examples/fac/fac.wasm and b/wasm2c/examples/fac/fac.wasm differ diff --git a/wasm2c/examples/fac/fac.wat b/wasm2c/examples/fac/fac.wat index 44b657700..017a97aaf 100644 --- a/wasm2c/examples/fac/fac.wat +++ b/wasm2c/examples/fac/fac.wat @@ -1,4 +1,3 @@ -(memory $mem 1) (func (export "fac") (param i32) (result i32) (if (result i32) (i32.eq (local.get 0) (i32.const 0)) (then (i32.const 1))