11cb0ef41Sopenharmony_ci#include "node_util.h"
21cb0ef41Sopenharmony_ci#include "base_object-inl.h"
31cb0ef41Sopenharmony_ci#include "node_errors.h"
41cb0ef41Sopenharmony_ci#include "node_external_reference.h"
51cb0ef41Sopenharmony_ci#include "util-inl.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cinamespace node {
81cb0ef41Sopenharmony_cinamespace util {
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciusing v8::ALL_PROPERTIES;
111cb0ef41Sopenharmony_ciusing v8::Array;
121cb0ef41Sopenharmony_ciusing v8::ArrayBufferView;
131cb0ef41Sopenharmony_ciusing v8::BigInt;
141cb0ef41Sopenharmony_ciusing v8::Boolean;
151cb0ef41Sopenharmony_ciusing v8::Context;
161cb0ef41Sopenharmony_ciusing v8::External;
171cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo;
181cb0ef41Sopenharmony_ciusing v8::FunctionTemplate;
191cb0ef41Sopenharmony_ciusing v8::HandleScope;
201cb0ef41Sopenharmony_ciusing v8::IndexFilter;
211cb0ef41Sopenharmony_ciusing v8::Integer;
221cb0ef41Sopenharmony_ciusing v8::Isolate;
231cb0ef41Sopenharmony_ciusing v8::KeyCollectionMode;
241cb0ef41Sopenharmony_ciusing v8::Local;
251cb0ef41Sopenharmony_ciusing v8::Object;
261cb0ef41Sopenharmony_ciusing v8::ONLY_CONFIGURABLE;
271cb0ef41Sopenharmony_ciusing v8::ONLY_ENUMERABLE;
281cb0ef41Sopenharmony_ciusing v8::ONLY_WRITABLE;
291cb0ef41Sopenharmony_ciusing v8::Promise;
301cb0ef41Sopenharmony_ciusing v8::PropertyFilter;
311cb0ef41Sopenharmony_ciusing v8::Proxy;
321cb0ef41Sopenharmony_ciusing v8::SKIP_STRINGS;
331cb0ef41Sopenharmony_ciusing v8::SKIP_SYMBOLS;
341cb0ef41Sopenharmony_ciusing v8::StackFrame;
351cb0ef41Sopenharmony_ciusing v8::StackTrace;
361cb0ef41Sopenharmony_ciusing v8::String;
371cb0ef41Sopenharmony_ciusing v8::Uint32;
381cb0ef41Sopenharmony_ciusing v8::Value;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci// Used in ToUSVString().
411cb0ef41Sopenharmony_ciconstexpr char16_t kUnicodeReplacementCharacter = 0xFFFD;
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci// If a UTF-16 character is a low/trailing surrogate.
441cb0ef41Sopenharmony_ciCHAR_TEST(16, IsUnicodeTrail, (ch & 0xFC00) == 0xDC00)
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci// If a UTF-16 character is a surrogate.
471cb0ef41Sopenharmony_ciCHAR_TEST(16, IsUnicodeSurrogate, (ch & 0xF800) == 0xD800)
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci// If a UTF-16 surrogate is a low/trailing one.
501cb0ef41Sopenharmony_ciCHAR_TEST(16, IsUnicodeSurrogateTrail, (ch & 0x400) != 0)
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_cistatic void GetOwnNonIndexProperties(
531cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args) {
541cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
551cb0ef41Sopenharmony_ci  Local<Context> context = env->context();
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
581cb0ef41Sopenharmony_ci  CHECK(args[1]->IsUint32());
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  Local<Object> object = args[0].As<Object>();
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  Local<Array> properties;
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  PropertyFilter filter =
651cb0ef41Sopenharmony_ci    static_cast<PropertyFilter>(args[1].As<Uint32>()->Value());
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  if (!object->GetPropertyNames(
681cb0ef41Sopenharmony_ci        context, KeyCollectionMode::kOwnOnly,
691cb0ef41Sopenharmony_ci        filter,
701cb0ef41Sopenharmony_ci        IndexFilter::kSkipIndices)
711cb0ef41Sopenharmony_ci          .ToLocal(&properties)) {
721cb0ef41Sopenharmony_ci    return;
731cb0ef41Sopenharmony_ci  }
741cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(properties);
751cb0ef41Sopenharmony_ci}
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_cistatic void GetConstructorName(
781cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args) {
791cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  Local<Object> object = args[0].As<Object>();
821cb0ef41Sopenharmony_ci  Local<String> name = object->GetConstructorName();
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(name);
851cb0ef41Sopenharmony_ci}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_cistatic void GetExternalValue(
881cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args) {
891cb0ef41Sopenharmony_ci  CHECK(args[0]->IsExternal());
901cb0ef41Sopenharmony_ci  Isolate* isolate = args.GetIsolate();
911cb0ef41Sopenharmony_ci  Local<External> external = args[0].As<External>();
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  void* ptr = external->Value();
941cb0ef41Sopenharmony_ci  uint64_t value = reinterpret_cast<uint64_t>(ptr);
951cb0ef41Sopenharmony_ci  Local<BigInt> ret = BigInt::NewFromUnsigned(isolate, value);
961cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(ret);
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_cistatic void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) {
1001cb0ef41Sopenharmony_ci  // Return undefined if it's not a Promise.
1011cb0ef41Sopenharmony_ci  if (!args[0]->IsPromise())
1021cb0ef41Sopenharmony_ci    return;
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  auto isolate = args.GetIsolate();
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  Local<Promise> promise = args[0].As<Promise>();
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  int state = promise->State();
1091cb0ef41Sopenharmony_ci  Local<Value> values[2] = { Integer::New(isolate, state) };
1101cb0ef41Sopenharmony_ci  size_t number_of_values = 1;
1111cb0ef41Sopenharmony_ci  if (state != Promise::PromiseState::kPending)
1121cb0ef41Sopenharmony_ci    values[number_of_values++] = promise->Result();
1131cb0ef41Sopenharmony_ci  Local<Array> ret = Array::New(isolate, values, number_of_values);
1141cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(ret);
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_cistatic void GetProxyDetails(const FunctionCallbackInfo<Value>& args) {
1181cb0ef41Sopenharmony_ci  // Return undefined if it's not a proxy.
1191cb0ef41Sopenharmony_ci  if (!args[0]->IsProxy())
1201cb0ef41Sopenharmony_ci    return;
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  Local<Proxy> proxy = args[0].As<Proxy>();
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  // TODO(BridgeAR): Remove the length check as soon as we prohibit access to
1251cb0ef41Sopenharmony_ci  // the util binding layer. It's accessed in the wild and `esm` would break in
1261cb0ef41Sopenharmony_ci  // case the check is removed.
1271cb0ef41Sopenharmony_ci  if (args.Length() == 1 || args[1]->IsTrue()) {
1281cb0ef41Sopenharmony_ci    Local<Value> ret[] = {
1291cb0ef41Sopenharmony_ci      proxy->GetTarget(),
1301cb0ef41Sopenharmony_ci      proxy->GetHandler()
1311cb0ef41Sopenharmony_ci    };
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(
1341cb0ef41Sopenharmony_ci        Array::New(args.GetIsolate(), ret, arraysize(ret)));
1351cb0ef41Sopenharmony_ci  } else {
1361cb0ef41Sopenharmony_ci    Local<Value> ret = proxy->GetTarget();
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(ret);
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci}
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_cistatic void GetCallerLocation(const FunctionCallbackInfo<Value>& args) {
1431cb0ef41Sopenharmony_ci  Isolate* isolate = args.GetIsolate();
1441cb0ef41Sopenharmony_ci  Local<StackTrace> trace = StackTrace::CurrentStackTrace(isolate, 2);
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  // This function is frame zero. The caller is frame one. If there aren't two
1471cb0ef41Sopenharmony_ci  // stack frames, return undefined.
1481cb0ef41Sopenharmony_ci  if (trace->GetFrameCount() != 2) {
1491cb0ef41Sopenharmony_ci    return;
1501cb0ef41Sopenharmony_ci  }
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  Local<StackFrame> frame = trace->GetFrame(isolate, 1);
1531cb0ef41Sopenharmony_ci  Local<Value> ret[] = {Integer::New(isolate, frame->GetLineNumber()),
1541cb0ef41Sopenharmony_ci                        Integer::New(isolate, frame->GetColumn()),
1551cb0ef41Sopenharmony_ci                        frame->GetScriptNameOrSourceURL()};
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Array::New(args.GetIsolate(), ret, arraysize(ret)));
1581cb0ef41Sopenharmony_ci}
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_cistatic void IsArrayBufferDetached(const FunctionCallbackInfo<Value>& args) {
1611cb0ef41Sopenharmony_ci  if (args[0]->IsArrayBuffer()) {
1621cb0ef41Sopenharmony_ci    auto buffer = args[0].As<v8::ArrayBuffer>();
1631cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(buffer->WasDetached());
1641cb0ef41Sopenharmony_ci    return;
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(false);
1671cb0ef41Sopenharmony_ci}
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_cistatic void PreviewEntries(const FunctionCallbackInfo<Value>& args) {
1701cb0ef41Sopenharmony_ci  if (!args[0]->IsObject())
1711cb0ef41Sopenharmony_ci    return;
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
1741cb0ef41Sopenharmony_ci  bool is_key_value;
1751cb0ef41Sopenharmony_ci  Local<Array> entries;
1761cb0ef41Sopenharmony_ci  if (!args[0].As<Object>()->PreviewEntries(&is_key_value).ToLocal(&entries))
1771cb0ef41Sopenharmony_ci    return;
1781cb0ef41Sopenharmony_ci  // Fast path for WeakMap and WeakSet.
1791cb0ef41Sopenharmony_ci  if (args.Length() == 1)
1801cb0ef41Sopenharmony_ci    return args.GetReturnValue().Set(entries);
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  Local<Value> ret[] = {
1831cb0ef41Sopenharmony_ci    entries,
1841cb0ef41Sopenharmony_ci    Boolean::New(env->isolate(), is_key_value)
1851cb0ef41Sopenharmony_ci  };
1861cb0ef41Sopenharmony_ci  return args.GetReturnValue().Set(
1871cb0ef41Sopenharmony_ci      Array::New(env->isolate(), ret, arraysize(ret)));
1881cb0ef41Sopenharmony_ci}
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_cistatic void Sleep(const FunctionCallbackInfo<Value>& args) {
1911cb0ef41Sopenharmony_ci  CHECK(args[0]->IsUint32());
1921cb0ef41Sopenharmony_ci  uint32_t msec = args[0].As<Uint32>()->Value();
1931cb0ef41Sopenharmony_ci  uv_sleep(msec);
1941cb0ef41Sopenharmony_ci}
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_civoid ArrayBufferViewHasBuffer(const FunctionCallbackInfo<Value>& args) {
1971cb0ef41Sopenharmony_ci  CHECK(args[0]->IsArrayBufferView());
1981cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(args[0].As<ArrayBufferView>()->HasBuffer());
1991cb0ef41Sopenharmony_ci}
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ciWeakReference::WeakReference(Realm* realm,
2021cb0ef41Sopenharmony_ci                             Local<Object> object,
2031cb0ef41Sopenharmony_ci                             Local<Object> target)
2041cb0ef41Sopenharmony_ci    : WeakReference(realm, object, target, 0) {}
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ciWeakReference::WeakReference(Realm* realm,
2071cb0ef41Sopenharmony_ci                             Local<Object> object,
2081cb0ef41Sopenharmony_ci                             Local<Object> target,
2091cb0ef41Sopenharmony_ci                             uint64_t reference_count)
2101cb0ef41Sopenharmony_ci    : SnapshotableObject(realm, object, type_int),
2111cb0ef41Sopenharmony_ci      reference_count_(reference_count) {
2121cb0ef41Sopenharmony_ci  MakeWeak();
2131cb0ef41Sopenharmony_ci  if (!target.IsEmpty()) {
2141cb0ef41Sopenharmony_ci    target_.Reset(realm->isolate(), target);
2151cb0ef41Sopenharmony_ci    if (reference_count_ == 0) {
2161cb0ef41Sopenharmony_ci      target_.SetWeak();
2171cb0ef41Sopenharmony_ci    }
2181cb0ef41Sopenharmony_ci  }
2191cb0ef41Sopenharmony_ci}
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_cibool WeakReference::PrepareForSerialization(Local<Context> context,
2221cb0ef41Sopenharmony_ci                                            v8::SnapshotCreator* creator) {
2231cb0ef41Sopenharmony_ci  if (target_.IsEmpty()) {
2241cb0ef41Sopenharmony_ci    target_index_ = 0;
2251cb0ef41Sopenharmony_ci    return true;
2261cb0ef41Sopenharmony_ci  }
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci  // Users can still hold strong references to target in addition to the
2291cb0ef41Sopenharmony_ci  // reference that we manage here, and they could expect that the referenced
2301cb0ef41Sopenharmony_ci  // object remains the same as long as that external strong reference
2311cb0ef41Sopenharmony_ci  // is alive. Since we have no way to know if there is any other reference
2321cb0ef41Sopenharmony_ci  // keeping the target alive, the best we can do to maintain consistency is to
2331cb0ef41Sopenharmony_ci  // simply save a reference to the target in the snapshot (effectively making
2341cb0ef41Sopenharmony_ci  // it strong) during serialization, and restore it during deserialization.
2351cb0ef41Sopenharmony_ci  // If there's no known counted reference from our side, we'll make the
2361cb0ef41Sopenharmony_ci  // reference here weak upon deserialization so that it can be GC'ed if users
2371cb0ef41Sopenharmony_ci  // do not hold additional references to it.
2381cb0ef41Sopenharmony_ci  Local<Object> target = target_.Get(context->GetIsolate());
2391cb0ef41Sopenharmony_ci  target_index_ = creator->AddData(context, target);
2401cb0ef41Sopenharmony_ci  DCHECK_NE(target_index_, 0);
2411cb0ef41Sopenharmony_ci  target_.Reset();
2421cb0ef41Sopenharmony_ci  return true;
2431cb0ef41Sopenharmony_ci}
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ciInternalFieldInfoBase* WeakReference::Serialize(int index) {
2461cb0ef41Sopenharmony_ci  DCHECK_EQ(index, BaseObject::kEmbedderType);
2471cb0ef41Sopenharmony_ci  InternalFieldInfo* info =
2481cb0ef41Sopenharmony_ci      InternalFieldInfoBase::New<InternalFieldInfo>(type());
2491cb0ef41Sopenharmony_ci  info->target = target_index_;
2501cb0ef41Sopenharmony_ci  info->reference_count = reference_count_;
2511cb0ef41Sopenharmony_ci  return info;
2521cb0ef41Sopenharmony_ci}
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_civoid WeakReference::Deserialize(Local<Context> context,
2551cb0ef41Sopenharmony_ci                                Local<Object> holder,
2561cb0ef41Sopenharmony_ci                                int index,
2571cb0ef41Sopenharmony_ci                                InternalFieldInfoBase* info) {
2581cb0ef41Sopenharmony_ci  DCHECK_EQ(index, BaseObject::kEmbedderType);
2591cb0ef41Sopenharmony_ci  HandleScope scope(context->GetIsolate());
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci  InternalFieldInfo* weak_info = reinterpret_cast<InternalFieldInfo*>(info);
2621cb0ef41Sopenharmony_ci  Local<Object> target;
2631cb0ef41Sopenharmony_ci  if (weak_info->target != 0) {
2641cb0ef41Sopenharmony_ci    target = context->GetDataFromSnapshotOnce<Object>(weak_info->target)
2651cb0ef41Sopenharmony_ci                 .ToLocalChecked();
2661cb0ef41Sopenharmony_ci  }
2671cb0ef41Sopenharmony_ci  new WeakReference(
2681cb0ef41Sopenharmony_ci      Realm::GetCurrent(context), holder, target, weak_info->reference_count);
2691cb0ef41Sopenharmony_ci}
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_civoid WeakReference::New(const FunctionCallbackInfo<Value>& args) {
2721cb0ef41Sopenharmony_ci  Realm* realm = Realm::GetCurrent(args);
2731cb0ef41Sopenharmony_ci  CHECK(args.IsConstructCall());
2741cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
2751cb0ef41Sopenharmony_ci  new WeakReference(realm, args.This(), args[0].As<Object>());
2761cb0ef41Sopenharmony_ci}
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_civoid WeakReference::Get(const FunctionCallbackInfo<Value>& args) {
2791cb0ef41Sopenharmony_ci  WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
2801cb0ef41Sopenharmony_ci  Isolate* isolate = args.GetIsolate();
2811cb0ef41Sopenharmony_ci  if (!weak_ref->target_.IsEmpty())
2821cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(weak_ref->target_.Get(isolate));
2831cb0ef41Sopenharmony_ci}
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_civoid WeakReference::IncRef(const FunctionCallbackInfo<Value>& args) {
2861cb0ef41Sopenharmony_ci  WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
2871cb0ef41Sopenharmony_ci  weak_ref->reference_count_++;
2881cb0ef41Sopenharmony_ci  if (weak_ref->target_.IsEmpty()) return;
2891cb0ef41Sopenharmony_ci  if (weak_ref->reference_count_ == 1) weak_ref->target_.ClearWeak();
2901cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
2911cb0ef41Sopenharmony_ci      v8::Number::New(args.GetIsolate(), weak_ref->reference_count_));
2921cb0ef41Sopenharmony_ci}
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_civoid WeakReference::DecRef(const FunctionCallbackInfo<Value>& args) {
2951cb0ef41Sopenharmony_ci  WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
2961cb0ef41Sopenharmony_ci  CHECK_GE(weak_ref->reference_count_, 1);
2971cb0ef41Sopenharmony_ci  weak_ref->reference_count_--;
2981cb0ef41Sopenharmony_ci  if (weak_ref->target_.IsEmpty()) return;
2991cb0ef41Sopenharmony_ci  if (weak_ref->reference_count_ == 0) weak_ref->target_.SetWeak();
3001cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
3011cb0ef41Sopenharmony_ci      v8::Number::New(args.GetIsolate(), weak_ref->reference_count_));
3021cb0ef41Sopenharmony_ci}
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_cistatic void GuessHandleType(const FunctionCallbackInfo<Value>& args) {
3051cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
3061cb0ef41Sopenharmony_ci  int fd;
3071cb0ef41Sopenharmony_ci  if (!args[0]->Int32Value(env->context()).To(&fd)) return;
3081cb0ef41Sopenharmony_ci  CHECK_GE(fd, 0);
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  uv_handle_type t = uv_guess_handle(fd);
3111cb0ef41Sopenharmony_ci  const char* type = nullptr;
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  switch (t) {
3141cb0ef41Sopenharmony_ci    case UV_TCP:
3151cb0ef41Sopenharmony_ci      type = "TCP";
3161cb0ef41Sopenharmony_ci      break;
3171cb0ef41Sopenharmony_ci    case UV_TTY:
3181cb0ef41Sopenharmony_ci      type = "TTY";
3191cb0ef41Sopenharmony_ci      break;
3201cb0ef41Sopenharmony_ci    case UV_UDP:
3211cb0ef41Sopenharmony_ci      type = "UDP";
3221cb0ef41Sopenharmony_ci      break;
3231cb0ef41Sopenharmony_ci    case UV_FILE:
3241cb0ef41Sopenharmony_ci      type = "FILE";
3251cb0ef41Sopenharmony_ci      break;
3261cb0ef41Sopenharmony_ci    case UV_NAMED_PIPE:
3271cb0ef41Sopenharmony_ci      type = "PIPE";
3281cb0ef41Sopenharmony_ci      break;
3291cb0ef41Sopenharmony_ci    case UV_UNKNOWN_HANDLE:
3301cb0ef41Sopenharmony_ci      type = "UNKNOWN";
3311cb0ef41Sopenharmony_ci      break;
3321cb0ef41Sopenharmony_ci    default:
3331cb0ef41Sopenharmony_ci      ABORT();
3341cb0ef41Sopenharmony_ci  }
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(OneByteString(env->isolate(), type));
3371cb0ef41Sopenharmony_ci}
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_cistatic void ToUSVString(const FunctionCallbackInfo<Value>& args) {
3401cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
3411cb0ef41Sopenharmony_ci  CHECK_GE(args.Length(), 2);
3421cb0ef41Sopenharmony_ci  CHECK(args[0]->IsString());
3431cb0ef41Sopenharmony_ci  CHECK(args[1]->IsNumber());
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  TwoByteValue value(env->isolate(), args[0]);
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci  int64_t start = args[1]->IntegerValue(env->context()).FromJust();
3481cb0ef41Sopenharmony_ci  CHECK_GE(start, 0);
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci  for (size_t i = start; i < value.length(); i++) {
3511cb0ef41Sopenharmony_ci    char16_t c = value[i];
3521cb0ef41Sopenharmony_ci    if (!IsUnicodeSurrogate(c)) {
3531cb0ef41Sopenharmony_ci      continue;
3541cb0ef41Sopenharmony_ci    } else if (IsUnicodeSurrogateTrail(c) || i == value.length() - 1) {
3551cb0ef41Sopenharmony_ci      value[i] = kUnicodeReplacementCharacter;
3561cb0ef41Sopenharmony_ci    } else {
3571cb0ef41Sopenharmony_ci      char16_t d = value[i + 1];
3581cb0ef41Sopenharmony_ci      if (IsUnicodeTrail(d)) {
3591cb0ef41Sopenharmony_ci        i++;
3601cb0ef41Sopenharmony_ci      } else {
3611cb0ef41Sopenharmony_ci        value[i] = kUnicodeReplacementCharacter;
3621cb0ef41Sopenharmony_ci      }
3631cb0ef41Sopenharmony_ci    }
3641cb0ef41Sopenharmony_ci  }
3651cb0ef41Sopenharmony_ci
3661cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
3671cb0ef41Sopenharmony_ci      String::NewFromTwoByte(env->isolate(),
3681cb0ef41Sopenharmony_ci                             *value,
3691cb0ef41Sopenharmony_ci                             v8::NewStringType::kNormal,
3701cb0ef41Sopenharmony_ci                             value.length()).ToLocalChecked());
3711cb0ef41Sopenharmony_ci}
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_civoid RegisterExternalReferences(ExternalReferenceRegistry* registry) {
3741cb0ef41Sopenharmony_ci  registry->Register(GetPromiseDetails);
3751cb0ef41Sopenharmony_ci  registry->Register(GetProxyDetails);
3761cb0ef41Sopenharmony_ci  registry->Register(GetCallerLocation);
3771cb0ef41Sopenharmony_ci  registry->Register(IsArrayBufferDetached);
3781cb0ef41Sopenharmony_ci  registry->Register(PreviewEntries);
3791cb0ef41Sopenharmony_ci  registry->Register(GetOwnNonIndexProperties);
3801cb0ef41Sopenharmony_ci  registry->Register(GetConstructorName);
3811cb0ef41Sopenharmony_ci  registry->Register(GetExternalValue);
3821cb0ef41Sopenharmony_ci  registry->Register(Sleep);
3831cb0ef41Sopenharmony_ci  registry->Register(ArrayBufferViewHasBuffer);
3841cb0ef41Sopenharmony_ci  registry->Register(WeakReference::New);
3851cb0ef41Sopenharmony_ci  registry->Register(WeakReference::Get);
3861cb0ef41Sopenharmony_ci  registry->Register(WeakReference::IncRef);
3871cb0ef41Sopenharmony_ci  registry->Register(WeakReference::DecRef);
3881cb0ef41Sopenharmony_ci  registry->Register(GuessHandleType);
3891cb0ef41Sopenharmony_ci  registry->Register(ToUSVString);
3901cb0ef41Sopenharmony_ci}
3911cb0ef41Sopenharmony_ci
3921cb0ef41Sopenharmony_civoid Initialize(Local<Object> target,
3931cb0ef41Sopenharmony_ci                Local<Value> unused,
3941cb0ef41Sopenharmony_ci                Local<Context> context,
3951cb0ef41Sopenharmony_ci                void* priv) {
3961cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(context);
3971cb0ef41Sopenharmony_ci  Isolate* isolate = env->isolate();
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  {
4001cb0ef41Sopenharmony_ci    Local<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate);
4011cb0ef41Sopenharmony_ci#define V(PropertyName, _)                                                     \
4021cb0ef41Sopenharmony_ci  tmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #PropertyName),              \
4031cb0ef41Sopenharmony_ci            env->PropertyName());
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
4061cb0ef41Sopenharmony_ci#undef V
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_ci    target
4091cb0ef41Sopenharmony_ci        ->Set(context,
4101cb0ef41Sopenharmony_ci              FIXED_ONE_BYTE_STRING(isolate, "privateSymbols"),
4111cb0ef41Sopenharmony_ci              tmpl->NewInstance(context).ToLocalChecked())
4121cb0ef41Sopenharmony_ci        .Check();
4131cb0ef41Sopenharmony_ci  }
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci  {
4161cb0ef41Sopenharmony_ci    Local<Object> constants = Object::New(isolate);
4171cb0ef41Sopenharmony_ci#define V(name)                                                                \
4181cb0ef41Sopenharmony_ci  constants                                                                    \
4191cb0ef41Sopenharmony_ci      ->Set(context,                                                           \
4201cb0ef41Sopenharmony_ci            FIXED_ONE_BYTE_STRING(isolate, #name),                             \
4211cb0ef41Sopenharmony_ci            Integer::New(isolate, Promise::PromiseState::name))                \
4221cb0ef41Sopenharmony_ci      .Check();
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci    V(kPending);
4251cb0ef41Sopenharmony_ci    V(kFulfilled);
4261cb0ef41Sopenharmony_ci    V(kRejected);
4271cb0ef41Sopenharmony_ci#undef V
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci#define V(name)                                                                \
4301cb0ef41Sopenharmony_ci  constants                                                                    \
4311cb0ef41Sopenharmony_ci      ->Set(context,                                                           \
4321cb0ef41Sopenharmony_ci            FIXED_ONE_BYTE_STRING(isolate, #name),                             \
4331cb0ef41Sopenharmony_ci            Integer::New(isolate, PropertyFilter::name))                       \
4341cb0ef41Sopenharmony_ci      .Check();
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ci    V(ALL_PROPERTIES);
4371cb0ef41Sopenharmony_ci    V(ONLY_WRITABLE);
4381cb0ef41Sopenharmony_ci    V(ONLY_ENUMERABLE);
4391cb0ef41Sopenharmony_ci    V(ONLY_CONFIGURABLE);
4401cb0ef41Sopenharmony_ci    V(SKIP_STRINGS);
4411cb0ef41Sopenharmony_ci    V(SKIP_SYMBOLS);
4421cb0ef41Sopenharmony_ci#undef V
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci    target->Set(context, env->constants_string(), constants).Check();
4451cb0ef41Sopenharmony_ci  }
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(
4481cb0ef41Sopenharmony_ci      context, target, "getPromiseDetails", GetPromiseDetails);
4491cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(context, target, "getProxyDetails", GetProxyDetails);
4501cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(
4511cb0ef41Sopenharmony_ci      context, target, "getCallerLocation", GetCallerLocation);
4521cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(
4531cb0ef41Sopenharmony_ci      context, target, "isArrayBufferDetached", IsArrayBufferDetached);
4541cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(context, target, "previewEntries", PreviewEntries);
4551cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(
4561cb0ef41Sopenharmony_ci      context, target, "getOwnNonIndexProperties", GetOwnNonIndexProperties);
4571cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(
4581cb0ef41Sopenharmony_ci      context, target, "getConstructorName", GetConstructorName);
4591cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(context, target, "getExternalValue", GetExternalValue);
4601cb0ef41Sopenharmony_ci  SetMethod(context, target, "sleep", Sleep);
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ci  SetMethod(
4631cb0ef41Sopenharmony_ci      context, target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer);
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci  Local<String> should_abort_on_uncaught_toggle =
4661cb0ef41Sopenharmony_ci      FIXED_ONE_BYTE_STRING(env->isolate(), "shouldAbortOnUncaughtToggle");
4671cb0ef41Sopenharmony_ci  CHECK(target
4681cb0ef41Sopenharmony_ci            ->Set(context,
4691cb0ef41Sopenharmony_ci                  should_abort_on_uncaught_toggle,
4701cb0ef41Sopenharmony_ci                  env->should_abort_on_uncaught_toggle().GetJSArray())
4711cb0ef41Sopenharmony_ci            .FromJust());
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ci  Local<FunctionTemplate> weak_ref =
4741cb0ef41Sopenharmony_ci      NewFunctionTemplate(isolate, WeakReference::New);
4751cb0ef41Sopenharmony_ci  weak_ref->InstanceTemplate()->SetInternalFieldCount(
4761cb0ef41Sopenharmony_ci      WeakReference::kInternalFieldCount);
4771cb0ef41Sopenharmony_ci  weak_ref->Inherit(BaseObject::GetConstructorTemplate(env));
4781cb0ef41Sopenharmony_ci  SetProtoMethod(isolate, weak_ref, "get", WeakReference::Get);
4791cb0ef41Sopenharmony_ci  SetProtoMethod(isolate, weak_ref, "incRef", WeakReference::IncRef);
4801cb0ef41Sopenharmony_ci  SetProtoMethod(isolate, weak_ref, "decRef", WeakReference::DecRef);
4811cb0ef41Sopenharmony_ci  SetConstructorFunction(context, target, "WeakReference", weak_ref);
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci  SetMethod(context, target, "guessHandleType", GuessHandleType);
4841cb0ef41Sopenharmony_ci
4851cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(context, target, "toUSVString", ToUSVString);
4861cb0ef41Sopenharmony_ci}
4871cb0ef41Sopenharmony_ci
4881cb0ef41Sopenharmony_ci}  // namespace util
4891cb0ef41Sopenharmony_ci}  // namespace node
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ciNODE_BINDING_CONTEXT_AWARE_INTERNAL(util, node::util::Initialize)
4921cb0ef41Sopenharmony_ciNODE_BINDING_EXTERNAL_REFERENCE(util, node::util::RegisterExternalReferences)
493