%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/node_util.cc |
#include "base_object-inl.h" #include "node_dotenv.h" #include "node_errors.h" #include "node_external_reference.h" #include "util-inl.h" #include "v8-fast-api-calls.h" namespace node { namespace util { using v8::ALL_PROPERTIES; using v8::Array; using v8::ArrayBufferView; using v8::BigInt; using v8::Boolean; using v8::CFunction; using v8::Context; using v8::External; using v8::FunctionCallbackInfo; using v8::IndexFilter; using v8::Integer; using v8::Isolate; using v8::KeyCollectionMode; using v8::Local; using v8::Object; using v8::ObjectTemplate; using v8::ONLY_CONFIGURABLE; using v8::ONLY_ENUMERABLE; using v8::ONLY_WRITABLE; using v8::Promise; using v8::PropertyFilter; using v8::Proxy; using v8::SKIP_STRINGS; using v8::SKIP_SYMBOLS; using v8::StackFrame; using v8::StackTrace; using v8::String; using v8::Uint32; using v8::Value; // If a UTF-16 character is a low/trailing surrogate. CHAR_TEST(16, IsUnicodeTrail, (ch & 0xFC00) == 0xDC00) // If a UTF-16 character is a surrogate. CHAR_TEST(16, IsUnicodeSurrogate, (ch & 0xF800) == 0xD800) // If a UTF-16 surrogate is a low/trailing one. CHAR_TEST(16, IsUnicodeSurrogateTrail, (ch & 0x400) != 0) static void GetOwnNonIndexProperties( const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args); Local<Context> context = env->context(); CHECK(args[0]->IsObject()); CHECK(args[1]->IsUint32()); Local<Object> object = args[0].As<Object>(); Local<Array> properties; PropertyFilter filter = static_cast<PropertyFilter>(args[1].As<Uint32>()->Value()); if (!object->GetPropertyNames( context, KeyCollectionMode::kOwnOnly, filter, IndexFilter::kSkipIndices) .ToLocal(&properties)) { return; } args.GetReturnValue().Set(properties); } static void GetConstructorName( const FunctionCallbackInfo<Value>& args) { CHECK(args[0]->IsObject()); Local<Object> object = args[0].As<Object>(); Local<String> name = object->GetConstructorName(); args.GetReturnValue().Set(name); } static void GetExternalValue( const FunctionCallbackInfo<Value>& args) { CHECK(args[0]->IsExternal()); Isolate* isolate = args.GetIsolate(); Local<External> external = args[0].As<External>(); void* ptr = external->Value(); uint64_t value = reinterpret_cast<uint64_t>(ptr); Local<BigInt> ret = BigInt::NewFromUnsigned(isolate, value); args.GetReturnValue().Set(ret); } static void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) { // Return undefined if it's not a Promise. if (!args[0]->IsPromise()) return; auto isolate = args.GetIsolate(); Local<Promise> promise = args[0].As<Promise>(); int state = promise->State(); Local<Value> values[2] = { Integer::New(isolate, state) }; size_t number_of_values = 1; if (state != Promise::PromiseState::kPending) values[number_of_values++] = promise->Result(); Local<Array> ret = Array::New(isolate, values, number_of_values); args.GetReturnValue().Set(ret); } static void GetProxyDetails(const FunctionCallbackInfo<Value>& args) { // Return undefined if it's not a proxy. if (!args[0]->IsProxy()) return; Local<Proxy> proxy = args[0].As<Proxy>(); // TODO(BridgeAR): Remove the length check as soon as we prohibit access to // the util binding layer. It's accessed in the wild and `esm` would break in // case the check is removed. if (args.Length() == 1 || args[1]->IsTrue()) { Local<Value> ret[] = { proxy->GetTarget(), proxy->GetHandler() }; args.GetReturnValue().Set( Array::New(args.GetIsolate(), ret, arraysize(ret))); } else { Local<Value> ret = proxy->GetTarget(); args.GetReturnValue().Set(ret); } } static void GetCallerLocation(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); Local<StackTrace> trace = StackTrace::CurrentStackTrace(isolate, 2); // This function is frame zero. The caller is frame one. If there aren't two // stack frames, return undefined. if (trace->GetFrameCount() != 2) { return; } Local<StackFrame> frame = trace->GetFrame(isolate, 1); Local<Value> ret[] = {Integer::New(isolate, frame->GetLineNumber()), Integer::New(isolate, frame->GetColumn()), frame->GetScriptNameOrSourceURL()}; args.GetReturnValue().Set(Array::New(args.GetIsolate(), ret, arraysize(ret))); } static void IsArrayBufferDetached(const FunctionCallbackInfo<Value>& args) { if (args[0]->IsArrayBuffer()) { auto buffer = args[0].As<v8::ArrayBuffer>(); args.GetReturnValue().Set(buffer->WasDetached()); return; } args.GetReturnValue().Set(false); } static void PreviewEntries(const FunctionCallbackInfo<Value>& args) { if (!args[0]->IsObject()) return; Environment* env = Environment::GetCurrent(args); bool is_key_value; Local<Array> entries; if (!args[0].As<Object>()->PreviewEntries(&is_key_value).ToLocal(&entries)) return; // Fast path for WeakMap and WeakSet. if (args.Length() == 1) return args.GetReturnValue().Set(entries); Local<Value> ret[] = { entries, Boolean::New(env->isolate(), is_key_value) }; return args.GetReturnValue().Set( Array::New(env->isolate(), ret, arraysize(ret))); } static void Sleep(const FunctionCallbackInfo<Value>& args) { CHECK(args[0]->IsUint32()); uint32_t msec = args[0].As<Uint32>()->Value(); uv_sleep(msec); } void ArrayBufferViewHasBuffer(const FunctionCallbackInfo<Value>& args) { CHECK(args[0]->IsArrayBufferView()); args.GetReturnValue().Set(args[0].As<ArrayBufferView>()->HasBuffer()); } static uint32_t GetUVHandleTypeCode(const uv_handle_type type) { // TODO(anonrig): We can use an enum here and then create the array in the // binding, which will remove the hard-coding in C++ and JS land. // Currently, the return type of this function corresponds to the index of the // array defined in the JS land. This is done as an optimization to reduce the // string serialization overhead. switch (type) { case UV_TCP: return 0; case UV_TTY: return 1; case UV_UDP: return 2; case UV_FILE: return 3; case UV_NAMED_PIPE: return 4; case UV_UNKNOWN_HANDLE: return 5; default: ABORT(); } } static void GuessHandleType(const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args); int fd; if (!args[0]->Int32Value(env->context()).To(&fd)) return; CHECK_GE(fd, 0); uv_handle_type t = uv_guess_handle(fd); args.GetReturnValue().Set(GetUVHandleTypeCode(t)); } static uint32_t FastGuessHandleType(Local<Value> receiver, const uint32_t fd) { uv_handle_type t = uv_guess_handle(fd); return GetUVHandleTypeCode(t); } CFunction fast_guess_handle_type_(CFunction::Make(FastGuessHandleType)); static void ParseEnv(const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args); CHECK_EQ(args.Length(), 1); // content CHECK(args[0]->IsString()); Utf8Value content(env->isolate(), args[0]); Dotenv dotenv{}; dotenv.ParseContent(content.ToStringView()); args.GetReturnValue().Set(dotenv.ToObject(env)); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetPromiseDetails); registry->Register(GetProxyDetails); registry->Register(GetCallerLocation); registry->Register(IsArrayBufferDetached); registry->Register(PreviewEntries); registry->Register(GetOwnNonIndexProperties); registry->Register(GetConstructorName); registry->Register(GetExternalValue); registry->Register(Sleep); registry->Register(ArrayBufferViewHasBuffer); registry->Register(GuessHandleType); registry->Register(FastGuessHandleType); registry->Register(fast_guess_handle_type_.GetTypeInfo()); registry->Register(ParseEnv); } void Initialize(Local<Object> target, Local<Value> unused, Local<Context> context, void* priv) { Environment* env = Environment::GetCurrent(context); Isolate* isolate = env->isolate(); { Local<ObjectTemplate> tmpl = ObjectTemplate::New(isolate); #define V(PropertyName, _) \ tmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #PropertyName), \ env->PropertyName()); PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V) #undef V target ->Set(context, FIXED_ONE_BYTE_STRING(isolate, "privateSymbols"), tmpl->NewInstance(context).ToLocalChecked()) .Check(); } { Local<Object> constants = Object::New(isolate); #define V(name) \ constants \ ->Set(context, \ FIXED_ONE_BYTE_STRING(isolate, #name), \ Integer::New(isolate, Promise::PromiseState::name)) \ .Check(); V(kPending); V(kFulfilled); V(kRejected); #undef V #define V(name) \ constants \ ->Set(context, \ FIXED_ONE_BYTE_STRING(isolate, #name), \ Integer::New(isolate, Environment::ExitInfoField::name)) \ .Check(); V(kExiting); V(kExitCode); V(kHasExitCode); #undef V #define V(name) \ constants \ ->Set(context, \ FIXED_ONE_BYTE_STRING(isolate, #name), \ Integer::New(isolate, PropertyFilter::name)) \ .Check(); V(ALL_PROPERTIES); V(ONLY_WRITABLE); V(ONLY_ENUMERABLE); V(ONLY_CONFIGURABLE); V(SKIP_STRINGS); V(SKIP_SYMBOLS); #undef V #define V(name) \ constants \ ->Set( \ context, \ FIXED_ONE_BYTE_STRING(isolate, #name), \ Integer::New(isolate, \ static_cast<int32_t>(BaseObject::TransferMode::name))) \ .Check(); V(kDisallowCloneAndTransfer); V(kTransferable); V(kCloneable); #undef V target->Set(context, env->constants_string(), constants).Check(); } SetMethodNoSideEffect( context, target, "getPromiseDetails", GetPromiseDetails); SetMethodNoSideEffect(context, target, "getProxyDetails", GetProxyDetails); SetMethodNoSideEffect( context, target, "getCallerLocation", GetCallerLocation); SetMethodNoSideEffect( context, target, "isArrayBufferDetached", IsArrayBufferDetached); SetMethodNoSideEffect(context, target, "previewEntries", PreviewEntries); SetMethodNoSideEffect( context, target, "getOwnNonIndexProperties", GetOwnNonIndexProperties); SetMethodNoSideEffect( context, target, "getConstructorName", GetConstructorName); SetMethodNoSideEffect(context, target, "getExternalValue", GetExternalValue); SetMethod(context, target, "sleep", Sleep); SetMethod(context, target, "parseEnv", ParseEnv); SetMethod( context, target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer); Local<String> should_abort_on_uncaught_toggle = FIXED_ONE_BYTE_STRING(env->isolate(), "shouldAbortOnUncaughtToggle"); CHECK(target ->Set(context, should_abort_on_uncaught_toggle, env->should_abort_on_uncaught_toggle().GetJSArray()) .FromJust()); SetFastMethodNoSideEffect(context, target, "guessHandleType", GuessHandleType, &fast_guess_handle_type_); } } // namespace util } // namespace node NODE_BINDING_CONTEXT_AWARE_INTERNAL(util, node::util::Initialize) NODE_BINDING_EXTERNAL_REFERENCE(util, node::util::RegisterExternalReferences)