@@ -23,12 +23,16 @@ void napi_clear_last_error(napi_env env);
23
23
24
24
class napi_env__ {
25
25
public:
26
- explicit napi_env__ (v8::Isolate* _isolate): isolate(_isolate), last_error() {}
26
+ explicit napi_env__ (v8::Isolate* _isolate): isolate(_isolate),
27
+ has_instance_available(true ), last_error() {}
27
28
~napi_env__ () {
28
29
last_exception.Reset ();
30
+ has_instance.Reset ();
29
31
}
30
32
v8::Isolate* isolate;
31
33
v8::Persistent<v8::Value> last_exception;
34
+ v8::Persistent<v8::Value> has_instance;
35
+ bool has_instance_available;
32
36
napi_extended_error_info last_error;
33
37
};
34
38
@@ -2156,28 +2160,43 @@ napi_status napi_instanceof(napi_env env,
2156
2160
return napi_set_last_error (env, napi_function_expected);
2157
2161
}
2158
2162
2159
- napi_value value, js_result;
2160
- napi_status status;
2161
- napi_valuetype value_type;
2163
+ if (env->has_instance_available ) {
2164
+ napi_value value, js_result, has_instance = nullptr ;
2165
+ napi_status status;
2166
+ napi_valuetype value_type;
2162
2167
2163
- // Get "Symbol" from the global object
2164
- status = napi_get_global (env, &value);
2165
- if (status != napi_ok) return status;
2166
- status = napi_get_named_property (env, value, " Symbol" , &value);
2167
- if (status != napi_ok) return status;
2168
- status = napi_typeof (env, value, &value_type);
2169
- if (status != napi_ok) return status;
2168
+ // Get "Symbol" from the global object
2169
+ if (env->has_instance .IsEmpty ()) {
2170
+ status = napi_get_global (env, &value);
2171
+ if (status != napi_ok) return status;
2172
+ status = napi_get_named_property (env, value, " Symbol" , &value);
2173
+ if (status != napi_ok) return status;
2174
+ status = napi_typeof (env, value, &value_type);
2175
+ if (status != napi_ok) return status;
2170
2176
2171
- // Get "hasInstance" from Symbol
2172
- if (value_type == napi_function) {
2173
- status = napi_get_named_property (env, value, " hasInstance" , &value);
2174
- if (status != napi_ok) return status;
2175
- status = napi_typeof (env, value, &value_type);
2176
- if (status != napi_ok) return status;
2177
+ // Get "hasInstance" from Symbol
2178
+ if (value_type == napi_function) {
2179
+ status = napi_get_named_property (env, value, " hasInstance" , &value);
2180
+ if (status != napi_ok) return status;
2181
+ status = napi_typeof (env, value, &value_type);
2182
+ if (status != napi_ok) return status;
2183
+
2184
+ // Store Symbol.hasInstance in a global persistent reference
2185
+ if (value_type == napi_symbol) {
2186
+ env->has_instance .Reset (env->isolate ,
2187
+ v8impl::V8LocalValueFromJsValue (value));
2188
+ if (status != napi_ok) return status;
2189
+ has_instance = value;
2190
+ }
2191
+ }
2192
+ } else {
2193
+ has_instance = v8impl::JsValueFromV8LocalValue (
2194
+ v8::Local<v8::Value>::New (env->isolate , env->has_instance ));
2195
+ if (status != napi_ok) return status;
2196
+ }
2177
2197
2178
- // Retrieve the function at the Symbol(hasInstance) key of the constructor
2179
- if (value_type == napi_symbol) {
2180
- status = napi_get_property (env, constructor, value, &value);
2198
+ if (has_instance) {
2199
+ status = napi_get_property (env, constructor, has_instance, &value);
2181
2200
if (status != napi_ok) return status;
2182
2201
status = napi_typeof (env, value, &value_type);
2183
2202
if (status != napi_ok) return status;
@@ -2191,6 +2210,8 @@ napi_status napi_instanceof(napi_env env,
2191
2210
return napi_get_value_bool (env, js_result, result);
2192
2211
}
2193
2212
}
2213
+
2214
+ env->has_instance_available = false ;
2194
2215
}
2195
2216
2196
2217
// If running constructor[Symbol.hasInstance](object) did not work, we perform
0 commit comments