Skip to content

Commit

Permalink
src: start annotating native code side effect
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyGu committed Jun 22, 2018
1 parent 2f1a23e commit 7132853
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 85 deletions.
10 changes: 7 additions & 3 deletions src/cares_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ using v8::Integer;
using v8::Local;
using v8::Null;
using v8::Object;
using v8::SideEffectType;
using v8::String;
using v8::Value;

Expand Down Expand Up @@ -2107,8 +2108,10 @@ void Initialize(Local<Object> target,

env->SetMethod(target, "getaddrinfo", GetAddrInfo);
env->SetMethod(target, "getnameinfo", GetNameInfo);
env->SetMethod(target, "isIPv6", IsIPv6);
env->SetMethod(target, "canonicalizeIP", CanonicalizeIP);
env->SetMethod(target, "isIPv6", IsIPv6,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "canonicalizeIP", CanonicalizeIP,
SideEffectType::kHasNoSideEffect);

env->SetMethod(target, "strerror", StrError);

Expand Down Expand Up @@ -2165,7 +2168,8 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(channel_wrap, "querySoa", Query<QuerySoaWrap>);
env->SetProtoMethod(channel_wrap, "getHostByAddr", Query<GetHostByAddrWrap>);

env->SetProtoMethod(channel_wrap, "getServers", GetServers);
env->SetProtoMethod(channel_wrap, "getServers", GetServers,
SideEffectType::kHasNoSideEffect);
env->SetProtoMethod(channel_wrap, "setServers", SetServers);
env->SetProtoMethod(channel_wrap, "cancel", Cancel);

Expand Down
33 changes: 23 additions & 10 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,17 +675,24 @@ inline void Environment::ThrowUVException(int errorno,
inline v8::Local<v8::FunctionTemplate>
Environment::NewFunctionTemplate(v8::FunctionCallback callback,
v8::Local<v8::Signature> signature,
v8::ConstructorBehavior behavior) {
v8::ConstructorBehavior behavior,
v8::SideEffectType side_effect_type) {
v8::Local<v8::External> 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<v8::Object> that,
const char* name,
v8::FunctionCallback callback) {
v8::FunctionCallback callback,
v8::SideEffectType side_effect_type) {
v8::Local<v8::Function> function =
NewFunctionTemplate(callback)->GetFunction();
NewFunctionTemplate(callback,
v8::Local<v8::Signature>(),
// TODO(TimothyGu): Investigate if SetMethod is ever
// used for constructors.
v8::ConstructorBehavior::kAllow,
side_effect_type)->GetFunction();
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
v8::Local<v8::String> name_string =
Expand All @@ -696,10 +703,12 @@ inline void Environment::SetMethod(v8::Local<v8::Object> that,

inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback) {
v8::FunctionCallback callback,
v8::SideEffectType side_effect_type) {
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
v8::Local<v8::FunctionTemplate> t =
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow);
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
side_effect_type);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
v8::Local<v8::String> name_string =
Expand All @@ -708,10 +717,14 @@ inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility.
}

inline void Environment::SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback) {
v8::Local<v8::FunctionTemplate> t = NewFunctionTemplate(callback);
inline void Environment::SetTemplateMethod(
v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback,
v8::SideEffectType side_effect_type) {
v8::Local<v8::FunctionTemplate> t =
NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
v8::ConstructorBehavior::kAllow, side_effect_type);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
v8::Local<v8::String> name_string =
Expand Down
16 changes: 12 additions & 4 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -752,18 +752,26 @@ class Environment {
v8::Local<v8::Signature> signature =
v8::Local<v8::Signature>(),
v8::ConstructorBehavior behavior =
v8::ConstructorBehavior::kAllow);
v8::ConstructorBehavior::kAllow,
v8::SideEffectType side_effect_type =
v8::SideEffectType::kHasSideEffect);

// Convenience methods for NewFunctionTemplate().
inline void SetMethod(v8::Local<v8::Object> that,
const char* name,
v8::FunctionCallback callback);
v8::FunctionCallback callback,
v8::SideEffectType side_effect_type =
v8::SideEffectType::kHasSideEffect);
inline void SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback);
v8::FunctionCallback callback,
v8::SideEffectType side_effect_type =
v8::SideEffectType::kHasSideEffect);
inline void SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback);
v8::FunctionCallback callback,
v8::SideEffectType side_effect_type =
v8::SideEffectType::kHasSideEffect);

void BeforeExit(void (*cb)(void* arg), void* arg);
void RunBeforeExitCallbacks();
Expand Down
7 changes: 5 additions & 2 deletions src/inspector_js_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ using v8::Local;
using v8::MaybeLocal;
using v8::NewStringType;
using v8::Object;
using v8::SideEffectType;
using v8::String;
using v8::Value;

Expand Down Expand Up @@ -289,7 +290,8 @@ void Initialize(Local<Object> target, Local<Value> unused,
if (agent->IsWaitingForConnect())
env->SetMethod(target, "callAndPauseOnStart", CallAndPauseOnStart);
env->SetMethod(target, "open", Open);
env->SetMethod(target, "url", Url);
env->SetMethod(target, "url", Url,
SideEffectType::kHasNoSideEffect);

env->SetMethod(target, "asyncTaskScheduled", AsyncTaskScheduledWrapper);
env->SetMethod(target, "asyncTaskCanceled",
Expand All @@ -300,7 +302,8 @@ void Initialize(Local<Object> target, Local<Value> unused,
InvokeAsyncTaskFnWithId<&Agent::AsyncTaskFinished>);

env->SetMethod(target, "registerAsyncHook", RegisterAsyncHookWrapper);
env->SetMethod(target, "isEnabled", IsEnabled);
env->SetMethod(target, "isEnabled", IsEnabled,
SideEffectType::kHasNoSideEffect);

auto conn_str = FIXED_ONE_BYTE_STRING(env->isolate(), "Connection");
Local<FunctionTemplate> tmpl =
Expand Down
13 changes: 9 additions & 4 deletions src/module_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ using v8::Object;
using v8::Promise;
using v8::ScriptCompiler;
using v8::ScriptOrigin;
using v8::SideEffectType;
using v8::String;
using v8::TryCatch;
using v8::Undefined;
Expand Down Expand Up @@ -789,11 +790,15 @@ void ModuleWrap::Initialize(Local<Object> 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, "namespace", Namespace,
SideEffectType::kHasNoSideEffect);
env->SetProtoMethod(tpl, "getStatus", GetStatus,
SideEffectType::kHasNoSideEffect);
env->SetProtoMethod(tpl, "getError", GetError,
SideEffectType::kHasNoSideEffect);
env->SetProtoMethod(tpl, "getStaticDependencySpecifiers",
GetStaticDependencySpecifiers);
GetStaticDependencySpecifiers,
SideEffectType::kHasNoSideEffect);

target->Set(FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"), tpl->GetFunction());
env->SetMethod(target, "resolve", Resolve);
Expand Down
27 changes: 19 additions & 8 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2252,17 +2256,24 @@ void SetupProcessObject(Environment* env,
env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
env->SetMethod(process, "_kill", Kill);

env->SetMethod(process, "cwd", Cwd);
env->SetMethod(process, "cwd", Cwd,
SideEffectType::kHasNoSideEffect);
env->SetMethod(process, "dlopen", DLOpen);
env->SetMethod(process, "reallyExit", Exit);
env->SetMethod(process, "uptime", Uptime);
env->SetMethod(process, "uptime", Uptime,
SideEffectType::kHasNoSideEffect);

#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->SetMethod(process, "getuid", GetUid,
SideEffectType::kHasNoSideEffect);
env->SetMethod(process, "geteuid", GetEUid,
SideEffectType::kHasNoSideEffect);
env->SetMethod(process, "getgid", GetGid,
SideEffectType::kHasNoSideEffect);
env->SetMethod(process, "getegid", GetEGid,
SideEffectType::kHasNoSideEffect);
env->SetMethod(process, "getgroups", GetGroups,
SideEffectType::kHasNoSideEffect);
#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
}

Expand Down
43 changes: 29 additions & 14 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ using v8::Local;
using v8::Maybe;
using v8::MaybeLocal;
using v8::Object;
using v8::SideEffectType;
using v8::String;
using v8::Uint32Array;
using v8::Uint8Array;
Expand Down Expand Up @@ -1083,12 +1084,18 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
Local<Object> proto = args[0].As<Object>();
env->set_buffer_prototype_object(proto);

env->SetMethod(proto, "asciiSlice", StringSlice<ASCII>);
env->SetMethod(proto, "base64Slice", StringSlice<BASE64>);
env->SetMethod(proto, "latin1Slice", StringSlice<LATIN1>);
env->SetMethod(proto, "hexSlice", StringSlice<HEX>);
env->SetMethod(proto, "ucs2Slice", StringSlice<UCS2>);
env->SetMethod(proto, "utf8Slice", StringSlice<UTF8>);
env->SetMethod(proto, "asciiSlice", StringSlice<ASCII>,
SideEffectType::kHasNoSideEffect);
env->SetMethod(proto, "base64Slice", StringSlice<BASE64>,
SideEffectType::kHasNoSideEffect);
env->SetMethod(proto, "latin1Slice", StringSlice<LATIN1>,
SideEffectType::kHasNoSideEffect);
env->SetMethod(proto, "hexSlice", StringSlice<HEX>,
SideEffectType::kHasNoSideEffect);
env->SetMethod(proto, "ucs2Slice", StringSlice<UCS2>,
SideEffectType::kHasNoSideEffect);
env->SetMethod(proto, "utf8Slice", StringSlice<UTF8>,
SideEffectType::kHasNoSideEffect);

env->SetMethod(proto, "asciiWrite", StringWrite<ASCII>);
env->SetMethod(proto, "base64Write", StringWrite<BASE64>);
Expand Down Expand Up @@ -1116,22 +1123,30 @@ void Initialize(Local<Object> target,
Environment* env = Environment::GetCurrent(context);

env->SetMethod(target, "setupBufferJS", SetupBufferJS);
env->SetMethod(target, "createFromString", CreateFromString);
env->SetMethod(target, "createFromString", CreateFromString,
SideEffectType::kHasNoSideEffect);

env->SetMethod(target, "byteLengthUtf8", ByteLengthUtf8);
env->SetMethod(target, "byteLengthUtf8", ByteLengthUtf8,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "copy", Copy);
env->SetMethod(target, "compare", Compare);
env->SetMethod(target, "compareOffset", CompareOffset);
env->SetMethod(target, "compare", Compare,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "compareOffset", CompareOffset,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "fill", Fill);
env->SetMethod(target, "indexOfBuffer", IndexOfBuffer);
env->SetMethod(target, "indexOfNumber", IndexOfNumber);
env->SetMethod(target, "indexOfString", IndexOfString);
env->SetMethod(target, "indexOfBuffer", IndexOfBuffer,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "indexOfNumber", IndexOfNumber,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "indexOfString", IndexOfString,
SideEffectType::kHasNoSideEffect);

env->SetMethod(target, "swap16", Swap16);
env->SetMethod(target, "swap32", Swap32);
env->SetMethod(target, "swap64", Swap64);

env->SetMethod(target, "encodeUtf8String", EncodeUtf8String);
env->SetMethod(target, "encodeUtf8String", EncodeUtf8String,
SideEffectType::kHasNoSideEffect);

target->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(), "kMaxLength"),
Expand Down
19 changes: 13 additions & 6 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,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;
Expand Down Expand Up @@ -5193,12 +5194,18 @@ void Initialize(Local<Object> target,
#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->SetMethod(target, "randomBytes", RandomBytes,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "timingSafeEqual", TimingSafeEqual,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "getSSLCiphers", GetSSLCiphers,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "getCiphers", GetCiphers,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "getHashes", GetHashes,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "getCurves", GetCurves,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "publicEncrypt",
PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
EVP_PKEY_encrypt_init,
Expand Down
7 changes: 5 additions & 2 deletions src/node_types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Local;
using v8::Object;
using v8::SideEffectType;
using v8::Value;

namespace node {
Expand Down Expand Up @@ -58,11 +59,13 @@ void InitializeTypes(Local<Object> target,

#define V(type) env->SetMethod(target, \
"is" #type, \
Is##type);
Is##type, \
SideEffectType::kHasNoSideEffect);
VALUE_METHOD_MAP(V)
#undef V

env->SetMethod(target, "isAnyArrayBuffer", IsAnyArrayBuffer);
env->SetMethod(target, "isAnyArrayBuffer", IsAnyArrayBuffer,
SideEffectType::kHasNoSideEffect);
}

} // anonymous namespace
Expand Down
13 changes: 9 additions & 4 deletions src/node_url.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ using v8::Local;
using v8::MaybeLocal;
using v8::Null;
using v8::Object;
using v8::SideEffectType;
using v8::String;
using v8::TryCatch;
using v8::Undefined;
Expand Down Expand Up @@ -2334,10 +2335,14 @@ static void Initialize(Local<Object> 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->SetMethod(target, "encodeAuth", EncodeAuthSet,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "toUSVString", ToUSVString,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "domainToASCII", DomainToASCII,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "domainToUnicode", DomainToUnicode,
SideEffectType::kHasNoSideEffect);
env->SetMethod(target, "setURLConstructor", SetURLConstructor);

#define XX(name, _) NODE_DEFINE_CONSTANT(target, name);
Expand Down
Loading

0 comments on commit 7132853

Please sign in to comment.