diff --git a/include/proxy-wasm/wasm.h b/include/proxy-wasm/wasm.h index 9caf90173..e77b9b03d 100644 --- a/include/proxy-wasm/wasm.h +++ b/include/proxy-wasm/wasm.h @@ -196,10 +196,10 @@ class WasmBase : public std::enable_shared_from_this { std::unordered_map envs_; // environment variables passed through wasi.environ_get - WasmCallVoid<0> _initialize_; /* Emscripten v1.39.17+ */ - WasmCallVoid<0> _start_; /* Emscripten v1.39.0+ */ - WasmCallVoid<0> __wasm_call_ctors_; + WasmCallVoid<0> _initialize_; /* WASI reactor (Emscripten v1.39.17+, Rust nightly) */ + WasmCallVoid<0> _start_; /* WASI command (Emscripten v1.39.0+, TinyGo) */ + WasmCallWord<2> main_; WasmCallWord<1> malloc_; // Calls into the VM. diff --git a/src/null/null_plugin.cc b/src/null/null_plugin.cc index dfc2dbfaa..25f575e19 100644 --- a/src/null/null_plugin.cc +++ b/src/null/null_plugin.cc @@ -37,8 +37,6 @@ void NullPlugin::getFunction(std::string_view function_name, WasmCallVoid<0> *f) *f = nullptr; } else if (function_name == "_start") { *f = nullptr; - } else if (function_name == "__wasm_call_ctors") { - *f = nullptr; } else if (!wasm_vm_->integration()->getNullVmFunction(function_name, false, 0, this, f)) { error("Missing getFunction for: " + std::string(function_name)); *f = nullptr; @@ -167,7 +165,9 @@ void NullPlugin::getFunction(std::string_view function_name, WasmCallWord<1> *f) void NullPlugin::getFunction(std::string_view function_name, WasmCallWord<2> *f) { auto plugin = this; - if (function_name == "proxy_on_vm_start") { + if (function_name == "main") { + *f = nullptr; + } else if (function_name == "proxy_on_vm_start") { *f = [plugin](ContextBase *context, Word context_id, Word configuration_size) { SaveRestoreContext saved_context(context); return Word(plugin->onStart(context_id, configuration_size)); diff --git a/src/wasm.cc b/src/wasm.cc index 2a6117ff0..7fda02629 100644 --- a/src/wasm.cc +++ b/src/wasm.cc @@ -147,8 +147,11 @@ void WasmBase::getFunctions() { #define _GET(_fn) wasm_vm_->getFunction(#_fn, &_fn##_); #define _GET_ALIAS(_fn, _alias) wasm_vm_->getFunction(#_alias, &_fn##_); _GET(_initialize); - _GET(_start); - _GET(__wasm_call_ctors); + if (_initialize_) { + _GET(main); + } else { + _GET(_start); + } _GET(malloc); if (!malloc_) { @@ -284,11 +287,19 @@ ContextBase *WasmBase::getRootContext(const std::shared_ptr &plugin, void WasmBase::startVm(ContextBase *root_context) { if (_initialize_) { + // WASI reactor. _initialize_(root_context); + if (main_) { + // Call main() if it exists in WASI reactor, to allow module to + // do early initialization (e.g. configure SDK). + // + // Re-using main() keeps this consistent when switching between + // WASI command (that calls main()) and reactor (that doesn't). + main_(root_context, Word(0), Word(0)); + } } else if (_start_) { + // WASI command. _start_(root_context); - } else if (__wasm_call_ctors_) { - __wasm_call_ctors_(root_context); } }