@@ -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
@@ -2129,28 +2133,44 @@ napi_status napi_instanceof(napi_env env,
21292133 return napi_set_last_error (env, napi_function_expected);
21302134 }
21312135
2132- napi_value value, js_result;
2133- napi_status status;
2134- napi_valuetype value_type;
2136+ if (env->has_instance_available ) {
2137+ napi_value value, js_result, has_instance = nullptr ;
2138+ napi_status status;
2139+ napi_valuetype value_type;
21352140
2136- // Get "Symbol" from the global object
2137- status = napi_get_global (env, &value);
2138- if (status != napi_ok) return status;
2139- status = napi_get_named_property (env, value, " Symbol" , &value);
2140- if (status != napi_ok) return status;
2141- status = napi_typeof (env, value, &value_type);
2142- if (status != napi_ok) return status;
2141+ if (env->has_instance .IsEmpty ()) {
21432142
2144- // Get "hasInstance" from Symbol
2145- if (value_type == napi_function) {
2146- status = napi_get_named_property (env, value, " hasInstance" , &value);
2147- if (status != napi_ok) return status;
2148- status = napi_typeof (env, value, &value_type);
2149- if (status != napi_ok) return status;
2143+ // Get "Symbol" from the global object
2144+ status = napi_get_global (env, &value);
2145+ if (status != napi_ok) return status;
2146+ status = napi_get_named_property (env, value, " Symbol" , &value);
2147+ if (status != napi_ok) return status;
2148+ status = napi_typeof (env, value, &value_type);
2149+ if (status != napi_ok) return status;
21502150
2151- // Retrieve the function at the Symbol(hasInstance) key of the constructor
2152- if (value_type == napi_symbol) {
2153- status = napi_get_property (env, constructor, value, &value);
2151+ // Get "hasInstance" from Symbol
2152+ if (value_type == napi_function) {
2153+ status = napi_get_named_property (env, value, " hasInstance" , &value);
2154+ if (status != napi_ok) return status;
2155+ status = napi_typeof (env, value, &value_type);
2156+ if (status != napi_ok) return status;
2157+
2158+ // Store Symbol.hasInstance in a global persistent reference
2159+ if (value_type == napi_symbol) {
2160+ env->has_instance .Reset (env->isolate ,
2161+ v8impl::V8LocalValueFromJsValue (value));
2162+ if (status != napi_ok) return status;
2163+ has_instance = value;
2164+ }
2165+ }
2166+ } else {
2167+ has_instance = v8impl::JsValueFromV8LocalValue (
2168+ v8::Local<v8::Value>::New (env->isolate , env->has_instance ));
2169+ if (status != napi_ok) return status;
2170+ }
2171+
2172+ if (has_instance) {
2173+ status = napi_get_property (env, constructor, has_instance, &value);
21542174 if (status != napi_ok) return status;
21552175 status = napi_typeof (env, value, &value_type);
21562176 if (status != napi_ok) return status;
@@ -2164,6 +2184,8 @@ napi_status napi_instanceof(napi_env env,
21642184 return napi_get_value_bool (env, js_result, result);
21652185 }
21662186 }
2187+
2188+ env->has_instance_available = false ;
21672189 }
21682190
21692191 // If running constructor[Symbol.hasInstance](object) did not work, we perform
0 commit comments