@@ -23,12 +23,16 @@ void napi_clear_last_error(napi_env env);
2323
2424class napi_env__ {
2525 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() {}
2728 ~napi_env__ () {
2829 last_exception.Reset ();
30+ has_instance.Reset ();
2931 }
3032 v8::Isolate* isolate;
3133 v8::Persistent<v8::Value> last_exception;
34+ v8::Persistent<v8::Value> has_instance;
35+ bool has_instance_available;
3236 napi_extended_error_info last_error;
3337};
3438
@@ -2149,28 +2153,43 @@ napi_status napi_instanceof(napi_env env,
21492153 return napi_set_last_error (env, napi_function_expected);
21502154 }
21512155
2152- napi_value value, js_result;
2153- napi_status status;
2154- napi_valuetype value_type;
2156+ if (env->has_instance_available ) {
2157+ napi_value value, js_result, has_instance = nullptr ;
2158+ napi_status status;
2159+ napi_valuetype value_type;
21552160
2156- // Get "Symbol" from the global object
2157- status = napi_get_global (env, &value);
2158- if (status != napi_ok) return status;
2159- status = napi_get_named_property (env, value, " Symbol" , &value);
2160- if (status != napi_ok) return status;
2161- status = napi_typeof (env, value, &value_type);
2162- if (status != napi_ok) return status;
2161+ // Get "Symbol" from the global object
2162+ if (env->has_instance .IsEmpty ()) {
2163+ status = napi_get_global (env, &value);
2164+ if (status != napi_ok) return status;
2165+ status = napi_get_named_property (env, value, " Symbol" , &value);
2166+ if (status != napi_ok) return status;
2167+ status = napi_typeof (env, value, &value_type);
2168+ if (status != napi_ok) return status;
21632169
2164- // Get "hasInstance" from Symbol
2165- if (value_type == napi_function) {
2166- status = napi_get_named_property (env, value, " hasInstance" , &value);
2167- if (status != napi_ok) return status;
2168- status = napi_typeof (env, value, &value_type);
2169- if (status != napi_ok) return status;
2170+ // Get "hasInstance" from Symbol
2171+ if (value_type == napi_function) {
2172+ status = napi_get_named_property (env, value, " hasInstance" , &value);
2173+ if (status != napi_ok) return status;
2174+ status = napi_typeof (env, value, &value_type);
2175+ if (status != napi_ok) return status;
2176+
2177+ // Store Symbol.hasInstance in a global persistent reference
2178+ if (value_type == napi_symbol) {
2179+ env->has_instance .Reset (env->isolate ,
2180+ v8impl::V8LocalValueFromJsValue (value));
2181+ if (status != napi_ok) return status;
2182+ has_instance = value;
2183+ }
2184+ }
2185+ } else {
2186+ has_instance = v8impl::JsValueFromV8LocalValue (
2187+ v8::Local<v8::Value>::New (env->isolate , env->has_instance ));
2188+ if (status != napi_ok) return status;
2189+ }
21702190
2171- // Retrieve the function at the Symbol(hasInstance) key of the constructor
2172- if (value_type == napi_symbol) {
2173- status = napi_get_property (env, constructor, value, &value);
2191+ if (has_instance) {
2192+ status = napi_get_property (env, constructor, has_instance, &value);
21742193 if (status != napi_ok) return status;
21752194 status = napi_typeof (env, value, &value_type);
21762195 if (status != napi_ok) return status;
@@ -2184,6 +2203,8 @@ napi_status napi_instanceof(napi_env env,
21842203 return napi_get_value_bool (env, js_result, result);
21852204 }
21862205 }
2206+
2207+ env->has_instance_available = false ;
21872208 }
21882209
21892210 // If running constructor[Symbol.hasInstance](object) did not work, we perform
0 commit comments