|
20 | 20 | #include <cstring> |
21 | 21 | #include <memory> |
22 | 22 |
|
| 23 | +namespace v8impl { |
| 24 | +static void ThrowNodeApiVersionError(node::Environment* node_env, |
| 25 | + const char* module_name, |
| 26 | + int32_t module_api_version) { |
| 27 | + std::string error_message; |
| 28 | + error_message += module_name; |
| 29 | + error_message += " requires Node-API version "; |
| 30 | + error_message += std::to_string(module_api_version); |
| 31 | + error_message += ", but this version of Node.js only supports version "; |
| 32 | + error_message += NODE_STRINGIFY(NODE_API_SUPPORTED_VERSION_MAX) " add-ons."; |
| 33 | + node_env->ThrowError(error_message.c_str()); |
| 34 | +} |
| 35 | +} // namespace v8impl |
| 36 | + |
| 37 | +/*static*/ napi_env node_napi_env__::New(v8::Local<v8::Context> context, |
| 38 | + const std::string& module_filename, |
| 39 | + int32_t module_api_version) { |
| 40 | + node_napi_env result; |
| 41 | + |
| 42 | + // Validate module_api_version. |
| 43 | + if (module_api_version < NODE_API_DEFAULT_MODULE_API_VERSION) { |
| 44 | + module_api_version = NODE_API_DEFAULT_MODULE_API_VERSION; |
| 45 | + } else if (module_api_version > NODE_API_SUPPORTED_VERSION_MAX && |
| 46 | + module_api_version != NAPI_VERSION_EXPERIMENTAL) { |
| 47 | + node::Environment* node_env = node::Environment::GetCurrent(context); |
| 48 | + CHECK_NOT_NULL(node_env); |
| 49 | + v8impl::ThrowNodeApiVersionError( |
| 50 | + node_env, module_filename.c_str(), module_api_version); |
| 51 | + return nullptr; |
| 52 | + } |
| 53 | + |
| 54 | + result = new node_napi_env__(context, module_filename, module_api_version); |
| 55 | + // TODO(addaleax): There was previously code that tried to delete the |
| 56 | + // napi_env when its v8::Context was garbage collected; |
| 57 | + // However, as long as N-API addons using this napi_env are in place, |
| 58 | + // the Context needs to be accessible and alive. |
| 59 | + // Ideally, we'd want an on-addon-unload hook that takes care of this |
| 60 | + // once all N-API addons using this napi_env are unloaded. |
| 61 | + // For now, a per-Environment cleanup hook is the best we can do. |
| 62 | + result->node_env()->AddCleanupHook( |
| 63 | + [](void* arg) { static_cast<napi_env>(arg)->Unref(); }, |
| 64 | + static_cast<void*>(result)); |
| 65 | + |
| 66 | + return result; |
| 67 | +} |
| 68 | + |
23 | 69 | node_napi_env__::node_napi_env__(v8::Local<v8::Context> context, |
24 | 70 | const std::string& module_filename, |
25 | 71 | int32_t module_api_version) |
@@ -152,50 +198,6 @@ class BufferFinalizer : private Finalizer { |
152 | 198 | ~BufferFinalizer() { env()->Unref(); } |
153 | 199 | }; |
154 | 200 |
|
155 | | -void ThrowNodeApiVersionError(node::Environment* node_env, |
156 | | - const char* module_name, |
157 | | - int32_t module_api_version) { |
158 | | - std::string error_message; |
159 | | - error_message += module_name; |
160 | | - error_message += " requires Node-API version "; |
161 | | - error_message += std::to_string(module_api_version); |
162 | | - error_message += ", but this version of Node.js only supports version "; |
163 | | - error_message += NODE_STRINGIFY(NODE_API_SUPPORTED_VERSION_MAX) " add-ons."; |
164 | | - node_env->ThrowError(error_message.c_str()); |
165 | | -} |
166 | | - |
167 | | -inline napi_env NewEnv(v8::Local<v8::Context> context, |
168 | | - const std::string& module_filename, |
169 | | - int32_t module_api_version) { |
170 | | - node_napi_env result; |
171 | | - |
172 | | - // Validate module_api_version. |
173 | | - if (module_api_version < NODE_API_DEFAULT_MODULE_API_VERSION) { |
174 | | - module_api_version = NODE_API_DEFAULT_MODULE_API_VERSION; |
175 | | - } else if (module_api_version > NODE_API_SUPPORTED_VERSION_MAX && |
176 | | - module_api_version != NAPI_VERSION_EXPERIMENTAL) { |
177 | | - node::Environment* node_env = node::Environment::GetCurrent(context); |
178 | | - CHECK_NOT_NULL(node_env); |
179 | | - ThrowNodeApiVersionError( |
180 | | - node_env, module_filename.c_str(), module_api_version); |
181 | | - return nullptr; |
182 | | - } |
183 | | - |
184 | | - result = new node_napi_env__(context, module_filename, module_api_version); |
185 | | - // TODO(addaleax): There was previously code that tried to delete the |
186 | | - // napi_env when its v8::Context was garbage collected; |
187 | | - // However, as long as N-API addons using this napi_env are in place, |
188 | | - // the Context needs to be accessible and alive. |
189 | | - // Ideally, we'd want an on-addon-unload hook that takes care of this |
190 | | - // once all N-API addons using this napi_env are unloaded. |
191 | | - // For now, a per-Environment cleanup hook is the best we can do. |
192 | | - result->node_env()->AddCleanupHook( |
193 | | - [](void* arg) { static_cast<napi_env>(arg)->Unref(); }, |
194 | | - static_cast<void*>(result)); |
195 | | - |
196 | | - return result; |
197 | | -} |
198 | | - |
199 | 201 | class ThreadSafeFunction : public node::AsyncResource { |
200 | 202 | public: |
201 | 203 | ThreadSafeFunction(v8::Local<v8::Function> func, |
@@ -728,7 +730,8 @@ void napi_module_register_by_symbol(v8::Local<v8::Object> exports, |
728 | 730 | } |
729 | 731 |
|
730 | 732 | // Create a new napi_env for this specific module. |
731 | | - napi_env env = v8impl::NewEnv(context, module_filename, module_api_version); |
| 733 | + napi_env env = |
| 734 | + node_napi_env__::New(context, module_filename, module_api_version); |
732 | 735 |
|
733 | 736 | napi_value _exports = nullptr; |
734 | 737 | env->CallIntoModule([&](napi_env env) { |
|
0 commit comments