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