diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 05ef2b7e12090e..3cf1d434d3ca71 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -2107,8 +2107,8 @@ void Initialize(Local target, env->SetMethod(target, "getaddrinfo", GetAddrInfo); env->SetMethod(target, "getnameinfo", GetNameInfo); - env->SetMethod(target, "isIPv6", IsIPv6); - env->SetMethod(target, "canonicalizeIP", CanonicalizeIP); + env->SetMethodNoSideEffect(target, "isIPv6", IsIPv6); + env->SetMethodNoSideEffect(target, "canonicalizeIP", CanonicalizeIP); env->SetMethod(target, "strerror", StrError); @@ -2165,7 +2165,7 @@ void Initialize(Local target, env->SetProtoMethod(channel_wrap, "querySoa", Query); env->SetProtoMethod(channel_wrap, "getHostByAddr", Query); - env->SetProtoMethod(channel_wrap, "getServers", GetServers); + env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers); env->SetProtoMethod(channel_wrap, "setServers", SetServers); env->SetProtoMethod(channel_wrap, "cancel", Cancel); diff --git a/src/env-inl.h b/src/env-inl.h index bbb80c6f7ae916..037f0659ed2ac7 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -675,17 +675,41 @@ inline void Environment::ThrowUVException(int errorno, inline v8::Local Environment::NewFunctionTemplate(v8::FunctionCallback callback, v8::Local signature, - v8::ConstructorBehavior behavior) { + v8::ConstructorBehavior behavior, + v8::SideEffectType side_effect_type) { v8::Local external = as_external(); return v8::FunctionTemplate::New(isolate(), callback, external, - signature, 0, behavior); + signature, 0, behavior, side_effect_type); } inline void Environment::SetMethod(v8::Local that, const char* name, v8::FunctionCallback callback) { v8::Local function = - NewFunctionTemplate(callback)->GetFunction(); + NewFunctionTemplate(callback, + v8::Local(), + // TODO(TimothyGu): Investigate if SetMethod is ever + // used for constructors. + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasSideEffect)->GetFunction(); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->Set(name_string, function); + function->SetName(name_string); // NODE_SET_METHOD() compatibility. +} + +inline void Environment::SetMethodNoSideEffect(v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local function = + NewFunctionTemplate(callback, + v8::Local(), + // TODO(TimothyGu): Investigate if SetMethod is ever + // used for constructors. + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasNoSideEffect)->GetFunction(); // kInternalized strings are created in the old space. const v8::NewStringType type = v8::NewStringType::kInternalized; v8::Local name_string = @@ -699,7 +723,24 @@ inline void Environment::SetProtoMethod(v8::Local that, v8::FunctionCallback callback) { v8::Local signature = v8::Signature::New(isolate(), that); v8::Local t = - NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow); + NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasSideEffect); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->PrototypeTemplate()->Set(name_string, t); + t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. +} + +inline void Environment::SetProtoMethodNoSideEffect( + v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local signature = v8::Signature::New(isolate(), that); + v8::Local t = + NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasNoSideEffect); // kInternalized strings are created in the old space. const v8::NewStringType type = v8::NewStringType::kInternalized; v8::Local name_string = @@ -711,7 +752,26 @@ inline void Environment::SetProtoMethod(v8::Local that, inline void Environment::SetTemplateMethod(v8::Local that, const char* name, v8::FunctionCallback callback) { - v8::Local t = NewFunctionTemplate(callback); + v8::Local t = + NewFunctionTemplate(callback, v8::Local(), + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasSideEffect); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->Set(name_string, t); + t->SetClassName(name_string); // NODE_SET_METHOD() compatibility. +} + +inline void Environment::SetTemplateMethodNoSideEffect( + v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local t = + NewFunctionTemplate(callback, v8::Local(), + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasNoSideEffect); // kInternalized strings are created in the old space. const v8::NewStringType type = v8::NewStringType::kInternalized; v8::Local name_string = diff --git a/src/env.h b/src/env.h index 786f0846f4ae1a..3febddea4c6a62 100644 --- a/src/env.h +++ b/src/env.h @@ -752,12 +752,15 @@ class Environment { v8::Local signature = v8::Local(), v8::ConstructorBehavior behavior = - v8::ConstructorBehavior::kAllow); + v8::ConstructorBehavior::kAllow, + v8::SideEffectType side_effect = + v8::SideEffectType::kHasSideEffect); // Convenience methods for NewFunctionTemplate(). inline void SetMethod(v8::Local that, const char* name, v8::FunctionCallback callback); + inline void SetProtoMethod(v8::Local that, const char* name, v8::FunctionCallback callback); @@ -765,6 +768,18 @@ class Environment { const char* name, v8::FunctionCallback callback); + // Safe variants denote the function has no side effects. + inline void SetMethodNoSideEffect(v8::Local that, + const char* name, + v8::FunctionCallback callback); + inline void SetProtoMethodNoSideEffect(v8::Local that, + const char* name, + v8::FunctionCallback callback); + inline void SetTemplateMethodNoSideEffect( + v8::Local that, + const char* name, + v8::FunctionCallback callback); + void BeforeExit(void (*cb)(void* arg), void* arg); void RunBeforeExitCallbacks(); void AtExit(void (*cb)(void* arg), void* arg); diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index 802029ac4f2e5a..fc12f32cd3b5af 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -289,7 +289,7 @@ void Initialize(Local target, Local unused, if (agent->IsWaitingForConnect()) env->SetMethod(target, "callAndPauseOnStart", CallAndPauseOnStart); env->SetMethod(target, "open", Open); - env->SetMethod(target, "url", Url); + env->SetMethodNoSideEffect(target, "url", Url); env->SetMethod(target, "asyncTaskScheduled", AsyncTaskScheduledWrapper); env->SetMethod(target, "asyncTaskCanceled", @@ -300,7 +300,7 @@ void Initialize(Local target, Local unused, InvokeAsyncTaskFnWithId<&Agent::AsyncTaskFinished>); env->SetMethod(target, "registerAsyncHook", RegisterAsyncHookWrapper); - env->SetMethod(target, "isEnabled", IsEnabled); + env->SetMethodNoSideEffect(target, "isEnabled", IsEnabled); auto conn_str = FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"); Local tmpl = diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 05daa2bb85ebe0..ab1950311ad631 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -789,11 +789,11 @@ void ModuleWrap::Initialize(Local target, env->SetProtoMethod(tpl, "link", Link); env->SetProtoMethod(tpl, "instantiate", Instantiate); env->SetProtoMethod(tpl, "evaluate", Evaluate); - env->SetProtoMethod(tpl, "namespace", Namespace); - env->SetProtoMethod(tpl, "getStatus", GetStatus); - env->SetProtoMethod(tpl, "getError", GetError); - env->SetProtoMethod(tpl, "getStaticDependencySpecifiers", - GetStaticDependencySpecifiers); + env->SetProtoMethodNoSideEffect(tpl, "namespace", Namespace); + env->SetProtoMethodNoSideEffect(tpl, "getStatus", GetStatus); + env->SetProtoMethodNoSideEffect(tpl, "getError", GetError); + env->SetProtoMethodNoSideEffect(tpl, "getStaticDependencySpecifiers", + GetStaticDependencySpecifiers); target->Set(FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"), tpl->GetFunction()); env->SetMethod(target, "resolve", Resolve); diff --git a/src/node.cc b/src/node.cc index 6cf5f2ad84b1db..660439371babb3 100644 --- a/src/node.cc +++ b/src/node.cc @@ -159,6 +159,7 @@ using v8::Promise; using v8::PropertyCallbackInfo; using v8::ScriptOrigin; using v8::SealHandleScope; +using v8::SideEffectType; using v8::String; using v8::TryCatch; using v8::Undefined; @@ -1947,7 +1948,10 @@ void SetupProcessObject(Environment* env, title_string, ProcessTitleGetter, env->is_main_thread() ? ProcessTitleSetter : nullptr, - env->as_external()).FromJust()); + env->as_external(), + v8::DEFAULT, + v8::None, + SideEffectType::kHasNoSideEffect).FromJust()); // process.version READONLY_PROPERTY(process, @@ -2252,17 +2256,17 @@ void SetupProcessObject(Environment* env, env->SetMethod(process, "_getActiveHandles", GetActiveHandles); env->SetMethod(process, "_kill", Kill); - env->SetMethod(process, "cwd", Cwd); + env->SetMethodNoSideEffect(process, "cwd", Cwd); env->SetMethod(process, "dlopen", DLOpen); env->SetMethod(process, "reallyExit", Exit); - env->SetMethod(process, "uptime", Uptime); + env->SetMethodNoSideEffect(process, "uptime", Uptime); #if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__) - env->SetMethod(process, "getuid", GetUid); - env->SetMethod(process, "geteuid", GetEUid); - env->SetMethod(process, "getgid", GetGid); - env->SetMethod(process, "getegid", GetEGid); - env->SetMethod(process, "getgroups", GetGroups); + env->SetMethodNoSideEffect(process, "getuid", GetUid); + env->SetMethodNoSideEffect(process, "geteuid", GetEUid); + env->SetMethodNoSideEffect(process, "getgid", GetGid); + env->SetMethodNoSideEffect(process, "getegid", GetEGid); + env->SetMethodNoSideEffect(process, "getgroups", GetGroups); #endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__) } diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 9465145ac37eb9..9eb351b443a111 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -1083,12 +1083,12 @@ void SetupBufferJS(const FunctionCallbackInfo& args) { Local proto = args[0].As(); env->set_buffer_prototype_object(proto); - env->SetMethod(proto, "asciiSlice", StringSlice); - env->SetMethod(proto, "base64Slice", StringSlice); - env->SetMethod(proto, "latin1Slice", StringSlice); - env->SetMethod(proto, "hexSlice", StringSlice); - env->SetMethod(proto, "ucs2Slice", StringSlice); - env->SetMethod(proto, "utf8Slice", StringSlice); + env->SetMethodNoSideEffect(proto, "asciiSlice", StringSlice); + env->SetMethodNoSideEffect(proto, "base64Slice", StringSlice); + env->SetMethodNoSideEffect(proto, "latin1Slice", StringSlice); + env->SetMethodNoSideEffect(proto, "hexSlice", StringSlice); + env->SetMethodNoSideEffect(proto, "ucs2Slice", StringSlice); + env->SetMethodNoSideEffect(proto, "utf8Slice", StringSlice); env->SetMethod(proto, "asciiWrite", StringWrite); env->SetMethod(proto, "base64Write", StringWrite); @@ -1116,22 +1116,22 @@ void Initialize(Local target, Environment* env = Environment::GetCurrent(context); env->SetMethod(target, "setupBufferJS", SetupBufferJS); - env->SetMethod(target, "createFromString", CreateFromString); + env->SetMethodNoSideEffect(target, "createFromString", CreateFromString); - env->SetMethod(target, "byteLengthUtf8", ByteLengthUtf8); + env->SetMethodNoSideEffect(target, "byteLengthUtf8", ByteLengthUtf8); env->SetMethod(target, "copy", Copy); - env->SetMethod(target, "compare", Compare); - env->SetMethod(target, "compareOffset", CompareOffset); + env->SetMethodNoSideEffect(target, "compare", Compare); + env->SetMethodNoSideEffect(target, "compareOffset", CompareOffset); env->SetMethod(target, "fill", Fill); - env->SetMethod(target, "indexOfBuffer", IndexOfBuffer); - env->SetMethod(target, "indexOfNumber", IndexOfNumber); - env->SetMethod(target, "indexOfString", IndexOfString); + env->SetMethodNoSideEffect(target, "indexOfBuffer", IndexOfBuffer); + env->SetMethodNoSideEffect(target, "indexOfNumber", IndexOfNumber); + env->SetMethodNoSideEffect(target, "indexOfString", IndexOfString); env->SetMethod(target, "swap16", Swap16); env->SetMethod(target, "swap32", Swap32); env->SetMethod(target, "swap64", Swap64); - env->SetMethod(target, "encodeUtf8String", EncodeUtf8String); + env->SetMethodNoSideEffect(target, "encodeUtf8String", EncodeUtf8String); target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "kMaxLength"), diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 8b152e65c3335c..02f2aad13700f0 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -63,6 +63,7 @@ namespace crypto { using v8::Array; using v8::Boolean; +using v8::ConstructorBehavior; using v8::Context; using v8::DontDelete; using v8::EscapableHandleScope; @@ -84,6 +85,7 @@ using v8::Null; using v8::Object; using v8::PropertyAttribute; using v8::ReadOnly; +using v8::SideEffectType; using v8::Signature; using v8::String; using v8::Uint32; @@ -346,12 +348,12 @@ void SecureContext::Initialize(Environment* env, Local target) { #ifndef OPENSSL_NO_ENGINE env->SetProtoMethod(t, "setClientCertEngine", SetClientCertEngine); #endif // !OPENSSL_NO_ENGINE - env->SetProtoMethod(t, "getTicketKeys", GetTicketKeys); + env->SetProtoMethodNoSideEffect(t, "getTicketKeys", GetTicketKeys); env->SetProtoMethod(t, "setTicketKeys", SetTicketKeys); env->SetProtoMethod(t, "setFreeListLength", SetFreeListLength); env->SetProtoMethod(t, "enableTicketKeyCallback", EnableTicketKeyCallback); - env->SetProtoMethod(t, "getCertificate", GetCertificate); - env->SetProtoMethod(t, "getIssuer", GetCertificate); + env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate); + env->SetProtoMethodNoSideEffect(t, "getIssuer", GetCertificate); t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kTicketKeyReturnIndex"), Integer::NewFromUnsigned(env->isolate(), kTicketKeyReturnIndex)); @@ -1367,32 +1369,34 @@ template void SSLWrap::AddMethods(Environment* env, Local t) { HandleScope scope(env->isolate()); - env->SetProtoMethod(t, "getPeerCertificate", GetPeerCertificate); - env->SetProtoMethod(t, "getFinished", GetFinished); - env->SetProtoMethod(t, "getPeerFinished", GetPeerFinished); - env->SetProtoMethod(t, "getSession", GetSession); + env->SetProtoMethodNoSideEffect(t, "getPeerCertificate", GetPeerCertificate); + env->SetProtoMethodNoSideEffect(t, "getFinished", GetFinished); + env->SetProtoMethodNoSideEffect(t, "getPeerFinished", GetPeerFinished); + env->SetProtoMethodNoSideEffect(t, "getSession", GetSession); env->SetProtoMethod(t, "setSession", SetSession); env->SetProtoMethod(t, "loadSession", LoadSession); - env->SetProtoMethod(t, "isSessionReused", IsSessionReused); - env->SetProtoMethod(t, "isInitFinished", IsInitFinished); - env->SetProtoMethod(t, "verifyError", VerifyError); - env->SetProtoMethod(t, "getCurrentCipher", GetCurrentCipher); + env->SetProtoMethodNoSideEffect(t, "isSessionReused", IsSessionReused); + env->SetProtoMethodNoSideEffect(t, "isInitFinished", IsInitFinished); + env->SetProtoMethodNoSideEffect(t, "verifyError", VerifyError); + env->SetProtoMethodNoSideEffect(t, "getCurrentCipher", GetCurrentCipher); env->SetProtoMethod(t, "endParser", EndParser); env->SetProtoMethod(t, "certCbDone", CertCbDone); env->SetProtoMethod(t, "renegotiate", Renegotiate); env->SetProtoMethod(t, "shutdownSSL", Shutdown); - env->SetProtoMethod(t, "getTLSTicket", GetTLSTicket); + env->SetProtoMethodNoSideEffect(t, "getTLSTicket", GetTLSTicket); env->SetProtoMethod(t, "newSessionDone", NewSessionDone); env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse); env->SetProtoMethod(t, "requestOCSP", RequestOCSP); - env->SetProtoMethod(t, "getEphemeralKeyInfo", GetEphemeralKeyInfo); - env->SetProtoMethod(t, "getProtocol", GetProtocol); + env->SetProtoMethodNoSideEffect(t, "getEphemeralKeyInfo", + GetEphemeralKeyInfo); + env->SetProtoMethodNoSideEffect(t, "getProtocol", GetProtocol); #ifdef SSL_set_max_send_fragment env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment); #endif // SSL_set_max_send_fragment - env->SetProtoMethod(t, "getALPNNegotiatedProtocol", GetALPNNegotiatedProto); + env->SetProtoMethodNoSideEffect(t, "getALPNNegotiatedProtocol", + GetALPNNegotiatedProto); env->SetProtoMethod(t, "setALPNProtocols", SetALPNProtocols); } @@ -2563,7 +2567,7 @@ void CipherBase::Initialize(Environment* env, Local target) { env->SetProtoMethod(t, "update", Update); env->SetProtoMethod(t, "final", Final); env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding); - env->SetProtoMethod(t, "getAuthTag", GetAuthTag); + env->SetProtoMethodNoSideEffect(t, "getAuthTag", GetAuthTag); env->SetProtoMethod(t, "setAuthTag", SetAuthTag); env->SetProtoMethod(t, "setAAD", SetAAD); @@ -3898,10 +3902,10 @@ void DiffieHellman::Initialize(Environment* env, Local target) { env->SetProtoMethod(t, "generateKeys", GenerateKeys); env->SetProtoMethod(t, "computeSecret", ComputeSecret); - env->SetProtoMethod(t, "getPrime", GetPrime); - env->SetProtoMethod(t, "getGenerator", GetGenerator); - env->SetProtoMethod(t, "getPublicKey", GetPublicKey); - env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey); + env->SetProtoMethodNoSideEffect(t, "getPrime", GetPrime); + env->SetProtoMethodNoSideEffect(t, "getGenerator", GetGenerator); + env->SetProtoMethodNoSideEffect(t, "getPublicKey", GetPublicKey); + env->SetProtoMethodNoSideEffect(t, "getPrivateKey", GetPrivateKey); env->SetProtoMethod(t, "setPublicKey", SetPublicKey); env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey); @@ -3909,7 +3913,11 @@ void DiffieHellman::Initialize(Environment* env, Local target) { FunctionTemplate::New(env->isolate(), DiffieHellman::VerifyErrorGetter, env->as_external(), - Signature::New(env->isolate(), t)); + Signature::New(env->isolate(), t), + /* length */ 0, + // TODO(TimothyGu): should be deny + ConstructorBehavior::kAllow, + SideEffectType::kHasNoSideEffect); t->InstanceTemplate()->SetAccessorProperty( env->verify_error_string(), @@ -3925,16 +3933,20 @@ void DiffieHellman::Initialize(Environment* env, Local target) { env->SetProtoMethod(t2, "generateKeys", GenerateKeys); env->SetProtoMethod(t2, "computeSecret", ComputeSecret); - env->SetProtoMethod(t2, "getPrime", GetPrime); - env->SetProtoMethod(t2, "getGenerator", GetGenerator); - env->SetProtoMethod(t2, "getPublicKey", GetPublicKey); - env->SetProtoMethod(t2, "getPrivateKey", GetPrivateKey); + env->SetProtoMethodNoSideEffect(t2, "getPrime", GetPrime); + env->SetProtoMethodNoSideEffect(t2, "getGenerator", GetGenerator); + env->SetProtoMethodNoSideEffect(t2, "getPublicKey", GetPublicKey); + env->SetProtoMethodNoSideEffect(t2, "getPrivateKey", GetPrivateKey); Local verify_error_getter_templ2 = FunctionTemplate::New(env->isolate(), DiffieHellman::VerifyErrorGetter, env->as_external(), - Signature::New(env->isolate(), t2)); + Signature::New(env->isolate(), t2), + /* length */ 0, + // TODO(TimothyGu): should be deny + ConstructorBehavior::kAllow, + SideEffectType::kHasNoSideEffect); t2->InstanceTemplate()->SetAccessorProperty( env->verify_error_string(), @@ -4286,8 +4298,8 @@ void ECDH::Initialize(Environment* env, Local target) { env->SetProtoMethod(t, "generateKeys", GenerateKeys); env->SetProtoMethod(t, "computeSecret", ComputeSecret); - env->SetProtoMethod(t, "getPublicKey", GetPublicKey); - env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey); + env->SetProtoMethodNoSideEffect(t, "getPublicKey", GetPublicKey); + env->SetProtoMethodNoSideEffect(t, "getPrivateKey", GetPrivateKey); env->SetProtoMethod(t, "setPublicKey", SetPublicKey); env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey); @@ -5178,27 +5190,27 @@ void Initialize(Local target, Sign::Initialize(env, target); Verify::Initialize(env, target); - env->SetMethod(target, "certVerifySpkac", VerifySpkac); - env->SetMethod(target, "certExportPublicKey", ExportPublicKey); - env->SetMethod(target, "certExportChallenge", ExportChallenge); + env->SetMethodNoSideEffect(target, "certVerifySpkac", VerifySpkac); + env->SetMethodNoSideEffect(target, "certExportPublicKey", ExportPublicKey); + env->SetMethodNoSideEffect(target, "certExportChallenge", ExportChallenge); - env->SetMethod(target, "ECDHConvertKey", ConvertKey); + env->SetMethodNoSideEffect(target, "ECDHConvertKey", ConvertKey); #ifndef OPENSSL_NO_ENGINE env->SetMethod(target, "setEngine", SetEngine); #endif // !OPENSSL_NO_ENGINE #ifdef NODE_FIPS_MODE - env->SetMethod(target, "getFipsCrypto", GetFipsCrypto); + env->SetMethodNoSideEffect(target, "getFipsCrypto", GetFipsCrypto); env->SetMethod(target, "setFipsCrypto", SetFipsCrypto); #endif env->SetMethod(target, "pbkdf2", PBKDF2); env->SetMethod(target, "randomBytes", RandomBytes); - env->SetMethod(target, "timingSafeEqual", TimingSafeEqual); - env->SetMethod(target, "getSSLCiphers", GetSSLCiphers); - env->SetMethod(target, "getCiphers", GetCiphers); - env->SetMethod(target, "getHashes", GetHashes); - env->SetMethod(target, "getCurves", GetCurves); + env->SetMethodNoSideEffect(target, "timingSafeEqual", TimingSafeEqual); + env->SetMethodNoSideEffect(target, "getSSLCiphers", GetSSLCiphers); + env->SetMethodNoSideEffect(target, "getCiphers", GetCiphers); + env->SetMethodNoSideEffect(target, "getHashes", GetHashes); + env->SetMethodNoSideEffect(target, "getCurves", GetCurves); env->SetMethod(target, "publicEncrypt", PublicKeyCipher::Cipher target, Local context) { Environment* env = Environment::GetCurrent(context); -#define V(type) env->SetMethod(target, \ - "is" #type, \ - Is##type); +#define V(type) env->SetMethodNoSideEffect(target, \ + "is" #type, \ + Is##type); VALUE_METHOD_MAP(V) #undef V - env->SetMethod(target, "isAnyArrayBuffer", IsAnyArrayBuffer); + env->SetMethodNoSideEffect(target, "isAnyArrayBuffer", IsAnyArrayBuffer); } } // anonymous namespace diff --git a/src/node_url.cc b/src/node_url.cc index 82c093d516bc4a..1cdb179ed254f5 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -2334,10 +2334,10 @@ static void Initialize(Local target, void* priv) { Environment* env = Environment::GetCurrent(context); env->SetMethod(target, "parse", Parse); - env->SetMethod(target, "encodeAuth", EncodeAuthSet); - env->SetMethod(target, "toUSVString", ToUSVString); - env->SetMethod(target, "domainToASCII", DomainToASCII); - env->SetMethod(target, "domainToUnicode", DomainToUnicode); + env->SetMethodNoSideEffect(target, "encodeAuth", EncodeAuthSet); + env->SetMethodNoSideEffect(target, "toUSVString", ToUSVString); + env->SetMethodNoSideEffect(target, "domainToASCII", DomainToASCII); + env->SetMethodNoSideEffect(target, "domainToUnicode", DomainToUnicode); env->SetMethod(target, "setURLConstructor", SetURLConstructor); #define XX(name, _) NODE_DEFINE_CONSTANT(target, name); diff --git a/src/node_util.cc b/src/node_util.cc index 2db68586459ab2..724bb3603cfddd 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -212,18 +212,19 @@ void Initialize(Local target, V(kRejected); #undef V - env->SetMethod(target, "getHiddenValue", GetHiddenValue); + env->SetMethodNoSideEffect(target, "getHiddenValue", GetHiddenValue); env->SetMethod(target, "setHiddenValue", SetHiddenValue); - env->SetMethod(target, "getPromiseDetails", GetPromiseDetails); - env->SetMethod(target, "getProxyDetails", GetProxyDetails); - env->SetMethod(target, "safeToString", SafeToString); - env->SetMethod(target, "previewEntries", PreviewEntries); + env->SetMethodNoSideEffect(target, "getPromiseDetails", GetPromiseDetails); + env->SetMethodNoSideEffect(target, "getProxyDetails", GetProxyDetails); + env->SetMethodNoSideEffect(target, "safeToString", SafeToString); + env->SetMethodNoSideEffect(target, "previewEntries", PreviewEntries); env->SetMethod(target, "startSigintWatchdog", StartSigintWatchdog); env->SetMethod(target, "stopSigintWatchdog", StopSigintWatchdog); - env->SetMethod(target, "watchdogHasPendingSigint", WatchdogHasPendingSigint); + env->SetMethodNoSideEffect(target, "watchdogHasPendingSigint", + WatchdogHasPendingSigint); - env->SetMethod(target, "createPromise", CreatePromise); + env->SetMethodNoSideEffect(target, "createPromise", CreatePromise); env->SetMethod(target, "promiseResolve", PromiseResolve); env->SetMethod(target, "promiseReject", PromiseReject); diff --git a/src/node_v8.cc b/src/node_v8.cc index d546eeba93f4d9..fb0a9fea1e5d27 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -122,7 +122,8 @@ void Initialize(Local target, Local context) { Environment* env = Environment::GetCurrent(context); - env->SetMethod(target, "cachedDataVersionTag", CachedDataVersionTag); + env->SetMethodNoSideEffect(target, "cachedDataVersionTag", + CachedDataVersionTag); env->SetMethod(target, "updateHeapStatisticsArrayBuffer", diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h index 4509825a60d184..bd451031737be1 100644 --- a/src/stream_base-inl.h +++ b/src/stream_base-inl.h @@ -277,29 +277,30 @@ void StreamBase::AddMethods(Environment* env, Local signature = Signature::New(env->isolate(), t); + // TODO(TimothyGu): None of these should have ConstructorBehavior::kAllow. Local get_fd_templ = - FunctionTemplate::New(env->isolate(), - GetFD, - env->as_external(), - signature); + env->NewFunctionTemplate(GetFD, + signature, + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasNoSideEffect); Local get_external_templ = - FunctionTemplate::New(env->isolate(), - GetExternal, - env->as_external(), - signature); + env->NewFunctionTemplate(GetExternal, + signature, + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasNoSideEffect); Local get_bytes_read_templ = - FunctionTemplate::New(env->isolate(), - GetBytesRead, - env->as_external(), - signature); + env->NewFunctionTemplate(GetBytesRead, + signature, + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasNoSideEffect); Local get_bytes_written_templ = - FunctionTemplate::New(env->isolate(), - GetBytesWritten, - env->as_external(), - signature); + env->NewFunctionTemplate(GetBytesWritten, + signature, + v8::ConstructorBehavior::kAllow, + v8::SideEffectType::kHasNoSideEffect); t->PrototypeTemplate()->SetAccessorProperty(env->fd_string(), get_fd_templ, diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc index 175b32879bbb83..83b6e34d630e73 100644 --- a/src/tty_wrap.cc +++ b/src/tty_wrap.cc @@ -58,15 +58,15 @@ void TTYWrap::Initialize(Local target, env->SetProtoMethod(t, "close", HandleWrap::Close); env->SetProtoMethod(t, "unref", HandleWrap::Unref); env->SetProtoMethod(t, "ref", HandleWrap::Ref); - env->SetProtoMethod(t, "hasRef", HandleWrap::HasRef); + env->SetProtoMethodNoSideEffect(t, "hasRef", HandleWrap::HasRef); LibuvStreamWrap::AddMethods(env, t); - env->SetProtoMethod(t, "getWindowSize", TTYWrap::GetWindowSize); + env->SetProtoMethodNoSideEffect(t, "getWindowSize", TTYWrap::GetWindowSize); env->SetProtoMethod(t, "setRawMode", SetRawMode); - env->SetMethod(target, "isTTY", IsTTY); - env->SetMethod(target, "guessHandleType", GuessHandleType); + env->SetMethodNoSideEffect(target, "isTTY", IsTTY); + env->SetMethodNoSideEffect(target, "guessHandleType", GuessHandleType); target->Set(ttyString, t->GetFunction()); env->set_tty_constructor_template(t);