node-linux-arm64 23.11.0 → 24.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +427 -1937
  2. package/LICENSE +2 -2
  3. package/README.md +2 -0
  4. package/bin/node +0 -0
  5. package/include/node/common.gypi +4 -11
  6. package/include/node/config.gypi +4 -6
  7. package/include/node/cppgc/allocation.h +1 -2
  8. package/include/node/cppgc/default-platform.h +3 -2
  9. package/include/node/cppgc/heap-consistency.h +1 -1
  10. package/include/node/cppgc/internal/api-constants.h +0 -17
  11. package/include/node/cppgc/internal/base-page-handle.h +2 -4
  12. package/include/node/cppgc/internal/caged-heap-local-data.h +0 -4
  13. package/include/node/cppgc/internal/caged-heap.h +0 -4
  14. package/include/node/cppgc/internal/conditional-stack-allocated.h +41 -0
  15. package/include/node/cppgc/internal/logging.h +3 -3
  16. package/include/node/cppgc/internal/member-storage.h +63 -20
  17. package/include/node/cppgc/internal/persistent-node.h +8 -3
  18. package/include/node/cppgc/internal/pointer-policies.h +48 -11
  19. package/include/node/cppgc/macros.h +21 -0
  20. package/include/node/cppgc/member.h +70 -36
  21. package/include/node/cppgc/name-provider.h +3 -0
  22. package/include/node/cppgc/platform.h +11 -0
  23. package/include/node/cppgc/type-traits.h +1 -0
  24. package/include/node/cppgc/visitor.h +25 -1
  25. package/include/node/libplatform/libplatform-export.h +2 -2
  26. package/include/node/libplatform/v8-tracing.h +0 -1
  27. package/include/node/node.h +58 -15
  28. package/include/node/node_version.h +3 -3
  29. package/include/node/v8-array-buffer.h +111 -34
  30. package/include/node/v8-callbacks.h +84 -26
  31. package/include/node/v8-context.h +7 -6
  32. package/include/node/v8-cppgc.h +2 -1
  33. package/include/node/v8-data.h +5 -0
  34. package/include/node/v8-debug.h +11 -0
  35. package/include/node/v8-embedder-heap.h +1 -32
  36. package/include/node/v8-exception.h +2 -0
  37. package/include/node/v8-function-callback.h +4 -33
  38. package/include/node/v8-function.h +7 -0
  39. package/include/node/v8-handle-base.h +18 -0
  40. package/include/node/v8-initialization.h +9 -1
  41. package/include/node/v8-internal.h +477 -399
  42. package/include/node/v8-isolate.h +218 -151
  43. package/include/node/v8-local-handle.h +56 -28
  44. package/include/node/v8-maybe.h +2 -1
  45. package/include/node/v8-memory-span.h +149 -24
  46. package/include/node/v8-message.h +9 -1
  47. package/include/node/v8-object.h +7 -2
  48. package/include/node/v8-persistent-handle.h +17 -17
  49. package/include/node/v8-platform.h +48 -13
  50. package/include/node/v8-primitive.h +131 -6
  51. package/include/node/v8-profiler.h +13 -1
  52. package/include/node/v8-proxy.h +0 -1
  53. package/include/node/v8-regexp.h +0 -1
  54. package/include/node/v8-sandbox.h +3 -3
  55. package/include/node/v8-script.h +21 -3
  56. package/include/node/v8-source-location.h +6 -1
  57. package/include/node/v8-template.h +8 -2
  58. package/include/node/v8-traced-handle.h +16 -17
  59. package/include/node/v8-typed-array.h +6 -10
  60. package/include/node/v8-value.h +18 -0
  61. package/include/node/v8-version.h +4 -4
  62. package/include/node/v8-wasm.h +24 -0
  63. package/include/node/v8-weak-callback-info.h +20 -12
  64. package/include/node/v8.h +3 -3
  65. package/include/node/v8config.h +34 -40
  66. package/package.json +1 -1
  67. package/share/doc/node/gdbinit +94 -30
  68. package/share/doc/node/lldb_commands.py +107 -13
  69. package/share/man/man1/node.1 +4 -1
  70. package/include/node/cppgc/ephemeron-pair.h +0 -30
@@ -8,10 +8,10 @@
8
8
  // These macros define the version number for the current version.
9
9
  // NOTE these macros are used by some of the tool scripts and the build
10
10
  // system so their names cannot be changed without changing the scripts.
11
- #define V8_MAJOR_VERSION 12
12
- #define V8_MINOR_VERSION 9
13
- #define V8_BUILD_NUMBER 202
14
- #define V8_PATCH_LEVEL 28
11
+ #define V8_MAJOR_VERSION 13
12
+ #define V8_MINOR_VERSION 6
13
+ #define V8_BUILD_NUMBER 233
14
+ #define V8_PATCH_LEVEL 8
15
15
 
16
16
  // Use 1 for candidates and 0 otherwise.
17
17
  // (Boolean macro values are not supported by all preprocessors.)
@@ -199,6 +199,30 @@ class V8_EXPORT WasmStreaming final {
199
199
  std::unique_ptr<WasmStreamingImpl> impl_;
200
200
  };
201
201
 
202
+ /**
203
+ * The V8 interface for a WebAssembly memory map descriptor. This is an
204
+ * experimental feature that may change and be removed without further
205
+ * communication.
206
+ */
207
+ class V8_EXPORT WasmMemoryMapDescriptor : public Object {
208
+ public:
209
+ WasmMemoryMapDescriptor() = delete;
210
+
211
+ V8_INLINE static WasmMemoryMapDescriptor* Cast(Value* value) {
212
+ #ifdef V8_ENABLE_CHECKS
213
+ CheckCast(value);
214
+ #endif
215
+ return static_cast<WasmMemoryMapDescriptor*>(value);
216
+ }
217
+
218
+ using WasmFileDescriptor = int32_t;
219
+
220
+ static Local<WasmMemoryMapDescriptor> New(Isolate* isolate,
221
+ WasmFileDescriptor fd);
222
+
223
+ private:
224
+ static void CheckCast(Value* object);
225
+ };
202
226
  } // namespace v8
203
227
 
204
228
  #endif // INCLUDE_V8_WASM_H_
@@ -5,6 +5,9 @@
5
5
  #ifndef INCLUDE_V8_WEAK_CALLBACK_INFO_H_
6
6
  #define INCLUDE_V8_WEAK_CALLBACK_INFO_H_
7
7
 
8
+ #include <cstring>
9
+
10
+ #include "cppgc/internal/conditional-stack-allocated.h" // NOLINT(build/include_directory)
8
11
  #include "v8config.h" // NOLINT(build/include_directory)
9
12
 
10
13
  namespace v8 {
@@ -15,11 +18,12 @@ namespace api_internal {
15
18
  V8_EXPORT void InternalFieldOutOfBounds(int index);
16
19
  } // namespace api_internal
17
20
 
18
- static const int kInternalFieldsInWeakCallback = 2;
19
- static const int kEmbedderFieldsInWeakCallback = 2;
21
+ static constexpr int kInternalFieldsInWeakCallback = 2;
22
+ static constexpr int kEmbedderFieldsInWeakCallback = 2;
20
23
 
21
24
  template <typename T>
22
- class WeakCallbackInfo {
25
+ class WeakCallbackInfo
26
+ : public cppgc::internal::ConditionalStackAllocatedBase<T> {
23
27
  public:
24
28
  using Callback = void (*)(const WeakCallbackInfo<T>& data);
25
29
 
@@ -27,21 +31,25 @@ class WeakCallbackInfo {
27
31
  void* embedder_fields[kEmbedderFieldsInWeakCallback],
28
32
  Callback* callback)
29
33
  : isolate_(isolate), parameter_(parameter), callback_(callback) {
30
- for (int i = 0; i < kEmbedderFieldsInWeakCallback; ++i) {
31
- embedder_fields_[i] = embedder_fields[i];
32
- }
34
+ memcpy(embedder_fields_, embedder_fields,
35
+ sizeof(embedder_fields[0]) * kEmbedderFieldsInWeakCallback);
33
36
  }
34
37
 
35
38
  V8_INLINE Isolate* GetIsolate() const { return isolate_; }
36
39
  V8_INLINE T* GetParameter() const { return parameter_; }
37
40
  V8_INLINE void* GetInternalField(int index) const;
38
41
 
39
- // When first called, the embedder MUST Reset() the Global which triggered the
40
- // callback. The Global itself is unusable for anything else. No v8 other api
41
- // calls may be called in the first callback. Should additional work be
42
- // required, the embedder must set a second pass callback, which will be
43
- // called after all the initial callbacks are processed.
44
- // Calling SetSecondPassCallback on the second pass will immediately crash.
42
+ /**
43
+ * When a weak callback is first invoked the embedders _must_ Reset() the
44
+ * handle which triggered the callback. The handle itself is unusable for
45
+ * anything else. No other V8 API calls may be called in the first callback.
46
+ * Additional work requires scheduling a second invocation via
47
+ * `SetSecondPassCallback()` which will be called some time after all the
48
+ * initial callbacks are processed.
49
+ *
50
+ * The second pass callback is prohibited from executing JavaScript. Embedders
51
+ * should schedule another callback in case this is required.
52
+ */
45
53
  void SetSecondPassCallback(Callback callback) const { *callback_ = callback; }
46
54
 
47
55
  private:
package/include/node/v8.h CHANGED
@@ -2,6 +2,9 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
+ #ifndef INCLUDE_V8_H_
6
+ #define INCLUDE_V8_H_
7
+
5
8
  /** \mainpage V8 API Reference Guide
6
9
  *
7
10
  * V8 is Google's open source JavaScript engine.
@@ -12,9 +15,6 @@
12
15
  * For other documentation see https://v8.dev/.
13
16
  */
14
17
 
15
- #ifndef INCLUDE_V8_H_
16
- #define INCLUDE_V8_H_
17
-
18
18
  #include <stddef.h>
19
19
  #include <stdint.h>
20
20
 
@@ -371,6 +371,7 @@ path. Add it with -I<path> to the command line
371
371
  # define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused))
372
372
  # define V8_HAS_ATTRIBUTE_USED (__has_attribute(used))
373
373
  # define V8_HAS_ATTRIBUTE_RETAIN (__has_attribute(retain))
374
+ # define V8_HAS_ATTRIBUTE_OPTNONE (__has_attribute(optnone))
374
375
  // Support for the "preserve_most" attribute is limited:
375
376
  // - 32-bit platforms do not implement it,
376
377
  // - component builds fail because _dl_runtime_resolve clobbers registers,
@@ -499,6 +500,16 @@ path. Add it with -I<path> to the command line
499
500
  # define V8_INLINE inline
500
501
  #endif
501
502
 
503
+ // A macro to force better inlining of calls in a statement. Don't bother for
504
+ // debug builds.
505
+ // Use like:
506
+ // V8_INLINE_STATEMENT foo = bar(); // Will force inlining the bar() call.
507
+ #if !defined(DEBUG) && defined(__clang__) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
508
+ # define V8_INLINE_STATEMENT [[clang::always_inline]]
509
+ #else
510
+ # define V8_INLINE_STATEMENT
511
+ #endif
512
+
502
513
  #if V8_HAS_BUILTIN_ASSUME
503
514
  #ifdef DEBUG
504
515
  // In debug mode, check assumptions in addition to adding annotations.
@@ -681,7 +692,7 @@ path. Add it with -I<path> to the command line
681
692
  // V8_NODISCARD Foo() { ... };
682
693
  // [[nodiscard]] comes in C++17 but supported in clang with -std >= c++11.
683
694
  #if V8_HAS_CPP_ATTRIBUTE_NODISCARD
684
- #define V8_NODISCARD
695
+ #define V8_NODISCARD [[nodiscard]]
685
696
  #else
686
697
  #define V8_NODISCARD /* NOT SUPPORTED */
687
698
  #endif
@@ -787,15 +798,11 @@ V8 shared library set USING_V8_SHARED.
787
798
  #else // V8_OS_WIN
788
799
 
789
800
  // Setup for Linux shared library export.
790
- #if V8_HAS_ATTRIBUTE_VISIBILITY
791
- # ifdef BUILDING_V8_SHARED
792
- # define V8_EXPORT __attribute__ ((visibility("default")))
793
- # else
794
- # define V8_EXPORT
795
- # endif
801
+ #if V8_HAS_ATTRIBUTE_VISIBILITY && (defined(BUILDING_V8_SHARED) || USING_V8_SHARED)
802
+ # define V8_EXPORT __attribute__((visibility("default")))
796
803
  #else
797
804
  # define V8_EXPORT
798
- #endif
805
+ # endif // V8_HAS_ATTRIBUTE_VISIBILITY && ...
799
806
 
800
807
  #endif // V8_OS_WIN
801
808
 
@@ -833,16 +840,9 @@ V8 shared library set USING_V8_SHARED.
833
840
  #elif defined(__PPC64__) || defined(_ARCH_PPC64)
834
841
  #define V8_HOST_ARCH_PPC64 1
835
842
  #define V8_HOST_ARCH_64_BIT 1
836
- #elif defined(__PPC__) || defined(_ARCH_PPC)
837
- #define V8_HOST_ARCH_PPC 1
838
- #define V8_HOST_ARCH_32_BIT 1
839
- #elif defined(__s390__) || defined(__s390x__)
840
- #define V8_HOST_ARCH_S390 1
841
- #if defined(__s390x__)
843
+ #elif defined(__s390x__)
844
+ #define V8_HOST_ARCH_S390X 1
842
845
  #define V8_HOST_ARCH_64_BIT 1
843
- #else
844
- #define V8_HOST_ARCH_32_BIT 1
845
- #endif
846
846
  #elif defined(__riscv) || defined(__riscv__)
847
847
  #if __riscv_xlen == 64
848
848
  #define V8_HOST_ARCH_RISCV64 1
@@ -862,10 +862,10 @@ V8 shared library set USING_V8_SHARED.
862
862
  // The macros may be set externally. If not, detect in the same way as the host
863
863
  // architecture, that is, target the native environment as presented by the
864
864
  // compiler.
865
- #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && \
866
- !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_PPC && \
867
- !V8_TARGET_ARCH_PPC64 && !V8_TARGET_ARCH_S390 && \
868
- !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64 && \
865
+ #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && \
866
+ !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS64 && \
867
+ !V8_TARGET_ARCH_PPC64 && !V8_TARGET_ARCH_S390X && \
868
+ !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64 && \
869
869
  !V8_TARGET_ARCH_RISCV32
870
870
  #if defined(_M_X64) || defined(__x86_64__)
871
871
  #define V8_TARGET_ARCH_X64 1
@@ -881,13 +881,8 @@ V8 shared library set USING_V8_SHARED.
881
881
  #define V8_TARGET_ARCH_LOONG64 1
882
882
  #elif defined(_ARCH_PPC64)
883
883
  #define V8_TARGET_ARCH_PPC64 1
884
- #elif defined(_ARCH_PPC)
885
- #define V8_TARGET_ARCH_PPC 1
886
- #elif defined(__s390__)
887
- #define V8_TARGET_ARCH_S390 1
888
- #if defined(__s390x__)
884
+ #elif defined(__s390x__)
889
885
  #define V8_TARGET_ARCH_S390X 1
890
- #endif
891
886
  #elif defined(__riscv) || defined(__riscv__)
892
887
  #if __riscv_xlen == 64
893
888
  #define V8_TARGET_ARCH_RISCV64 1
@@ -920,16 +915,10 @@ V8 shared library set USING_V8_SHARED.
920
915
  #define V8_TARGET_ARCH_64_BIT 1
921
916
  #elif V8_TARGET_ARCH_LOONG64
922
917
  #define V8_TARGET_ARCH_64_BIT 1
923
- #elif V8_TARGET_ARCH_PPC
924
- #define V8_TARGET_ARCH_32_BIT 1
925
918
  #elif V8_TARGET_ARCH_PPC64
926
919
  #define V8_TARGET_ARCH_64_BIT 1
927
- #elif V8_TARGET_ARCH_S390
928
- #if V8_TARGET_ARCH_S390X
920
+ #elif V8_TARGET_ARCH_S390X
929
921
  #define V8_TARGET_ARCH_64_BIT 1
930
- #else
931
- #define V8_TARGET_ARCH_32_BIT 1
932
- #endif
933
922
  #elif V8_TARGET_ARCH_RISCV64
934
923
  #define V8_TARGET_ARCH_64_BIT 1
935
924
  #elif V8_TARGET_ARCH_RISCV32
@@ -986,14 +975,14 @@ V8 shared library set USING_V8_SHARED.
986
975
  #else
987
976
  #define V8_TARGET_LITTLE_ENDIAN 1
988
977
  #endif
989
- #elif defined(__BIG_ENDIAN__) // FOR PPCGR on AIX
978
+ #elif V8_TARGET_ARCH_PPC64
979
+ #if V8_OS_AIX
990
980
  #define V8_TARGET_BIG_ENDIAN 1
991
- #elif V8_TARGET_ARCH_PPC_LE
981
+ #else
992
982
  #define V8_TARGET_LITTLE_ENDIAN 1
993
- #elif V8_TARGET_ARCH_PPC_BE
994
- #define V8_TARGET_BIG_ENDIAN 1
995
- #elif V8_TARGET_ARCH_S390
996
- #if V8_TARGET_ARCH_S390_LE_SIM
983
+ #endif
984
+ #elif V8_TARGET_ARCH_S390X
985
+ #if V8_TARGET_ARCH_S390X_LE_SIM
997
986
  #define V8_TARGET_LITTLE_ENDIAN 1
998
987
  #else
999
988
  #define V8_TARGET_BIG_ENDIAN 1
@@ -1017,5 +1006,10 @@ V8 shared library set USING_V8_SHARED.
1017
1006
  #else
1018
1007
  #define V8_STATIC_ROOTS_BOOL true
1019
1008
  #endif
1009
+ #ifdef V8_TARGET_BIG_ENDIAN
1010
+ #define V8_TARGET_BIG_ENDIAN_BOOL true
1011
+ #else
1012
+ #define V8_TARGET_BIG_ENDIAN_BOOL false
1013
+ #endif
1020
1014
 
1021
1015
  #endif // V8CONFIG_H_
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-linux-arm64",
3
- "version": "v23.11.0",
3
+ "version": "v24.0.0",
4
4
  "description": "node",
5
5
  "bin": {
6
6
  "node": "bin/node"
@@ -81,9 +81,12 @@ class PrintV8InternalHandleCommand(PrintV8HandleCommand):
81
81
  # Indirect handles contain a location_.
82
82
  if gdb.types.has_field(value.type, "location_"):
83
83
  return self.print_indirect(value["location_"], from_tty)
84
- # Direct handles contain a obj_.
84
+ # With v8_enable_direct_handle=true, direct handles contain a obj_.
85
85
  if gdb.types.has_field(value.type, "obj_"):
86
86
  return self.print_direct(value["obj_"], from_tty)
87
+ # Without v8_enable_direct_handle=true, direct handles contain a handle_.
88
+ if gdb.types.has_field(value.type, "handle_"):
89
+ return self.print_handle(value["handle_"], from_tty)
87
90
  # We don't know how to print this...
88
91
  return False
89
92
 
@@ -108,12 +111,21 @@ Print a v8 Code object from an internal code address
108
111
  Usage: jco pc
109
112
  end
110
113
 
114
+ # Print JSDispatchEntry object in the JSDispatchTable with the given dispatch handle
115
+ define jdh
116
+ call (void) _v8_internal_Print_Dispatch_Handle((uint32_t)($arg0))
117
+ end
118
+ document jdh
119
+ Print JSDispatchEntry object in the JSDispatchTable with the given dispatch handle
120
+ Usage: jdh dispatch_handle
121
+ end
122
+
111
123
  # Print Code objects assembly code surrounding given PC.
112
124
  define jca
113
125
  if $argc == 0
114
126
  call (void) _v8_internal_Print_OnlyCode((void*)($pc), 30)
115
127
  else
116
- if $argc == 0
128
+ if $argc == 1
117
129
  call (void) _v8_internal_Print_OnlyCode((void*)($arg0), 30)
118
130
  else
119
131
  call (void) _v8_internal_Print_OnlyCode((void*)($arg0), (size_t)($arg1))
@@ -282,7 +294,7 @@ except gdb.error:
282
294
  end
283
295
 
284
296
  # Configuring ASLR may not be possible on some platforms, such running via the
285
- # `rr` debuggger.
297
+ # `rr` debugger.
286
298
  python
287
299
  try:
288
300
  gdb.execute("set disable-randomization off")
@@ -309,15 +321,26 @@ def v8_stop_handler(event):
309
321
  # walk if we see this frame.
310
322
  if frame.type() == gdb.DUMMY_FRAME: break
311
323
 
312
- if frame.name() == 'V8_Dcheck':
313
- frame_message = gdb.lookup_symbol('message', frame.block())[0]
314
- if frame_message:
315
- message = frame_message.value(frame).string()
324
+ frame_name = frame.name()
325
+ if frame_name is None:
326
+ frame = frame.older()
327
+ continue
328
+ if frame_name == 'V8_Dcheck' or frame_name.endswith('::DefaultDcheckHandler'):
329
+ try:
330
+ frame_message = gdb.lookup_symbol('message', frame.block())[0]
331
+ if frame_message:
332
+ message = frame_message.value(frame).string()
333
+ except:
334
+ pass
316
335
  select_frame = frame.older()
317
- break
318
- if frame.name() is not None and frame.name().startswith('V8_Fatal'):
319
- select_frame = frame.older()
320
- if frame.name() == 'v8::base::OS::DebugBreak':
336
+ if any([
337
+ frame_name.startswith('V8_Fatal'),
338
+ frame_name == 'v8::base::OS::DebugBreak',
339
+ frame_name == '__GI_abort',
340
+ frame_name == '__GI_raise',
341
+ frame_name == 'v8::base::OS::Abort',
342
+ frame_name == 'v8::Utils::ApiCheck',
343
+ ]):
321
344
  select_frame = frame.older()
322
345
  frame = frame.older()
323
346
 
@@ -325,7 +348,7 @@ def v8_stop_handler(event):
325
348
  select_frame.select()
326
349
  gdb.execute('frame')
327
350
  if message:
328
- print('DCHECK error: {}'.format(message))
351
+ print('==> DCHECK error: {}'.format(message))
329
352
 
330
353
  gdb.events.stop.connect(v8_stop_handler)
331
354
  end
@@ -384,24 +407,6 @@ end
384
407
 
385
408
  ### CppGC helpers.
386
409
 
387
- # Print compressed pointer.
388
- define cpcp
389
- call _cppgc_internal_Decompress_Compressed_Pointer((unsigned)($arg0))
390
- end
391
- document cpcp
392
- Prints compressed pointer (raw value) after decompression.
393
- Usage: cpcp compressed_pointer
394
- end
395
-
396
- # Print member.
397
- define cpm
398
- call _cppgc_internal_Print_Member((cppgc::internal::MemberBase*)(&$arg0))
399
- end
400
- document cpm
401
- Prints member, compressed or not.
402
- Usage: cpm member
403
- end
404
-
405
410
  # Pretty printer for cppgc::Member.
406
411
  python
407
412
 
@@ -450,5 +455,64 @@ def cppgc_pretty_printers(val):
450
455
 
451
456
 
452
457
  gdb.pretty_printers.append(cppgc_pretty_printers)
458
+ class TaggedPrintCommand(gdb.Command):
459
+ """
460
+ The equivalent of the print command that deals with tagged objects
461
+
462
+ Usage: tp <expression>
463
+ Example: tp Isolate::Current()->context()->get(3)
464
+ """
465
+
466
+ def __init__(self):
467
+ super(TaggedPrintCommand, self).__init__("tp", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION)
468
+
469
+ def invoke(self, arg, from_tty):
470
+ """Called when the 'tp' command is invoked."""
471
+ try:
472
+ # Split the expression by '->' to handle chained calls.
473
+ parts = arg.split("->")
474
+ if not parts:
475
+ print("Error: No expression provided.")
476
+ return
477
+
478
+ if len(parts) == 1:
479
+ gdb.execute(f"print {parts[0]}")
480
+ else:
481
+ current_val = gdb.parse_and_eval(parts[0])
482
+ for part in parts[1:-1]:
483
+ current_val = self._evaluate_part(current_val, part, False)
484
+ if current_val is None: # Early exit if an evaluation fails.
485
+ return
486
+
487
+ self._evaluate_part(current_val, parts[-1], True)
488
+
489
+ except gdb.error as e:
490
+ print(f"Error: {e}")
491
+
492
+ def _evaluate_part(self, current_val, part, last):
493
+ """Evaluates a single part of the expression (method call or member access)."""
494
+
495
+ storage = None
496
+ target = f"(({current_val.type}){current_val})"
497
+
498
+ type = current_val.type
499
+ if type.tag and type.tag.startswith("v8::internal::Tagged<"):
500
+ storage = gdb.parse_and_eval(f"malloc({type.sizeof})").cast(type.pointer())
501
+ command = f"(({storage.type}){storage})->ptr_ = {current_val['ptr_']}"
502
+ gdb.parse_and_eval(command)
503
+ target = f"(({storage.type}){storage})->ToRawPtr()"
504
+
505
+ # Check for a method call (ends with parentheses).
506
+ command = f"{target}->{part}"
507
+ result = None
508
+ if last:
509
+ gdb.execute(f"print {command}")
510
+ else:
511
+ result = gdb.parse_and_eval(command)
512
+ if storage:
513
+ gdb.parse_and_eval(f"free({storage})")
514
+ return result
515
+
516
+ TaggedPrintCommand()
453
517
 
454
518
  end
@@ -10,6 +10,7 @@ from __future__ import print_function
10
10
 
11
11
  import os
12
12
  import re
13
+ import shlex
13
14
 
14
15
  import lldb
15
16
 
@@ -42,12 +43,27 @@ def no_arg_cmd(debugger, cmd, print_error=True):
42
43
  return (is_success, result, cmd)
43
44
 
44
45
 
45
- def ptr_arg_cmd(debugger, name, param, cmd, print_error=True):
46
+ def ptr_arg_cmd(debugger, name, param, cmd, fields=[], print_error=True):
46
47
  if not param:
47
48
  print("'{}' requires an argument".format(name))
48
49
  return (False, None, "")
49
- param = '(void*)({})'.format(param)
50
- return no_arg_cmd(debugger, cmd.format(param), print_error)
50
+ value = current_frame(debugger).EvaluateExpression(param)
51
+ error = value.GetError()
52
+ if error.fail:
53
+ print("Error evaluating {}\n{}".format(param, error))
54
+ return (False, error, "")
55
+ # Proceed, ignoring visualizers if they are enabled.
56
+ value = value.GetNonSyntheticValue()
57
+ # Process interesting fields, if this is a structure.
58
+ while True:
59
+ for f in fields:
60
+ field = value.GetValueForExpressionPath(f)
61
+ if field.IsValid():
62
+ value = field
63
+ break
64
+ else:
65
+ break
66
+ return no_arg_cmd(debugger, cmd.format(value.GetValue()), print_error)
51
67
 
52
68
 
53
69
  def print_handle(debugger, command_name, param, print_func):
@@ -66,12 +82,12 @@ def print_handle(debugger, command_name, param, print_func):
66
82
 
67
83
  def print_direct(debugger, command_name, value):
68
84
  CMD = "_v8_internal_Print_Object((v8::internal::Address*)({}))"
69
- return ptr_arg_cmd(debugger, command_name, value, CMD.format(value))
85
+ return no_arg_cmd(debugger, CMD.format(value))
70
86
 
71
87
 
72
88
  def print_indirect(debugger, command_name, value):
73
- CMD = "_v8_internal_Print_Object(*(v8::internal::Object**)({}))"
74
- return ptr_arg_cmd(debugger, command_name, value, CMD.format(value))
89
+ CMD = "_v8_internal_Print_Object(*(v8::internal::Address**)({}))"
90
+ return no_arg_cmd(debugger, CMD.format(value))
75
91
 
76
92
 
77
93
  V8_LLDB_COMMANDS = []
@@ -89,7 +105,9 @@ def lldbCommand(fn):
89
105
  @lldbCommand
90
106
  def job(debugger, param, *args):
91
107
  """Print a v8 heap object"""
92
- ptr_arg_cmd(debugger, 'job', param, "_v8_internal_Print_Object({})")
108
+ CMD = "_v8_internal_Print_Object((void*)({}))"
109
+ # Allow for Tagged<T>, containing a ptr_.
110
+ ptr_arg_cmd(debugger, 'job', param, CMD, [".ptr_"])
93
111
 
94
112
 
95
113
  @lldbCommand
@@ -101,10 +119,14 @@ def jh(debugger, param, *args):
101
119
  field = value.GetValueForExpressionPath(".location_")
102
120
  if field.IsValid():
103
121
  return print_indirect(debugger, 'jh', field.value)
104
- # Direct handles contain a obj_.
122
+ # With v8_enable_direct_handle=true, direct handles contain a obj_.
105
123
  field = value.GetValueForExpressionPath(".obj_")
106
124
  if field.IsValid():
107
- return print_indirect(debugger, 'jh', field.value)
125
+ return print_direct(debugger, 'jh', field.value)
126
+ # Without v8_enable_direct_handle=true, direct handles contain a handle_.
127
+ field = value.GetValueForExpressionPath(".handle_")
128
+ if field.IsValid():
129
+ return print_func(field)
108
130
  # We don't know how to print this...
109
131
  return (False, None, "")
110
132
 
@@ -147,15 +169,47 @@ def jl(debugger, param, *args):
147
169
  @lldbCommand
148
170
  def jco(debugger, param, *args):
149
171
  """Print the code object at the given pc (default: current pc)"""
172
+ CMD = "_v8_internal_Print_Code((void*)({}))"
150
173
  if not param:
151
174
  param = str(current_frame(debugger).FindRegister("pc").value)
152
- ptr_arg_cmd(debugger, 'jco', param, "_v8_internal_Print_Code({})")
175
+ no_arg_cmd(debugger, CMD.format(param))
176
+
177
+
178
+ @lldbCommand
179
+ def jdh(debugger, param, *args):
180
+ """Print JSDispatchEntry object in the JSDispatchTable with the given dispatch handle"""
181
+ CMD = "_v8_internal_Print_Dispatch_Handle((uint32_t)({}))"
182
+ # Allow for JSDispatchHandle, containing a value_.
183
+ ptr_arg_cmd(debugger, 'jdh', param, CMD, [".value_"])
184
+
185
+
186
+ @lldbCommand
187
+ def jca(debugger, param, *args):
188
+ """Print a v8 Code object assembly code from an internal code address"""
189
+ param = shlex.split(param)
190
+ if not param:
191
+ obj = str(current_frame(debugger).FindRegister("pc").value)
192
+ else:
193
+ obj = param[0]
194
+ range_limit = param[1] if len(param) > 1 else 30
195
+ CMD = "_v8_internal_Print_OnlyCode((void*)({}), (size_t)({}))"
196
+ no_arg_cmd(debugger, CMD.format(obj, range_limit))
153
197
 
154
198
 
155
199
  @lldbCommand
156
200
  def jtt(debugger, param, *args):
157
- """Print the transition tree of a v8 Map"""
158
- ptr_arg_cmd(debugger, 'jtt', param, "_v8_internal_Print_TransitionTree({})")
201
+ """Print the complete transition tree starting at the given v8 map"""
202
+ CMD = "_v8_internal_Print_TransitionTree((void*)({}), false)"
203
+ # Allow for Tagged<T>, containing a ptr_.
204
+ ptr_arg_cmd(debugger, 'jtt', param, CMD, [".ptr_"])
205
+
206
+
207
+ @lldbCommand
208
+ def jttr(debugger, param, *args):
209
+ """Print the complete transition tree starting at the root map of the given v8 map"""
210
+ CMD = "_v8_internal_Print_TransitionTree((void*)({}), true)"
211
+ # Allow for Tagged<T>, containing a ptr_.
212
+ ptr_arg_cmd(debugger, 'jttr', param, CMD, [".ptr_"])
159
213
 
160
214
 
161
215
  @lldbCommand
@@ -164,6 +218,14 @@ def jst(debugger, *args):
164
218
  no_arg_cmd(debugger, "_v8_internal_Print_StackTrace()")
165
219
 
166
220
 
221
+ @lldbCommand
222
+ def pn(debugger, param, *args):
223
+ """Print a v8 TurboFan graph node"""
224
+ CMD = "_v8_internal_Node_Print((void*)({}))"
225
+ # Allow for Tagged<T>, containing a ptr_.
226
+ ptr_arg_cmd(debugger, 'pn', param, CMD, [".ptr_"])
227
+
228
+
167
229
  @lldbCommand
168
230
  def jss(debugger, *args):
169
231
  """Skip the jitted stack on x64 to where we entered JS last"""
@@ -180,6 +242,37 @@ def jss(debugger, *args):
180
242
  pc.value = js_entry_sp + sizeof_void
181
243
 
182
244
 
245
+ @lldbCommand
246
+ def jfci(debugger, param, *args):
247
+ """Print v8::FunctionCallbackInfo<T>& info"""
248
+ CMD = "_v8_internal_Print_FunctionCallbackInfo((void*)(&{}))"
249
+ if not param:
250
+ print("'jfci' requires an argument")
251
+ else:
252
+ no_arg_cmd(debugger, CMD.format(param))
253
+
254
+
255
+ @lldbCommand
256
+ def jpci(debugger, param, *args):
257
+ """Print v8::PropertyCallbackInfo<T>& info"""
258
+ CMD = "_v8_internal_Print_PropertyCallbackInfo((void*)(&{}))"
259
+ if not param:
260
+ print("'jpci' requires an argument")
261
+ else:
262
+ no_arg_cmd(debugger, CMD.format(param))
263
+
264
+
265
+ # Print whether the object is marked, the mark-bit cell and index. The address
266
+ # of the cell is handy for reverse debugging to check when the object was
267
+ # marked/unmarked.
268
+ @lldbCommand
269
+ def jomb(debugger, param, *args):
270
+ """Print whether the object is marked, the markbit cell and index"""
271
+ CMD = "_v8_internal_Print_Object_MarkBit((void*)({}))"
272
+ # Allow for Tagged<T>, containing a ptr_.
273
+ ptr_arg_cmd(debugger, 'jomb', param, CMD, [".ptr_"])
274
+
275
+
183
276
  @lldbCommand
184
277
  def bta(debugger, *args):
185
278
  """Print stack trace with assertion scopes"""
@@ -194,7 +287,7 @@ def bta(debugger, *args):
194
287
  functionName = func_name_re.match(functionSignature)
195
288
  line = frame.GetLineEntry().GetLine()
196
289
  sourceFile = frame.GetLineEntry().GetFileSpec().GetFilename()
197
- if line:
290
+ if sourceFile and line:
198
291
  sourceFile = sourceFile + ":" + str(line)
199
292
 
200
293
  if sourceFile is None:
@@ -213,6 +306,7 @@ def bta(debugger, *args):
213
306
  print("%s -> %s %s (%s)\033[0m" % (
214
307
  color, prefix, match.group(2), match.group(1)))
215
308
 
309
+
216
310
  def setup_source_map_for_relative_paths(debugger):
217
311
  # Copied from Chromium's tools/lldb/lldbinit.py.
218
312
  # When relative paths are used for debug symbols, lldb cannot find source
@@ -464,6 +464,9 @@ Require a minimum threshold for line coverage (0 - 100).
464
464
  Configures the test runner to exit the process once all known tests have
465
465
  finished executing even if the event loop would otherwise remain active.
466
466
  .
467
+ .It Fl -test-global-setup
468
+ Specifies a module containing global setup and teardown functions for the test runner.
469
+ .
467
470
  .It Fl -test-isolation Ns = Ns Ar mode
468
471
  Configures the type of test isolation used in the test runner.
469
472
  .
@@ -616,7 +619,7 @@ If set to 0 then V8 will choose an appropriate size of the thread pool based on
616
619
  If the value provided is larger than V8's maximum, then the largest value will be chosen.
617
620
  .
618
621
  .It Fl -zero-fill-buffers
619
- Automatically zero-fills all newly allocated Buffer and SlowBuffer instances.
622
+ Automatically zero-fills all newly allocated Buffer instances.
620
623
  .
621
624
  .It Fl c , Fl -check
622
625
  Check the script's syntax without executing it.