Lib/javascript/v8: use context-aware initialization.

Context-aware initialization allows to instantiate add-ons multiple
times, most importantly in multiple Workers' contexts. Workers made
first appearance in v10.5. Context-aware initialization was option
earlier than that, even before supported minimum v6.x, yet condition
is chosen more conservatively as NODE_MODULE_VERSION >= 64, a.k.a.
v10.0.
This commit is contained in:
Andy Polyakov 2021-02-28 17:08:14 +01:00
commit b0c01ea851
4 changed files with 35 additions and 26 deletions

View file

@ -432,7 +432,7 @@ fail:
$jsmangledname_class_0->SetHiddenPrototype(true); $jsmangledname_class_0->SetHiddenPrototype(true);
v8::Local<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction(); v8::Local<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction();
#else #else
v8::Local<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked(); v8::Local<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction(context).ToLocalChecked();
#endif #endif
%} %}
@ -447,7 +447,7 @@ fail:
#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) #if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
$jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj); $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj);
#else #else
SWIGV8_MAYBE_CHECK($jsparent_obj->Set(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj)); SWIGV8_MAYBE_CHECK($jsparent_obj->Set(context, SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj));
#endif #endif
%} %}
@ -472,7 +472,7 @@ fail:
#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) #if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
$jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj); $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj);
#else #else
SWIGV8_MAYBE_CHECK($jsparent_obj->Set(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj)); SWIGV8_MAYBE_CHECK($jsparent_obj->Set(context, SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj));
#endif #endif
%} %}
@ -509,7 +509,7 @@ fail:
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
%fragment("jsv8_register_static_function", "templates") %fragment("jsv8_register_static_function", "templates")
%{ %{
SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper); SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper, context);
%} %}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -523,5 +523,5 @@ fail:
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
%fragment("jsv8_register_static_variable", "templates") %fragment("jsv8_register_static_variable", "templates")
%{ %{
SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter, context);
%} %}

View file

@ -61,11 +61,11 @@ SWIGRUNTIME void SWIGV8_AddMemberVariable(SWIGV8_FUNCTION_TEMPLATE class_templ,
* Registers a class method with given name for a given object. * Registers a class method with given name for a given object.
*/ */
SWIGRUNTIME void SWIGV8_AddStaticFunction(SWIGV8_OBJECT obj, const char* symbol, SWIGRUNTIME void SWIGV8_AddStaticFunction(SWIGV8_OBJECT obj, const char* symbol,
const SwigV8FunctionCallback& _func) { const SwigV8FunctionCallback& _func, v8::Local<v8::Context> context) {
#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) || (SWIG_V8_VERSION < 0x0704) #if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
obj->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction()); obj->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction());
#else #else
SWIGV8_MAYBE_CHECK(obj->Set(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked())); SWIGV8_MAYBE_CHECK(obj->Set(context, SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction(context).ToLocalChecked()));
#endif #endif
} }
@ -73,11 +73,12 @@ SWIGRUNTIME void SWIGV8_AddStaticFunction(SWIGV8_OBJECT obj, const char* symbol,
* Registers a class method with given name for a given object. * Registers a class method with given name for a given object.
*/ */
SWIGRUNTIME void SWIGV8_AddStaticVariable(SWIGV8_OBJECT obj, const char* symbol, SWIGRUNTIME void SWIGV8_AddStaticVariable(SWIGV8_OBJECT obj, const char* symbol,
SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter,
v8::Local<v8::Context> context) {
#if (V8_MAJOR_VERSION-0) < 5 #if (V8_MAJOR_VERSION-0) < 5
obj->SetAccessor(SWIGV8_SYMBOL_NEW(symbol), getter, setter); obj->SetAccessor(SWIGV8_SYMBOL_NEW(symbol), getter, setter);
#else #else
SWIGV8_MAYBE_CHECK(obj->SetAccessor(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW(symbol), getter, setter)); SWIGV8_MAYBE_CHECK(obj->SetAccessor(context, SWIGV8_SYMBOL_NEW(symbol), getter, setter));
#endif #endif
} }

View file

@ -5,27 +5,27 @@
%insert(init) %{ %insert(init) %{
SWIGRUNTIME void SWIGRUNTIME void
SWIG_V8_SetModule(void *, swig_module_info *swig_module) { SWIG_V8_SetModule(v8::Local<v8::Context> context, swig_module_info *swig_module) {
v8::Local<v8::Object> global_obj = SWIGV8_CURRENT_CONTEXT()->Global(); v8::Local<v8::Object> global_obj = context->Global();
v8::Local<v8::External> mod = SWIGV8_EXTERNAL_NEW(swig_module); v8::Local<v8::External> mod = SWIGV8_EXTERNAL_NEW(swig_module);
assert(!mod.IsEmpty()); assert(!mod.IsEmpty());
#if (V8_MAJOR_VERSION-0) < 5 #if (V8_MAJOR_VERSION-0) < 5
global_obj->SetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data"), mod); global_obj->SetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data"), mod);
#else #else
v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data")); v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data"));
global_obj->SetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey, mod); global_obj->SetPrivate(context, privateKey, mod);
#endif #endif
} }
SWIGRUNTIME swig_module_info * SWIGRUNTIME swig_module_info *
SWIG_V8_GetModule(void *) { SWIG_V8_GetModule(v8::Local<v8::Context> context) {
v8::Local<v8::Object> global_obj = SWIGV8_CURRENT_CONTEXT()->Global(); v8::Local<v8::Object> global_obj = context->Global();
#if (V8_MAJOR_VERSION-0) < 5 #if (V8_MAJOR_VERSION-0) < 5
v8::Local<v8::Value> moduleinfo = global_obj->GetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data")); v8::Local<v8::Value> moduleinfo = global_obj->GetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data"));
#else #else
v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data")); v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data"));
v8::Local<v8::Value> moduleinfo; v8::Local<v8::Value> moduleinfo;
if (!global_obj->GetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey).ToLocal(&moduleinfo)) if (!global_obj->GetPrivate(context, privateKey).ToLocal(&moduleinfo))
return 0; return 0;
#endif #endif
@ -52,6 +52,7 @@ SWIG_V8_GetModule(void *) {
#define SWIG_GetModule(clientdata) SWIG_V8_GetModule(clientdata) #define SWIG_GetModule(clientdata) SWIG_V8_GetModule(clientdata)
#define SWIG_SetModule(clientdata, pointer) SWIG_V8_SetModule(clientdata, pointer) #define SWIG_SetModule(clientdata, pointer) SWIG_V8_SetModule(clientdata, pointer)
#define SWIG_INIT_CLIENT_DATA_TYPE v8::Local<v8::Context>
%} %}
@ -64,20 +65,20 @@ SWIG_V8_GetModule(void *) {
%} %}
%insert(init) %{ %insert(init) %{
#if !defined(NODE_MODULE_VERSION) || (NODE_MODULE_VERSION < 12)
// Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually // Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually
// TODO: is it ok to do that? extern "C" void SWIGV8_INIT (SWIGV8_OBJECT exports_obj)
extern "C" #elif (NODE_MODULE_VERSION < 64)
#if (NODE_MODULE_VERSION < 0x000C) void SWIGV8_INIT (SWIGV8_OBJECT exports_obj, SWIGV8_VALUE /*module*/, void*)
void SWIGV8_INIT (SWIGV8_OBJECT exports)
#else #else
void SWIGV8_INIT (SWIGV8_OBJECT exports, SWIGV8_OBJECT /*module*/) void SWIGV8_INIT (SWIGV8_OBJECT exports_obj, SWIGV8_VALUE /*module*/, v8::Local<v8::Context> context, void*)
#endif #endif
{ {
SWIG_InitializeModule(static_cast<void *>(&exports)); #if !defined(NODE_MODULE_VERSION) || NODE_MODULE_VERSION < 64
v8::Local<v8::Context> context = SWIGV8_CURRENT_CONTEXT();
#endif
SWIGV8_HANDLESCOPE(); SWIG_InitializeModule(context);
SWIGV8_OBJECT exports_obj = exports;
%} %}
@ -124,6 +125,10 @@ void SWIGV8_INIT (SWIGV8_OBJECT exports, SWIGV8_OBJECT /*module*/)
} }
#if defined(BUILDING_NODE_EXTENSION) #if defined(BUILDING_NODE_EXTENSION)
#if (NODE_MODULE_VERSION < 64)
NODE_MODULE($jsname, $jsname_initialize) NODE_MODULE($jsname, $jsname_initialize)
#else
NODE_MODULE_CONTEXT_AWARE($jsname, $jsname_initialize)
#endif
#endif #endif
%} %}

View file

@ -50,9 +50,12 @@ extern "C" {
#define SWIGRUNTIME_DEBUG #define SWIGRUNTIME_DEBUG
#endif #endif
#ifndef SWIG_INIT_CLIENT_DATA_TYPE
#define SWIG_INIT_CLIENT_DATA_TYPE void *
#endif
SWIGRUNTIME void SWIGRUNTIME void
SWIG_InitializeModule(void *clientdata) { SWIG_InitializeModule(SWIG_INIT_CLIENT_DATA_TYPE clientdata) {
size_t i; size_t i;
swig_module_info *module_head, *iter; swig_module_info *module_head, *iter;
int init; int init;