diff --git a/src/wasm/worker.cpp b/src/wasm/worker.cpp index 35ec87e..9bbcdb4 100644 --- a/src/wasm/worker.cpp +++ b/src/wasm/worker.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -247,10 +248,54 @@ public: String parse_error; if(!wasm_parse_sections(bytes, core_dylink, abi_ignored, parse_error)) return("core module: " + parse_error); + + String core_cached_path = cfg.core_wasm_path; + if(core_cached_path.size() >= 5 && core_cached_path.rfind(".wasm", core_cached_path.size() - 5) == core_cached_path.size() - 5) + core_cached_path = core_cached_path.substr(0, core_cached_path.size() - 5) + ".cwasm"; + else + core_cached_path += ".cwasm"; + struct stat core_stat; + struct stat cached_stat; + if(stat(core_cached_path.c_str(), &cached_stat) == 0 && stat(cfg.core_wasm_path.c_str(), &core_stat) == 0) + { + if(cached_stat.st_mtime > core_stat.st_mtime) + { + auto deserialized = wasmtime::Module::deserialize_file(engine, core_cached_path); + if(deserialized) + { + core_module.emplace(deserialized.ok()); + return(""); + } + } + } + auto compiled = wasmtime::Module::compile(engine, bytes); if(!compiled) return("core module compile failed: " + String(compiled.err().message())); core_module.emplace(compiled.ok()); + + auto serialized = core_module->serialize(); + if(serialized) + { + String tmp = core_cached_path + "." + std::to_string((long long)getpid()) + ".tmp"; + auto data = serialized.ok(); + { + std::ofstream out(tmp, std::ios::binary | std::ios::trunc); + if(out) + { + out.write((const char*)data.data(), (std::streamsize)data.size()); + if(out) + { + out.flush(); + out.close(); + if(std::rename(tmp.c_str(), core_cached_path.c_str()) != 0) + (void)std::remove(tmp.c_str()); + } + } + else + (void)std::remove(tmp.c_str()); + } + } return(""); }