Coverage Report

Created: 2025-09-04 06:34

/src/hermes/lib/VM/HermesValue.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) Meta Platforms, Inc. and affiliates.
3
 *
4
 * This source code is licensed under the MIT license found in the
5
 * LICENSE file in the root directory of this source tree.
6
 */
7
8
#include "hermes/VM/HermesValue.h"
9
10
#include "hermes/VM/BigIntPrimitive.h"
11
#include "hermes/VM/GC.h"
12
#include "hermes/VM/Runtime.h"
13
#include "hermes/VM/StringPrimitive.h"
14
15
#include "hermes/Support/UTF8.h"
16
17
#include "llvh/Support/ErrorHandling.h"
18
#include "llvh/Support/Format.h"
19
#include "llvh/Support/raw_ostream.h"
20
21
namespace hermes {
22
namespace vm {
23
24
0
void HermesValue::dump(llvh::raw_ostream &os) const {
25
0
  os << *this << "\n";
26
0
}
27
28
0
llvh::raw_ostream &operator<<(llvh::raw_ostream &OS, HermesValue hv) {
29
0
  switch (hv.getETag()) {
30
0
    case HermesValue::ETag::Object1:
31
0
    case HermesValue::ETag::Object2: {
32
0
      auto *cell = static_cast<GCCell *>(hv.getObject());
33
0
      return OS << "[Object " << (cell ? cellKindStr(cell->getKind()) : "")
34
0
                << ":" << (cell ? cell->getDebugAllocationId() : 0) << " "
35
0
                << llvh::format_hex((uintptr_t)cell, 10) << "]";
36
0
    }
37
0
    case HermesValue::ETag::Str1:
38
0
    case HermesValue::ETag::Str2: {
39
0
      auto *cell = static_cast<GCCell *>(hv.getPointer());
40
0
      OS << "[String " << ":" << (cell ? cell->getDebugAllocationId() : 0)
41
0
         << " " << llvh::format_hex((uintptr_t)cell, 10);
42
      // Note contained StringPrimitive may be NULL.
43
0
      if (hv.getString()) {
44
0
        llvh::SmallVector<char16_t, 16> storage;
45
0
        hv.getString()->appendUTF16String(storage);
46
0
        std::string narrowStr;
47
0
        convertUTF16ToUTF8WithReplacements(narrowStr, storage);
48
0
        OS << " '";
49
0
        OS.write_escaped(narrowStr);
50
0
        OS << "'";
51
0
      }
52
0
      return OS << ']';
53
0
    }
54
0
    case HermesValue::ETag::BigInt1:
55
0
    case HermesValue::ETag::BigInt2: {
56
0
      auto *cell = static_cast<GCCell *>(hv.getPointer());
57
0
      OS << "[BigInt " << ":" << (cell ? cell->getDebugAllocationId() : 0)
58
0
         << " " << llvh::format_hex((uintptr_t)cell, 10);
59
      // Note contained BigIntPrimitive may be NULL.
60
0
      if (hv.getBigInt()) {
61
0
        llvh::ArrayRef<uint8_t> storage = hv.getBigInt()->getRawDataCompact();
62
0
        for (auto it = storage.rbegin(); it != storage.rend(); ++it) {
63
0
          OS << " " << llvh::format_hex(*it, 2);
64
0
        }
65
0
      }
66
0
      return OS << ']';
67
0
    }
68
0
    case HermesValue::ETag::Native1:
69
0
    case HermesValue::ETag::Native2:
70
0
      return OS << "[NativeValue " << hv.getNativeUInt32() << "]";
71
0
    case HermesValue::ETag::Symbol:
72
0
      return OS << "[Symbol "
73
0
                << (hv.getSymbol().isNotUniqued() ? "(External)" : "(Internal)")
74
0
                << ' ' << hv.getSymbol().unsafeGetIndex() << "]";
75
0
    case HermesValue::ETag::Bool:
76
0
      return OS << (hv.getBool() ? "true" : "false");
77
0
    case HermesValue::ETag::Undefined:
78
0
      return OS << "undefined";
79
0
    case HermesValue::ETag::Null:
80
0
      return OS << "null";
81
0
    case HermesValue::ETag::Empty:
82
0
      return OS << "empty";
83
0
#ifdef HERMES_SLOW_DEBUG
84
0
    case HermesValue::ETag::Invalid:
85
0
      return OS << "invalid";
86
0
#endif
87
0
    default:
88
0
      double num = hv.getDouble();
89
      // Is it representable as int64_t?
90
0
      if (num >= std::numeric_limits<int64_t>::lowest() &&
91
          // The cast is to ignore the following warning:
92
          // implicit conversion from 'int64_t' to 'double' changes value.
93
0
          num <= (double)std::numeric_limits<int64_t>::max() &&
94
0
          (int64_t)num == num) {
95
0
        return OS << "[double " << (int64_t)num << "]";
96
0
      } else {
97
0
        return OS << "[double " << num << "]";
98
0
      }
99
0
  }
100
0
}
101
102
} // namespace vm
103
} // namespace hermes