deps: update V8 to 12.7.224.16

This commit is contained in:
Michaël Zasso 2024-07-17 09:03:06 +02:00
parent aca49fc7d1
commit 0ec8f7eea3
No known key found for this signature in database
GPG key ID: 770F7A9A5AE15600
2108 changed files with 107786 additions and 59784 deletions

2
deps/v8/.gitignore vendored
View file

@ -40,6 +40,7 @@
.torquelint-cache
.vscode
/_*
/base
/build
/buildtools
/check-header-includes
@ -96,6 +97,7 @@
/tools/luci-go
/tools/oom_dump/oom_dump
/tools/oom_dump/oom_dump.o
/tools/protoc_wrapper
/tools/turbolizer/build
/tools/turbolizer/.rpt2_cache
/tools/turbolizer/deploy

2
deps/v8/.gn vendored
View file

@ -25,6 +25,8 @@ no_check_targets = [
]
default_args = {
# Disable js dependencies like the closure compiler.
enable_js_protobuf = false
# Disable rust dependencies.
enable_rust = false
}

3
deps/v8/AUTHORS vendored
View file

@ -57,6 +57,7 @@ Alexander Botero-Lowry <alexbl@FreeBSD.org>
Alexander Karpinsky <homm86@gmail.com>
Alexander Neville <dark@volatile.bz>
Alexandre Vassalotti <avassalotti@gmail.com>
Alexey Pavlyutkin <alexey.pavlyutkin.community@gmail.com>
Alexis Campailla <alexis@janeasystems.com>
Allan Sandfeld Jensen <allan.jensen@qt.io>
Amos Lim <eui-sang.lim@samsung.com>
@ -181,7 +182,6 @@ Kevin Gibbons <bakkot@gmail.com>
Keyhan Vakil <kvakil@googlecontrib.kvakil.me>
Kris Selden <kris.selden@gmail.com>
Kyounga Ra <kyounga@alticast.com>
Levi Zim <rsworktech@outlook.com>
Loo Rong Jie <loorongjie@gmail.com>
Lu Yahan <yahan@iscas.ac.cn>
Ludovic Mermod <ludovic.mermod@gmail.com>
@ -258,6 +258,7 @@ Sander Mathijs van Veen <sander@leaningtech.com>
Sandro Santilli <strk@keybit.net>
Sanjoy Das <sanjoy@playingwithpointers.com>
Sam James <sam@gentoo.org>
Sébastien Doeraene <sjrdoeraene@gmail.com>
Seo Sanghyeon <sanxiyn@gmail.com>
Shawn Anastasio <shawnanastasio@gmail.com>
Shawn Presser <shawnpresser@gmail.com>

197
deps/v8/BUILD.bazel vendored
View file

@ -274,18 +274,6 @@ v8_flag(
default = True,
)
# Shared RO heap. Flag has to be set to false when
# v8_enable_pointer_compression_shared_cage is set to false.
v8_flag(
name = "v8_enable_shared_ro_heap",
default = True,
)
v8_flag(
name = "v8_enable_extensible_ro_snapshot",
default = True,
)
# Enable shared cage if v8_enable_pointer_compression
# and v8_enable_pointer_compression_shared_cage.
selects.config_setting_group(
@ -429,6 +417,7 @@ v8_config(
"V8_ADVANCED_BIGINT_ALGORITHMS",
"V8_CONCURRENT_MARKING",
"V8_ENABLE_SPARKPLUG",
"V8_ENABLE_EXTENSIBLE_RO_SNAPSHOT",
] + select({
"@v8//bazel/config:is_debug": [
"DEBUG",
@ -497,13 +486,13 @@ v8_config(
],
"//conditions:default": [],
}) + select({
":is_v8_enable_shared_ro_heap": [
# Shared RO heap is unconfigurable in bazel. However, we
# still have to make sure that the flag is disabled when
# v8_enable_pointer_compression_shared_cage is set to false.
":is_v8_enable_pointer_compression_shared_cage": [
"V8_SHARED_RO_HEAP",
],
}) + select({
":is_v8_enable_extensible_ro_snapshot": [
"V8_ENABLE_EXTENSIBLE_RO_SNAPSHOT",
],
"//conditions:default": [],
}) + select({
":is_v8_enable_short_builtin_calls": [
"V8_SHORT_BUILTIN_CALLS",
@ -653,6 +642,7 @@ filegroup(
"include/v8-promise.h",
"include/v8-proxy.h",
"include/v8-regexp.h",
"include/v8-sandbox.h",
"include/v8-script.h",
"include/v8-snapshot.h",
"include/v8-statistics.h",
@ -798,6 +788,10 @@ filegroup(
"src/base/strings.h",
"src/base/sys-info.cc",
"src/base/sys-info.h",
"src/base/template-meta-programming/algorithm.h",
"src/base/template-meta-programming/functional.h",
"src/base/template-meta-programming/list.h",
"src/base/template-meta-programming/string-literal.h",
"src/base/template-utils.h",
"src/base/threaded-list.h",
"src/base/timezone-cache.h",
@ -1070,6 +1064,7 @@ filegroup(
"src/objects/js-atomics-synchronization.tq",
"src/objects/js-collection.tq",
"src/objects/js-collection-iterator.tq",
"src/objects/js-disposable-stack.tq",
"src/objects/js-function.tq",
"src/objects/js-generator.tq",
"src/objects/js-iterator-helpers.tq",
@ -1209,15 +1204,6 @@ filegroup(
],
)
# Default setting for v8_enable_pointer_compression when target is x64.
selects.config_setting_group(
name = "is_v8_enable_webassembly_on_non_android_posix_x64",
match_all = [
":is_v8_enable_webassembly",
"@v8//bazel/config:is_non_android_posix_x64",
],
)
filegroup(
name = "v8_base_without_compiler_files",
srcs = [
@ -1292,6 +1278,7 @@ filegroup(
"src/builtins/builtins-date.cc",
"src/builtins/builtins-definitions.h",
"src/builtins/builtins-descriptors.h",
"src/builtins/builtins-disposable-stack.cc",
"src/builtins/builtins-error.cc",
"src/builtins/builtins-function.cc",
"src/builtins/builtins-global.cc",
@ -1409,6 +1396,7 @@ filegroup(
"src/common/ptr-compr.cc",
"src/common/ptr-compr.h",
"src/common/ptr-compr-inl.h",
"src/common/simd128.h",
"src/compiler-dispatcher/lazy-compile-dispatcher.cc",
"src/compiler-dispatcher/lazy-compile-dispatcher.h",
"src/compiler-dispatcher/optimizing-compile-dispatcher.cc",
@ -1572,6 +1560,7 @@ filegroup(
"src/heap/base/active-system-pages.h",
"src/heap/memory-chunk-metadata.cc",
"src/heap/memory-chunk-metadata.h",
"src/heap/memory-chunk-metadata-inl.h",
"src/heap/code-range.cc",
"src/heap/code-range.h",
"src/heap/trusted-range.cc",
@ -1621,8 +1610,6 @@ filegroup(
"src/heap/free-list.h",
"src/heap/free-list-inl.h",
"src/heap/gc-callbacks.h",
"src/heap/gc-idle-time-handler.cc",
"src/heap/gc-idle-time-handler.h",
"src/heap/gc-tracer.cc",
"src/heap/gc-tracer.h",
"src/heap/gc-tracer-inl.h",
@ -1648,8 +1635,9 @@ filegroup(
"src/heap/incremental-marking-job.h",
"src/heap/index-generator.cc",
"src/heap/index-generator.h",
"src/heap/large-page.cc",
"src/heap/large-page.h",
"src/heap/large-page-metadata.cc",
"src/heap/large-page-metadata.h",
"src/heap/large-page-metadata-inl.h",
"src/heap/large-spaces.cc",
"src/heap/large-spaces.h",
"src/heap/linear-allocation-area.h",
@ -1688,11 +1676,12 @@ filegroup(
"src/heap/memory-allocator.h",
"src/heap/memory-balancer.cc",
"src/heap/memory-balancer.h",
"src/heap/mutable-page.cc",
"src/heap/mutable-page.h",
"src/heap/mutable-page-metadata.cc",
"src/heap/mutable-page-metadata.h",
"src/heap/mutable-page-metadata-inl.h",
"src/heap/memory-chunk.cc",
"src/heap/memory-chunk.h",
"src/heap/mutable-page-inl.h",
"src/heap/memory-chunk-inl.h",
"src/heap/memory-chunk-layout.cc",
"src/heap/memory-chunk-layout.h",
"src/heap/memory-measurement.cc",
@ -1706,14 +1695,15 @@ filegroup(
"src/heap/new-spaces.h",
"src/heap/new-spaces-inl.h",
"src/heap/object-lock.h",
"src/heap/object-lock-inl.h",
"src/heap/object-stats.cc",
"src/heap/object-stats.h",
"src/heap/objects-visiting.cc",
"src/heap/objects-visiting.h",
"src/heap/objects-visiting-inl.h",
"src/heap/page.cc",
"src/heap/page.h",
"src/heap/page-inl.h",
"src/heap/page-metadata.cc",
"src/heap/page-metadata.h",
"src/heap/page-metadata-inl.h",
"src/heap/paged-spaces.cc",
"src/heap/paged-spaces.h",
"src/heap/paged-spaces-inl.h",
@ -1774,8 +1764,8 @@ filegroup(
"src/init/heap-symbols.h",
"src/init/icu_util.cc",
"src/init/icu_util.h",
"src/init/isolate-allocator.cc",
"src/init/isolate-allocator.h",
"src/init/isolate-group.cc",
"src/init/isolate-group.h",
"src/init/setup-isolate.h",
"src/init/startup-data-util.cc",
"src/init/startup-data-util.h",
@ -1792,8 +1782,8 @@ filegroup(
"src/interpreter/bytecode-array-writer.h",
"src/interpreter/bytecode-decoder.cc",
"src/interpreter/bytecode-decoder.h",
"src/interpreter/bytecode-flags.cc",
"src/interpreter/bytecode-flags.h",
"src/interpreter/bytecode-flags-and-tokens.cc",
"src/interpreter/bytecode-flags-and-tokens.h",
"src/interpreter/bytecode-generator.cc",
"src/interpreter/bytecode-generator.h",
"src/interpreter/bytecode-jump-table.h",
@ -1877,6 +1867,7 @@ filegroup(
"src/objects/call-site-info.cc",
"src/objects/call-site-info.h",
"src/objects/call-site-info-inl.h",
"src/objects/casting.h",
"src/objects/cell.h",
"src/objects/cell-inl.h",
"src/objects/code.cc",
@ -1960,6 +1951,9 @@ filegroup(
"src/objects/js-collection-inl.h",
"src/objects/js-collection-iterator.h",
"src/objects/js-collection-iterator-inl.h",
"src/objects/js-disposable-stack.cc",
"src/objects/js-disposable-stack.h",
"src/objects/js-disposable-stack-inl.h",
"src/objects/js-function.cc",
"src/objects/js-function.h",
"src/objects/js-function-inl.h",
@ -2142,6 +2136,8 @@ filegroup(
"src/objects/visitors.cc",
"src/objects/visitors.h",
"src/objects/visitors-inl.h",
"src/objects/waiter-queue-node.cc",
"src/objects/waiter-queue-node.h",
"src/parsing/expression-scope.h",
"src/parsing/func-name-inferrer.cc",
"src/parsing/func-name-inferrer.h",
@ -2292,6 +2288,10 @@ filegroup(
"src/sandbox/external-pointer-table.cc",
"src/sandbox/external-pointer-table.h",
"src/sandbox/external-pointer-table-inl.h",
"src/sandbox/cppheap-pointer-inl.h",
"src/sandbox/cppheap-pointer-table.cc",
"src/sandbox/cppheap-pointer-table.h",
"src/sandbox/cppheap-pointer-table-inl.h",
"src/sandbox/code-pointer-table.cc",
"src/sandbox/code-pointer-table.h",
"src/sandbox/code-pointer-table-inl.h",
@ -2300,18 +2300,27 @@ filegroup(
"src/sandbox/trusted-pointer-table-inl.h",
"src/sandbox/code-pointer.h",
"src/sandbox/code-pointer-inl.h",
"src/sandbox/compactible-external-entity-table-inl.h",
"src/sandbox/compactible-external-entity-table.h",
"src/sandbox/isolate.h",
"src/sandbox/isolate-inl.h",
"src/sandbox/indirect-pointer.h",
"src/sandbox/indirect-pointer-tag.h",
"src/sandbox/indirect-pointer-inl.h",
"src/sandbox/code-entrypoint-tag.h",
"src/sandbox/external-buffer.h",
"src/sandbox/external-buffer-tag.h",
"src/sandbox/external-buffer-inl.h",
"src/sandbox/external-buffer-table.cc",
"src/sandbox/external-buffer-table-inl.h",
"src/sandbox/external-buffer-table.h",
"src/sandbox/external-entity-table.h",
"src/sandbox/external-entity-table-inl.h",
"src/sandbox/sandbox.cc",
"src/sandbox/sandbox.h",
"src/sandbox/sandboxed-pointer.h",
"src/sandbox/sandboxed-pointer-inl.h",
"src/sandbox/tagged-payload.h",
"src/sandbox/testing.cc",
"src/sandbox/testing.h",
"src/snapshot/code-serializer.cc",
@ -2364,6 +2373,7 @@ filegroup(
"src/strings/char-predicates.h",
"src/strings/char-predicates-inl.h",
"src/strings/string-builder.cc",
"src/strings/string-builder.h",
"src/strings/string-builder-inl.h",
"src/strings/string-case.cc",
"src/strings/string-case.h",
@ -2393,6 +2403,7 @@ filegroup(
"src/torque/runtime-macro-shims.h",
"src/tracing/trace-event.cc",
"src/tracing/trace-event.h",
"src/tracing/trace-event-no-perfetto.h",
"src/tracing/traced-value.cc",
"src/tracing/traced-value.h",
"src/tracing/tracing-category-observer.cc",
@ -2663,12 +2674,7 @@ filegroup(
"src/wasm/baseline/ppc/liftoff-assembler-ppc-inl.h",
],
}) + select({
# Only for x64 builds and for arm64 with x64 host simulator.
":is_v8_enable_webassembly_on_non_android_posix_x64": [
"src/trap-handler/handler-inside-posix.cc",
"src/trap-handler/handler-outside-posix.cc",
],
"@v8//bazel/config:is_macos_arm64": [
"@v8//bazel/config:is_posix": [
"src/trap-handler/handler-inside-posix.cc",
"src/trap-handler/handler-outside-posix.cc",
],
@ -2786,6 +2792,7 @@ filegroup(
"src/wasm/baseline/liftoff-compiler.cc",
"src/wasm/baseline/liftoff-compiler.h",
"src/wasm/baseline/liftoff-register.h",
"src/wasm/baseline/liftoff-varstate.h",
"src/wasm/baseline/parallel-move.cc",
"src/wasm/baseline/parallel-move.h",
"src/wasm/baseline/parallel-move-inl.h",
@ -2831,6 +2838,7 @@ filegroup(
"src/wasm/pgo.cc",
"src/wasm/pgo.h",
"src/wasm/serialized-signature-inl.h",
"src/wasm/signature-hashing.h",
"src/wasm/simd-shuffle.cc",
"src/wasm/simd-shuffle.h",
"src/wasm/stacks.cc",
@ -2852,6 +2860,8 @@ filegroup(
"src/wasm/wasm-code-manager.h",
"src/wasm/wasm-debug.cc",
"src/wasm/wasm-debug.h",
"src/wasm/wasm-deopt-data.cc",
"src/wasm/wasm-deopt-data.h",
"src/wasm/wasm-disassembler.cc",
"src/wasm/wasm-disassembler.h",
"src/wasm/wasm-disassembler-impl.h",
@ -3022,8 +3032,6 @@ filegroup(
"src/compiler/const-tracking-let-helpers.h",
"src/compiler/control-equivalence.cc",
"src/compiler/control-equivalence.h",
"src/compiler/control-flow-optimizer.cc",
"src/compiler/control-flow-optimizer.h",
"src/compiler/control-path-state.h",
"src/compiler/csa-load-elimination.cc",
"src/compiler/csa-load-elimination.h",
@ -3032,8 +3040,6 @@ filegroup(
"src/compiler/decompression-optimizer.cc",
"src/compiler/decompression-optimizer.h",
"src/compiler/diamond.h",
"src/compiler/effect-control-linearizer.cc",
"src/compiler/effect-control-linearizer.h",
"src/compiler/escape-analysis.cc",
"src/compiler/escape-analysis.h",
"src/compiler/escape-analysis-reducer.cc",
@ -3177,8 +3183,6 @@ filegroup(
"src/compiler/simplified-operator-reducer.h",
"src/compiler/state-values-utils.cc",
"src/compiler/state-values-utils.h",
"src/compiler/store-store-elimination.cc",
"src/compiler/store-store-elimination.h",
"src/compiler/string-builder-optimizer.cc",
"src/compiler/string-builder-optimizer.h",
"src/compiler/turbofan.h",
@ -3198,6 +3202,8 @@ filegroup(
"src/compiler/turboshaft/dataview-lowering-reducer.h",
"src/compiler/turboshaft/code-elimination-and-simplification-phase.cc",
"src/compiler/turboshaft/code-elimination-and-simplification-phase.h",
"src/compiler/turboshaft/copying-phase.cc",
"src/compiler/turboshaft/copying-phase.h",
"src/compiler/turboshaft/dead-code-elimination-reducer.h",
"src/compiler/turboshaft/debug-feature-lowering-phase.cc",
"src/compiler/turboshaft/debug-feature-lowering-phase.h",
@ -3219,6 +3225,7 @@ filegroup(
"src/compiler/turboshaft/graph-visualizer.h",
"src/compiler/turboshaft/js-generic-lowering-reducer.h",
"src/compiler/turboshaft/index.h",
"src/compiler/turboshaft/instruction-selection-normalization-reducer.h",
"src/compiler/turboshaft/instruction-selection-phase.cc",
"src/compiler/turboshaft/instruction-selection-phase.h",
"src/compiler/turboshaft/late-escape-analysis-reducer.cc",
@ -3249,12 +3256,12 @@ filegroup(
"src/compiler/turboshaft/operations.cc",
"src/compiler/turboshaft/operations.h",
"src/compiler/turboshaft/opmasks.h",
"src/compiler/turboshaft/copying-phase.cc",
"src/compiler/turboshaft/copying-phase.h",
"src/compiler/turboshaft/optimize-phase.cc",
"src/compiler/turboshaft/optimize-phase.h",
"src/compiler/turboshaft/phase.cc",
"src/compiler/turboshaft/phase.h",
"src/compiler/turboshaft/pipelines.cc",
"src/compiler/turboshaft/pipelines.h",
"src/compiler/turboshaft/pretenuring-propagation-reducer.cc",
"src/compiler/turboshaft/pretenuring-propagation-reducer.h",
"src/compiler/turboshaft/recreate-schedule.cc",
@ -3262,6 +3269,7 @@ filegroup(
"src/compiler/turboshaft/recreate-schedule-phase.cc",
"src/compiler/turboshaft/recreate-schedule-phase.h",
"src/compiler/turboshaft/reducer-traits.h",
"src/compiler/turboshaft/register-allocation-phase.h",
"src/compiler/turboshaft/representations.cc",
"src/compiler/turboshaft/representations.h",
"src/compiler/turboshaft/required-optimization-reducer.h",
@ -3279,7 +3287,7 @@ filegroup(
"src/compiler/turboshaft/stack-check-lowering-reducer.h",
"src/compiler/turboshaft/store-store-elimination-phase.cc",
"src/compiler/turboshaft/store-store-elimination-phase.h",
"src/compiler/turboshaft/store-store-elimination-reducer.h",
"src/compiler/turboshaft/store-store-elimination-reducer-inl.h",
"src/compiler/turboshaft/structural-optimization-reducer.h",
"src/compiler/turboshaft/tracing.h",
"src/compiler/turboshaft/type-assertions-phase.cc",
@ -3304,6 +3312,7 @@ filegroup(
"src/compiler/turboshaft/value-numbering-reducer.h",
"src/compiler/turboshaft/variable-reducer.h",
"src/compiler/turboshaft/wasm-js-lowering-reducer.h",
"src/compiler/turboshaft/zone-with-name.h",
"src/compiler/type-cache.cc",
"src/compiler/type-cache.h",
"src/compiler/type-narrowing-reducer.cc",
@ -3425,6 +3434,34 @@ filegroup(
"src/compiler/wasm-typer.h",
],
"//conditions:default": [],
}) + select({
# Turboshaft's Maglev graph builder needs some Maglev files. We only
# include them explicitely when Maglev is disabled.
":enable_maglev": [],
"//conditions:default": [
"src/maglev/maglev-basic-block.h",
"src/maglev/maglev-code-gen-state.h",
"src/maglev/maglev-compilation-info.cc",
"src/maglev/maglev-compilation-info.h",
"src/maglev/maglev-compilation-unit.cc",
"src/maglev/maglev-compilation-unit.h",
"src/maglev/maglev-graph-builder.cc",
"src/maglev/maglev-graph-builder.h",
"src/maglev/maglev-graph.h",
"src/maglev/maglev-graph-labeller.h",
"src/maglev/maglev-graph-printer.cc",
"src/maglev/maglev-graph-printer.h",
"src/maglev/maglev-graph-processor.h",
"src/maglev/maglev-graph-verifier.h",
"src/maglev/maglev-interpreter-frame-state.cc",
"src/maglev/maglev-interpreter-frame-state.h",
"src/maglev/maglev-ir.cc",
"src/maglev/maglev-ir.h",
"src/maglev/maglev-ir-inl.h",
"src/maglev/maglev-register-frame-array.h",
"src/maglev/maglev-phi-representation-selector.cc",
"src/maglev/maglev-phi-representation-selector.h",
],
}),
)
@ -3519,32 +3556,6 @@ filegroup(
"src/builtins/builtins-wasm-gen.h",
],
"//conditions:default": [],
}) + select({
# Turboshaft's Maglev graph builder needs some Maglev files. We only
# include them explicitely when Maglev is disabled.
":enable_maglev": [],
"//conditions:default": [
"src/maglev/maglev-basic-block.h",
"src/maglev/maglev-code-gen-state.h",
"src/maglev/maglev-compilation-info.cc",
"src/maglev/maglev-compilation-info.h",
"src/maglev/maglev-compilation-unit.cc",
"src/maglev/maglev-compilation-unit.h",
"src/maglev/maglev-graph-builder.cc",
"src/maglev/maglev-graph-builder.h",
"src/maglev/maglev-graph.h",
"src/maglev/maglev-graph-labeller.h",
"src/maglev/maglev-graph-printer.cc",
"src/maglev/maglev-graph-printer.h",
"src/maglev/maglev-graph-processor.h",
"src/maglev/maglev-graph-verifier.h",
"src/maglev/maglev-interpreter-frame-state.cc",
"src/maglev/maglev-interpreter-frame-state.h",
"src/maglev/maglev-ir.cc",
"src/maglev/maglev-ir.h",
"src/maglev/maglev-ir-inl.h",
"src/maglev/maglev-register-frame-array.h",
],
}),
)
@ -4188,7 +4199,6 @@ v8_library(
deps = [
":lib_fp16",
":v8_libbase",
"//external:base_trace_event_common",
"//external:absl_btree",
"//external:absl_flat_hash_map",
"//external:absl_flat_hash_set",
@ -4372,6 +4382,11 @@ alias(
v8_build_config(
name = "v8_build_config",
arch = select({
"//third_party/v8/v12_4/google3/config:v8_target_arm64": "arm64",
"//third_party/v8/v12_4/google3/config:v8_target_x64": "x64",
"//conditions:default": "x64",
}),
)
# Runs mjsunit with d8.
@ -4389,6 +4404,15 @@ py_test(
"--variant=google3_noicu",
"--outdir noicu",
"--verbose",
] + select({
"//third_party/v8/v12_4/google3/config:v8_target_arm64": [
"--arch=arm64",
],
"//third_party/v8/v12_4/google3/config:v8_target_x64": [
"--arch=x64",
],
"//conditions:default": [],
}) + [
"mjsunit",
],
data = [
@ -4419,6 +4443,15 @@ py_test(
"--variant=google3_icu",
"--outdir icu",
"--verbose",
] + select({
"//third_party/v8/v12_4/google3/config:v8_target_arm64": [
"--arch=arm64",
],
"//third_party/v8/v12_4/google3/config:v8_target_x64": [
"--arch=x64",
],
"//conditions:default": [],
}) + [
"mjsunit",
],
data = [

805
deps/v8/BUILD.gn vendored

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
adamk@chromium.org
ahaas@chromium.org
alexschulze@chromium.org
bikineev@chromium.org
bmeurer@chromium.org
cbruni@chromium.org
@ -9,6 +10,7 @@ dinfuehr@chromium.org
dlehmann@chromium.org
dmercadier@chromium.org
ecmziegler@chromium.org
evih@chromium.org
gdeepti@chromium.org
hablich@chromium.org
hpayer@chromium.org
@ -16,21 +18,22 @@ ishell@chromium.org
jgruber@chromium.org
jkummerow@chromium.org
leszeks@chromium.org
liviurau@chromium.org
machenbach@chromium.org
manoskouk@chromium.org
mathias@chromium.org
marja@chromium.org
mathias@chromium.org
mliedtke@chromium.org
mlippautz@chromium.org
mslekova@chromium.org
nicohartmann@chromium.org
nikolaos@chromium.org
olivf@chromium.org
omerkatz@chromium.org
pthier@chromium.org
rezvan@chromium.org
sroettger@google.com
syg@chromium.org
szuend@chromium.org
tebbi@chromium.org
thibaudm@chromium.org
vahl@chromium.org
verwaest@chromium.org

178
deps/v8/DEPS vendored
View file

@ -57,7 +57,7 @@ vars = {
'checkout_fuchsia_no_hooks': False,
# reclient CIPD package version
'reclient_version': 're_client_version:0.134.1.2c9285b-gomaip',
'reclient_version': 're_client_version:0.141.1.29a9d3c-gomaip',
# Fetch configuration files required for the 'use_remoteexec' gn arg
'download_remoteexec_cfg': False,
@ -73,22 +73,22 @@ vars = {
'build_with_chromium': False,
# GN CIPD package version.
'gn_version': 'git_revision:59c4bb920542ee903ee1df39097ae024e2e8226f',
'gn_version': 'git_revision:b3a0bff47dd81073bfe67a402971bad92e4f2423',
# ninja CIPD package version
# https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja
'ninja_version': 'version:2@1.11.1.chromium.6',
# siso CIPD package version
'siso_version': 'git_revision:110b1d8c0528de153cef259f09f3dc5ee627e6cb',
'siso_version': 'git_revision:4524544994f4eac131378143f498ee4d0b7d1f36',
# luci-go CIPD package version.
'luci_go': 'git_revision:623f8d17a069eaea6d0fca13147888284ec76ff1',
'luci_go': 'git_revision:69f852c6aea2797c75712d59145efd38d7032196',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling Fuchsia sdk
# and whatever else without interference from each other.
'fuchsia_version': 'version:19.20240305.3.1',
'fuchsia_version': 'version:20.20240430.3.1',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_build-tools_version
@ -125,12 +125,10 @@ vars = {
}
deps = {
'base/trace_event/common':
Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + '29ac73db520575590c3aceb0a6f1f58dda8934f6',
'build':
Var('chromium_url') + '/chromium/src/build.git' + '@' + 'bca39698b291b392f0b4336857caf929c603ada3',
Var('chromium_url') + '/chromium/src/build.git' + '@' + 'faf20f32f1d19bd492f8f16ac4a7ecfabdbb60c1',
'buildtools':
Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '68fce43789231d29d2028ca85530e4814aac6f50',
Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '2bd8dea61c53448c67f70419004ded4032590fe7',
'buildtools/linux64': {
'packages': [
{
@ -176,9 +174,9 @@ deps = {
'test/mozilla/data':
Var('chromium_url') + '/v8/deps/third_party/mozilla-tests.git' + '@' + 'f6c578a10ea707b1a8ab0b88943fe5115ce2b9be',
'test/test262/data':
Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '0b1abd5ee70867311bea78e851bd609ad842011a',
Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + 'a15874163e6a4f19ee7cd3e47592af382af0f5fd',
'third_party/android_platform': {
'url': Var('chromium_url') + '/chromium/src/third_party/android_platform.git' + '@' + 'eeb2d566f963bb66212fdc0d9bbe1dde550b4969',
'url': Var('chromium_url') + '/chromium/src/third_party/android_platform.git' + '@' + '6337c445f9963ec3914e7e0c5787941d07b46509',
'condition': 'checkout_android',
},
'third_party/android_sdk/public': {
@ -230,19 +228,19 @@ deps = {
'dep_type': 'cipd',
},
'third_party/boringssl': {
'url': Var('chromium_url') + '/chromium/src/third_party/boringssl.git' + '@' + '9ead20bdbf0ecc33219d25fd3a426876c54d126e',
'url': Var('chromium_url') + '/chromium/src/third_party/boringssl.git' + '@' + 'd246272069be506602bd2a7dcf49526d7de603f9',
'condition': "checkout_centipede_deps",
},
'third_party/boringssl/src': {
'url': Var('boringssl_url') + '/boringssl.git' + '@' + '414f69504d30d0848b69f6453ea7fb5e88004cb4',
'url': Var('boringssl_url') + '/boringssl.git' + '@' + '2db0eb3f96a5756298dcd7f9319e56a98585bd10',
'condition': "checkout_centipede_deps",
},
'third_party/catapult': {
'url': Var('chromium_url') + '/catapult.git' + '@' + '97c002a33e5b777eaa60e3ddc977a185f89446f7',
'url': Var('chromium_url') + '/catapult.git' + '@' + '0a2c28ef7c96c683a79869455a1b6814fce293c6',
'condition': 'checkout_android',
},
'third_party/clang-format/script':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/clang/tools/clang-format.git' + '@' + 'e5337933f2951cacd3aeacd238ce4578163ca0b9',
Var('chromium_url') + '/external/github.com/llvm/llvm-project/clang/tools/clang-format.git' + '@' + '3c0acd2d4e73dd911309d9e970ba09d58bf23a62',
'third_party/colorama/src': {
'url': Var('chromium_url') + '/external/colorama.git' + '@' + '3de9f013df4b470069d03d250224062e8cf15c49',
'condition': 'checkout_android',
@ -252,11 +250,11 @@ deps = {
'condition': 'checkout_android',
},
'third_party/depot_tools':
Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'fe6a359a803f55829ede3666215d080f6775f173',
Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '954a8d771345d12f8920da03359b56c001632a7b',
'third_party/fp16/src':
Var('chromium_url') + '/external/github.com/Maratyszcza/FP16.git' + '@' + '0a92994d729ff76a58f692d3028ca1b64b145d91',
'third_party/fuchsia-gn-sdk': {
'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + '727f65f8dae76c0d5c39c0f95d9d8f3a90de79f1',
'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + '30fee7b68b3675e351fa47303c3b6ef322941ccd',
'condition': 'checkout_fuchsia',
},
# Exists for rolling the Fuchsia SDK. Check out of the SDK should always
@ -278,15 +276,17 @@ deps = {
'url': Var('chromium_url') + '/external/github.com/google/benchmark.git' + '@' + '344117638c8ff7e239044fd0fa7085839fc03021',
},
'third_party/fuzztest':
Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + 'daea7ab861050a6445f59758f09cc3173f5add76',
Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + '647d62d39768e90bbb71b0c7758a436cba9c60d5',
'third_party/fuzztest/src':
Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + 'bddcd9f77ba0a81a99ce50bcadf5149efe545df0',
Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + '32eb84a95951fa3a0148fb3e6a1a02f830ded136',
'third_party/googletest/src':
Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + 'b479e7a3c161d7087113a05f8cb034b870313a55',
Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + 'a7f443b80b105f940225332ed3c31f2790092f47',
'third_party/icu':
Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'a622de35ac311c5ad390a7af80724634e5dc61ed',
'third_party/instrumented_libraries':
Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + '0893d760101b3ddf9a2408b9d20f15ec2b80b2c1',
Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '98f2494518c2dbb9c488e83e507b070ea5910e95',
'third_party/instrumented_libs': {
'url': Var('chromium_url') + '/chromium/third_party/instrumented_libraries.git' + '@' + 'bb6dbcf2df7a9beb34c3773ef4df161800e3aed9',
'condition': 'checkout_instrumented_libraries',
},
'third_party/ittapi': {
# Force checkout ittapi libraries to pass v8 header includes check on
# bots that has check_v8_header_includes enabled.
@ -294,15 +294,15 @@ deps = {
'condition': "checkout_ittapi or check_v8_header_includes",
},
'third_party/jinja2':
Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'c9c77525ea20c871a1d4658f8d312b51266d4bad',
Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + '2f6f2ff5e4c1d727377f5e1b9e1903d871f41e74',
'third_party/jsoncpp/source':
Var('chromium_url') + '/external/github.com/open-source-parsers/jsoncpp.git'+ '@' + '42e892d96e47b1f6e29844cc705e148ec4856448',
'third_party/libc++/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + '80307e66e74bae927fb8709a549859e777e3bf0b',
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + '852bc6746f45add53fec19f3a29280e69e358d44',
'third_party/libc++abi/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + 'fc6253a642c9e336480b17fb17771e2c1efc7fff',
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + '43dd5b4bf62e8593461dce9a95e3d43fdcd0b9f2',
'third_party/libunwind/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '8bad7bd6ec30f94bce82f7cb5b58ecbd6ce02996',
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + 'ab43b1d3c9f762db4c6a04c8c7c0955dfe3fb957',
'third_party/logdog/logdog':
Var('chromium_url') + '/infra/luci/luci-py/client/libs/logdog' + '@' + '0b2078a90f7a638d576b3a7c407d136f2fb62399',
'third_party/markupsafe':
@ -319,10 +319,10 @@ deps = {
},
'third_party/perfetto':
Var('android_url') + '/platform/external/perfetto.git' + '@' + '6fc824d618d2f06b5d9cd8655ba0419b6b3b366e',
'third_party/protobuf':
Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + '6a59a2ad1f61d9696092f79b6d74368b4d7970a3',
'third_party/protobuf_chrome':
Var('chromium_url') + '/chromium/src/third_party/protobuf.git' + '@' + 'ed9284c473211491ae6de41d60ac0329a79270d8',
'third_party/re2/src':
Var('chromium_url') + '/external/github.com/google/re2.git' + '@' + '108914d28a79243d4300e7e651cd0a0d5883ca0f',
Var('chromium_url') + '/external/github.com/google/re2.git' + '@' + 'e38a588a09495409575df9ec5af55cdb61831bb5',
'third_party/requests': {
'url': Var('chromium_url') + '/external/github.com/kennethreitz/requests.git' + '@' + 'c7e0fc087ceeadb8b4c84a0953a422c474093d6d',
'condition': 'checkout_android',
@ -338,9 +338,9 @@ deps = {
'condition': 'not build_with_chromium and host_cpu != "s390" and host_cpu != "ppc"',
},
'third_party/zlib':
Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + 'c5bf1b566e5df14e763507e2ce30cbfebefeeccf',
Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '209717dd69cd62f24cbacc4758261ae2dd78cfac',
'tools/clang':
Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '1ed379eda880f53d895559815cd3e30b370abff5',
Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'd15b951fe7cc998369040819c7c6e7160125ea9f',
'tools/luci-go': {
'packages': [
{
@ -355,8 +355,10 @@ deps = {
'condition': 'host_cpu != "s390" and host_os != "aix"',
'dep_type': 'cipd',
},
'tools/protoc_wrapper':
Var('chromium_url') + '/chromium/src/tools/protoc_wrapper.git' + '@' + 'dbcbea90c20ae1ece442d8ef64e61c7b10e2b013',
'third_party/abseil-cpp': {
'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + 'b3ae305fd5dbc6ad41eed9add26768c29181219f',
'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + 'bfe59c2726fda7494a800f7d0ee461f0564653b3',
'condition': 'not build_with_chromium',
}
}
@ -456,57 +458,6 @@ hooks = [
'-o', 'tools/clang/dsymutil/bin/dsymutil',
],
},
# Pull clang-format binaries using checked-in hashes.
{
'name': 'clang_format_win',
'pattern': '.',
'condition': 'host_os == "win"',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-clang-format',
'-s', 'buildtools/win/clang-format.exe.sha1',
],
},
{
'name': 'clang_format_mac_x64',
'pattern': '.',
'condition': 'host_os == "mac" and host_cpu == "x64"',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-clang-format',
'-s', 'buildtools/mac/clang-format.x64.sha1',
'-o', 'buildtools/mac/clang-format',
],
},
{
'name': 'clang_format_mac_arm64',
'pattern': '.',
'condition': 'host_os == "mac" and host_cpu == "arm64"',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-clang-format',
'-s', 'buildtools/mac/clang-format.arm64.sha1',
'-o', 'buildtools/mac/clang-format',
],
},
{
'name': 'clang_format_linux',
'pattern': '.',
'condition': 'host_os == "linux"',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-clang-format',
'-s', 'buildtools/linux64/clang-format.sha1',
],
},
{
'name': 'gcmole',
'pattern': '.',
@ -555,58 +506,6 @@ hooks = [
'-s', 'test/wasm-js/tests.tar.gz.sha1',
],
},
{
'name': 'sysroot_arm',
'pattern': '.',
'condition': '(checkout_linux and checkout_arm)',
'action': ['python3', 'build/linux/sysroot_scripts/install-sysroot.py',
'--arch=arm'],
},
{
'name': 'sysroot_arm64',
'pattern': '.',
'condition': '(checkout_linux and checkout_arm64)',
'action': ['python3', 'build/linux/sysroot_scripts/install-sysroot.py',
'--arch=arm64'],
},
{
'name': 'sysroot_x86',
'pattern': '.',
'condition': '(checkout_linux and (checkout_x86 or checkout_x64))',
'action': ['python3', 'build/linux/sysroot_scripts/install-sysroot.py',
'--arch=x86'],
},
{
'name': 'sysroot_x64',
'pattern': '.',
'condition': 'checkout_linux and checkout_x64',
'action': ['python3', 'build/linux/sysroot_scripts/install-sysroot.py',
'--arch=x64'],
},
{
'name': 'msan_chained_origins_focal',
'pattern': '.',
'condition': 'checkout_instrumented_libraries',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-instrumented-libraries',
'-s', 'third_party/instrumented_libraries/binaries/msan-chained-origins-focal.tgz.sha1',
],
},
{
'name': 'msan_no_origins_focal',
'pattern': '.',
'condition': 'checkout_instrumented_libraries',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-instrumented-libraries',
'-s', 'third_party/instrumented_libraries/binaries/msan-no-origins-focal.tgz.sha1',
],
},
{
# Case-insensitivity for the Win SDK. Must run before win_toolchain below.
'name': 'ciopfs_linux',
@ -718,6 +617,7 @@ hooks = [
'python3',
'tools/builtins-pgo/download_profiles.py',
'download',
'--quiet',
],
},
{
@ -773,3 +673,9 @@ hooks = [
],
},
]
recursedeps = [
'build',
'buildtools',
'third_party/instrumented_libs',
]

View file

@ -4,8 +4,10 @@
adamk@chromium.org
danno@chromium.org
gdeepti@chromium.org
hpayer@chromium.org
leszeks@chromium.org
mlippautz@chromium.org
syg@chromium.org
verwaest@chromium.org
vahl@chromium.org

24
deps/v8/PRESUBMIT.py vendored
View file

@ -31,10 +31,12 @@ See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
import ast
import json
import os
import re
import sys
import traceback
# This line is 'magic' in that git-cl looks for it to decide whether to
# use Python3 instead of Python2 when running the code in this file.
@ -138,6 +140,27 @@ def _V8PresubmitChecks(input_api, output_api):
return results
def _CheckPythonLiterals(input_api, output_api):
"""Checks that all .pyl files are valid python literals."""
affected_files = [
af for af in input_api.AffectedFiles()
if af.LocalPath().endswith('.pyl')
]
results = []
for af in affected_files:
try:
ast.literal_eval('\n'.join(af.NewContents()))
except SyntaxError as e:
results.append(output_api.PresubmitError(
f'Failed to parse python literal {af.LocalPath()}:\n' +
traceback.format_exc(0)
))
return results
def _CheckUnwantedDependencies(input_api, output_api):
"""Runs checkdeps on #include statements added in this
change. Breaking - rules is an error, breaking ! rules is a
@ -416,6 +439,7 @@ def _CommonChecks(input_api, output_api):
_CheckJSONFiles,
_CheckNoexceptAnnotations,
_RunTestsWithVPythonSpec,
_CheckPythonLiterals,
]
return sum([check(input_api, output_api) for check in checks], [])

6
deps/v8/WATCHLISTS vendored
View file

@ -104,9 +104,6 @@
'trap-handler': {
'filepath': 'src/trap-handler/',
},
'tests': {
'filepath': 'test/',
},
},
'WATCHLISTS': {
@ -180,8 +177,5 @@
'mark@chromium.org',
'mseaborn@chromium.org',
],
'tests': [
'almuthanna+watch@chromium.org',
],
},
}

11
deps/v8/WORKSPACE vendored
View file

@ -70,17 +70,6 @@ bind(
actual = "@com_googlesource_chromium_icu//:icu",
)
new_local_repository(
name = "com_googlesource_chromium_base_trace_event_common",
build_file = "//:bazel/BUILD.trace_event_common",
path = "base/trace_event/common",
)
bind(
name = "base_trace_event_common",
actual = "@com_googlesource_chromium_base_trace_event_common//:trace_event_common",
)
http_archive(
name = "intel_ittapi",
add_prefix = "third_party/ittapi",

View file

@ -1,10 +0,0 @@
# Copyright 2021 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
cc_library(
name = "trace_event_common",
hdrs = ["trace_event_common.h"],
include_prefix = "base/trace_event/common",
visibility = ["//visibility:public"],
)

View file

@ -201,14 +201,6 @@ selects.config_setting_group(
]
)
selects.config_setting_group(
name = "is_non_android_posix",
match_any = [
":is_linux",
":is_macos",
],
)
selects.config_setting_group(
name = "is_posix_x64",
match_all = [
@ -217,14 +209,6 @@ selects.config_setting_group(
],
)
selects.config_setting_group(
name = "is_non_android_posix_x64",
match_all = [
":is_non_android_posix",
":is_x64",
],
)
selects.config_setting_group(
name = "is_inline_asm_x64",
match_all = [
@ -305,14 +289,6 @@ selects.config_setting_group(
],
)
selects.config_setting_group(
name = "is_macos_arm64",
match_all = [
":is_macos",
":is_arm64",
],
)
config_setting(
name = "is_compiler_default",
flag_values = {

View file

@ -109,7 +109,8 @@ def _default_args():
"-Werror",
"-Wextra",
"-Wno-unneeded-internal-declaration",
"-Wno-unknown-warning-option",
"-Wno-unknown-warning-option", # b/330781959
"-Wno-cast-function-type-mismatch", # b/330781959
"-Wno-bitwise-instead-of-logical",
"-Wno-builtin-assume-aligned-alignment",
"-Wno-unused-parameter",
@ -122,7 +123,8 @@ def _default_args():
}) + select({
"@v8//bazel/config:is_clang": [
"-Wno-invalid-offsetof",
"-std=c++17",
"-Wno-deprecated-this-capture",
"-std=c++20",
],
"@v8//bazel/config:is_gcc": [
"-Wno-extra",
@ -137,12 +139,13 @@ def _default_args():
"-Wno-redundant-move",
"-Wno-return-type",
"-Wno-stringop-overflow",
"-Wno-deprecated-this-capture",
# Use GNU dialect, because GCC doesn't allow using
# ##__VA_ARGS__ when in standards-conforming mode.
"-std=gnu++17",
"-std=gnu++2a",
],
"@v8//bazel/config:is_windows": [
"/std:c++17",
"/std:c++20",
],
"//conditions:default": [],
}) + select({
@ -560,6 +563,7 @@ def build_config_content(cpu, icu):
("js_shared_memory", "false"),
("lite_mode", "false"),
("local_off_stack_check", "false"),
("memory_corruption_api", "false"),
("mips_arch_variant", '""'),
("mips_use_msa", "false"),
("msan", "false"),
@ -589,8 +593,8 @@ def build_config_content(cpu, icu):
# TODO(victorgomes): Create a rule (instead of a macro), that can
# dynamically populate the build config.
def v8_build_config(name):
cpu = _quote("x64")
def v8_build_config(name, arch):
cpu = '"' + arch + '"'
native.genrule(
name = "noicu/" + name,
outs = ["noicu/" + name + ".json"],

View file

@ -3,7 +3,7 @@ Exposes the rule v8_binary_non_pointer_compression, which forces a label
to be compiled without pointer compression.
"""
def _v8_disable_pointer_compression():
def _v8_disable_pointer_compression(settings, attr):
return {
"//:v8_enable_pointer_compression": "False",
}

View file

@ -17,11 +17,14 @@ build_with_node = false
# chromium build.
perfetto_build_with_embedder = true
# When embedding perfetto, its build files need to know in which BUILD.gn file
# the embedder (v8) declared the protobuf targets. In the v8 case they are
# declared in the root v8/BUILD.gn.
perfetto_protobuf_target_prefix = "//"
perfetto_protobuf_gni = "//gni/proto_library.gni"
# TODO(https://crbug.com/337736622): Perfetto and FuzzTest need to know the
# path to protobuf targets. V8 stores them in a different location than Chrome
# until M129. Thereafter, it can move to //third_party/protobuf and these
# variables can be removed.
protobuf_target_prefix = "//third_party/protobuf_chrome/"
perfetto_protobuf_target_prefix = protobuf_target_prefix
perfetto_protobuf_gni = "//third_party/protobuf_chrome/proto_library.gni"
perfetto_protobuf_src_dir = "//third_party/protobuf_chrome/src"
# We use Perfetto's Trace Processor to convert traces to the legacy JSON
# format.

View file

@ -1,282 +0,0 @@
# Copyright 2019 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build_overrides/build.gni")
# This file should not be pulled in chromium builds.
assert(!build_with_chromium)
if (host_os == "win") {
_host_executable_suffix = ".exe"
} else {
_host_executable_suffix = ""
}
template("proto_library") {
assert(defined(invoker.sources))
proto_sources = invoker.sources
# All the proto imports should be relative to the project root.
proto_in_dir = "//"
if (defined(invoker.proto_in_dir)) {
proto_in_dir = invoker.proto_in_dir
}
assert(defined(invoker.proto_out_dir),
"proto_out_dir must be explicitly defined")
proto_out_dir = invoker.proto_out_dir
# We don't support generate_python in the standalone build, but still must
# check that the caller sets this to false. This is because when building in
# the chromium tree, chromium's proto_library.gni in chrome (!= this) defaults
# generate_python = true.
assert(defined(invoker.generate_python) && !invoker.generate_python)
import_dirs = []
if (defined(invoker.import_dirs)) {
import_dirs = invoker.import_dirs
}
# If false will not generate the default .pb.{cc,h} files. Used for custom
# codegen plugins.
generate_cc = true
if (defined(invoker.generate_cc)) {
generate_cc = invoker.generate_cc
}
generate_descriptor = ""
if (defined(invoker.generate_descriptor)) {
generate_descriptor = invoker.generate_descriptor
}
if (defined(invoker.generator_plugin_label)) {
plugin_host_label = invoker.generator_plugin_label + "($host_toolchain)"
plugin_path =
get_label_info(plugin_host_label, "root_out_dir") + "/" +
get_label_info(plugin_host_label, "name") + _host_executable_suffix
generate_with_plugin = true
} else if (defined(invoker.generator_plugin_script)) {
plugin_path = invoker.generator_plugin_script
generate_with_plugin = true
} else {
generate_with_plugin = false
}
if (generate_with_plugin) {
if (defined(invoker.generator_plugin_suffix)) {
generator_plugin_suffixes = [
"${invoker.generator_plugin_suffix}.h",
"${invoker.generator_plugin_suffix}.cc",
]
} else {
generator_plugin_suffixes = invoker.generator_plugin_suffixes
}
}
out_dir = "$root_gen_dir/" + proto_out_dir
rel_out_dir = rebase_path(out_dir, root_build_dir)
# exclude_imports is only used for generating the descriptor. Therefore, the
# check needs to be here to avoid complaints from GN about the unused
# variable.
if (generate_descriptor != "") {
if (defined(invoker.exclude_imports)) {
exclude_imports = invoker.exclude_imports
} else {
exclude_imports = false
}
}
# Prevent unused errors when generating descriptor only.
if (generate_descriptor != "") {
not_needed([ "rel_out_dir" ])
}
protos = rebase_path(proto_sources, proto_in_dir)
protogens = []
if (generate_descriptor != "") {
protogens += [ "$out_dir/${generate_descriptor}" ]
}
foreach(proto, protos) {
proto_dir = get_path_info(proto, "dir")
proto_name = get_path_info(proto, "name")
proto_path = proto_dir + "/" + proto_name
# Prevent unused errors when generating descriptor only.
if (generate_descriptor != "") {
not_needed([ "proto_path" ])
}
if (generate_cc) {
protogens += [
"$out_dir/$proto_path.pb.h",
"$out_dir/$proto_path.pb.cc",
]
}
if (generate_with_plugin) {
foreach(suffix, generator_plugin_suffixes) {
protogens += [ "$out_dir/${proto_path}${suffix}" ]
}
}
}
config_name = "${target_name}_config"
if (generate_descriptor == "") {
action_name = "${target_name}_gen"
source_set_name = target_name
} else {
action_name = target_name
}
config(config_name) {
include_dirs = [ out_dir ]
}
# The XXX_gen action that generates the .pb.{cc,h} files.
action(action_name) {
if (generate_descriptor == "") {
visibility = [ ":$source_set_name" ]
}
sources = proto_sources
outputs = get_path_info(protogens, "abspath")
protoc_label = "//:protoc($host_toolchain)"
protoc_path = get_label_info(protoc_label, "root_out_dir") + "/protoc" +
_host_executable_suffix
protoc_rebased_path = "./" + rebase_path(protoc_path, root_build_dir)
script = "//gni/protoc.py"
args = [
# Path should be rebased because |root_build_dir| for current toolchain
# may be different from |root_out_dir| of protoc built on host toolchain.
protoc_rebased_path,
"--proto_path",
rebase_path(proto_in_dir, root_build_dir),
]
foreach(path, import_dirs) {
args += [
"--proto_path",
rebase_path(path, root_build_dir),
]
}
if (generate_cc) {
cc_generator_options_ = ""
if (defined(invoker.cc_generator_options)) {
cc_generator_options_ = invoker.cc_generator_options
}
args += [
"--cpp_out",
cc_generator_options_ + rel_out_dir,
]
}
if (generate_descriptor != "") {
depfile = "$out_dir/$generate_descriptor.d"
if (!exclude_imports) {
args += [ "--include_imports" ]
}
args += [
"--descriptor_set_out",
rebase_path("$out_dir/$generate_descriptor", root_build_dir),
"--dependency_out",
rebase_path(depfile, root_build_dir),
]
}
if (generate_with_plugin) {
plugin_path_rebased = rebase_path(plugin_path, root_build_dir)
plugin_out_args = ""
if (defined(invoker.generator_plugin_options)) {
plugin_out_args += invoker.generator_plugin_options
}
plugin_out_args += ":$rel_out_dir"
args += [
"--plugin=protoc-gen-plugin=$plugin_path_rebased",
"--plugin_out=$plugin_out_args",
]
}
args += rebase_path(proto_sources, root_build_dir)
inputs = [ protoc_path ]
deps = [ protoc_label ]
# TODO(hjd): Avoid adding to deps here this.
# When we generate BUILD files we need find the transitive proto,
# dependencies, so also add link_deps to actual deps so they show up
# in gn desc.
if (defined(invoker.link_deps)) {
deps += invoker.link_deps
}
if (generate_with_plugin) {
inputs += [ plugin_path ]
if (defined(plugin_host_label)) {
# Action depends on native generator plugin but for host toolchain only.
deps += [ plugin_host_label ]
}
}
if (defined(invoker.deps)) {
deps += invoker.deps
}
} # action(action_name)
# The source_set that builds the generated .pb.cc files.
if (generate_descriptor == "") {
source_set(source_set_name) {
forward_variables_from(invoker,
[
"defines",
"include_dirs",
"public_configs",
"testonly",
"visibility",
])
sources = get_target_outputs(":$action_name")
if (defined(invoker.extra_configs)) {
configs += invoker.extra_configs
}
if (!defined(invoker.public_configs)) {
public_configs = []
}
public_configs += [
"//:protobuf_gen_config",
":$config_name",
]
# By default, propagate the config for |include_dirs| to dependent
# targets, so that public imports can be resolved to corresponding header
# files. In some cases, the embedder target handles include directory
# propagation itself, e.g. via a common config.
propagate_imports_configs = !defined(invoker.propagate_imports_configs) ||
invoker.propagate_imports_configs
if (propagate_imports_configs) {
public_configs += [ ":$config_name" ]
} else {
configs += [ ":$config_name" ]
}
# Use protobuf_full only for tests.
if (defined(invoker.use_protobuf_full) &&
invoker.use_protobuf_full == true) {
deps = [ "//:protobuf_full" ]
} else if (generate_cc) {
deps = [ "//:protobuf_lite" ]
} else {
deps = []
}
deps += [ ":$action_name" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
} # source_set(source_set_name)
}
} # template

51
deps/v8/gni/protoc.py vendored
View file

@ -1,51 +0,0 @@
#!/usr/bin/env python3
# Copyright 2021 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script to wrap protoc execution.
This script exists to work-around the bad depfile generation by protoc when
generating descriptors."""
from __future__ import print_function
import argparse
import os
import sys
import subprocess
import tempfile
import uuid
from codecs import open
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--descriptor_set_out', default=None)
parser.add_argument('--dependency_out', default=None)
parser.add_argument('protoc')
args, remaining = parser.parse_known_args()
if args.dependency_out and args.descriptor_set_out:
tmp_path = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))
custom = [
'--descriptor_set_out', args.descriptor_set_out, '--dependency_out',
tmp_path
]
try:
cmd = [args.protoc] + custom + remaining
subprocess.check_call(cmd)
with open(tmp_path, 'rb') as tmp_rd:
dependency_data = tmp_rd.read().decode('utf-8')
finally:
if os.path.exists(tmp_path):
os.unlink(tmp_path)
with open(args.dependency_out, 'w', encoding='utf-8') as f:
f.write(args.descriptor_set_out + ":")
f.write(dependency_data)
else:
subprocess.check_call(sys.argv[1:])
if __name__ == '__main__':
sys.exit(main())

32
deps/v8/gni/v8.gni vendored
View file

@ -6,6 +6,7 @@ import("//build/config/chrome_build.gni")
import("//build/config/compiler/pgo/pgo.gni")
import("//build/config/gclient_args.gni")
import("//build/config/ios/config.gni")
import("//build/config/ios/ios_sdk_overrides.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/config/v8_target_cpu.gni")
import("//build_overrides/build.gni")
@ -39,6 +40,10 @@ declare_args() {
# Includes profiles to optimize builtins.
v8_enable_builtins_optimization = ""
# Turns on all V8 debug features. Enables running V8 in a pseudo debug mode
# within a release Chrome.
v8_enable_debugging_features = is_debug
# Enable ECMAScript Internationalization API. Enabling this feature will
# add a dependency on the ICU library.
v8_enable_i18n_support = true
@ -70,6 +75,14 @@ declare_args() {
# Sets -DV8_LITE_MODE.
v8_enable_lite_mode = false
# iOS executable code pages is in 17.4 SDK. We
# use target_os == "ios" here because it isn't equivalent
# to is_ios (is_ios is based on host_os).
if (target_os == "ios") {
# TODO(dtapuska): Change this to an assert.
v8_enable_lite_mode = ios_deployment_target != "17.4"
}
# Enable the Turbofan compiler.
# Sets -dV8_ENABLE_TURBOFAN.
v8_enable_turbofan = ""
@ -138,7 +151,7 @@ declare_args() {
cppgc_enable_2gb_cage = false
# Enable support for larger cages, up to 16GB.
cppgc_enable_larger_cage = false
cppgc_enable_larger_cage = true
# Enable advanced BigInt algorithms, costing about 10-30 KB binary size
# depending on platform. Disabled on Android to save binary size.
@ -147,11 +160,6 @@ declare_args() {
# TODO: macros for determining endian type are clang specific.
v8_use_libm_trig_functions = is_clang
# iOS device does not support executable code pages. Not we
# use target_os == "ios" here because it isn't equivalent
# to is_ios (is_ios is based on host_os).
target_is_ios_device = target_os == "ios" && target_environment == "device"
# Location of icu.
v8_icu_path = "//third_party/icu"
@ -176,9 +184,9 @@ if (v8_enable_backtrace == "") {
v8_enable_backtrace = is_debug && !v8_optimized_debug
}
# If chromium is configured to use the perfetto client library, v8 should also
# Chromium is configured to use the perfetto client library, v8 should also
# use perfetto for tracing.
if (build_with_chromium && use_perfetto_client_library) {
if (build_with_chromium) {
v8_use_perfetto = true
}
@ -196,18 +204,14 @@ if (v8_enable_builtins_optimization == "") {
# v8_jitless.
# WebAssembly is enabled by default, except in lite mode.
if (v8_enable_webassembly == "") {
# iOS (non-simulator) does not have executable pages for 3rd party
# applications yet so disable webassembly.
v8_enable_webassembly = !v8_enable_lite_mode && !target_is_ios_device
v8_enable_webassembly = !v8_enable_lite_mode
}
assert(!(v8_enable_webassembly && v8_enable_lite_mode),
"Webassembly is not available in lite mode.")
# Turbofan is enabled by default, except in lite mode.
if (v8_enable_turbofan == "") {
# iOS (non-simulator) does not have executable pages for 3rd party
# applications yet so disable turbofan.
v8_enable_turbofan = !v8_enable_lite_mode && !target_is_ios_device
v8_enable_turbofan = !v8_enable_lite_mode
}
assert(v8_enable_turbofan || !v8_enable_webassembly,
"Webassembly is not available when Turbofan is disabled.")

View file

@ -47,7 +47,7 @@ namespace internal {
// Similar to C++17 std::align_val_t;
enum class AlignVal : size_t {};
class V8_EXPORT MakeGarbageCollectedTraitInternal {
class MakeGarbageCollectedTraitInternal {
protected:
static inline void MarkObjectAsFullyConstructed(const void* payload) {
// See api_constants for an explanation of the constants.
@ -121,16 +121,15 @@ class V8_EXPORT MakeGarbageCollectedTraitInternal {
};
private:
static void* CPPGC_DEFAULT_ALIGNED Allocate(cppgc::AllocationHandle&, size_t,
GCInfoIndex);
static void* CPPGC_DOUBLE_WORD_ALIGNED Allocate(cppgc::AllocationHandle&,
size_t, AlignVal,
GCInfoIndex);
static void* CPPGC_DEFAULT_ALIGNED Allocate(cppgc::AllocationHandle&, size_t,
GCInfoIndex, CustomSpaceIndex);
static void* CPPGC_DOUBLE_WORD_ALIGNED Allocate(cppgc::AllocationHandle&,
size_t, AlignVal, GCInfoIndex,
CustomSpaceIndex);
V8_EXPORT static void* CPPGC_DEFAULT_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, GCInfoIndex);
V8_EXPORT static void* CPPGC_DOUBLE_WORD_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, AlignVal, GCInfoIndex);
V8_EXPORT static void* CPPGC_DEFAULT_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, GCInfoIndex, CustomSpaceIndex);
V8_EXPORT static void* CPPGC_DOUBLE_WORD_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, AlignVal, GCInfoIndex,
CustomSpaceIndex);
friend class HeapObjectHeader;
};

View file

@ -102,6 +102,8 @@ struct HeapStatistics final {
size_t resident_size_bytes = 0;
/** Amount of memory actually used on the heap. */
size_t used_size_bytes = 0;
/** Memory retained in the page pool, not used directly by the heap. */
size_t pooled_memory_size_bytes = 0;
/** Detail level of this HeapStatistics. */
DetailLevel detail_level;

View file

@ -34,6 +34,10 @@ static constexpr size_t kPageSize = size_t{1} << 17;
#if defined(V8_HOST_ARCH_ARM64) && defined(V8_OS_DARWIN)
constexpr size_t kGuardPageSize = 0;
#elif defined(V8_HOST_ARCH_PPC64)
constexpr size_t kGuardPageSize = 0;
#elif defined(V8_HOST_ARCH_LOONG64) || defined(V8_HOST_ARCH_MIPS64)
constexpr size_t kGuardPageSize = 0;
#else
constexpr size_t kGuardPageSize = 4096;
#endif

View file

@ -94,12 +94,11 @@ struct GCInfoTrait final {
return index;
}
static constexpr bool CheckCallbacksAreDefined() {
static constexpr void CheckCallbacksAreDefined() {
// No USE() macro available.
(void)static_cast<TraceCallback>(TraceTrait<T>::Trace);
(void)static_cast<FinalizationCallback>(FinalizerTrait<T>::kCallback);
(void)static_cast<NameCallback>(NameTrait<T>::GetName);
return true;
}
};
@ -127,19 +126,22 @@ struct GCInfoFolding final {
// configuration. Only a single GCInfo (for `ResultType` below) will actually
// be instantiated but existence (and well-formedness) of all callbacks is
// checked.
static constexpr bool kCheckTypeGuardAlwaysTrue =
GCInfoTrait<T>::CheckCallbacksAreDefined() &&
static constexpr bool WantToFold() {
if constexpr ((kHasVirtualDestructorAtBase ||
kBothTypesAreTriviallyDestructible ||
kHasCustomFinalizerDispatchAtBase) &&
!kWantsDetailedObjectNames) {
GCInfoTrait<T>::CheckCallbacksAreDefined();
GCInfoTrait<ParentMostGarbageCollectedType>::CheckCallbacksAreDefined();
return true;
}
return false;
}
// Folding would regress name resolution when deriving names from C++
// class names as it would just folds a name to the base class name.
using ResultType =
std::conditional_t<kCheckTypeGuardAlwaysTrue &&
(kHasVirtualDestructorAtBase ||
kBothTypesAreTriviallyDestructible ||
kHasCustomFinalizerDispatchAtBase) &&
!kWantsDetailedObjectNames,
ParentMostGarbageCollectedType, T>;
std::conditional_t<WantToFold(), ParentMostGarbageCollectedType, T>;
};
} // namespace internal

View file

@ -158,6 +158,12 @@ class V8_TRIVIAL_ABI CompressedPointer final {
static V8_INLINE void* Decompress(IntegralType ptr) {
CPPGC_DCHECK(CageBaseGlobal::IsSet());
const uintptr_t base = CageBaseGlobal::Get();
return Decompress(ptr, base);
}
static V8_INLINE void* Decompress(IntegralType ptr, uintptr_t base) {
CPPGC_DCHECK(CageBaseGlobal::IsSet());
CPPGC_DCHECK(base == CageBaseGlobal::Get());
// Treat compressed pointer as signed and cast it to uint64_t, which will
// sign-extend it.
#if defined(CPPGC_2GB_CAGE)

View file

@ -121,7 +121,11 @@ class NameTrait final : public NameTraitBase {
#undef PRETTY_FUNCTION_VALUE
#else // !CPPGC_SUPPORTS_OBJECT_NAMES
return {NameProvider::kHiddenName, true};
// We wanted to use a class name but were unable to provide one due to
// compiler limitations or build configuration. As such, return the hidden
// name with name_was_hidden=false, which will cause this object to be
// visible in the snapshot.
return {NameProvider::kHiddenName, false};
#endif // !CPPGC_SUPPORTS_OBJECT_NAMES
}
};

View file

@ -87,6 +87,9 @@ class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase {
* Assumes that the backing_store was allocated by the ArrayBuffer allocator
* of the given isolate.
*/
V8_DEPRECATED(
"Reallocate is unsafe, please do not use. Please allocate a new "
"BackingStore and copy instead.")
static std::unique_ptr<BackingStore> Reallocate(
v8::Isolate* isolate, std::unique_ptr<BackingStore> backing_store,
size_t byte_length);
@ -179,6 +182,9 @@ class V8_EXPORT ArrayBuffer : public Object {
*
* The default implementation allocates a new block and copies data.
*/
V8_DEPRECATED(
"Reallocate is unsafe, please do not use. Please allocate new memory "
"and copy instead.")
virtual void* Reallocate(void* data, size_t old_length, size_t new_length);
/**
@ -287,7 +293,7 @@ class V8_EXPORT ArrayBuffer : public Object {
* preventing JavaScript from ever accessing underlying backing store.
* ArrayBuffer should have been externalized and must be detachable.
*/
V8_DEPRECATE_SOON(
V8_DEPRECATED(
"Use the version which takes a key parameter (passing a null handle is "
"ok).")
void Detach();

View file

@ -152,9 +152,6 @@ using JitCodeEventHandler = void (*)(const JitCodeEvent* event);
enum GCType {
kGCTypeScavenge = 1 << 0,
kGCTypeMinorMarkSweep = 1 << 1,
kGCTypeMinorMarkCompact V8_DEPRECATE_SOON(
"Use kGCTypeMinorMarkSweep instead of kGCTypeMinorMarkCompact.") =
kGCTypeMinorMarkSweep,
kGCTypeMarkSweepCompact = 1 << 2,
kGCTypeIncrementalMarking = 1 << 3,
kGCTypeProcessWeakCallbacks = 1 << 4,

View file

@ -107,6 +107,10 @@ class V8_EXPORT Context : public Data {
* configured if the default context snapshot contains no pointer embedder
* data, or if no custom startup snapshot is configured in the
* v8::CreateParams used to create the isolate.
*
* \param api_wrapper_deserializer An optional callback used to deserialize
* API wrapper objects that was initially set with v8::Object::Wrap() and then
* serialized using SerializeAPIWrapperCallback.
*/
static Local<Context> New(
Isolate* isolate, ExtensionConfiguration* extensions = nullptr,
@ -116,17 +120,19 @@ class V8_EXPORT Context : public Data {
DeserializeInternalFieldsCallback(),
MicrotaskQueue* microtask_queue = nullptr,
DeserializeContextDataCallback context_data_deserializer =
DeserializeContextDataCallback());
DeserializeContextDataCallback(),
DeserializeAPIWrapperCallback api_wrapper_deserializer =
DeserializeAPIWrapperCallback());
/**
* Create a new context from a (non-default) context snapshot. There
* is no way to provide a global object template since we do not create
* a new global object from template, but we can reuse a global object.
*
* \param isolate See v8::Context::New.
* \param isolate See v8::Context::New().
*
* \param context_snapshot_index The index of the context snapshot to
* deserialize from. Use v8::Context::New for the default snapshot.
* deserialize from. Use v8::Context::New() for the default snapshot.
*
* \param internal_fields_deserializer An optional callback used
* to deserialize fields set by
@ -136,19 +142,23 @@ class V8_EXPORT Context : public Data {
* pointer fields in the default context snapshot or if no startup
* snapshot is configured when the isolate is created.
*
* \param extensions See v8::Context::New.
* \param extensions See v8::Context::New().
*
* \param global_object See v8::Context::New.
* \param global_object See v8::Context::New().
*
* \param internal_fields_deserializer Similar to
* internal_fields_deserializer in v8::Context::New but applies to
* internal_fields_deserializer in v8::Context::New() but applies to
* the context specified by the context_snapshot_index.
*
* \param microtask_queue See v8::Context::New.
* \param microtask_queue See v8::Context::New().
*
* \param context_data_deserializer Similar to
* context_data_deserializer in v8::Context::New but applies to
* context_data_deserializer in v8::Context::New() but applies to
* the context specified by the context_snapshot_index.
*
*\param api_wrapper_deserializer Similar to api_wrapper_deserializer in
* v8::Context::New() but applies to the context specified by the
* context_snapshot_index.
*/
static MaybeLocal<Context> FromSnapshot(
Isolate* isolate, size_t context_snapshot_index,
@ -158,7 +168,9 @@ class V8_EXPORT Context : public Data {
MaybeLocal<Value> global_object = MaybeLocal<Value>(),
MicrotaskQueue* microtask_queue = nullptr,
DeserializeContextDataCallback context_data_deserializer =
DeserializeContextDataCallback());
DeserializeContextDataCallback(),
DeserializeAPIWrapperCallback api_wrapper_deserializer =
DeserializeAPIWrapperCallback());
/**
* Returns an global object that isn't backed by an actual context.
@ -290,6 +302,8 @@ class V8_EXPORT Context : public Data {
* SetAlignedPointerInEmbedderData with the same index. Note that index 0
* currently has a special meaning for Chrome's debugger.
*/
V8_INLINE void* GetAlignedPointerFromEmbedderData(Isolate* isolate,
int index);
V8_INLINE void* GetAlignedPointerFromEmbedderData(int index);
/**
@ -444,6 +458,24 @@ Local<Value> Context::GetEmbedderData(int index) {
#endif
}
void* Context::GetAlignedPointerFromEmbedderData(Isolate* isolate, int index) {
#if !defined(V8_ENABLE_CHECKS)
using A = internal::Address;
using I = internal::Internals;
A ctx = internal::ValueHelper::ValueAsAddress(this);
A embedder_data =
I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
int value_offset = I::kEmbedderDataArrayHeaderSize +
(I::kEmbedderDataSlotSize * index) +
I::kEmbedderDataSlotExternalPointerOffset;
return reinterpret_cast<void*>(
I::ReadExternalPointerField<internal::kEmbedderDataSlotPayloadTag>(
isolate, embedder_data, value_offset));
#else
return SlowGetAlignedPointerFromEmbedderData(index);
#endif
}
void* Context::GetAlignedPointerFromEmbedderData(int index) {
#if !defined(V8_ENABLE_CHECKS)
using A = internal::Address;

View file

@ -46,10 +46,14 @@ struct WrapperDescriptor final {
/**
* Unknown embedder id. The value is reserved for internal usages and must not
* be used with `CppHeap`.
* be used with `CppHeap`. The value is considered as not traceable.
*/
static constexpr uint16_t kUnknownEmbedderId = UINT16_MAX;
V8_DEPRECATED("WrapperDescriptor is deprecated, see crbug.com/338411141.")
constexpr WrapperDescriptor() = default;
V8_DEPRECATED("WrapperDescriptor is deprecated, see crbug.com/338411141.")
constexpr WrapperDescriptor(InternalFieldIndex wrappable_type_index,
InternalFieldIndex wrappable_instance_index,
uint16_t embedder_id_for_garbage_collected)
@ -60,12 +64,12 @@ struct WrapperDescriptor final {
/**
* Index of the wrappable type.
*/
InternalFieldIndex wrappable_type_index;
InternalFieldIndex wrappable_type_index = -1;
/**
* Index of the wrappable instance.
*/
InternalFieldIndex wrappable_instance_index;
InternalFieldIndex wrappable_instance_index = -1;
/**
* Embedder id identifying instances of garbage-collected objects. It is
@ -73,10 +77,17 @@ struct WrapperDescriptor final {
* the id. Only references to instances of wrappables types with an id of
* `embedder_id_for_garbage_collected` will be considered by CppHeap.
*/
uint16_t embedder_id_for_garbage_collected;
uint16_t embedder_id_for_garbage_collected = kUnknownEmbedderId;
};
struct V8_EXPORT CppHeapCreateParams {
START_ALLOW_USE_DEPRECATED()
explicit CppHeapCreateParams(
std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces)
: custom_spaces(std::move(custom_spaces)) {}
END_ALLOW_USE_DEPRECATED()
V8_DEPRECATED("WrapperDescriptor is deprecated, see crbug.com/338411141.")
CppHeapCreateParams(
std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces,
WrapperDescriptor wrapper_descriptor)
@ -180,6 +191,7 @@ class V8_EXPORT CppHeap {
/**
* \returns the wrapper descriptor of this CppHeap.
*/
V8_DEPRECATED("WrapperDescriptor is deprecated, see crbug.com/338411141.")
v8::WrapperDescriptor wrapper_descriptor() const;
private:

View file

@ -21,6 +21,10 @@ class V8_EXPORT Date : public Object {
static V8_WARN_UNUSED_RESULT MaybeLocal<Value> New(Local<Context> context,
double time);
static V8_WARN_UNUSED_RESULT MaybeLocal<Value> Parse(
Local<Context> context,
Local<String> date_string);
/**
* A specialization of Value::NumberValue that is more efficient
* because we know the structure of this object.
@ -32,6 +36,11 @@ class V8_EXPORT Date : public Object {
*/
v8::Local<v8::String> ToISOString() const;
/**
* Generates UTC string representation.
*/
v8::Local<v8::String> ToUTCString() const;
V8_INLINE static Date* Cast(Value* value) {
#ifdef V8_ENABLE_CHECKS
CheckCast(value);

View file

@ -29,6 +29,8 @@ class V8_EXPORT EmbedderRootsHandler {
virtual ~EmbedderRootsHandler() = default;
EmbedderRootsHandler() = default;
V8_DEPRECATE_SOON("Use the default constructor instead.")
explicit EmbedderRootsHandler(RootHandling default_traced_reference_handling)
: default_traced_reference_handling_(default_traced_reference_handling) {}
@ -47,6 +49,7 @@ class V8_EXPORT EmbedderRootsHandler {
*
* The concrete implementations must be thread-safe.
*/
V8_DEPRECATE_SOON("Use TracedReferenceHandling::kDroppable instead.")
virtual bool IsRoot(const v8::TracedReference<v8::Value>& handle) = 0;
/**

View file

@ -8,6 +8,7 @@
#include <stddef.h>
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-object.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
namespace v8 {
@ -58,6 +59,13 @@ class V8_EXPORT Exception {
* of a given exception, or an empty handle if not available.
*/
static Local<StackTrace> GetStackTrace(Local<Value> exception);
/**
* Captures the current stack trace and attaches it to the given object in the
* form of `stack` property.
*/
static Maybe<bool> CaptureStackTrace(Local<Context> context,
Local<Object> object);
};
/**

View file

@ -577,7 +577,7 @@ struct FastApiCallbackOptions {
* returned instance may be filled with mock data.
*/
static FastApiCallbackOptions CreateForTesting(Isolate* isolate) {
return {false, {0}, nullptr};
return {};
}
/**
@ -591,21 +591,26 @@ struct FastApiCallbackOptions {
* fallback conditions are checked, because otherwise executing the slow
* callback might produce visible side-effects twice.
*/
bool fallback;
V8_DEPRECATE_SOON(
"It is not necessary to use the `fallback` flag anymore, as it is "
"possible now to trigger GC, throw exceptions, and call back into "
"JavaScript even in API functions called with a fast API call.")
bool fallback = false;
/**
* The `data` passed to the FunctionTemplate constructor, or `undefined`.
* `data_ptr` allows for default constructing FastApiCallbackOptions.
*/
union {
uintptr_t data_ptr;
v8::Local<v8::Value> data;
};
v8::Local<v8::Value> data;
/**
* When called from WebAssembly, a view of the calling module's memory.
*/
FastApiTypedArray<uint8_t>* const wasm_memory;
V8_DEPRECATE_SOON(
"The wasm memory should either be provided as a field of the receiver, "
"the data object of the FunctionTemplate, or as a normal parameter of "
"the API function. Since regular API calls don't have this magic "
"`wasm_memory parameter, one of the options above should be possible.")
FastApiTypedArray<uint8_t>* const wasm_memory = nullptr;
};
namespace internal {

View file

@ -8,6 +8,7 @@
#include <cstdint>
#include <limits>
#include "v8-internal.h" // NOLINT(build/include_directory)
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-primitive.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
@ -31,6 +32,11 @@ namespace debug {
class ConsoleCallArguments;
} // namespace debug
namespace api_internal {
V8_EXPORT v8::Local<v8::Value> GetFunctionTemplateData(
v8::Isolate* isolate, v8::Local<v8::Data> raw_target);
} // namespace api_internal
template <typename T>
class ReturnValue {
public:
@ -38,7 +44,7 @@ class ReturnValue {
V8_INLINE ReturnValue(const ReturnValue<S>& that) : value_(that.value_) {
static_assert(std::is_base_of<T, S>::value, "type check");
}
// Local setters
// Handle-based setters.
template <typename S>
V8_INLINE void Set(const Global<S>& handle);
template <typename S>
@ -51,12 +57,15 @@ class ReturnValue {
V8_INLINE void Set(const Local<S> handle);
template <typename S>
V8_INLINE void SetNonEmpty(const Local<S> handle);
// Fast primitive setters
// Fast primitive number setters.
V8_INLINE void Set(bool value);
V8_INLINE void Set(double i);
V8_INLINE void Set(int16_t i);
V8_INLINE void Set(int32_t i);
V8_INLINE void Set(int64_t i);
V8_INLINE void Set(uint16_t i);
V8_INLINE void Set(uint32_t i);
V8_INLINE void Set(uint16_t);
V8_INLINE void Set(uint64_t i);
// Fast JS primitive setters
V8_INLINE void SetNull();
V8_INLINE void SetUndefined();
@ -127,6 +136,12 @@ class FunctionCallbackInfo {
* referencing this callback was found (which in V8 internally is often
* referred to as holder [sic]).
*/
V8_DEPRECATED(
"V8 will stop providing access to hidden prototype (i.e. "
"JSGlobalObject). Use This() instead. \n"
"DO NOT try to workaround this by accessing JSGlobalObject via "
"v8::Object::GetPrototype() - it'll be deprecated soon too. \n"
"See http://crbug.com/333672197. ")
V8_INLINE Local<Object> Holder() const;
/** For construct calls, this returns the "new.target" value. */
V8_INLINE Local<Value> NewTarget() const;
@ -139,6 +154,11 @@ class FunctionCallbackInfo {
/** The ReturnValue for the call. */
V8_INLINE ReturnValue<T> GetReturnValue() const;
// This is a temporary replacement for Holder() added just for the purpose
// of testing the deprecated Holder() machinery until it's removed for real.
// DO NOT use it.
V8_INLINE Local<Object> HolderSoonToBeDeprecated() const;
private:
friend class internal::FunctionCallbackArguments;
friend class internal::CustomArguments<FunctionCallbackInfo>;
@ -148,7 +168,7 @@ class FunctionCallbackInfo {
static constexpr int kIsolateIndex = 1;
static constexpr int kUnusedIndex = 2;
static constexpr int kReturnValueIndex = 3;
static constexpr int kDataIndex = 4;
static constexpr int kTargetIndex = 4;
static constexpr int kNewTargetIndex = 5;
static constexpr int kArgsLength = 6;
@ -244,8 +264,23 @@ class PropertyCallbackInfo {
*
* \note For security reasons, do not pass the object back into the runtime.
*/
V8_DEPRECATE_SOON(
"V8 will stop providing access to hidden prototype (i.e. "
"JSGlobalObject). Use HolderV2() instead. \n"
"DO NOT try to workaround this by accessing JSGlobalObject via "
"v8::Object::GetPrototype() - it'll be deprecated soon too. \n"
"See http://crbug.com/333672197. ")
V8_INLINE Local<Object> Holder() const;
/**
* \return The object in the prototype chain of the receiver that has the
* interceptor. Suppose you have `x` and its prototype is `y`, and `y`
* has an interceptor. Then `info.This()` is `x` and `info.Holder()` is `y`.
* In case the property is installed on the global object the Holder()
* would return the global proxy.
*/
V8_INLINE Local<Object> HolderV2() const;
/**
* \return The return value of the callback.
* Can be changed by calling Set().
@ -265,14 +300,23 @@ class PropertyCallbackInfo {
*/
V8_INLINE bool ShouldThrowOnError() const;
V8_DEPRECATED(
"This is a temporary workaround to ease migration of Chromium bindings "
"code to the new interceptors Api. This constructor will be removed in "
"V8 12.8.")
explicit PropertyCallbackInfo(const PropertyCallbackInfo<void>& info)
: PropertyCallbackInfo(info.args_) {}
private:
template <typename U>
friend class PropertyCallbackInfo;
friend class MacroAssembler;
friend class internal::PropertyCallbackArguments;
friend class internal::CustomArguments<PropertyCallbackInfo>;
static constexpr int kShouldThrowOnErrorIndex = 0;
static constexpr int kHolderIndex = 1;
static constexpr int kIsolateIndex = 2;
static constexpr int kUnusedIndex = 3;
static constexpr int kHolderV2Index = 3;
static constexpr int kReturnValueIndex = 4;
static constexpr int kDataIndex = 5;
static constexpr int kThisIndex = 6;
@ -379,26 +423,32 @@ void ReturnValue<T>::Set(double i) {
}
template <typename T>
void ReturnValue<T>::Set(int32_t i) {
void ReturnValue<T>::Set(int16_t i) {
static_assert(std::is_base_of<T, Integer>::value, "type check");
using I = internal::Internals;
if (V8_LIKELY(I::IsValidSmi(i))) {
SetInternal(I::IntToSmi(i));
static_assert(I::IsValidSmi(std::numeric_limits<int16_t>::min()));
static_assert(I::IsValidSmi(std::numeric_limits<int16_t>::max()));
SetInternal(I::IntegralToSmi(i));
}
template <typename T>
void ReturnValue<T>::Set(int32_t i) {
static_assert(std::is_base_of<T, Integer>::value, "type check");
if (const auto result = internal::Internals::TryIntegralToSmi(i)) {
SetInternal(*result);
return;
}
SetNonEmpty(Integer::New(GetIsolate(), i));
}
template <typename T>
void ReturnValue<T>::Set(uint32_t i) {
void ReturnValue<T>::Set(int64_t i) {
static_assert(std::is_base_of<T, Integer>::value, "type check");
// Can't simply use INT32_MAX here for whatever reason.
bool fits_into_int32_t = (i & (1U << 31)) == 0;
if (V8_LIKELY(fits_into_int32_t)) {
Set(static_cast<int32_t>(i));
if (const auto result = internal::Internals::TryIntegralToSmi(i)) {
SetInternal(*result);
return;
}
SetNonEmpty(Integer::NewFromUnsigned(GetIsolate(), i));
SetNonEmpty(Number::New(GetIsolate(), static_cast<double>(i)));
}
template <typename T>
@ -407,7 +457,27 @@ void ReturnValue<T>::Set(uint16_t i) {
using I = internal::Internals;
static_assert(I::IsValidSmi(std::numeric_limits<uint16_t>::min()));
static_assert(I::IsValidSmi(std::numeric_limits<uint16_t>::max()));
SetInternal(I::IntToSmi(i));
SetInternal(I::IntegralToSmi(i));
}
template <typename T>
void ReturnValue<T>::Set(uint32_t i) {
static_assert(std::is_base_of<T, Integer>::value, "type check");
if (const auto result = internal::Internals::TryIntegralToSmi(i)) {
SetInternal(*result);
return;
}
SetNonEmpty(Integer::NewFromUnsigned(GetIsolate(), i));
}
template <typename T>
void ReturnValue<T>::Set(uint64_t i) {
static_assert(std::is_base_of<T, Integer>::value, "type check");
if (const auto result = internal::Internals::TryIntegralToSmi(i)) {
SetInternal(*result);
return;
}
SetNonEmpty(Number::New(GetIsolate(), static_cast<double>(i)));
}
template <typename T>
@ -532,10 +602,15 @@ Local<Object> FunctionCallbackInfo<T>::This() const {
}
template <typename T>
Local<Object> FunctionCallbackInfo<T>::Holder() const {
Local<Object> FunctionCallbackInfo<T>::HolderSoonToBeDeprecated() const {
return Local<Object>::FromSlot(&implicit_args_[kHolderIndex]);
}
template <typename T>
Local<Object> FunctionCallbackInfo<T>::Holder() const {
return HolderSoonToBeDeprecated();
}
template <typename T>
Local<Value> FunctionCallbackInfo<T>::NewTarget() const {
return Local<Value>::FromSlot(&implicit_args_[kNewTargetIndex]);
@ -543,7 +618,8 @@ Local<Value> FunctionCallbackInfo<T>::NewTarget() const {
template <typename T>
Local<Value> FunctionCallbackInfo<T>::Data() const {
return Local<Value>::FromSlot(&implicit_args_[kDataIndex]);
auto target = Local<v8::Data>::FromSlot(&implicit_args_[kTargetIndex]);
return api_internal::GetFunctionTemplateData(GetIsolate(), target);
}
template <typename T>
@ -586,6 +662,23 @@ Local<Object> PropertyCallbackInfo<T>::Holder() const {
return Local<Object>::FromSlot(&args_[kHolderIndex]);
}
namespace api_internal {
// Returns JSGlobalProxy if holder is JSGlobalObject or unmodified holder
// otherwise.
V8_EXPORT internal::Address ConvertToJSGlobalProxyIfNecessary(
internal::Address holder);
} // namespace api_internal
template <typename T>
Local<Object> PropertyCallbackInfo<T>::HolderV2() const {
using I = internal::Internals;
if (!I::HasHeapObjectTag(args_[kHolderV2Index])) {
args_[kHolderV2Index] =
api_internal::ConvertToJSGlobalProxyIfNecessary(args_[kHolderIndex]);
}
return Local<Object>::FromSlot(&args_[kHolderV2Index]);
}
template <typename T>
ReturnValue<T> PropertyCallbackInfo<T>::GetReturnValue() const {
return ReturnValue<T>(&args_[kReturnValueIndex]);
@ -595,8 +688,8 @@ template <typename T>
bool PropertyCallbackInfo<T>::ShouldThrowOnError() const {
using I = internal::Internals;
if (args_[kShouldThrowOnErrorIndex] !=
I::IntToSmi(I::kInferShouldThrowMode)) {
return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kDontThrow);
I::IntegralToSmi(I::kInferShouldThrowMode)) {
return args_[kShouldThrowOnErrorIndex] != I::IntegralToSmi(I::kDontThrow);
}
return v8::internal::ShouldThrowOnError(
reinterpret_cast<v8::internal::Isolate*>(GetIsolate()));

View file

@ -59,9 +59,6 @@ class V8_EXPORT Function : public Object {
void SetName(Local<String> name);
Local<Value> GetName() const;
V8_DEPRECATED("No direct replacement")
MaybeLocal<UnboundScript> GetUnboundScript() const;
/**
* Name inferred from variable or property assignment of this function.
* Used to facilitate debugging and profiling of JavaScript code written

View file

@ -52,6 +52,9 @@ using ReturnAddressLocationResolver =
using DcheckErrorCallback = void (*)(const char* file, int line,
const char* message);
using V8FatalErrorCallback = void (*)(const char* file, int line,
const char* message);
/**
* Container class for static utility functions.
*/
@ -77,6 +80,12 @@ class V8_EXPORT V8 {
/** Set the callback to invoke in case of Dcheck failures. */
static void SetDcheckErrorHandler(DcheckErrorCallback that);
/** Set the callback to invoke in the case of CHECK failures or fatal
* errors. This is distinct from Isolate::SetFatalErrorHandler, which
* is invoked in response to API usage failures.
* */
static void SetFatalErrorHandler(V8FatalErrorCallback that);
/**
* Sets V8 flags from a string.
*/
@ -97,10 +106,17 @@ class V8_EXPORT V8 {
* is created. It always returns true.
*/
V8_INLINE static bool Initialize() {
#ifdef V8_TARGET_OS_ANDROID
const bool kV8TargetOsIsAndroid = true;
#else
const bool kV8TargetOsIsAndroid = false;
#endif
const int kBuildConfiguration =
(internal::PointerCompressionIsEnabled() ? kPointerCompression : 0) |
(internal::SmiValuesAre31Bits() ? k31BitSmis : 0) |
(internal::SandboxIsEnabled() ? kSandbox : 0);
(internal::SandboxIsEnabled() ? kSandbox : 0) |
(kV8TargetOsIsAndroid ? kTargetOsIsAndroid : 0);
return Initialize(kBuildConfiguration);
}
@ -271,6 +287,7 @@ class V8_EXPORT V8 {
kPointerCompression = 1 << 0,
k31BitSmis = 1 << 1,
kSandbox = 1 << 2,
kTargetOsIsAndroid = 1 << 3,
};
/**

View file

@ -11,7 +11,9 @@
#include <atomic>
#include <iterator>
#include <limits>
#include <memory>
#include <optional>
#include <type_traits>
#include "v8config.h" // NOLINT(build/include_directory)
@ -87,7 +89,10 @@ struct SmiTagging<4> {
// Truncate and shift down (requires >> to be sign extending).
return static_cast<int32_t>(static_cast<uint32_t>(value)) >> shift_bits;
}
V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
template <class T, typename std::enable_if_t<std::is_integral_v<T> &&
std::is_signed_v<T>>* = nullptr>
V8_INLINE static constexpr bool IsValidSmi(T value) {
// Is value in range [kSmiMinValue, kSmiMaxValue].
// Use unsigned operations in order to avoid undefined behaviour in case of
// signed integer overflow.
@ -96,6 +101,28 @@ struct SmiTagging<4> {
(static_cast<uintptr_t>(kSmiMaxValue) -
static_cast<uintptr_t>(kSmiMinValue));
}
template <class T,
typename std::enable_if_t<std::is_integral_v<T> &&
std::is_unsigned_v<T>>* = nullptr>
V8_INLINE static constexpr bool IsValidSmi(T value) {
static_assert(kSmiMaxValue <= std::numeric_limits<uintptr_t>::max());
return value <= static_cast<uintptr_t>(kSmiMaxValue);
}
// Same as the `intptr_t` version but works with int64_t on 32-bit builds
// without slowing down anything else.
V8_INLINE static constexpr bool IsValidSmi(int64_t value) {
return (static_cast<uint64_t>(value) -
static_cast<uint64_t>(kSmiMinValue)) <=
(static_cast<uint64_t>(kSmiMaxValue) -
static_cast<uint64_t>(kSmiMinValue));
}
V8_INLINE static constexpr bool IsValidSmi(uint64_t value) {
static_assert(kSmiMaxValue <= std::numeric_limits<uint64_t>::max());
return value <= static_cast<uint64_t>(kSmiMaxValue);
}
};
// Smi constants for systems where tagged pointer is a 64-bit value.
@ -112,10 +139,21 @@ struct SmiTagging<8> {
// Shift down and throw away top 32 bits.
return static_cast<int>(static_cast<intptr_t>(value) >> shift_bits);
}
V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
template <class T, typename std::enable_if_t<std::is_integral_v<T> &&
std::is_signed_v<T>>* = nullptr>
V8_INLINE static constexpr bool IsValidSmi(T value) {
// To be representable as a long smi, the value must be a 32-bit integer.
return (value == static_cast<int32_t>(value));
}
template <class T,
typename std::enable_if_t<std::is_integral_v<T> &&
std::is_unsigned_v<T>>* = nullptr>
V8_INLINE static constexpr bool IsValidSmi(T value) {
return (static_cast<uintptr_t>(value) ==
static_cast<uintptr_t>(static_cast<int32_t>(value)));
}
};
#ifdef V8_COMPRESS_POINTERS
@ -253,15 +291,15 @@ static_assert(1ULL << (64 - kBoundedSizeShift) ==
// size allows omitting bounds checks on table accesses if the indices are
// guaranteed (e.g. through shifting) to be below the maximum index. This
// value must be a power of two.
constexpr size_t kExternalPointerTableReservationSize = 512 * MB;
constexpr size_t kExternalPointerTableReservationSize = 256 * MB;
// The external pointer table indices stored in HeapObjects as external
// pointers are shifted to the left by this amount to guarantee that they are
// smaller than the maximum table size.
constexpr uint32_t kExternalPointerIndexShift = 6;
constexpr uint32_t kExternalPointerIndexShift = 7;
#else
constexpr size_t kExternalPointerTableReservationSize = 1024 * MB;
constexpr uint32_t kExternalPointerIndexShift = 5;
constexpr size_t kExternalPointerTableReservationSize = 512 * MB;
constexpr uint32_t kExternalPointerIndexShift = 6;
#endif // V8_TARGET_OS_ANDROID
// The maximum number of entries in an external pointer table.
@ -301,6 +339,95 @@ using ExternalPointer_t = Address;
constexpr ExternalPointer_t kNullExternalPointer = 0;
constexpr ExternalPointerHandle kNullExternalPointerHandle = 0;
// See `ExternalPointerHandle` for the main documentation. The difference to
// `ExternalPointerHandle` is that the handle does not represent an arbitrary
// external pointer but always refers to an object managed by `CppHeap`. The
// handles are using in combination with a dedicated table for `CppHeap`
// references.
using CppHeapPointerHandle = uint32_t;
// The actual pointer to objects located on the `CppHeap`. When pointer
// compression is enabled these pointers are stored as `CppHeapPointerHandle`.
// In non-compressed configurations the pointers are simply stored as raw
// pointers.
#ifdef V8_COMPRESS_POINTERS
using CppHeapPointer_t = CppHeapPointerHandle;
#else
using CppHeapPointer_t = Address;
#endif
constexpr CppHeapPointer_t kNullCppHeapPointer = 0;
constexpr CppHeapPointerHandle kNullCppHeapPointerHandle = 0;
constexpr uint64_t kCppHeapPointerMarkBit = 1ULL;
constexpr uint64_t kCppHeapPointerTagShift = 1;
constexpr uint64_t kCppHeapPointerPayloadShift = 16;
#ifdef V8_COMPRESS_POINTERS
// CppHeapPointers use a dedicated pointer table. These constants control the
// size and layout of the table. See the corresponding constants for the
// external pointer table for further details.
constexpr size_t kCppHeapPointerTableReservationSize =
kExternalPointerTableReservationSize;
constexpr uint32_t kCppHeapPointerIndexShift = kExternalPointerIndexShift;
constexpr int kCppHeapPointerTableEntrySize = 8;
constexpr int kCppHeapPointerTableEntrySizeLog2 = 3;
constexpr size_t kMaxCppHeapPointers =
kCppHeapPointerTableReservationSize / kCppHeapPointerTableEntrySize;
static_assert((1 << (32 - kCppHeapPointerIndexShift)) == kMaxCppHeapPointers,
"kCppHeapPointerTableReservationSize and "
"kCppHeapPointerIndexShift don't match");
#else // !V8_COMPRESS_POINTERS
// Needed for the V8.SandboxedCppHeapPointersCount histogram.
constexpr size_t kMaxCppHeapPointers = 0;
#endif // V8_COMPRESS_POINTERS
// See `ExternalPointerHandle` for the main documentation. The difference to
// `ExternalPointerHandle` is that the handle always refers to a
// (external pointer, size) tuple. The handles are used in combination with a
// dedicated external buffer table (EBT).
using ExternalBufferHandle = uint32_t;
// ExternalBuffer point to buffer located outside the sandbox. When the V8
// sandbox is enabled, these are stored on heap as ExternalBufferHandles,
// otherwise they are simply raw pointers.
#ifdef V8_ENABLE_SANDBOX
using ExternalBuffer_t = ExternalBufferHandle;
#else
using ExternalBuffer_t = Address;
#endif
#ifdef V8_TARGET_OS_ANDROID
// The size of the virtual memory reservation for the external buffer table.
// As with the external pointer table, a maximum table size in combination with
// shifted indices allows omitting bounds checks.
constexpr size_t kExternalBufferTableReservationSize = 64 * MB;
// The external buffer handles are stores shifted to the left by this amount
// to guarantee that they are smaller than the maximum table size.
constexpr uint32_t kExternalBufferHandleShift = 10;
#else
constexpr size_t kExternalBufferTableReservationSize = 128 * MB;
constexpr uint32_t kExternalBufferHandleShift = 9;
#endif // V8_TARGET_OS_ANDROID
// A null handle always references an entry that contains nullptr.
constexpr ExternalBufferHandle kNullExternalBufferHandle = 0;
// The maximum number of entries in an external buffer table.
constexpr int kExternalBufferTableEntrySize = 16;
constexpr int kExternalBufferTableEntrySizeLog2 = 4;
constexpr size_t kMaxExternalBufferPointers =
kExternalBufferTableReservationSize / kExternalBufferTableEntrySize;
static_assert((1 << (32 - kExternalBufferHandleShift)) ==
kMaxExternalBufferPointers,
"kExternalBufferTableReservationSize and "
"kExternalBufferHandleShift don't match");
//
// External Pointers.
//
@ -365,7 +492,7 @@ constexpr ExternalPointerHandle kNullExternalPointerHandle = 0;
// extension (MTE) which would use bits [56, 60).
//
// External pointer tables are also available even when the sandbox is off but
// pointer compression is on. In that case, the mechanism can be used to easy
// pointer compression is on. In that case, the mechanism can be used to ease
// alignment requirements as it turns unaligned 64-bit raw pointers into
// aligned 32-bit indices. To "opt-in" to the external pointer table mechanism
// for this purpose, instead of using the ExternalPointer accessors one needs to
@ -380,7 +507,7 @@ constexpr uint64_t kExternalPointerTagShift = 48;
// These are sorted so that tags can be grouped together and it can efficiently
// be checked if a tag belongs to a given group. See for example the
// IsSharedExternalPointerType routine.
constexpr uint64_t kAllExternalPointerTypeTags[] = {
constexpr uint64_t kAllTagsForAndBasedTypeChecking[] = {
0b00001111, 0b00010111, 0b00011011, 0b00011101, 0b00011110, 0b00100111,
0b00101011, 0b00101101, 0b00101110, 0b00110011, 0b00110101, 0b00110110,
0b00111001, 0b00111010, 0b00111100, 0b01000111, 0b01001011, 0b01001101,
@ -394,8 +521,8 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
0b11001100, 0b11010001, 0b11010010, 0b11010100, 0b11011000, 0b11100001,
0b11100010, 0b11100100, 0b11101000, 0b11110000};
#define TAG(i) \
((kAllExternalPointerTypeTags[i] << kExternalPointerTagShift) | \
#define TAG(i) \
((kAllTagsForAndBasedTypeChecking[i] << kExternalPointerTagShift) | \
kExternalPointerMarkBit)
// clang-format off
@ -418,22 +545,46 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
// External pointers using these tags are kept in a per-Isolate external
// pointer table and can only be accessed when this Isolate is active.
#define PER_ISOLATE_EXTERNAL_POINTER_TAGS(V) \
V(kForeignForeignAddressTag, TAG(10)) \
V(kNativeContextMicrotaskQueueTag, TAG(11)) \
V(kEmbedderDataSlotPayloadTag, TAG(12)) \
V(kNativeContextMicrotaskQueueTag, TAG(10)) \
V(kEmbedderDataSlotPayloadTag, TAG(11)) \
/* This tag essentially stands for a `void*` pointer in the V8 API, and */ \
/* it is the Embedder's responsibility to ensure type safety (against */ \
/* substitution) and lifetime validity of these objects. */ \
V(kExternalObjectValueTag, TAG(13)) \
V(kFunctionTemplateInfoCallbackTag, TAG(14)) \
V(kAccessorInfoGetterTag, TAG(15)) \
V(kAccessorInfoSetterTag, TAG(16)) \
V(kWasmInternalFunctionCallTargetTag, TAG(17)) \
V(kWasmTypeInfoNativeTypeTag, TAG(18)) \
V(kWasmExportedFunctionDataSignatureTag, TAG(19)) \
V(kWasmContinuationJmpbufTag, TAG(20)) \
V(kWasmIndirectFunctionTargetTag, TAG(21)) \
V(kArrayBufferExtensionTag, TAG(22))
V(kExternalObjectValueTag, TAG(12)) \
V(kFunctionTemplateInfoCallbackTag, TAG(13)) \
V(kAccessorInfoGetterTag, TAG(14)) \
V(kAccessorInfoSetterTag, TAG(15)) \
V(kWasmInternalFunctionCallTargetTag, TAG(16)) \
V(kWasmTypeInfoNativeTypeTag, TAG(17)) \
V(kWasmExportedFunctionDataSignatureTag, TAG(18)) \
V(kWasmContinuationJmpbufTag, TAG(19)) \
V(kWasmIndirectFunctionTargetTag, TAG(20)) \
/* Foreigns */ \
V(kGenericForeignTag, TAG(30)) \
/* Managed */ \
V(kFirstManagedResourceTag, TAG(40)) \
V(kGenericManagedTag, TAG(40)) \
V(kWasmWasmStreamingTag, TAG(41)) \
V(kWasmFuncDataTag, TAG(42)) \
V(kWasmManagedDataTag, TAG(43)) \
V(kWasmNativeModuleTag, TAG(44)) \
V(kWasmStackMemoryTag, TAG(45)) \
V(kIcuBreakIteratorTag, TAG(46)) \
V(kIcuUnicodeStringTag, TAG(47)) \
V(kIcuListFormatterTag, TAG(48)) \
V(kIcuLocaleTag, TAG(49)) \
V(kIcuSimpleDateFormatTag, TAG(50)) \
V(kIcuDateIntervalFormatTag, TAG(51)) \
V(kIcuRelativeDateTimeFormatterTag, TAG(52)) \
V(kIcuLocalizedNumberFormatterTag, TAG(53)) \
V(kIcuPluralRulesTag, TAG(54)) \
V(kIcuCollatorTag, TAG(55)) \
V(kDisplayNamesInternalTag, TAG(56)) \
/* External resources whose lifetime is tied to */ \
/* their entry in the external pointer table but */ \
/* which are not referenced via a Managed */ \
V(kArrayBufferExtensionTag, TAG(57)) \
V(kLastManagedResourceTag, TAG(57)) \
// All external pointer tags.
#define ALL_EXTERNAL_POINTER_TAGS(V) \
@ -449,12 +600,18 @@ enum ExternalPointerTag : uint64_t {
kExternalPointerNullTag = MAKE_TAG(1, 0b00000000),
// External pointer tag that will match any external pointer. Use with care!
kAnyExternalPointerTag = MAKE_TAG(1, 0b11111111),
// External pointer tag that will match any external pointer in a Foreign.
// Use with care! If desired, this could be made more fine-granular.
kAnyForeignTag = kAnyExternalPointerTag,
// The free entry tag has all type bits set so every type check with a
// different type fails. It also doesn't have the mark bit set as free
// entries are (by definition) not alive.
kExternalPointerFreeEntryTag = MAKE_TAG(0, 0b11111111),
// Evacuation entries are used during external pointer table compaction.
kExternalPointerEvacuationEntryTag = MAKE_TAG(1, 0b11100111),
kExternalPointerEvacuationEntryTag = MAKE_TAG(1, 0b11111110),
// Tag for zapped/invalidated entries. Those are considered to no longer be
// in use and so have the marking bit cleared.
kExternalPointerZappedEntryTag = MAKE_TAG(0, 0b11111101),
ALL_EXTERNAL_POINTER_TAGS(EXTERNAL_POINTER_TAG_ENUM)
};
@ -481,6 +638,15 @@ V8_INLINE static constexpr bool IsMaybeReadOnlyExternalPointerType(
tag == kFunctionTemplateInfoCallbackTag;
}
// True if the external pointer references an external object whose lifetime is
// tied to the entry in the external pointer table.
// In this case, the entry in the ExternalPointerTable always points to an
// object derived from ExternalPointerTable::ManagedResource.
V8_INLINE static constexpr bool IsManagedExternalPointerType(
ExternalPointerTag tag) {
return tag >= kFirstManagedResourceTag && tag <= kLastManagedResourceTag;
}
// Sanity checks.
#define CHECK_SHARED_EXTERNAL_POINTER_TAGS(Tag, ...) \
static_assert(IsSharedExternalPointerType(Tag));
@ -576,11 +742,11 @@ using CodePointerHandle = IndirectPointerHandle;
// The size of the virtual memory reservation for the code pointer table.
// As with the other tables, a maximum table size in combination with shifted
// indices allows omitting bounds checks.
constexpr size_t kCodePointerTableReservationSize = 16 * MB;
constexpr size_t kCodePointerTableReservationSize = 128 * MB;
// Code pointer handles are shifted by a different amount than indirect pointer
// handles as the tables have a different maximum size.
constexpr uint32_t kCodePointerHandleShift = 12;
constexpr uint32_t kCodePointerHandleShift = 9;
// A null handle always references an entry that contains nullptr.
constexpr CodePointerHandle kNullCodePointerHandle = kNullIndirectPointerHandle;
@ -647,6 +813,13 @@ class Internals {
static const int kOddballKindOffset = 4 * kApiTaggedSize + kApiDoubleSize;
static const int kJSObjectHeaderSize = 3 * kApiTaggedSize;
#ifdef V8_COMPRESS_POINTERS
static const int kJSAPIObjectWithEmbedderSlotsHeaderSize =
kJSObjectHeaderSize + kApiInt32Size;
#else // !V8_COMPRESS_POINTERS
static const int kJSAPIObjectWithEmbedderSlotsHeaderSize =
kJSObjectHeaderSize + kApiTaggedSize;
#endif // !V8_COMPRESS_POINTERS
static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize;
static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize;
static const int kEmbedderDataSlotSize = kApiSystemPointerSize;
@ -676,6 +849,7 @@ class Internals {
// ExternalPointerTable and TrustedPointerTable layout guarantees.
static const int kExternalPointerTableBasePointerOffset = 0;
static const int kExternalPointerTableSize = 2 * kApiSystemPointerSize;
static const int kExternalBufferTableSize = 2 * kApiSystemPointerSize;
static const int kTrustedPointerTableSize = 2 * kApiSystemPointerSize;
static const int kTrustedPointerTableBasePointerOffset = 0;
@ -719,16 +893,22 @@ class Internals {
kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize;
static const int kIsolateSharedExternalPointerTableAddressOffset =
kIsolateExternalPointerTableOffset + kExternalPointerTableSize;
static const int kIsolateCppHeapPointerTableOffset =
kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
#ifdef V8_ENABLE_SANDBOX
static const int kIsolateTrustedCageBaseOffset =
kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
kIsolateCppHeapPointerTableOffset + kExternalPointerTableSize;
static const int kIsolateTrustedPointerTableOffset =
kIsolateTrustedCageBaseOffset + kApiSystemPointerSize;
static const int kIsolateApiCallbackThunkArgumentOffset =
static const int kIsolateExternalBufferTableOffset =
kIsolateTrustedPointerTableOffset + kTrustedPointerTableSize;
static const int kIsolateSharedExternalBufferTableAddressOffset =
kIsolateExternalBufferTableOffset + kExternalBufferTableSize;
static const int kIsolateApiCallbackThunkArgumentOffset =
kIsolateSharedExternalBufferTableAddressOffset + kApiSystemPointerSize;
#else
static const int kIsolateApiCallbackThunkArgumentOffset =
kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
kIsolateCppHeapPointerTableOffset + kExternalPointerTableSize;
#endif // V8_ENABLE_SANDBOX
#else
static const int kIsolateApiCallbackThunkArgumentOffset =
@ -736,13 +916,8 @@ class Internals {
#endif // V8_COMPRESS_POINTERS
static const int kContinuationPreservedEmbedderDataOffset =
kIsolateApiCallbackThunkArgumentOffset + kApiSystemPointerSize;
static const int kWasm64OOBOffsetAlignmentPaddingSize = 0;
static const int kWasm64OOBOffsetOffset =
kContinuationPreservedEmbedderDataOffset + kApiSystemPointerSize +
kWasm64OOBOffsetAlignmentPaddingSize;
static const int kIsolateRootsOffset =
kWasm64OOBOffsetOffset + sizeof(int64_t);
kContinuationPreservedEmbedderDataOffset + kApiSystemPointerSize;
#if V8_STATIC_ROOTS_BOOL
@ -753,7 +928,7 @@ class Internals {
V(TrueValue, 0xc9) \
V(FalseValue, 0xad) \
V(EmptyString, 0xa1) \
V(TheHoleValue, 0x719)
V(TheHoleValue, 0x741)
using Tagged_t = uint32_t;
struct StaticReadOnlyRoot {
@ -836,14 +1011,36 @@ class Internals {
return PlatformSmiTagging::SmiToInt(value);
}
V8_INLINE static constexpr Address IntToSmi(int value) {
return internal::IntToSmi(value);
V8_INLINE static constexpr Address AddressToSmi(Address value) {
return (value << (kSmiTagSize + PlatformSmiTagging::kSmiShiftSize)) |
kSmiTag;
}
V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
V8_INLINE static constexpr Address IntToSmi(int value) {
return AddressToSmi(static_cast<Address>(value));
}
template <typename T,
typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
V8_INLINE static constexpr Address IntegralToSmi(T value) {
return AddressToSmi(static_cast<Address>(value));
}
template <typename T,
typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
V8_INLINE static constexpr bool IsValidSmi(T value) {
return PlatformSmiTagging::IsValidSmi(value);
}
template <typename T,
typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
static constexpr std::optional<Address> TryIntegralToSmi(T value) {
if (V8_LIKELY(PlatformSmiTagging::IsValidSmi(value))) {
return {AddressToSmi(static_cast<Address>(value))};
}
return {};
}
#if V8_STATIC_ROOTS_BOOL
V8_INLINE static bool is_identical(Address obj, Tagged_t constant) {
return static_cast<Tagged_t>(obj) == constant;
@ -1116,7 +1313,7 @@ class V8_EXPORT StrongRootAllocatorBase {
protected:
explicit StrongRootAllocatorBase(Heap* heap) : heap_(heap) {}
explicit StrongRootAllocatorBase(v8::Isolate* isolate);
explicit StrongRootAllocatorBase(Isolate* isolate);
// Allocate/deallocate a range of n elements of type internal::Address.
Address* allocate_impl(size_t n);
@ -1132,17 +1329,15 @@ class V8_EXPORT StrongRootAllocatorBase {
// and internal::StrongRootAllocator<v8::Local<T>> register the allocated range
// as strong roots.
template <typename T>
class StrongRootAllocator : public StrongRootAllocatorBase,
private std::allocator<T> {
class StrongRootAllocator : private std::allocator<T> {
public:
using value_type = T;
explicit StrongRootAllocator(Heap* heap) : StrongRootAllocatorBase(heap) {}
explicit StrongRootAllocator(v8::Isolate* isolate)
: StrongRootAllocatorBase(isolate) {}
explicit StrongRootAllocator(Heap* heap) {}
explicit StrongRootAllocator(Isolate* isolate) {}
explicit StrongRootAllocator(v8::Isolate* isolate) {}
template <typename U>
StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept
: StrongRootAllocatorBase(other) {}
StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept {}
using std::allocator<T>::allocate;
using std::allocator<T>::deallocate;
@ -1383,10 +1578,6 @@ class HandleHelper final {
if (rhs.IsEmpty()) return false;
return lhs.ptr() == rhs.ptr();
}
static V8_EXPORT bool IsOnStack(const void* ptr);
static V8_EXPORT void VerifyOnStack(const void* ptr);
static V8_EXPORT void VerifyOnMainThread();
};
V8_EXPORT void VerifyHandleIsNonEmpty(bool is_empty);

View file

@ -276,11 +276,6 @@ class V8_EXPORT Isolate {
*/
bool allow_atomics_wait = true;
/**
* Termination is postponed when there is no active SafeForTerminationScope.
*/
bool only_terminate_in_safe_scope = false;
/**
* The following parameters describe the offsets for addressing type info
* for wrapped API objects and are used by the fast C API
@ -389,21 +384,6 @@ class V8_EXPORT Isolate {
friend class internal::ThreadLocalTop;
};
/**
* This scope allows terminations inside direct V8 API calls and forbid them
* inside any recursive API calls without explicit SafeForTerminationScope.
*/
class V8_EXPORT V8_NODISCARD SafeForTerminationScope {
public:
V8_DEPRECATE_SOON("All code should be safe for termination")
explicit SafeForTerminationScope(v8::Isolate* v8_isolate) {}
~SafeForTerminationScope() {}
// Prevent copying of Scope objects.
SafeForTerminationScope(const SafeForTerminationScope&) = delete;
SafeForTerminationScope& operator=(const SafeForTerminationScope&) = delete;
};
/**
* Types of garbage collections that can be requested via
* RequestGarbageCollectionForTesting.
@ -563,6 +543,8 @@ class V8_EXPORT Isolate {
kWasmExnRef = 138,
kWasmTypedFuncRef = 139,
kInvalidatedStringWrapperToPrimitiveProtector = 140,
kDocumentAllLegacyCall = 141,
kDocumentAllLegacyConstruct = 142,
// If you add new values here, you'll also need to update Chromium's:
// web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to
@ -691,6 +673,11 @@ class V8_EXPORT Isolate {
*/
void SetPrepareStackTraceCallback(PrepareStackTraceCallback callback);
/**
* Get the stackTraceLimit property of Error.
*/
int GetStackTraceLimit();
#if defined(V8_OS_WIN)
/**
* This specifies the callback called when an ETW tracing session starts.
@ -1362,24 +1349,6 @@ class V8_EXPORT Isolate {
*/
void SetAddCrashKeyCallback(AddCrashKeyCallback);
/**
* Optional notification that the embedder is idle.
* V8 uses the notification to perform garbage collection.
* This call can be used repeatedly if the embedder remains idle.
* Returns true if the embedder should stop calling IdleNotificationDeadline
* until real work has been done. This indicates that V8 has done
* as much cleanup as it will be able to do.
*
* The deadline_in_seconds argument specifies the deadline V8 has to finish
* garbage collection work. deadline_in_seconds is compared with
* MonotonicallyIncreasingTime() and should be based on the same timebase as
* that function. There is no guarantee that the actual work will be done
* within the time limit.
*/
V8_DEPRECATE_SOON(
"Use MemoryPressureNotification() to influence the GC schedule.")
bool IdleNotificationDeadline(double deadline_in_seconds);
/**
* Optional notification that the system is running low on memory.
* V8 uses these notifications to attempt to free memory.
@ -1656,7 +1625,7 @@ class V8_EXPORT Isolate {
* heap. GC is not invoked prior to iterating, therefore there is no
* guarantee that visited objects are still alive.
*/
V8_DEPRECATE_SOON("Will be removed without replacement. crbug.com/v8/14172")
V8_DEPRECATED("Will be removed without replacement. crbug.com/v8/14172")
void VisitExternalResources(ExternalResourceVisitor* visitor);
/**

View file

@ -51,8 +51,6 @@ class Isolate;
class Object;
template <class F1, class F2, class F3>
class PersistentValueMapBase;
template <class F1, class F2>
class PersistentValueVector;
class Primitive;
class Private;
template <class F>
@ -382,8 +380,6 @@ class V8_TRIVIAL_ABI Local : public LocalBase<T>,
friend class InternalEscapableScope;
template <class F1, class F2, class F3>
friend class PersistentValueMapBase;
template <class F1, class F2>
friend class PersistentValueVector;
template <class F>
friend class ReturnValue;
template <class F>
@ -440,12 +436,12 @@ class V8_TRIVIAL_ABI LocalUnchecked : public Local<T> {
// In this case, the check is also enforced in the copy constructor and we
// need to suppress it.
LocalUnchecked(const LocalUnchecked& other)
: Local<T>(other, Local<T>::do_not_check) {}
LocalUnchecked& operator=(const LocalUnchecked&) = default;
: Local<T>(other, Local<T>::do_not_check) noexcept {}
LocalUnchecked& operator=(const LocalUnchecked&) noexcept = default;
#endif
// Implicit conversion from Local.
LocalUnchecked(const Local<T>& other) // NOLINT(runtime/explicit)
LocalUnchecked(const Local<T>& other) noexcept // NOLINT(runtime/explicit)
: Local<T>(other, Local<T>::do_not_check) {}
};
@ -461,8 +457,10 @@ class StrongRootAllocator<LocalUnchecked<T>> : public StrongRootAllocatorBase {
static_assert(sizeof(value_type) == sizeof(Address));
explicit StrongRootAllocator(Heap* heap) : StrongRootAllocatorBase(heap) {}
explicit StrongRootAllocator(v8::Isolate* isolate)
explicit StrongRootAllocator(Isolate* isolate)
: StrongRootAllocatorBase(isolate) {}
explicit StrongRootAllocator(v8::Isolate* isolate)
: StrongRootAllocatorBase(reinterpret_cast<Isolate*>(isolate)) {}
template <typename U>
StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept
: StrongRootAllocatorBase(other) {}
@ -561,6 +559,7 @@ class LocalVector {
LocalVector<T>& operator=(std::initializer_list<Local<T>> init) {
backing_.clear();
backing_.reserve(init.size());
backing_.insert(backing_.end(), init.begin(), init.end());
return *this;
}

View file

@ -61,27 +61,6 @@ class ScriptOriginOptions {
*/
class V8_EXPORT ScriptOrigin {
public:
V8_DEPRECATE_SOON("Use constructor without the isolate.")
V8_INLINE ScriptOrigin(Isolate* isolate, Local<Value> resource_name,
int resource_line_offset = 0,
int resource_column_offset = 0,
bool resource_is_shared_cross_origin = false,
int script_id = -1,
Local<Value> source_map_url = Local<Value>(),
bool resource_is_opaque = false, bool is_wasm = false,
bool is_module = false,
Local<Data> host_defined_options = Local<Data>())
: resource_name_(resource_name),
resource_line_offset_(resource_line_offset),
resource_column_offset_(resource_column_offset),
options_(resource_is_shared_cross_origin, resource_is_opaque, is_wasm,
is_module),
script_id_(script_id),
source_map_url_(source_map_url),
host_defined_options_(host_defined_options) {
VerifyHostDefinedOptions();
}
V8_INLINE ScriptOrigin(Local<Value> resource_name,
int resource_line_offset = 0,
int resource_column_offset = 0,

View file

@ -118,11 +118,6 @@ class V8_EXPORT V8_NODISCARD MicrotasksScope {
public:
enum Type { kRunMicrotasks, kDoNotRunMicrotasks };
V8_DEPRECATE_SOON(
"May be incorrect if context was created with non-default microtask "
"queue")
MicrotasksScope(Isolate* isolate, Type type);
MicrotasksScope(Local<Context> context, Type type);
MicrotasksScope(Isolate* isolate, MicrotaskQueue* microtask_queue, Type type);
~MicrotasksScope();

View file

@ -5,10 +5,12 @@
#ifndef INCLUDE_V8_OBJECT_H_
#define INCLUDE_V8_OBJECT_H_
#include "v8-internal.h" // NOLINT(build/include_directory)
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-maybe.h" // NOLINT(build/include_directory)
#include "v8-persistent-handle.h" // NOLINT(build/include_directory)
#include "v8-primitive.h" // NOLINT(build/include_directory)
#include "v8-sandbox.h" // NOLINT(build/include_directory)
#include "v8-traced-handle.h" // NOLINT(build/include_directory)
#include "v8-value.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
@ -146,18 +148,22 @@ enum PropertyAttribute {
};
/**
* Accessor[Getter|Setter] are used as callback functions when
* setting|getting a particular property. See Object and ObjectTemplate's
* method SetAccessor.
* Accessor[Getter|Setter] are used as callback functions when setting|getting
* a particular data property. See Object::SetNativeDataProperty and
* ObjectTemplate::SetNativeDataProperty methods.
*/
using AccessorGetterCallback =
void (*)(Local<String> property, const PropertyCallbackInfo<Value>& info);
using AccessorGetterCallback V8_DEPRECATED(
"Use AccessorNameGetterCallback signature instead. This type will be "
"removed in V8 12.8.") = void (*)(Local<String> property,
const PropertyCallbackInfo<Value>& info);
using AccessorNameGetterCallback =
void (*)(Local<Name> property, const PropertyCallbackInfo<Value>& info);
using AccessorSetterCallback = void (*)(Local<String> property,
Local<Value> value,
const PropertyCallbackInfo<void>& info);
using AccessorSetterCallback V8_DEPRECATED(
"Use AccessorNameSetterCallback signature instead. This type will be "
"removed in V8 12.8.") = void (*)(Local<String> property,
Local<Value> value,
const PropertyCallbackInfo<void>& info);
using AccessorNameSetterCallback =
void (*)(Local<Name> property, Local<Value> value,
const PropertyCallbackInfo<void>& info);
@ -339,7 +345,10 @@ class V8_EXPORT Object : public Value {
V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,
uint32_t index);
V8_DEPRECATE_SOON("Use SetNativeDataProperty instead")
V8_DEPRECATED(
"Use SetNativeDataProperty or SetAccessorProperty instead depending on "
"the required semantics. See http://crbug.com/336325111. This method "
"will be removed in V8 12.8.")
V8_WARN_UNUSED_RESULT Maybe<bool> SetAccessor(
Local<Context> context, Local<Name> name,
AccessorNameGetterCallback getter,
@ -429,16 +438,41 @@ class V8_EXPORT Object : public Value {
* be skipped by __proto__ and it does not consult the security
* handler.
*/
V8_DEPRECATE_SOON(
"V8 will stop providing access to hidden prototype (i.e. "
"JSGlobalObject). Use GetPrototypeV2() instead. "
"See http://crbug.com/333672197.")
Local<Value> GetPrototype();
/**
* Get the prototype object (same as getting __proto__ property). This does
* not consult the security handler.
* TODO(333672197): rename back to GetPrototype() once the old version goes
* through the deprecation process and is removed.
*/
Local<Value> GetPrototypeV2();
/**
* Set the prototype object. This does not skip objects marked to
* be skipped by __proto__ and it does not consult the security
* handler.
*/
V8_DEPRECATE_SOON(
"V8 will stop providing access to hidden prototype (i.e. "
"JSGlobalObject). Use SetPrototypeV2() instead. "
"See http://crbug.com/333672197.")
V8_WARN_UNUSED_RESULT Maybe<bool> SetPrototype(Local<Context> context,
Local<Value> prototype);
/**
* Set the prototype object (same as setting __proto__ property). This does
* does not consult the security handler.
* TODO(333672197): rename back to SetPrototype() once the old version goes
* through the deprecation process and is removed.
*/
V8_WARN_UNUSED_RESULT Maybe<bool> SetPrototypeV2(Local<Context> context,
Local<Value> prototype);
/**
* Finds an instance of the given function template in the prototype
* chain.
@ -526,7 +560,72 @@ class V8_EXPORT Object : public Value {
void* values[]);
/**
* HasOwnProperty() is like JavaScript's Object.prototype.hasOwnProperty().
* Unwraps a JS wrapper object.
*
* \param tag The tag for retrieving the wrappable instance. Must match the
* tag that has been used for a previous `Wrap()` operation.
* \param isolate The Isolate for the `wrapper` object.
* \param wrapper The JS wrapper object that should be unwrapped.
* \returns the C++ wrappable instance, or nullptr if the JS object has never
* been wrapped.
*/
template <CppHeapPointerTag tag, typename T = void>
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const v8::Local<v8::Object>& wrapper);
template <CppHeapPointerTag tag, typename T = void>
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const PersistentBase<Object>& wrapper);
template <CppHeapPointerTag tag, typename T = void>
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper);
template <typename T = void>
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const v8::Local<v8::Object>& wrapper,
CppHeapPointerTagRange tag_range);
template <typename T = void>
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const PersistentBase<Object>& wrapper,
CppHeapPointerTagRange tag_range);
template <typename T = void>
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper,
CppHeapPointerTagRange tag_range);
/**
* Wraps a JS wrapper with a C++ instance.
*
* \param tag The pointer tag that should be used for storing this object.
* Future `Unwrap()` operations must provide a matching tag.
* \param isolate The Isolate for the `wrapper` object.
* \param wrapper The JS wrapper object.
* \param wrappable The C++ object instance that is wrapped by the JS object.
*/
template <CppHeapPointerTag tag>
static V8_INLINE void Wrap(v8::Isolate* isolate,
const v8::Local<v8::Object>& wrapper,
void* wrappable);
template <CppHeapPointerTag tag>
static V8_INLINE void Wrap(v8::Isolate* isolate,
const PersistentBase<Object>& wrapper,
void* wrappable);
template <CppHeapPointerTag tag>
static V8_INLINE void Wrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper,
void* wrappable);
static V8_INLINE void Wrap(v8::Isolate* isolate,
const v8::Local<v8::Object>& wrapper,
void* wrappable, CppHeapPointerTag tag);
static V8_INLINE void Wrap(v8::Isolate* isolate,
const PersistentBase<Object>& wrapper,
void* wrappable, CppHeapPointerTag tag);
static V8_INLINE void Wrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper,
void* wrappable, CppHeapPointerTag tag);
/**
* HasOwnProperty() is like JavaScript's
* Object.prototype.hasOwnProperty().
*
* See also v8::Object::Has() and v8::Object::HasRealNamedProperty().
*/
@ -610,12 +709,16 @@ class V8_EXPORT Object : public Value {
/**
* Returns the context in which the object was created.
* Prefer using version with Isolate parameter.
*/
MaybeLocal<Context> GetCreationContext(v8::Isolate* isolate);
MaybeLocal<Context> GetCreationContext();
/**
* Shortcut for GetCreationContext().ToLocalChecked().
* Shortcut for GetCreationContext(...).ToLocalChecked().
* Prefer using version with Isolate parameter.
**/
Local<Context> GetCreationContextChecked(v8::Isolate* isolate);
Local<Context> GetCreationContextChecked();
/** Same as above, but works for Persistents */
@ -634,7 +737,12 @@ class V8_EXPORT Object : public Value {
* try to expand the embedder data attached to the context.
* In case the Local<Context> is already available because of other reasons,
* it's fine to keep using Context::GetAlignedPointerFromEmbedderData().
*
* Prefer using version with Isolate parameter if you have an Isolate,
* otherwise use the other one.
*/
void* GetAlignedPointerFromEmbedderDataInCreationContext(v8::Isolate* isolate,
int index);
void* GetAlignedPointerFromEmbedderDataInCreationContext(int index);
/**
@ -650,11 +758,15 @@ class V8_EXPORT Object : public Value {
bool IsConstructor() const;
/**
* True if this object can carry information relevant to the embedder in its
* embedder fields, false otherwise. This is generally true for objects
* constructed through function templates but also holds for other types where
* V8 automatically adds internal fields at compile time, such as e.g.
* v8::ArrayBuffer.
* Returns true if this object can be generally used to wrap object objects.
* This means that the object either follows the convention of using embedder
* fields to denote type/instance pointers or is using the Wrap()/Unwrap()
* APIs for the same purpose. Returns false otherwise.
*
* Note that there may be other objects that use embedder fields but are not
* used as API wrapper objects. E.g., v8::Promise may in certain configuration
* use embedder fields but promises are not generally supported as API
* wrappers. The method will return false in those cases.
*/
bool IsApiWrapper() const;
@ -729,6 +841,11 @@ class V8_EXPORT Object : public Value {
bool IsCodeLike(Isolate* isolate) const;
private:
static void* Unwrap(v8::Isolate* isolate, internal::Address wrapper_obj,
CppHeapPointerTagRange tag_range);
static void Wrap(v8::Isolate* isolate, internal::Address wrapper_obj,
CppHeapPointerTag tag, void* wrappable);
Object();
static void CheckCast(Value* obj);
Local<Data> SlowGetInternalField(int index);
@ -747,7 +864,8 @@ Local<Data> Object::GetInternalField(int index) {
// know where to find the internal fields and can return the value directly.
int instance_type = I::GetInstanceType(obj);
if (I::CanHaveInternalField(instance_type)) {
int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
(I::kEmbedderDataSlotSize * index);
A value = I::ReadRawField<A>(obj, offset);
#ifdef V8_COMPRESS_POINTERS
// We read the full pointer value and then decompress it in order to avoid
@ -773,7 +891,8 @@ void* Object::GetAlignedPointerFromInternalField(v8::Isolate* isolate,
// know where to find the internal fields and can return the value directly.
auto instance_type = I::GetInstanceType(obj);
if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index) +
int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
(I::kEmbedderDataSlotSize * index) +
I::kEmbedderDataSlotExternalPointerOffset;
A value =
I::ReadExternalPointerField<internal::kEmbedderDataSlotPayloadTag>(
@ -793,7 +912,8 @@ void* Object::GetAlignedPointerFromInternalField(int index) {
// know where to find the internal fields and can return the value directly.
auto instance_type = I::GetInstanceType(obj);
if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index) +
int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
(I::kEmbedderDataSlotSize * index) +
I::kEmbedderDataSlotExternalPointerOffset;
Isolate* isolate = I::GetIsolateForSandbox(obj);
A value =
@ -805,6 +925,142 @@ void* Object::GetAlignedPointerFromInternalField(int index) {
return SlowGetAlignedPointerFromInternalField(index);
}
// static
template <CppHeapPointerTag tag, typename T>
T* Object::Unwrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper) {
CppHeapPointerTagRange tag_range(tag, tag);
auto obj = internal::ValueHelper::ValueAsAddress(*wrapper);
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField<T>(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast<T*>(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template <CppHeapPointerTag tag, typename T>
T* Object::Unwrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper) {
CppHeapPointerTagRange tag_range(tag, tag);
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField<T>(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast<T*>(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template <CppHeapPointerTag tag, typename T>
T* Object::Unwrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper) {
CppHeapPointerTagRange tag_range(tag, tag);
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField<T>(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast<T*>(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template <typename T>
T* Object::Unwrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper,
CppHeapPointerTagRange tag_range) {
auto obj = internal::ValueHelper::ValueAsAddress(*wrapper);
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField<T>(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast<T*>(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template <typename T>
T* Object::Unwrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper,
CppHeapPointerTagRange tag_range) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField<T>(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast<T*>(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template <typename T>
T* Object::Unwrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper,
CppHeapPointerTagRange tag_range) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField<T>(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast<T*>(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template <CppHeapPointerTag tag>
void Object::Wrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper,
void* wrappable) {
auto obj = internal::ValueHelper::ValueAsAddress(*wrapper);
Wrap(isolate, obj, tag, wrappable);
}
// static
template <CppHeapPointerTag tag>
void Object::Wrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper,
void* wrappable) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
Wrap(isolate, obj, tag, wrappable);
}
// static
template <CppHeapPointerTag tag>
void Object::Wrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper,
void* wrappable) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
Wrap(isolate, obj, tag, wrappable);
}
// static
void Object::Wrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper,
void* wrappable, CppHeapPointerTag tag) {
auto obj = internal::ValueHelper::ValueAsAddress(*wrapper);
Wrap(isolate, obj, tag, wrappable);
}
// static
void Object::Wrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper,
void* wrappable, CppHeapPointerTag tag) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
Wrap(isolate, obj, tag, wrappable);
}
// static
void Object::Wrap(v8::Isolate* isolate,
const BasicTracedReference<Object>& wrapper, void* wrappable,
CppHeapPointerTag tag) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>());
Wrap(isolate, obj, tag, wrappable);
}
Private* Private::Cast(Data* data) {
#ifdef V8_ENABLE_CHECKS
CheckCast(data);

View file

@ -15,8 +15,6 @@ namespace v8 {
class Isolate;
template <class K, class V, class T>
class PersistentValueMapBase;
template <class V, class T>
class PersistentValueVector;
template <class T>
class Global;
template <class T>
@ -204,8 +202,6 @@ class PersistentBase : public api_internal::IndirectHandleBase {
friend class ReturnValue;
template <class F1, class F2, class F3>
friend class PersistentValueMapBase;
template <class F1, class F2>
friend class PersistentValueVector;
friend class Object;
friend class internal::ValueHelper;
@ -236,21 +232,6 @@ class NonCopyablePersistentTraits {
}
};
/**
* Helper class traits to allow copying and assignment of Persistent.
* This will clone the contents of storage cell, but not any of the flags, etc.
*/
template <class T>
struct CopyablePersistentTraits {
using CopyablePersistent = Persistent<T, CopyablePersistentTraits<T>>;
static const bool kResetInDestructor = true;
template <class S, class M>
static V8_INLINE void Copy(const Persistent<S, M>& source,
CopyablePersistent* dest) {
// do nothing, just allow copy
}
};
/**
* A PersistentBase which allows copy and assignment.
*

View file

@ -79,8 +79,10 @@ class TaskRunner {
*
* Embedders should override PostTaskImpl instead of this.
*/
virtual void PostTask(std::unique_ptr<Task> task) {
PostTaskImpl(std::move(task), SourceLocation::Current());
void PostTask(
std::unique_ptr<Task> task,
const SourceLocation& location = SourceLocation::Current()) {
PostTaskImpl(std::move(task), location);
}
/**
@ -100,8 +102,10 @@ class TaskRunner {
*
* Embedders should override PostNonNestableTaskImpl instead of this.
*/
virtual void PostNonNestableTask(std::unique_ptr<Task> task) {
PostNonNestableTaskImpl(std::move(task), SourceLocation::Current());
void PostNonNestableTask(
std::unique_ptr<Task> task,
const SourceLocation& location = SourceLocation::Current()) {
PostNonNestableTaskImpl(std::move(task), location);
}
/**
@ -111,10 +115,10 @@ class TaskRunner {
*
* Embedders should override PostDelayedTaskImpl instead of this.
*/
virtual void PostDelayedTask(std::unique_ptr<Task> task,
double delay_in_seconds) {
PostDelayedTaskImpl(std::move(task), delay_in_seconds,
SourceLocation::Current());
void PostDelayedTask(
std::unique_ptr<Task> task, double delay_in_seconds,
const SourceLocation& location = SourceLocation::Current()) {
PostDelayedTaskImpl(std::move(task), delay_in_seconds, location);
}
/**
@ -135,10 +139,10 @@ class TaskRunner {
*
* Embedders should override PostNonNestableDelayedTaskImpl instead of this.
*/
virtual void PostNonNestableDelayedTask(std::unique_ptr<Task> task,
double delay_in_seconds) {
PostNonNestableDelayedTaskImpl(std::move(task), delay_in_seconds,
SourceLocation::Current());
void PostNonNestableDelayedTask(
std::unique_ptr<Task> task, double delay_in_seconds,
const SourceLocation& location = SourceLocation::Current()) {
PostNonNestableDelayedTaskImpl(std::move(task), delay_in_seconds, location);
}
/**
@ -151,8 +155,10 @@ class TaskRunner {
*
* Embedders should override PostIdleTaskImpl instead of this.
*/
virtual void PostIdleTask(std::unique_ptr<IdleTask> task) {
PostIdleTaskImpl(std::move(task), SourceLocation::Current());
void PostIdleTask(
std::unique_ptr<IdleTask> task,
const SourceLocation& location = SourceLocation::Current()) {
PostIdleTaskImpl(std::move(task), location);
}
/**
@ -389,7 +395,7 @@ class TracingController {
/**
* Adds a trace event to the platform tracing system. These function calls are
* usually the result of a TRACE_* macro from trace_event_common.h when
* usually the result of a TRACE_* macro from trace-event-no-perfetto.h when
* tracing and the category of the particular trace are enabled. It is not
* advisable to call these functions on their own; they are really only meant
* to be used by the trace macros. The returned handle can be used by

View file

@ -899,9 +899,28 @@ class V8_EXPORT EmbedderGraph {
/**
* Returns a node corresponding to the given V8 value. Ownership is not
* transferred. The result pointer is valid while the graph is alive.
*
* For now the variant that takes v8::Data is not marked as abstract for
* compatibility, but embedders who subclass EmbedderGraph are expected to
* implement it. Then in the implementation of the variant that takes
* v8::Value, they can simply forward the call to the one that takes
* v8::Local<v8::Data>.
*/
virtual Node* V8Node(const v8::Local<v8::Value>& value) = 0;
/**
* Returns a node corresponding to the given V8 value. Ownership is not
* transferred. The result pointer is valid while the graph is alive.
*
* For API compatibility, this default implementation just checks that the
* data is a v8::Value and forward it to the variant that takes v8::Value,
* which is currently required to be implemented. In the future we'll remove
* the v8::Value variant, and make this variant that takes v8::Data abstract
* instead. If the embedder subclasses v8::EmbedderGraph and also use
* v8::TracedReference<v8::Data>, they must override this variant.
*/
virtual Node* V8Node(const v8::Local<v8::Data>& value);
/**
* Adds the given node to the graph and takes ownership of the node.
* Returns a raw pointer to the node that is valid while the graph is alive.
@ -956,7 +975,7 @@ class V8_EXPORT HeapProfiler {
/**
* Callback function invoked during heap snapshot generation to retrieve
* the detachedness state of an object referenced by a TracedReference.
* the detachedness state of a JS object referenced by a TracedReference.
*
* The callback takes Local<Value> as parameter to allow the embedder to
* unpack the TracedReference into a Local and reuse that Local for different

163
deps/v8/include/v8-sandbox.h vendored Normal file
View file

@ -0,0 +1,163 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_V8_SANDBOX_H_
#define INCLUDE_V8_SANDBOX_H_
#include <cstdint>
#include "v8-internal.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
namespace v8 {
/**
* A pointer tag used for wrapping and unwrapping `CppHeap` pointers as used
* with JS API wrapper objects that rely on `v8::Object::Wrap()` and
* `v8::Object::Unwrap()`.
*
* The CppHeapPointers use a range-based type checking scheme, where on access
* to a pointer, the actual type of the pointer is checked to be within a
* specified range of types. This allows supporting type hierarchies, where a
* type check for a supertype must succeed for any subtype.
*
* The tag is currently in practice limited to 15 bits since it needs to fit
* together with a marking bit into the unused parts of a pointer (the top 16
* bits).
*/
enum class CppHeapPointerTag : uint16_t {
kFirstTag = 0,
kNullTag = 0,
/**
* The lower type ids are reserved for the embedder to assign. For that, the
* main requirement is that all (transitive) child classes of a given parent
* class have type ids in the same range, and that there are no unrelated
* types in that range. For example, given the following type hierarchy:
*
* A F
* / \
* B E
* / \
* C D
*
* a potential type id assignment that satistifes these requirements is
* {C: 0, D: 1, B: 2, A: 3, E: 4, F: 5}. With that, the type check for type A
* would check for the range [0, 4], while the check for B would check range
* [0, 2], and for F it would simply check [5, 5].
*
* In addition, there is an option for performance tweaks: if the size of the
* type range corresponding to a supertype is a power of two and starts at a
* power of two (e.g. [0x100, 0x13f]), then the compiler can often optimize
* the type check to use even fewer instructions (essentially replace a AND +
* SUB with a single AND).
*/
kDefaultTag = 0x7000,
kZappedEntryTag = 0x7ffd,
kEvacuationEntryTag = 0x7ffe,
kFreeEntryTag = 0x7fff,
// The tags are limited to 15 bits, so the last tag is 0x7fff.
kLastTag = 0x7fff,
};
// Convenience struct to represent tag ranges. This is used for type checks
// against supertypes, which cover a range of types (their subtypes).
// Both the lower- and the upper bound are inclusive. In other words, this
// struct represents the range [lower_bound, upper_bound].
struct CppHeapPointerTagRange {
constexpr CppHeapPointerTagRange(CppHeapPointerTag lower,
CppHeapPointerTag upper)
: lower_bound(lower), upper_bound(upper) {}
CppHeapPointerTag lower_bound;
CppHeapPointerTag upper_bound;
// Check whether the tag of the given CppHeapPointerTable entry is within
// this range. This method encodes implementation details of the
// CppHeapPointerTable, which is necessary as it is used by
// ReadCppHeapPointerField below.
// Returns true if the check is successful and the tag of the given entry is
// within this range, false otherwise.
bool CheckTagOf(uint64_t entry) {
// Note: the cast to uint32_t is important here. Otherwise, the uint16_t's
// would be promoted to int in the range check below, which would result in
// undefined behavior (signed integer undeflow) if the actual value is less
// than the lower bound. Then, the compiler would take advantage of the
// undefined behavior and turn the range check into a simple
// `actual_tag <= last_tag` comparison, which is incorrect.
uint32_t actual_tag = static_cast<uint16_t>(entry);
// The actual_tag is shifted to the left by one and contains the marking
// bit in the LSB. To ignore that during the type check, simply add one to
// the (shifted) range.
constexpr int kTagShift = internal::kCppHeapPointerTagShift;
uint32_t first_tag = static_cast<uint32_t>(lower_bound) << kTagShift;
uint32_t last_tag = (static_cast<uint32_t>(upper_bound) << kTagShift) + 1;
return actual_tag >= first_tag && actual_tag <= last_tag;
}
};
constexpr CppHeapPointerTagRange kAnyCppHeapPointer(
CppHeapPointerTag::kFirstTag, CppHeapPointerTag::kLastTag);
namespace internal {
#ifdef V8_COMPRESS_POINTERS
V8_INLINE static Address* GetCppHeapPointerTableBase(v8::Isolate* isolate) {
Address addr = reinterpret_cast<Address>(isolate) +
Internals::kIsolateCppHeapPointerTableOffset +
Internals::kExternalPointerTableBasePointerOffset;
return *reinterpret_cast<Address**>(addr);
}
#endif // V8_COMPRESS_POINTERS
template <typename T>
V8_INLINE static T* ReadCppHeapPointerField(v8::Isolate* isolate,
Address heap_object_ptr, int offset,
CppHeapPointerTagRange tag_range) {
#ifdef V8_COMPRESS_POINTERS
// See src/sandbox/cppheap-pointer-table-inl.h. Logic duplicated here so
// it can be inlined and doesn't require an additional call.
const CppHeapPointerHandle handle =
Internals::ReadRawField<CppHeapPointerHandle>(heap_object_ptr, offset);
const uint32_t index = handle >> kExternalPointerIndexShift;
const Address* table = GetCppHeapPointerTableBase(isolate);
const std::atomic<Address>* ptr =
reinterpret_cast<const std::atomic<Address>*>(&table[index]);
Address entry = std::atomic_load_explicit(ptr, std::memory_order_relaxed);
Address pointer = entry;
if (V8_LIKELY(tag_range.CheckTagOf(entry))) {
pointer = entry >> kCppHeapPointerPayloadShift;
} else {
// If the type check failed, we simply return nullptr here. That way:
// 1. The null handle always results in nullptr being returned here, which
// is a desired property. Otherwise, we would need an explicit check for
// the null handle above, and therefore an additional branch. This
// works because the 0th entry of the table always contains nullptr
// tagged with the null tag (i.e. an all-zeros entry). As such,
// regardless of whether the type check succeeds, the result will
// always be nullptr.
// 2. The returned pointer is guaranteed to crash even on platforms with
// top byte ignore (TBI), such as Arm64. The alternative would be to
// simply return the original entry with the left-shifted payload.
// However, due to TBI, an access to that may not always result in a
// crash (specifically, if the second most significant byte happens to
// be zero). In addition, there shouldn't be a difference on Arm64
// between returning nullptr or the original entry, since it will
// simply compile to a `csel x0, x8, xzr, lo` instead of a
// `csel x0, x10, x8, lo` instruction.
pointer = 0;
}
return reinterpret_cast<T*>(pointer);
#else // !V8_COMPRESS_POINTERS
return reinterpret_cast<T*>(
Internals::ReadRawField<Address>(heap_object_ptr, offset));
#endif // !V8_COMPRESS_POINTERS
}
} // namespace internal
} // namespace v8
#endif // INCLUDE_V8_SANDBOX_H_

View file

@ -322,6 +322,14 @@ class V8_EXPORT Module : public Data {
static void CheckCast(Data* obj);
};
class V8_EXPORT CompileHintsCollector : public Data {
public:
/**
* Returns the positions of lazy functions which were compiled and executed.
*/
std::vector<int> GetCompileHints(Isolate* isolate) const;
};
/**
* A compiled JavaScript script, tied to a Context which was active when the
* script was compiled.
@ -359,7 +367,15 @@ class V8_EXPORT Script : public Data {
* If the script was compiled, returns the positions of lazy functions which
* were eventually compiled and executed.
*/
V8_DEPRECATE_SOON("Use GetCompileHintsCollector instead")
std::vector<int> GetProducedCompileHints() const;
/**
* Get a compile hints collector object which we can use later for retrieving
* compile hints (= positions of lazy functions which were compiled and
* executed).
*/
Local<CompileHintsCollector> GetCompileHintsCollector() const;
};
enum class ScriptType { kClassic, kModule };
@ -787,15 +803,6 @@ class V8_EXPORT ScriptCompiler {
* It is possible to specify multiple context extensions (obj in the above
* example).
*/
V8_DEPRECATED("Use CompileFunction")
static V8_WARN_UNUSED_RESULT MaybeLocal<Function> CompileFunctionInContext(
Local<Context> context, Source* source, size_t arguments_count,
Local<String> arguments[], size_t context_extension_count,
Local<Object> context_extensions[],
CompileOptions options = kNoCompileOptions,
NoCacheReason no_cache_reason = kNoCacheNoReason,
Local<ScriptOrModule>* script_or_module_out = nullptr);
static V8_WARN_UNUSED_RESULT MaybeLocal<Function> CompileFunction(
Local<Context> context, Source* source, size_t arguments_count = 0,
Local<String> arguments[] = nullptr, size_t context_extension_count = 0,

View file

@ -68,6 +68,22 @@ struct SerializeContextDataCallback {
void* data;
};
/**
* Similar to `SerializeInternalFieldsCallback`, but is used exclusively to
* serialize API wrappers. The pointers for API wrappers always point into the
* CppHeap.
*/
struct SerializeAPIWrapperCallback {
using CallbackFunction = StartupData (*)(Local<Object> holder,
void* cpp_heap_pointer, void* data);
explicit SerializeAPIWrapperCallback(CallbackFunction function = nullptr,
void* data = nullptr)
: callback(function), data(data) {}
CallbackFunction callback;
void* data;
};
/**
* Callback and supporting data used to implement embedder logic to deserialize
* internal fields of v8::Objects.
@ -97,6 +113,17 @@ struct DeserializeContextDataCallback {
void* data;
};
struct DeserializeAPIWrapperCallback {
using CallbackFunction = void (*)(Local<Object> holder, StartupData payload,
void* data);
explicit DeserializeAPIWrapperCallback(CallbackFunction function = nullptr,
void* data = nullptr)
: callback(function), data(data) {}
CallbackFunction callback;
void* data;
};
/**
* Helper class to create a snapshot data blob.
*
@ -187,13 +214,17 @@ class V8_EXPORT SnapshotCreator {
* context embedder data set by
* v8::Context::SetAlignedPointerInEmbedderData().
*
* \param api_wrapper_serializer An optional callback used to serialize API
* wrapper references set via `v8::Object::Wrap()`.
*/
void SetDefaultContext(
Local<Context> context,
SerializeInternalFieldsCallback internal_fields_serializer =
SerializeInternalFieldsCallback(),
SerializeContextDataCallback context_data_serializer =
SerializeContextDataCallback());
SerializeContextDataCallback(),
SerializeAPIWrapperCallback api_wrapper_serializer =
SerializeAPIWrapperCallback());
/**
* Add additional context to be included in the snapshot blob.
@ -204,12 +235,17 @@ class V8_EXPORT SnapshotCreator {
*
* \param context_data_serializer Similar to context_data_serializer
* in SetDefaultContext() but only applies to the context being added.
*
* \param api_wrapper_serializer Similar to api_wrapper_serializer
* in SetDefaultContext() but only applies to the context being added.
*/
size_t AddContext(Local<Context> context,
SerializeInternalFieldsCallback internal_fields_serializer =
SerializeInternalFieldsCallback(),
SerializeContextDataCallback context_data_serializer =
SerializeContextDataCallback());
SerializeContextDataCallback(),
SerializeAPIWrapperCallback api_wrapper_serializer =
SerializeAPIWrapperCallback());
/**
* Attach arbitrary V8::Data to the context snapshot, which can be retrieved

View file

@ -60,17 +60,13 @@ class V8_EXPORT Template : public Data {
V8_INLINE void Set(Isolate* isolate, const char* name, Local<Data> value,
PropertyAttribute attributes = None);
void SetAccessorProperty(
Local<Name> name,
Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
PropertyAttribute attribute = None);
/**
* Sets an "accessor property" on the object template, see
* https://tc39.es/ecma262/#sec-object-type.
*
* Whenever the property with the given name is accessed on objects
* created from this Template the getter and setter callbacks
* are called instead of getting and setting the property directly
* on the JavaScript object.
* created from this ObjectTemplate the getter and setter functions
* are called.
*
* \param name The name of the property for which an accessor is added.
* \param getter The callback to invoke when getting the property.
@ -80,27 +76,32 @@ class V8_EXPORT Template : public Data {
* \param attribute The attributes of the property for which an accessor
* is added.
*/
V8_DEPRECATE_SOON("Use SetNativeDataProperty without AccessControl instead")
void SetNativeDataProperty(
Local<String> name, AccessorGetterCallback getter,
AccessorSetterCallback setter, Local<Value> data,
PropertyAttribute attribute, AccessControl settings,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
V8_DEPRECATE_SOON("Use SetNativeDataProperty without AccessControl instead")
void SetNativeDataProperty(
Local<Name> name, AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter, Local<Value> data,
PropertyAttribute attribute, AccessControl settings,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
V8_DEPRECATE_SOON("Use SetNativeDataProperty with Local<Name> instead")
void SetNativeDataProperty(
Local<String> name, AccessorGetterCallback getter,
AccessorSetterCallback setter = nullptr,
Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
void SetAccessorProperty(
Local<Name> name,
Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
PropertyAttribute attribute = None);
/**
* Sets a "data property" on the object template, see
* https://tc39.es/ecma262/#sec-object-type.
*
* Whenever the property with the given name is accessed on objects
* created from this Template the getter and setter callbacks
* are called instead of getting and setting the property directly
* on the JavaScript object.
* Note that in case a property is written via a "child" object, the setter
* will not be called according to the JavaScript specification. See
* https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver.
*
* \param name The name of the data property for which an accessor is added.
* \param getter The callback to invoke when getting the property.
* \param setter The callback to invoke when setting the property.
* \param data A piece of data that will be passed to the getter and setter
* callbacks whenever they are invoked.
* \param attribute The attributes of the property for which an accessor
* is added.
*/
void SetNativeDataProperty(
Local<Name> name, AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter = nullptr,
@ -142,7 +143,8 @@ enum class Intercepted : uint8_t { kNo = 0, kYes = 1 };
* Interceptor for get requests on an object.
*
* If the interceptor handles the request (i.e. the property should not be
* looked up beyond the interceptor) it should
* looked up beyond the interceptor or in case an exception was thrown) it
* should
* - (optionally) use info.GetReturnValue().Set()` to set the return value
* (by default the result is set to v8::Undefined),
* - return `Intercepted::kYes`.
@ -194,7 +196,8 @@ using GenericNamedPropertyGetterCallback =
* Interceptor for set requests on an object.
*
* If the interceptor handles the request (i.e. the property should not be
* looked up beyond the interceptor) it should return `Intercepted::kYes`.
* looked up beyond the interceptor or in case an exception was thrown) it
* should return `Intercepted::kYes`.
* If the interceptor does not handle the request it must return
* `Intercepted::kNo` and it must not produce side effects.
*
@ -229,9 +232,10 @@ using GenericNamedPropertySetterCallback =
* defineProperty().
*
* If the interceptor handles the request (i.e. the property should not be
* looked up beyond the interceptor) it should
* - use `info.GetReturnValue().Set()` to set to an Integer value encoding
* a `v8::PropertyAttribute` bits,
* looked up beyond the interceptor or in case an exception was thrown) it
* should
* - (optionally) use `info.GetReturnValue().Set()` to set to an Integer
* value encoding a `v8::PropertyAttribute` bits,
* - return `Intercepted::kYes`.
* If the interceptor does not handle the request it must return
* `Intercepted::kNo` and it must not produce side effects.
@ -263,9 +267,10 @@ using GenericNamedPropertyQueryCallback =
* Interceptor for delete requests on an object.
*
* If the interceptor handles the request (i.e. the property should not be
* looked up beyond the interceptor) it should
* - use `info.GetReturnValue().Set()` to set to a Boolean value indicating
* whether the property deletion was successful or not,
* looked up beyond the interceptor or in case an exception was thrown) it
* should
* - (optionally) use `info.GetReturnValue().Set()` to set to a Boolean value
* indicating whether the property deletion was successful or not,
* - return `Intercepted::kYes`.
* If the interceptor does not handle the request it must return
* `Intercepted::kNo` and it must not produce side effects.
@ -311,7 +316,8 @@ using GenericNamedPropertyEnumeratorCallback = NamedPropertyEnumeratorCallback;
* Interceptor for defineProperty requests on an object.
*
* If the interceptor handles the request (i.e. the property should not be
* looked up beyond the interceptor) it should return `Intercepted::kYes`.
* looked up beyond the interceptor or in case an exception was thrown) it
* should return `Intercepted::kYes`.
* If the interceptor does not handle the request it must return
* `Intercepted::kNo` and it must not produce side effects.
*
@ -344,10 +350,11 @@ using GenericNamedPropertyDefinerCallback =
* Interceptor for getOwnPropertyDescriptor requests on an object.
*
* If the interceptor handles the request (i.e. the property should not be
* looked up beyond the interceptor) it should
* - use `info.GetReturnValue().Set()` to set the return value which must be
* object that can be converted to a PropertyDescriptor (for example,
* a value returned by `v8::Object::getOwnPropertyDescriptor`),
* looked up beyond the interceptor or in case an exception was thrown) it
* should
* - (optionally) use `info.GetReturnValue().Set()` to set the return value
* which must be object that can be converted to a PropertyDescriptor (for
* example, a value returned by `v8::Object::getOwnPropertyDescriptor`),
* - return `Intercepted::kYes`.
* If the interceptor does not handle the request it must return
* `Intercepted::kNo` and it must not produce side effects.
@ -379,7 +386,7 @@ using GenericNamedPropertyDescriptorCallback =
// removed.
/**
* See `v8::GenericNamedPropertyGetterCallback`.
* See `v8::NamedPropertyGetterCallback`.
*/
using IndexedPropertyGetterCallbackV2 =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Value>& info);
@ -388,7 +395,7 @@ using IndexedPropertyGetterCallback =
void (*)(uint32_t index, const PropertyCallbackInfo<Value>& info);
/**
* See `v8::GenericNamedPropertySetterCallback`.
* See `v8::NamedPropertySetterCallback`.
*/
using IndexedPropertySetterCallbackV2 = Intercepted (*)(
uint32_t index, Local<Value> value, const PropertyCallbackInfo<void>& info);
@ -398,7 +405,7 @@ using IndexedPropertySetterCallback =
const PropertyCallbackInfo<Value>& info);
/**
* See `v8::GenericNamedPropertyQueryCallback`.
* See `v8::NamedPropertyQueryCallback`.
*/
using IndexedPropertyQueryCallbackV2 =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Integer>& info);
@ -407,7 +414,7 @@ using IndexedPropertyQueryCallback =
void (*)(uint32_t index, const PropertyCallbackInfo<Integer>& info);
/**
* See `v8::GenericNamedPropertyDeleterCallback`.
* See `v8::NamedPropertyDeleterCallback`.
*/
using IndexedPropertyDeleterCallbackV2 =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Boolean>& info);
@ -425,7 +432,7 @@ using IndexedPropertyEnumeratorCallback =
void (*)(const PropertyCallbackInfo<Array>& info);
/**
* See `v8::GenericNamedPropertyDefinerCallback`.
* See `v8::NamedPropertyDefinerCallback`.
*/
using IndexedPropertyDefinerCallbackV2 =
Intercepted (*)(uint32_t index, const PropertyDescriptor& desc,
@ -436,7 +443,7 @@ using IndexedPropertyDefinerCallback =
const PropertyCallbackInfo<Value>& info);
/**
* See `v8::GenericNamedPropertyDescriptorCallback`.
* See `v8::NamedPropertyDescriptorCallback`.
*/
using IndexedPropertyDescriptorCallbackV2 =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Value>& info);
@ -489,8 +496,8 @@ enum class ConstructorBehavior { kThrow, kAllow };
* proto_t->Set(isolate, "proto_const", v8::Number::New(isolate, 2));
*
* v8::Local<v8::ObjectTemplate> instance_t = t->InstanceTemplate();
* instance_t->SetAccessor(
String::NewFromUtf8Literal(isolate, "instance_accessor"),
* instance_t->SetNativeDataProperty(
* String::NewFromUtf8Literal(isolate, "instance_accessor"),
* InstanceAccessorCallback);
* instance_t->SetHandler(
* NamedPropertyHandlerConfiguration(PropertyHandlerCallback));
@ -762,7 +769,9 @@ struct NamedPropertyHandlerConfiguration {
data(data),
flags(WithNewSignatureFlag(flags)) {}
// This variant will be deprecated soon.
V8_DEPRECATED(
"Provide interceptor callbacks with new signatures instead "
"(NamedPropertyXxxCallback)")
NamedPropertyHandlerConfiguration(
GenericNamedPropertyGetterCallback getter,
GenericNamedPropertySetterCallback setter,
@ -801,7 +810,9 @@ struct NamedPropertyHandlerConfiguration {
data(data),
flags(WithNewSignatureFlag(flags)) {}
// This variant will be deprecated soon.
V8_DEPRECATED(
"Provide interceptor callbacks with new signatures instead "
"(NamedPropertyXxxCallback)")
explicit NamedPropertyHandlerConfiguration(
GenericNamedPropertyGetterCallback getter,
GenericNamedPropertySetterCallback setter = nullptr,
@ -839,7 +850,9 @@ struct NamedPropertyHandlerConfiguration {
data(data),
flags(WithNewSignatureFlag(flags)) {}
// This variant will be deprecated soon.
V8_DEPRECATED(
"Provide interceptor callbacks with new signatures instead "
"(NamedPropertyXxxCallback)")
NamedPropertyHandlerConfiguration(
GenericNamedPropertyGetterCallback getter,
GenericNamedPropertySetterCallback setter,
@ -901,7 +914,9 @@ struct IndexedPropertyHandlerConfiguration {
data(data),
flags(WithNewSignatureFlag(flags)) {}
// This variant will be deprecated soon.
V8_DEPRECATED(
"Provide interceptor callbacks with new signatures instead "
"(IndexedPropertyXxxCallbackV2)")
IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter, //
IndexedPropertySetterCallback setter, //
@ -940,7 +955,9 @@ struct IndexedPropertyHandlerConfiguration {
data(data),
flags(WithNewSignatureFlag(flags)) {}
// This variant will be deprecated soon.
V8_DEPRECATED(
"Provide interceptor callbacks with new signatures instead "
"(IndexedPropertyXxxCallbackV2)")
explicit IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter,
IndexedPropertySetterCallback setter = nullptr,
@ -978,7 +995,9 @@ struct IndexedPropertyHandlerConfiguration {
data(data),
flags(WithNewSignatureFlag(flags)) {}
// This variant will be deprecated soon.
V8_DEPRECATED(
"Provide interceptor callbacks with new signatures instead "
"(IndexedPropertyXxxCallbackV2)")
IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter,
IndexedPropertySetterCallback setter,
@ -1045,13 +1064,10 @@ class V8_EXPORT ObjectTemplate : public Template {
* \param attribute The attributes of the property for which an accessor
* is added.
*/
V8_DEPRECATE_SOON("Use SetAccessor with Local<Name> instead")
void SetAccessor(
Local<String> name, AccessorGetterCallback getter,
AccessorSetterCallback setter = nullptr,
Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
V8_DEPRECATED(
"Use SetNativeDataProperty or SetAccessorProperty instead depending on "
"the required semantics. See http://crbug.com/336325111. This method "
"will be removed in V8 12.8.")
void SetAccessor(
Local<Name> name, AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter = nullptr,
@ -1072,34 +1088,6 @@ class V8_EXPORT ObjectTemplate : public Template {
*/
void SetHandler(const NamedPropertyHandlerConfiguration& configuration);
/**
* Sets an indexed property handler on the object template.
*
* Whenever an indexed property is accessed on objects created from
* this object template, the provided callback is invoked instead of
* accessing the property directly on the JavaScript object.
*
* \param getter The callback to invoke when getting a property.
* \param setter The callback to invoke when setting a property.
* \param query The callback to invoke to check if an object has a property.
* \param deleter The callback to invoke when deleting a property.
* \param enumerator The callback to invoke to enumerate all the indexed
* properties of an object.
* \param data A piece of data that will be passed to the callbacks
* whenever they are invoked.
*/
V8_DEPRECATE_SOON("Use SetHandler instead")
void SetIndexedPropertyHandler(
IndexedPropertyGetterCallback getter,
IndexedPropertySetterCallback setter = nullptr,
IndexedPropertyQueryCallback query = nullptr,
IndexedPropertyDeleterCallback deleter = nullptr,
IndexedPropertyEnumeratorCallback enumerator = nullptr,
Local<Value> data = Local<Value>()) {
SetHandler(IndexedPropertyHandlerConfiguration(getter, setter, query,
deleter, enumerator, data));
}
/**
* Sets an indexed property handler on the object template.
*

View file

@ -62,11 +62,11 @@ class TracedReferenceBase : public api_internal::IndirectHandleBase {
V8_INLINE void Reset();
/**
* Construct a Local<Value> from this handle.
* Construct a Local<Data> from this handle.
*/
V8_INLINE Local<Value> Get(Isolate* isolate) const {
if (IsEmpty()) return Local<Value>();
return Local<Value>::New(isolate, this->value<Value>());
V8_INLINE Local<Data> Get(Isolate* isolate) const {
if (IsEmpty()) return Local<Data>();
return Local<Data>::New(isolate, this->value<Data>());
}
/**
@ -135,17 +135,6 @@ class BasicTracedReference : public TracedReferenceBase {
const_cast<BasicTracedReference<T>&>(*this));
}
V8_DEPRECATE_SOON("Use Get to convert to Local instead")
V8_INLINE T* operator->() const {
#ifdef V8_ENABLE_CHECKS
CheckValue();
#endif // V8_ENABLE_CHECKS
return this->template value<T>();
}
V8_DEPRECATE_SOON("Use Get to convert to Local instead")
V8_INLINE T* operator*() const { return this->operator->(); }
private:
/**
* An empty BasicTracedReference without storage cell.

View file

@ -42,7 +42,8 @@ enum StateTag : uint16_t {
OTHER,
EXTERNAL,
ATOMICS_WAIT,
IDLE
IDLE,
LOGGING,
};
// The output structure filled up by GetStackSample API function.

View file

@ -544,122 +544,6 @@ class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
: GlobalValueMap<K, V, Traits>(isolate) {}
};
class DefaultPersistentValueVectorTraits {
public:
typedef std::vector<PersistentContainerValue> Impl;
static void Append(Impl* impl, PersistentContainerValue value) {
impl->push_back(value);
}
static bool IsEmpty(const Impl* impl) {
return impl->empty();
}
static size_t Size(const Impl* impl) {
return impl->size();
}
static PersistentContainerValue Get(const Impl* impl, size_t i) {
return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
}
static void ReserveCapacity(Impl* impl, size_t capacity) {
impl->reserve(capacity);
}
static void Clear(Impl* impl) {
impl->clear();
}
};
/**
* A vector wrapper that safely stores Global values.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* This class relies on a backing vector implementation, whose type and methods
* are described by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template <typename V, typename Traits = DefaultPersistentValueVectorTraits>
class V8_DEPRECATE_SOON("Use std::vector<Global<V>>.") PersistentValueVector {
public:
explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
~PersistentValueVector() {
Clear();
}
/**
* Append a value to the vector.
*/
void Append(Local<V> value) {
Global<V> persistent(isolate_, value);
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Append a persistent's value to the vector.
*/
void Append(Global<V> persistent) {
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Are there any values in the vector?
*/
bool IsEmpty() const {
return Traits::IsEmpty(&impl_);
}
/**
* How many elements are in the vector?
*/
size_t Size() const {
return Traits::Size(&impl_);
}
/**
* Retrieve the i-th value in the vector.
*/
Local<V> Get(size_t index) const {
return Local<V>::New(isolate_, internal::ValueHelper::SlotAsValue<V>(
Traits::Get(&impl_, index)));
}
/**
* Remove all elements from the vector.
*/
void Clear() {
size_t length = Traits::Size(&impl_);
for (size_t i = 0; i < length; i++) {
Global<V> p;
p.slot() = reinterpret_cast<internal::Address>(Traits::Get(&impl_, i));
}
Traits::Clear(&impl_);
}
/**
* Reserve capacity in the vector.
* (Efficiency gains depend on the backing implementation.)
*/
void ReserveCapacity(size_t capacity) {
Traits::ReserveCapacity(&impl_, capacity);
}
private:
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
auto slot = persistent->slot();
persistent->Clear();
return reinterpret_cast<PersistentContainerValue>(slot);
}
static V* FromVal(PersistentContainerValue v) {
return internal::ValueHelper::SlotAsValue<V>(
reinterpret_cast<internal::Address*>(v));
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
} // namespace v8
#endif // V8_UTIL_H

View file

@ -9,9 +9,9 @@
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define V8_MAJOR_VERSION 12
#define V8_MINOR_VERSION 4
#define V8_BUILD_NUMBER 254
#define V8_PATCH_LEVEL 21
#define V8_MINOR_VERSION 7
#define V8_BUILD_NUMBER 224
#define V8_PATCH_LEVEL 16
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)

View file

@ -9,6 +9,7 @@
#include <memory>
#include <string>
#include "v8-internal.h" // NOLINT(build/include_directory)
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-memory-span.h" // NOLINT(build/include_directory)
#include "v8-object.h" // NOLINT(build/include_directory)
@ -129,6 +130,8 @@ class V8_EXPORT WasmModuleObject : public Object {
*/
class V8_EXPORT WasmStreaming final {
public:
static constexpr internal::ExternalPointerTag kManagedTag =
internal::kWasmWasmStreamingTag;
class WasmStreamingImpl;
explicit WasmStreaming(std::unique_ptr<WasmStreamingImpl> impl);

View file

@ -5,8 +5,16 @@
#ifndef V8CONFIG_H_
#define V8CONFIG_H_
// gcc 10 defines __cplusplus to "an unspecified value strictly larger than
// 201703L" for its experimental -std=gnu++2a config.
// TODO(leszeks): Change to `__cplusplus <= 202002L` once we only support
// compilers with full C++20 support.
#if __cplusplus <= 201703L
#error "C++20 or later required."
#endif
#ifdef V8_GN_HEADER
#if __cplusplus >= 201703L && !__has_include("v8-gn.h")
#if !__has_include("v8-gn.h")
#error Missing v8-gn.h. The configuration for v8 is missing from the include \
path. Add it with -I<path> to the command line
#endif
@ -477,22 +485,32 @@ path. Add it with -I<path> to the command line
# define V8_INLINE inline
#endif
#if V8_HAS_BUILTIN_ASSUME
#ifdef DEBUG
// In debug mode, check assumptions instead of actually adding annotations.
# define V8_ASSUME DCHECK
#elif V8_HAS_BUILTIN_ASSUME
// In debug mode, check assumptions in addition to adding annotations.
// This helps GCC (and maybe other compilers) figure out that certain
// situations are unreachable.
# define V8_ASSUME(condition) \
do { \
DCHECK(condition); \
__builtin_assume(condition); \
} while (false)
#else // DEBUG
# define V8_ASSUME __builtin_assume
#endif // DEBUG
#elif V8_HAS_BUILTIN_UNREACHABLE
# define V8_ASSUME(condition) \
do { \
DCHECK(condition); \
if (!(condition)) __builtin_unreachable(); \
} while (false)
#else
# define V8_ASSUME USE
#endif
// Prefer c++20 std::assume_aligned
#if __cplusplus >= 202002L && defined(__cpp_lib_assume_aligned)
// Prefer c++20 std::assume_aligned. Don't use it on MSVC though, because it's
// not happy with our large 4GB alignment values.
#if __cplusplus >= 202002L && defined(__cpp_lib_assume_aligned) && !V8_CC_MSVC
# define V8_ASSUME_ALIGNED(ptr, alignment) \
std::assume_aligned<(alignment)>(ptr)
#elif V8_HAS_BUILTIN_ASSUME_ALIGNED

23
deps/v8/infra/builder_properties.pyl vendored Normal file
View file

@ -0,0 +1,23 @@
# Copyright 2024 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Override builder properties in V8's CI. This can be useful if a configuration
# change is suspected to cause a regression, and should be aligned with a
# specific V8 commit.
# A typical scenario is a performance bot change. The perf bot itself is defined
# on the recipe side and applied independent of the V8 revision. A regression
# might falsely suspect the first revision using the new bot. Using this file,
# the bot can be migrated in a three step approach:
# 1. Add {'buildername': {'swarming_bot_ids': ['new-bot']}} to this file.
# It might take a while till all relevant CI bots have processed this revision.
# Cherry-picks for branches might also be needed.
# 2. Add the new bot to the recipe itself.
# 3. Remove the override in this file again to ensure there is a single
# configuration only.
{}

View file

@ -66,7 +66,6 @@
'V8 Linux - verify csa - builder': 'release_x86_verify_csa',
# Linux64.
'V8 Linux64 - builder': 'release_x64_gcmole',
'V8 Linux64 - builder (goma cache silo)': 'release_x64',
'V8 Linux64 - builder (reclient)': 'release_x64_reclient',
'V8 Linux64 - builder (reclient compare)': 'release_x64_reclient',
'V8 Linux64 - official - builder': 'official_x64_on_release_branch',
@ -82,8 +81,8 @@
'V8 Linux64 - verify csa - builder': 'release_x64_verify_csa',
'V8 Linux64 - no wasm - builder': 'release_x64_webassembly_disabled',
# Windows.
'V8 Win - arm64 - debug builder': 'debug_arm64',
'V8 Win32 - builder': 'release_x86_minimal_symbols',
'V8 Win32 - builder (goma cache silo)': 'release_x86',
'V8 Win32 - builder (reclient)': 'release_x86_minimal_symbols_reclient',
'V8 Win32 - builder (reclient compare)': 'release_x86_minimal_symbols_reclient',
'V8 Win32 - debug builder': 'debug_x86_minimal_symbols',
@ -95,6 +94,7 @@
'V8 Win64 - builder (reclient compare)': 'release_x64_minimal_symbols_reclient',
'V8 Win64 - dev image': 'release_x64_minimal_symbols',
'V8 Win64 - debug builder': 'debug_x64_minimal_symbols',
'V8 Win64 - drumbrake - debug builder': 'debug_x64_drumbrake',
'V8 Win64 - msvc - builder': 'release_x64_msvc',
# Mac.
'V8 Mac64 - builder': 'release_x64',
@ -128,6 +128,7 @@
'V8 Linux64 - disable runtime call stats - builder': 'release_x64_disable_runtime_call_stats',
'V8 Linux64 - debug - single generation - builder': 'debug_x64_single_generation',
'V8 Linux64 - no pointer compression - builder': 'release_x64_no_pointer_compression',
'V8 Linux64 - sticky mark bits - debug builder': 'debug_x64_sticky_mark_bits',
'V8 Linux64 css - debug builder': 'debug_x64_conservative_stack_scanning',
'V8 Linux64 gcc - builder': 'release_x64_gcc',
'V8 Linux64 gcc - debug builder': 'debug_x64_gcc',
@ -306,6 +307,7 @@
'v8_linux_riscv32_compile_rel': 'release_simulate_riscv32',
'v8_linux64_riscv64_compile_rel': 'release_simulate_riscv64',
'v8_linux64_riscv64_pointer_compression_compile_rel': 'release_simulate_riscv64_pointer_compression',
'v8_linux64_sticky_mark_bits_compile_dbg': 'debug_x64_sticky_mark_bits',
'v8_linux64_tsan_compile_rel': 'release_x64_tsan_minimal_symbols',
'v8_linux64_tsan_compile_dbg': 'debug_x64_tsan_minimal_symbols',
'v8_linux64_tsan_no_cm_compile_rel': 'release_x64_tsan_no_cm',
@ -314,8 +316,8 @@
'v8_linux64_ubsan_compile_rel': 'release_x64_ubsan_minimal_symbols',
'v8_linux64_verify_builtins_rel': 'release_x64_verify_builtins',
'v8_linux64_verify_deterministic_rel': 'release_x64_verify_deterministic',
'v8_odroid_arm_compile_rel': 'release_arm',
'v8_linux_torque_compare': 'torque_compare',
'v8_win_arm64_compile_dbg': 'debug_arm64',
# TODO(machenbach): Remove after switching to x64 on infra side.
'v8_win_compile_dbg': 'debug_x86_trybot',
'v8_win_compile_rel': 'release_x86_trybot',
@ -323,6 +325,7 @@
'v8_win64_asan_compile_rel': 'release_x64_asan_no_lsan',
'v8_win64_msvc_light_compile_rel': 'release_x64_msvc',
'v8_win64_compile_dbg': 'debug_x64_minimal_symbols',
'v8_win64_drumbrake_compile_dbg': 'debug_x64_drumbrake',
'v8_win64_msvc_compile_rel': 'release_x64_msvc',
'v8_win64_compile_rel': 'release_x64_trybot',
'v8_mac_arm64_compile_rel': 'release_arm64',
@ -673,6 +676,8 @@
'debug_bot', 'x64', 'clang_coverage'],
'debug_x64_custom': [
'debug_bot', 'x64', 'v8_snapshot_custom'],
'debug_x64_drumbrake': [
'debug_bot', 'x64', 'v8_enable_drumbrake'],
'debug_x64_external_code_space': [
'debug_bot', 'x64', 'external_code_space'],
'debug_x64_fuchsia': [
@ -693,6 +698,8 @@
'debug_bot', 'x64', 'no_sandbox'],
'debug_x64_single_generation': [
'debug_bot', 'x64', 'v8_enable_single_generation'],
'debug_x64_sticky_mark_bits': [
'debug_bot', 'x64', 'v8_enable_sticky_mark_bits'],
'debug_x64_trybot': [
'debug_trybot', 'x64'],
'debug_x64_dict_tracking_trybot': [
@ -724,8 +731,6 @@
'debug', 'x86', 'reclient', 'v8_enable_slow_dchecks', 'v8_full_debug'],
# Release configs for x86.
'release_x86': [
'release_bot', 'x86'],
'release_x86_asan_symbolized_verify_heap': [
'release_bot', 'x86', 'asan', 'lsan', 'symbolized',
'v8_verify_heap'],
@ -889,7 +894,7 @@
},
'ios_simulator': {
'gn_args': 'target_cpu="x64" target_os="ios"',
'gn_args': 'target_cpu="x64" target_os="ios" use_blink=true',
},
'lld': {
@ -907,12 +912,12 @@
'msan': {
'mixins': ['v8_enable_test_features'],
'gn_args': 'is_msan=true msan_track_origins=2 instrumented_libraries_release="focal"',
'gn_args': 'is_msan=true msan_track_origins=2 instrumented_libraries_release="noble"',
},
'msan_no_origins': {
'mixins': ['v8_enable_test_features'],
'gn_args': 'is_msan=true msan_track_origins=0 instrumented_libraries_release="focal"',
'gn_args': 'is_msan=true msan_track_origins=0 instrumented_libraries_release="noble"',
},
'msvc': {
@ -1056,6 +1061,10 @@
'gn_args': 'v8_enable_verify_heap=false',
},
'v8_enable_drumbrake': {
'gn_args': 'v8_enable_drumbrake=true',
},
'v8_enable_memory_corruption_api': {
'gn_args': 'v8_enable_memory_corruption_api=true',
},
@ -1101,6 +1110,9 @@
'gn_args': 'v8_enable_single_generation=true '
'v8_disable_write_barriers=true',
},
'v8_enable_sticky_mark_bits': {
'gn_args': 'v8_enable_sticky_mark_bits=true',
},
'v8_enable_test_features': {
'gn_args': 'v8_enable_test_features=true',
},

View file

@ -649,6 +649,15 @@
{'name': 'v8testing', 'variant': 'default'},
],
},
'v8_linux64_sandbox_testing_rel': {
'swarming_dimensions' : {
'cpu': 'x86-64',
'os': 'Ubuntu-22.04',
},
'tests': [
{'name': 'mjsunit', 'variant': 'default'},
],
},
'v8_linux64_single_generation_dbg': {
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
@ -657,6 +666,15 @@
{'name': 'v8testing', 'shards': 3},
],
},
'v8_linux64_sticky_mark_bits_dbg': {
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
'cpu': 'x86-64',
},
'tests': [
{'name': 'v8testing', 'shards': 3},
],
},
'v8_linux64_rel': {
'swarming_dimensions' : {
'cpu': 'x86-64-avx2',
@ -733,6 +751,7 @@
{'name': 'v8testing', 'variant': 'extra', 'shards': 6},
{'name': 'v8testing', 'variant': 'slow_path', 'shards': 2},
{'name': 'v8testing', 'variant': 'stress_concurrent_allocation', 'shards': 2},
{'name': 'v8testing', 'variant': 'minor_ms', 'shards': 2},
],
},
'v8_linux64_tsan_dbg': {
@ -870,24 +889,6 @@
],
},
##############################################################################
# Odroids with native arm
'v8_odroid_arm_rel': {
'swarming_dimensions' : {
'cores': '8',
'cpu': 'armv7l-32-Hardkernel_ODROID-XU4',
'os': 'Ubuntu',
},
'swarming_task_attrs': {
# Use same prio as CI due to limited resources.
'priority': 25,
},
'tests': [
{'name': 'benchmarks'},
{'name': 'optimize_for_size'},
{'name': 'v8testing', 'shards': 2},
],
},
##############################################################################
# Win32
'v8_win_dbg': {
'swarming_dimensions' : {
@ -928,11 +929,21 @@
'tests': [
{'name': 'mozilla'},
{'name': 'test262', 'variant': 'default', 'shards': 4},
{'name': 'v8testing', 'shards': 3},
{'name': 'v8testing', 'variant': 'extra', 'shards': 2},
{'name': 'v8testing', 'shards': 4},
{'name': 'v8testing', 'variant': 'extra', 'shards': 3},
{'name': 'v8testing', 'variant': 'minor_ms'},
],
},
'v8_win64_drumbrake_dbg': {
'swarming_dimensions': {
'cpu': 'x86-64',
'os': 'Windows-10-19045',
},
'tests': [
{'name': 'v8testing', 'shards': 4},
{'name': 'v8testing', 'variant': 'extra', 'shards': 3},
],
},
'v8_win64_msvc_rel': {
'swarming_dimensions' : {
'cpu': 'x86-64',
@ -1698,6 +1709,15 @@
{'name': 'v8testing', 'shards': 2},
],
},
'V8 Linux64 - sandbox testing': {
'swarming_dimensions' : {
'cpu': 'x86-64',
'os': 'Ubuntu-22.04',
},
'tests': [
{'name': 'mjsunit', 'variant': 'default'},
],
},
'V8 Linux64 - shared': {
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
@ -1708,6 +1728,15 @@
{'name': 'v8testing'},
],
},
'V8 Linux64 - sticky mark bits - debug': {
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
'cpu': 'x86-64',
},
'tests': [
{'name': 'v8testing', 'shards': 3},
],
},
'V8 Linux64 - verify csa': {
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
@ -1770,6 +1799,7 @@
{'name': 'v8testing', 'variant': 'extra', 'shards': 5},
{'name': 'v8testing', 'variant': 'slow_path', 'shards': 2},
{'name': 'v8testing', 'variant': 'stress_concurrent_allocation', 'shards': 2},
{'name': 'v8testing', 'variant': 'minor_ms', 'shards': 2},
],
},
'V8 Linux64 TSAN - debug': {
@ -2005,6 +2035,21 @@
{'name': 'v8testing', 'variant': 'minor_ms'},
],
},
'V8 Win64 - drumbrake - debug': {
'swarming_dimensions': {
'cpu': 'x86-64',
'os': 'Windows-10-19045',
},
'swarming_task_attrs': {
'expiration': 14400,
'hard_timeout': 7200,
'priority': 35,
},
'tests': [
{'name': 'v8testing', 'shards': 4},
{'name': 'v8testing', 'variant': 'extra', 'shards': 3},
],
},
'V8 Win64 - msvc': {
'swarming_dimensions': {
'os': 'Windows-10-19045',
@ -2045,83 +2090,6 @@
{'name': 'v8testing', 'variant': 'default', 'shards': 4},
],
},
'V8 Arm': {
'swarming_dimensions': {
'cores': '8',
'cpu': 'armv7l-32-Hardkernel_ODROID-XU4',
'os': 'Ubuntu',
},
'swarming_task_attrs': {
'expiration': 21600,
'hard_timeout': 5400,
},
'tests': [
# Odroid.
{
'name': 'benchmarks',
'suffix': 'ODROID',
# Less parallelism to prevent OOMs in benchmarks.
'test_args': ['-j2'],
},
{
'name': 'optimize_for_size',
'suffix': 'ODROID',
},
{
'name': 'v8testing',
'suffix': 'ODROID',
'shards': 2,
},
],
},
'V8 Arm - debug': {
'swarming_dimensions': {
'cores': '8',
'cpu': 'armv7l-32-Hardkernel_ODROID-XU4',
'os': 'Ubuntu',
},
'swarming_task_attrs': {
'expiration': 21600,
'hard_timeout': 3600,
},
'tests': [
# Odroid.
{
'name': 'optimize_for_size',
'suffix': 'ODROID',
'variant': 'default',
'test_args': ['--extra-flags=--verify-heap-skip-remembered-set'],
'shards': 2,
},
{
'name': 'v8testing',
'suffix': 'ODROID',
'variant': 'default',
'test_args': ['--extra-flags=--verify-heap-skip-remembered-set'],
'shards': 3,
},
],
},
'V8 Arm GC Stress': {
'swarming_dimensions': {
'cores': '8',
'cpu': 'armv7l-32-Hardkernel_ODROID-XU4',
'os': 'Ubuntu',
},
'swarming_task_attrs': {
'expiration': 21600,
'hard_timeout': 7200,
},
'tests': [
{
'name': 'd8testing',
'suffix': 'ODROID',
'variant': 'default',
'test_args': ['--gc-stress', '--extra-flags=--verify-heap-skip-remembered-set'],
'shards': 3,
},
],
},
'V8 Linux - arm - sim': {
'swarming_dimensions': {
'os': 'Ubuntu-22.04',

View file

@ -150,9 +150,10 @@ class JsHttpRequestProcessor : public HttpRequestProcessor {
const PropertyCallbackInfo<Value>& info);
// Callbacks that access maps
static void MapGet(Local<Name> name, const PropertyCallbackInfo<Value>& info);
static void MapSet(Local<Name> name, Local<Value> value,
const PropertyCallbackInfo<Value>& info);
static v8::Intercepted MapGet(Local<Name> name,
const PropertyCallbackInfo<Value>& info);
static v8::Intercepted MapSet(Local<Name> name, Local<Value> value,
const PropertyCallbackInfo<void>& info);
// Utility methods for wrapping C++ objects as JavaScript objects,
// and going back again.
@ -399,13 +400,12 @@ string ObjectToString(v8::Isolate* isolate, Local<Value> value) {
return string(*utf8_value);
}
void JsHttpRequestProcessor::MapGet(Local<Name> name,
const PropertyCallbackInfo<Value>& info) {
if (name->IsSymbol()) return;
v8::Intercepted JsHttpRequestProcessor::MapGet(
Local<Name> name, const PropertyCallbackInfo<Value>& info) {
if (name->IsSymbol()) return v8::Intercepted::kNo;
// Fetch the map wrapped by this object.
map<string, string>* obj = UnwrapMap(info.Holder());
map<string, string>* obj = UnwrapMap(info.HolderV2());
// Convert the JavaScript string to a std::string.
string key = ObjectToString(info.GetIsolate(), name.As<String>());
@ -414,7 +414,7 @@ void JsHttpRequestProcessor::MapGet(Local<Name> name,
map<string, string>::iterator iter = obj->find(key);
// If the key is not present return an empty handle as signal
if (iter == obj->end()) return;
if (iter == obj->end()) return v8::Intercepted::kNo;
// Otherwise fetch the value and wrap it in a JavaScript string
const string& value = (*iter).second;
@ -422,15 +422,16 @@ void JsHttpRequestProcessor::MapGet(Local<Name> name,
String::NewFromUtf8(info.GetIsolate(), value.c_str(),
NewStringType::kNormal,
static_cast<int>(value.length())).ToLocalChecked());
return v8::Intercepted::kYes;
}
void JsHttpRequestProcessor::MapSet(Local<Name> name, Local<Value> value_obj,
const PropertyCallbackInfo<Value>& info) {
if (name->IsSymbol()) return;
v8::Intercepted JsHttpRequestProcessor::MapSet(
Local<Name> name, Local<Value> value_obj,
const PropertyCallbackInfo<void>& info) {
if (name->IsSymbol()) return v8::Intercepted::kNo;
// Fetch the map wrapped by this object.
map<string, string>* obj = UnwrapMap(info.Holder());
map<string, string>* obj = UnwrapMap(info.HolderV2());
// Convert the key and value to std::strings.
string key = ObjectToString(info.GetIsolate(), name.As<String>());
@ -441,9 +442,9 @@ void JsHttpRequestProcessor::MapSet(Local<Name> name, Local<Value> value_obj,
// Return the value; any non-empty handle will work.
info.GetReturnValue().Set(value_obj);
return v8::Intercepted::kYes;
}
Local<ObjectTemplate> JsHttpRequestProcessor::MakeMapTemplate(
Isolate* isolate) {
EscapableHandleScope handle_scope(isolate);
@ -510,7 +511,7 @@ HttpRequest* JsHttpRequestProcessor::UnwrapRequest(Local<Object> obj) {
void JsHttpRequestProcessor::GetPath(Local<Name> name,
const PropertyCallbackInfo<Value>& info) {
// Extract the C++ request object from the JavaScript wrapper.
HttpRequest* request = UnwrapRequest(info.Holder());
HttpRequest* request = UnwrapRequest(info.HolderV2());
// Fetch the path.
const string& path = request->Path();
@ -524,7 +525,7 @@ void JsHttpRequestProcessor::GetPath(Local<Name> name,
void JsHttpRequestProcessor::GetReferrer(
Local<Name> name, const PropertyCallbackInfo<Value>& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
HttpRequest* request = UnwrapRequest(info.HolderV2());
const string& path = request->Referrer();
info.GetReturnValue().Set(
String::NewFromUtf8(info.GetIsolate(), path.c_str(),
@ -534,7 +535,7 @@ void JsHttpRequestProcessor::GetReferrer(
void JsHttpRequestProcessor::GetHost(Local<Name> name,
const PropertyCallbackInfo<Value>& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
HttpRequest* request = UnwrapRequest(info.HolderV2());
const string& path = request->Host();
info.GetReturnValue().Set(
String::NewFromUtf8(info.GetIsolate(), path.c_str(),
@ -544,7 +545,7 @@ void JsHttpRequestProcessor::GetHost(Local<Name> name,
void JsHttpRequestProcessor::GetUserAgent(
Local<Name> name, const PropertyCallbackInfo<Value>& info) {
HttpRequest* request = UnwrapRequest(info.Holder());
HttpRequest* request = UnwrapRequest(info.HolderV2());
const string& path = request->UserAgent();
info.GetReturnValue().Set(
String::NewFromUtf8(info.GetIsolate(), path.c_str(),
@ -560,18 +561,20 @@ Local<ObjectTemplate> JsHttpRequestProcessor::MakeRequestTemplate(
result->SetInternalFieldCount(1);
// Add accessors for each of the fields of the request.
result->SetAccessor(
result->SetNativeDataProperty(
String::NewFromUtf8Literal(isolate, "path", NewStringType::kInternalized),
GetPath);
result->SetAccessor(String::NewFromUtf8Literal(isolate, "referrer",
NewStringType::kInternalized),
GetReferrer);
result->SetAccessor(
result->SetNativeDataProperty(
String::NewFromUtf8Literal(isolate, "referrer",
NewStringType::kInternalized),
GetReferrer);
result->SetNativeDataProperty(
String::NewFromUtf8Literal(isolate, "host", NewStringType::kInternalized),
GetHost);
result->SetAccessor(String::NewFromUtf8Literal(isolate, "userAgent",
NewStringType::kInternalized),
GetUserAgent);
result->SetNativeDataProperty(
String::NewFromUtf8Literal(isolate, "userAgent",
NewStringType::kInternalized),
GetUserAgent);
// Again, return the result through the current handle scope.
return handle_scope.Escape(result);

9
deps/v8/src/DEPS vendored
View file

@ -1,5 +1,4 @@
include_rules = [
"+base/trace_event/common/trace_event_common.h",
"+src",
"-src/asmjs",
"+src/asmjs/asm-js.h",
@ -38,9 +37,10 @@ include_rules = [
"+src/heap/local-heap-inl.h",
"+src/heap/pretenuring-handler-inl.h",
# TODO(v8:10496): Don't expose memory chunk outside of heap/.
"+src/heap/mutable-page.h",
"+src/heap/mutable-page-inl.h",
"+src/heap/mutable-page-metadata.h",
"+src/heap/mutable-page-metadata-inl.h",
"+src/heap/memory-chunk.h",
"+src/heap/page-metadata-inl.h",
"+src/heap/paged-spaces-inl.h",
"+src/heap/parked-scope-inl.h",
"+src/heap/parked-scope.h",
@ -55,7 +55,7 @@ include_rules = [
"+src/interpreter/bytecode-array-iterator.h",
"+src/interpreter/bytecode-array-random-iterator.h",
"+src/interpreter/bytecode-decoder.h",
"+src/interpreter/bytecode-flags.h",
"+src/interpreter/bytecode-flags-and-tokens.h",
"+src/interpreter/bytecode-register.h",
"+src/interpreter/bytecodes.h",
"+src/interpreter/interpreter.h",
@ -69,6 +69,7 @@ include_rules = [
"+src/regexp/regexp-flags.h",
"+src/regexp/regexp-stack.h",
"+src/regexp/regexp-utils.h",
"+src/tracing/trace-event-no-perfetto.h",
"-src/trap-handler",
"+src/trap-handler/handler-inside-posix.h",
"+src/trap-handler/handler-inside-win.h",

View file

@ -4,7 +4,6 @@ ishell@chromium.org
jkummerow@chromium.org
leszeks@chromium.org
mlippautz@chromium.org
mslekova@chromium.org
verwaest@chromium.org
# For v8-debug.h implementations.

View file

@ -103,7 +103,6 @@ Handle<Object> FunctionCallbackArguments::Call(
RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
v8::FunctionCallback f =
reinterpret_cast<v8::FunctionCallback>(function->callback(isolate));
Handle<Object> receiver_check_unsupported;
if (isolate->should_check_side_effects() &&
!isolate->debug()->PerformSideEffectCheckForCallback(
handle(function, isolate))) {
@ -141,8 +140,10 @@ Handle<Object> PropertyCallbackArguments::CallNamedQuery(
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedQueryCallback);
Handle<Object> receiver_check_unsupported;
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertyQueryCallback f =
ToCData<NamedPropertyQueryCallback>(interceptor->query());
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Integer, interceptor);
@ -165,6 +166,9 @@ Handle<Object> PropertyCallbackArguments::CallNamedGetter(
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedGetterCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertyGetterCallback f =
ToCData<NamedPropertyGetterCallback>(interceptor->getter());
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor);
@ -187,6 +191,9 @@ Handle<Object> PropertyCallbackArguments::CallNamedDescriptor(
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDescriptorCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertyDescriptorCallback f =
ToCData<NamedPropertyDescriptorCallback>(interceptor->descriptor());
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor);
@ -206,12 +213,15 @@ Handle<Object> PropertyCallbackArguments::CallNamedDescriptor(
// TODO(ishell): just return v8::Intercepted.
Handle<Object> PropertyCallbackArguments::CallNamedSetter(
Handle<InterceptorInfo> interceptor, Handle<Name> name,
DirectHandle<InterceptorInfo> interceptor, Handle<Name> name,
Handle<Object> value) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedSetterCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertySetterCallback f =
ToCData<NamedPropertySetterCallback>(interceptor->setter());
Handle<InterceptorInfo> has_side_effects;
@ -234,12 +244,15 @@ Handle<Object> PropertyCallbackArguments::CallNamedSetter(
// TODO(ishell): just return v8::Intercepted.
Handle<Object> PropertyCallbackArguments::CallNamedDefiner(
Handle<InterceptorInfo> interceptor, Handle<Name> name,
DirectHandle<InterceptorInfo> interceptor, Handle<Name> name,
const v8::PropertyDescriptor& desc) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDefinerCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertyDefinerCallback f =
ToCData<NamedPropertyDefinerCallback>(interceptor->definer());
Handle<InterceptorInfo> has_side_effects;
@ -261,11 +274,14 @@ Handle<Object> PropertyCallbackArguments::CallNamedDefiner(
// TODO(ishell): return Handle<Boolean>
Handle<Object> PropertyCallbackArguments::CallNamedDeleter(
Handle<InterceptorInfo> interceptor, Handle<Name> name) {
DirectHandle<InterceptorInfo> interceptor, Handle<Name> name) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDeleterCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertyDeleterCallback f =
ToCData<NamedPropertyDeleterCallback>(interceptor->deleter());
Handle<InterceptorInfo> has_side_effects;
@ -302,6 +318,9 @@ Handle<Object> PropertyCallbackArguments::CallIndexedQuery(
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedQueryCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyQueryCallbackV2 f =
ToCData<IndexedPropertyQueryCallbackV2>(interceptor->query());
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Integer, interceptor);
@ -321,11 +340,14 @@ Handle<Object> PropertyCallbackArguments::CallIndexedQuery(
Handle<Object> PropertyCallbackArguments::CallIndexedGetter(
Handle<InterceptorInfo> interceptor, uint32_t index) {
DCHECK(!interceptor->is_named());
RCS_SCOPE(isolate(), RuntimeCallCounterId::kNamedGetterCallback);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedGetterCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyGetterCallbackV2 f =
ToCData<IndexedPropertyGetterCallbackV2>(interceptor->getter());
Isolate* isolate = this->isolate();
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor);
auto intercepted = f(index, callback_info);
if (intercepted == v8::Intercepted::kNo) return {};
@ -334,7 +356,6 @@ Handle<Object> PropertyCallbackArguments::CallIndexedGetter(
} else {
IndexedPropertyGetterCallback f =
ToCData<IndexedPropertyGetterCallback>(interceptor->getter());
Isolate* isolate = this->isolate();
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor);
f(index, callback_info);
return GetReturnValue<Object>(isolate);
@ -347,6 +368,9 @@ Handle<Object> PropertyCallbackArguments::CallIndexedDescriptor(
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDescriptorCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyDescriptorCallbackV2 f =
ToCData<IndexedPropertyDescriptorCallbackV2>(interceptor->descriptor());
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor);
@ -365,11 +389,15 @@ Handle<Object> PropertyCallbackArguments::CallIndexedDescriptor(
// TODO(ishell): just return v8::Intercepted.
Handle<Object> PropertyCallbackArguments::CallIndexedSetter(
Handle<InterceptorInfo> interceptor, uint32_t index, Handle<Object> value) {
DirectHandle<InterceptorInfo> interceptor, uint32_t index,
Handle<Object> value) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedSetterCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertySetterCallbackV2 f =
ToCData<IndexedPropertySetterCallbackV2>(interceptor->setter());
Handle<InterceptorInfo> has_side_effects;
@ -391,12 +419,15 @@ Handle<Object> PropertyCallbackArguments::CallIndexedSetter(
// TODO(ishell): just return v8::Intercepted.
Handle<Object> PropertyCallbackArguments::CallIndexedDefiner(
Handle<InterceptorInfo> interceptor, uint32_t index,
DirectHandle<InterceptorInfo> interceptor, uint32_t index,
const v8::PropertyDescriptor& desc) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDefinerCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyDefinerCallbackV2 f =
ToCData<IndexedPropertyDefinerCallbackV2>(interceptor->definer());
Handle<InterceptorInfo> has_side_effects;
@ -423,6 +454,9 @@ Handle<Object> PropertyCallbackArguments::CallIndexedDeleter(
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDeleterCallback);
if (interceptor->has_new_callbacks_signature()) {
// New Api relies on the return value to be set to undefined.
// TODO(ishell): do this in the constructor once the old Api is deprecated.
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyDeleterCallbackV2 f =
ToCData<IndexedPropertyDeleterCallbackV2>(interceptor->deleter());
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, interceptor);
@ -456,7 +490,7 @@ Handle<JSObject> PropertyCallbackArguments::CallPropertyEnumerator(
// Accessors
Handle<Object> PropertyCallbackArguments::CallAccessorGetter(
Handle<AccessorInfo> info, Handle<Name> name) {
DirectHandle<AccessorInfo> info, Handle<Name> name) {
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
// Unlike interceptor callbacks we know that the property exists, so
@ -472,7 +506,7 @@ Handle<Object> PropertyCallbackArguments::CallAccessorGetter(
}
Handle<Object> PropertyCallbackArguments::CallAccessorSetter(
Handle<AccessorInfo> accessor_info, Handle<Name> name,
DirectHandle<AccessorInfo> accessor_info, Handle<Name> name,
Handle<Object> value) {
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorSetterCallback);

View file

@ -32,18 +32,17 @@ PropertyCallbackArguments::PropertyCallbackArguments(
// It cannot escape into js as it's removed in Call below.
Tagged<HeapObject> the_hole_value = ReadOnlyRoots(isolate).the_hole_value();
slot_at(T::kReturnValueIndex).store(the_hole_value);
slot_at(T::kUnusedIndex).store(Smi::zero());
slot_at(T::kHolderV2Index).store(Smi::zero());
DCHECK(IsHeapObject(*slot_at(T::kHolderIndex)));
DCHECK(IsSmi(*slot_at(T::kIsolateIndex)));
}
FunctionCallbackArguments::FunctionCallbackArguments(
internal::Isolate* isolate, internal::Tagged<internal::Object> data,
internal::Tagged<internal::Object> holder,
internal::Tagged<internal::HeapObject> new_target, internal::Address* argv,
Isolate* isolate, Tagged<FunctionTemplateInfo> target,
Tagged<Object> holder, Tagged<HeapObject> new_target, Address* argv,
int argc)
: Super(isolate), argv_(argv), argc_(argc) {
slot_at(T::kDataIndex).store(data);
slot_at(T::kTargetIndex).store(target);
slot_at(T::kHolderIndex).store(holder);
slot_at(T::kNewTargetIndex).store(new_target);
slot_at(T::kIsolateIndex)

View file

@ -78,7 +78,7 @@ class PropertyCallbackArguments final
static constexpr int kArgsLength = T::kArgsLength;
static constexpr int kThisIndex = T::kThisIndex;
static constexpr int kDataIndex = T::kDataIndex;
static constexpr int kUnusedIndex = T::kUnusedIndex;
static constexpr int kHolderV2Index = T::kHolderV2Index;
static constexpr int kHolderIndex = T::kHolderIndex;
static constexpr int kIsolateIndex = T::kIsolateIndex;
static constexpr int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex;
@ -97,11 +97,11 @@ class PropertyCallbackArguments final
// -------------------------------------------------------------------------
// Accessor Callbacks
// Also used for AccessorSetterCallback.
inline Handle<Object> CallAccessorSetter(Handle<AccessorInfo> info,
inline Handle<Object> CallAccessorSetter(DirectHandle<AccessorInfo> info,
Handle<Name> name,
Handle<Object> value);
// Also used for AccessorGetterCallback, AccessorNameGetterCallback.
inline Handle<Object> CallAccessorGetter(Handle<AccessorInfo> info,
inline Handle<Object> CallAccessorGetter(DirectHandle<AccessorInfo> info,
Handle<Name> name);
// -------------------------------------------------------------------------
@ -110,14 +110,14 @@ class PropertyCallbackArguments final
Handle<Name> name);
inline Handle<Object> CallNamedGetter(Handle<InterceptorInfo> interceptor,
Handle<Name> name);
inline Handle<Object> CallNamedSetter(Handle<InterceptorInfo> interceptor,
Handle<Name> name,
Handle<Object> value);
inline Handle<Object> CallNamedDefiner(Handle<InterceptorInfo> interceptor,
Handle<Name> name,
const v8::PropertyDescriptor& desc);
inline Handle<Object> CallNamedDeleter(Handle<InterceptorInfo> interceptor,
Handle<Name> name);
inline Handle<Object> CallNamedSetter(
DirectHandle<InterceptorInfo> interceptor, Handle<Name> name,
Handle<Object> value);
inline Handle<Object> CallNamedDefiner(
DirectHandle<InterceptorInfo> interceptor, Handle<Name> name,
const v8::PropertyDescriptor& desc);
inline Handle<Object> CallNamedDeleter(
DirectHandle<InterceptorInfo> interceptor, Handle<Name> name);
inline Handle<Object> CallNamedDescriptor(Handle<InterceptorInfo> interceptor,
Handle<Name> name);
inline Handle<JSObject> CallNamedEnumerator(
@ -129,11 +129,12 @@ class PropertyCallbackArguments final
uint32_t index);
inline Handle<Object> CallIndexedGetter(Handle<InterceptorInfo> interceptor,
uint32_t index);
inline Handle<Object> CallIndexedSetter(Handle<InterceptorInfo> interceptor,
uint32_t index, Handle<Object> value);
inline Handle<Object> CallIndexedDefiner(Handle<InterceptorInfo> interceptor,
uint32_t index,
const v8::PropertyDescriptor& desc);
inline Handle<Object> CallIndexedSetter(
DirectHandle<InterceptorInfo> interceptor, uint32_t index,
Handle<Object> value);
inline Handle<Object> CallIndexedDefiner(
DirectHandle<InterceptorInfo> interceptor, uint32_t index,
const v8::PropertyDescriptor& desc);
inline Handle<Object> CallIndexedDeleter(Handle<InterceptorInfo> interceptor,
uint32_t index);
inline Handle<Object> CallIndexedDescriptor(
@ -141,7 +142,7 @@ class PropertyCallbackArguments final
inline Handle<JSObject> CallIndexedEnumerator(
Handle<InterceptorInfo> interceptor);
// Accept potential JavaScript side effects that might occurr during life
// Accept potential JavaScript side effects that might occur during life
// time of this object.
inline void AcceptSideEffects() {
#ifdef DEBUG
@ -183,7 +184,7 @@ class FunctionCallbackArguments
static constexpr int kHolderIndex = T::kHolderIndex;
static constexpr int kIsolateIndex = T::kIsolateIndex;
static constexpr int kUnusedIndex = T::kUnusedIndex;
static constexpr int kDataIndex = T::kDataIndex;
static constexpr int kTargetIndex = T::kTargetIndex;
static constexpr int kNewTargetIndex = T::kNewTargetIndex;
static_assert(T::kThisValuesIndex == BuiltinArguments::kReceiverArgsOffset);
@ -199,7 +200,8 @@ class FunctionCallbackArguments
static_assert(T::kValuesOffset == offsetof(T, values_));
static_assert(T::kLengthOffset == offsetof(T, length_));
FunctionCallbackArguments(Isolate* isolate, Tagged<Object> data,
FunctionCallbackArguments(Isolate* isolate,
Tagged<FunctionTemplateInfo> target,
Tagged<Object> holder,
Tagged<HeapObject> new_target, Address* argv,
int argc);
@ -214,10 +216,17 @@ class FunctionCallbackArguments
*/
inline Handle<Object> Call(Tagged<FunctionTemplateInfo> function);
// Unofficial way of getting target FunctionTemplateInfo from
// v8::FunctionCallbackInfo<T>.
template <typename T>
static Tagged<Object> GetTarget(const FunctionCallbackInfo<T>& info) {
return Tagged<Object>(info.implicit_args_[kTargetIndex]);
}
private:
inline Tagged<JSReceiver> holder() const;
internal::Address* argv_;
Address* argv_;
int const argc_;
};

View file

@ -22,14 +22,16 @@ inline T ToCData(v8::internal::Tagged<v8::internal::Object> obj) {
static_assert(sizeof(T) == sizeof(v8::internal::Address));
if (obj == v8::internal::Smi::zero()) return nullptr;
return reinterpret_cast<T>(
v8::internal::Foreign::cast(obj)->foreign_address());
v8::internal::Foreign::cast(obj)
->foreign_address<internal::kGenericForeignTag>());
}
template <>
inline v8::internal::Address ToCData(
v8::internal::Tagged<v8::internal::Object> obj) {
if (obj == v8::internal::Smi::zero()) return v8::internal::kNullAddress;
return v8::internal::Foreign::cast(obj)->foreign_address();
return v8::internal::Foreign::cast(obj)
->foreign_address<internal::kGenericForeignTag>();
}
template <typename T>
@ -37,7 +39,7 @@ inline v8::internal::Handle<v8::internal::Object> FromCData(
v8::internal::Isolate* isolate, T obj) {
static_assert(sizeof(T) == sizeof(v8::internal::Address));
if (obj == nullptr) return handle(v8::internal::Smi::zero(), isolate);
return isolate->factory()->NewForeign(
return isolate->factory()->NewForeign<internal::kGenericForeignTag>(
reinterpret_cast<v8::internal::Address>(obj));
}
@ -47,7 +49,7 @@ inline v8::internal::Handle<v8::internal::Object> FromCData(
if (obj == v8::internal::kNullAddress) {
return handle(v8::internal::Smi::zero(), isolate);
}
return isolate->factory()->NewForeign(obj);
return isolate->factory()->NewForeign<internal::kGenericForeignTag>(obj);
}
template <class From, class To>
@ -271,7 +273,7 @@ template <typename T>
void CopySmiElementsToTypedBuffer(T* dst, uint32_t length,
i::Tagged<i::FixedArray> elements) {
for (uint32_t i = 0; i < length; ++i) {
double value = i::Object::Number(elements->get(static_cast<int>(i)));
double value = i::Object::NumberValue(elements->get(static_cast<int>(i)));
// TODO(mslekova): Avoid converting back-and-forth when possible, e.g
// avoid int->double->int conversions to boost performance.
dst[i] = i::ConvertDouble<T>(value);

View file

@ -5,6 +5,7 @@
#include "src/api/api-natives.h"
#include "src/api/api-inl.h"
#include "src/common/globals.h"
#include "src/common/message-template.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/protectors-inl.h"
@ -83,9 +84,8 @@ MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
ASSIGN_RETURN_ON_EXCEPTION(
isolate, getter,
InstantiateFunction(isolate,
Handle<FunctionTemplateInfo>::cast(getter)),
Object);
Handle<Code> trampoline = BUILTIN_CODE(isolate, DebugBreakTrampoline);
Handle<FunctionTemplateInfo>::cast(getter)));
DirectHandle<Code> trampoline = BUILTIN_CODE(isolate, DebugBreakTrampoline);
Handle<JSFunction>::cast(getter)->set_code(*trampoline);
}
if (IsFunctionTemplateInfo(*setter) &&
@ -93,15 +93,12 @@ MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
ASSIGN_RETURN_ON_EXCEPTION(
isolate, setter,
InstantiateFunction(isolate,
Handle<FunctionTemplateInfo>::cast(setter)),
Object);
Handle<Code> trampoline = BUILTIN_CODE(isolate, DebugBreakTrampoline);
Handle<FunctionTemplateInfo>::cast(setter)));
DirectHandle<Code> trampoline = BUILTIN_CODE(isolate, DebugBreakTrampoline);
Handle<JSFunction>::cast(setter)->set_code(*trampoline);
}
RETURN_ON_EXCEPTION(isolate,
JSObject::DefineOwnAccessorIgnoreAttributes(
object, name, getter, setter, attributes),
Object);
RETURN_ON_EXCEPTION(isolate, JSObject::DefineOwnAccessorIgnoreAttributes(
object, name, getter, setter, attributes));
return object;
}
@ -112,7 +109,7 @@ MaybeHandle<Object> DefineDataProperty(Isolate* isolate,
PropertyAttributes attributes) {
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
Instantiate(isolate, prop_data, name), Object);
Instantiate(isolate, prop_data, name));
PropertyKey key(isolate, name);
LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
@ -123,8 +120,7 @@ MaybeHandle<Object> DefineDataProperty(Isolate* isolate,
if (it.IsFound()) {
THROW_NEW_ERROR(
isolate,
NewTypeError(MessageTemplate::kDuplicateTemplateProperty, name),
Object);
NewTypeError(MessageTemplate::kDuplicateTemplateProperty, name));
}
#endif
@ -134,15 +130,15 @@ MaybeHandle<Object> DefineDataProperty(Isolate* isolate,
return value;
}
void DisableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
void DisableAccessChecks(Isolate* isolate, DirectHandle<JSObject> object) {
Handle<Map> old_map(object->map(), isolate);
// Copy map so it won't interfere constructor's initial map.
Handle<Map> new_map = Map::Copy(isolate, old_map, "DisableAccessChecks");
new_map->set_is_access_check_needed(false);
JSObject::MigrateToMap(isolate, Handle<JSObject>::cast(object), new_map);
JSObject::MigrateToMap(isolate, object, new_map);
}
void EnableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
void EnableAccessChecks(Isolate* isolate, DirectHandle<JSObject> object) {
Handle<Map> old_map(object->map(), isolate);
// Copy map so it won't interfere constructor's initial map.
Handle<Map> new_map = Map::Copy(isolate, old_map, "EnableAccessChecks");
@ -236,7 +232,8 @@ MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
Tagged<Object> maybe_property_list = data->property_list();
if (IsUndefined(maybe_property_list, isolate)) return obj;
Handle<ArrayList> properties(ArrayList::cast(maybe_property_list), isolate);
DirectHandle<ArrayList> properties(ArrayList::cast(maybe_property_list),
isolate);
if (properties->length() == 0) return obj;
int i = 0;
@ -250,17 +247,14 @@ MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
if (kind == PropertyKind::kData) {
auto prop_data = handle(properties->get(i++), isolate);
RETURN_ON_EXCEPTION(
isolate,
DefineDataProperty(isolate, obj, name, prop_data, attributes),
JSObject);
RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
prop_data, attributes));
} else {
auto getter = handle(properties->get(i++), isolate);
auto setter = handle(properties->get(i++), isolate);
RETURN_ON_EXCEPTION(isolate,
DefineAccessorProperty(isolate, obj, name, getter,
setter, attributes),
JSObject);
RETURN_ON_EXCEPTION(
isolate, DefineAccessorProperty(isolate, obj, name, getter, setter,
attributes));
}
} else {
// Intrinsic data property --- Get appropriate value from the current
@ -273,10 +267,8 @@ MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
static_cast<v8::Intrinsic>(Smi::ToInt(properties->get(i++)));
auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate);
RETURN_ON_EXCEPTION(
isolate,
DefineDataProperty(isolate, obj, name, prop_data, attributes),
JSObject);
RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
prop_data, attributes));
}
}
return obj;
@ -331,24 +323,28 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
FunctionTemplateInfo::cast(maybe_constructor_info), isolate);
Handle<JSFunction> tmp_constructor;
ASSIGN_RETURN_ON_EXCEPTION(isolate, tmp_constructor,
InstantiateFunction(isolate, cons_templ),
JSObject);
InstantiateFunction(isolate, cons_templ));
constructor = scope.CloseAndEscape(tmp_constructor);
}
if (new_target.is_null()) new_target = constructor;
}
const auto new_js_object_type =
constructor->has_initial_map() &&
IsJSApiWrapperObject(constructor->initial_map())
? NewJSObjectType::kAPIWrapper
: NewJSObjectType::kNoAPIWrapper;
Handle<JSObject> object;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, object,
JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
JSObject);
JSObject::New(constructor, new_target, Handle<AllocationSite>::null(),
new_js_object_type));
if (is_prototype) JSObject::OptimizeAsPrototype(object);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result, ConfigureInstance(isolate, object, info), JSObject);
ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
ConfigureInstance(isolate, object, info));
if (info->immutable_proto()) {
JSObject::SetImmutableProto(object);
}
@ -377,15 +373,13 @@ MaybeHandle<Object> GetInstancePrototype(Isolate* isolate,
ASSIGN_RETURN_ON_EXCEPTION(
isolate, parent_instance,
InstantiateFunction(
isolate, Handle<FunctionTemplateInfo>::cast(function_template)),
JSFunction);
isolate, Handle<FunctionTemplateInfo>::cast(function_template)));
Handle<Object> instance_prototype;
// TODO(cbruni): decide what to do here.
ASSIGN_RETURN_ON_EXCEPTION(
isolate, instance_prototype,
JSObject::GetProperty(isolate, parent_instance,
isolate->factory()->prototype_string()),
JSFunction);
isolate->factory()->prototype_string()));
return scope.CloseAndEscape(instance_prototype);
}
} // namespace
@ -415,22 +409,20 @@ MaybeHandle<JSFunction> InstantiateFunction(
} else {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, prototype,
GetInstancePrototype(isolate, protoype_provider_templ), JSFunction);
GetInstancePrototype(isolate, protoype_provider_templ));
}
} else {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, prototype,
InstantiateObject(isolate,
Handle<ObjectTemplateInfo>::cast(prototype_templ),
Handle<JSReceiver>(), true),
JSFunction);
Handle<JSReceiver>(), true));
}
Handle<Object> parent(data->GetParentTemplate(), isolate);
if (!IsUndefined(*parent, isolate)) {
Handle<Object> parent_prototype;
ASSIGN_RETURN_ON_EXCEPTION(isolate, parent_prototype,
GetInstancePrototype(isolate, parent),
JSFunction);
GetInstancePrototype(isolate, parent));
CHECK(IsHeapObject(*parent_prototype));
JSObject::ForceSetPrototype(isolate, Handle<JSObject>::cast(prototype),
Handle<HeapObject>::cast(parent_prototype));
@ -464,8 +456,9 @@ MaybeHandle<JSFunction> InstantiateFunction(
return function;
}
void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ,
int length, Handle<Object>* data) {
void AddPropertyToPropertyList(Isolate* isolate,
DirectHandle<TemplateInfo> templ, int length,
Handle<Object>* data) {
Tagged<Object> maybe_list = templ->property_list();
Handle<ArrayList> list;
if (IsUndefined(maybe_list, isolate)) {
@ -475,7 +468,7 @@ void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ,
}
templ->set_number_of_properties(templ->number_of_properties() + 1);
for (int i = 0; i < length; i++) {
Handle<Object> value =
DirectHandle<Object> value =
data[i].is_null()
? Handle<Object>::cast(isolate->factory()->undefined_value())
: data[i];
@ -522,29 +515,32 @@ MaybeHandle<JSObject> ApiNatives::InstantiateObject(
}
MaybeHandle<JSObject> ApiNatives::InstantiateRemoteObject(
Handle<ObjectTemplateInfo> data) {
DirectHandle<ObjectTemplateInfo> data) {
Isolate* isolate = data->GetIsolate();
InvokeScope invoke_scope(isolate);
Handle<FunctionTemplateInfo> constructor(
DirectHandle<FunctionTemplateInfo> constructor(
FunctionTemplateInfo::cast(data->constructor()), isolate);
Handle<Map> object_map = isolate->factory()->NewContextlessMap(
DirectHandle<Map> object_map = isolate->factory()->NewContextlessMap(
JS_SPECIAL_API_OBJECT_TYPE,
JSObject::kHeaderSize +
JSSpecialObject::kHeaderSize +
data->embedder_field_count() * kEmbedderDataSlotSize,
TERMINAL_FAST_ELEMENTS_KIND);
object_map->SetConstructor(*constructor);
object_map->set_is_access_check_needed(true);
object_map->set_may_have_interesting_properties(true);
Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(object_map);
Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(
object_map, AllocationType::kYoung, DirectHandle<AllocationSite>::null(),
NewJSObjectType::kAPIWrapper);
JSObject::ForceSetPrototype(isolate, object,
isolate->factory()->null_value());
return object;
}
void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
void ApiNatives::AddDataProperty(Isolate* isolate,
DirectHandle<TemplateInfo> info,
Handle<Name> name, Handle<Object> value,
PropertyAttributes attributes) {
PropertyDetails details(PropertyKind::kData, attributes,
@ -554,7 +550,8 @@ void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
AddPropertyToPropertyList(isolate, info, arraysize(data), data);
}
void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
void ApiNatives::AddDataProperty(Isolate* isolate,
DirectHandle<TemplateInfo> info,
Handle<Name> name, v8::Intrinsic intrinsic,
PropertyAttributes attributes) {
auto value = handle(Smi::FromInt(intrinsic), isolate);
@ -567,7 +564,7 @@ void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
}
void ApiNatives::AddAccessorProperty(Isolate* isolate,
Handle<TemplateInfo> info,
DirectHandle<TemplateInfo> info,
Handle<Name> name,
Handle<FunctionTemplateInfo> getter,
Handle<FunctionTemplateInfo> setter,
@ -582,8 +579,8 @@ void ApiNatives::AddAccessorProperty(Isolate* isolate,
}
void ApiNatives::AddNativeDataProperty(Isolate* isolate,
Handle<TemplateInfo> info,
Handle<AccessorInfo> property) {
DirectHandle<TemplateInfo> info,
DirectHandle<AccessorInfo> property) {
Tagged<Object> maybe_list = info->property_accessors();
Handle<ArrayList> list;
if (IsUndefined(maybe_list, isolate)) {
@ -597,7 +594,7 @@ void ApiNatives::AddNativeDataProperty(Isolate* isolate,
Handle<JSFunction> ApiNatives::CreateApiFunction(
Isolate* isolate, Handle<NativeContext> native_context,
Handle<FunctionTemplateInfo> obj, Handle<Object> prototype,
DirectHandle<FunctionTemplateInfo> obj, Handle<Object> prototype,
InstanceType type, MaybeHandle<Name> maybe_name) {
RCS_SCOPE(isolate, RuntimeCallCounterId::kCreateApiFunction);
Handle<SharedFunctionInfo> shared =
@ -636,7 +633,7 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
int embedder_field_count = 0;
bool immutable_proto = false;
if (!IsUndefined(obj->GetInstanceTemplate(), isolate)) {
Handle<ObjectTemplateInfo> GetInstanceTemplate = Handle<ObjectTemplateInfo>(
DirectHandle<ObjectTemplateInfo> GetInstanceTemplate(
ObjectTemplateInfo::cast(obj->GetInstanceTemplate()), isolate);
embedder_field_count = GetInstanceTemplate->embedder_field_count();
immutable_proto = GetInstanceTemplate->immutable_proto();

View file

@ -43,29 +43,31 @@ class ApiNatives {
Handle<JSReceiver> new_target = Handle<JSReceiver>());
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> InstantiateRemoteObject(
Handle<ObjectTemplateInfo> data);
DirectHandle<ObjectTemplateInfo> data);
static Handle<JSFunction> CreateApiFunction(
Isolate* isolate, Handle<NativeContext> native_context,
Handle<FunctionTemplateInfo> obj, Handle<Object> prototype,
DirectHandle<FunctionTemplateInfo> obj, Handle<Object> prototype,
InstanceType type, MaybeHandle<Name> name = MaybeHandle<Name>());
static void AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
static void AddDataProperty(Isolate* isolate, DirectHandle<TemplateInfo> info,
Handle<Name> name, Handle<Object> value,
PropertyAttributes attributes);
static void AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
static void AddDataProperty(Isolate* isolate, DirectHandle<TemplateInfo> info,
Handle<Name> name, v8::Intrinsic intrinsic,
PropertyAttributes attributes);
static void AddAccessorProperty(Isolate* isolate, Handle<TemplateInfo> info,
static void AddAccessorProperty(Isolate* isolate,
DirectHandle<TemplateInfo> info,
Handle<Name> name,
Handle<FunctionTemplateInfo> getter,
Handle<FunctionTemplateInfo> setter,
PropertyAttributes attributes);
static void AddNativeDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
Handle<AccessorInfo> property);
static void AddNativeDataProperty(Isolate* isolate,
DirectHandle<TemplateInfo> info,
DirectHandle<AccessorInfo> property);
};
} // namespace internal

865
deps/v8/src/api/api.cc vendored

File diff suppressed because it is too large Load diff

View file

@ -127,7 +127,8 @@ class RegisteredExtension {
V(ToLocalPrimitive, Object, Primitive) \
V(FixedArrayToLocal, FixedArray, FixedArray) \
V(PrimitiveArrayToLocal, FixedArray, PrimitiveArray) \
V(ToLocal, ScriptOrModule, ScriptOrModule)
V(ToLocal, ScriptOrModule, ScriptOrModule) \
IF_WASM(V, ToLocal, WasmModuleObject, WasmModuleObject)
#define OPEN_HANDLE_LIST(V) \
V(Template, TemplateInfo) \
@ -164,6 +165,7 @@ class RegisteredExtension {
V(UnboundScript, SharedFunctionInfo) \
V(Module, Module) \
V(Function, JSReceiver) \
V(CompileHintsCollector, Script) \
V(Message, JSMessageObject) \
V(Context, NativeContext) \
V(External, Object) \

View file

@ -57,7 +57,8 @@ bool AreStdlibMembersValid(Isolate* isolate, Handle<JSReceiver> stdlib,
members.Remove(wasm::AsmJsParser::StandardMember::kInfinity);
Handle<Name> name = isolate->factory()->Infinity_string();
Handle<Object> value = JSReceiver::GetDataProperty(isolate, stdlib, name);
if (!IsNumber(*value) || !std::isinf(Object::Number(*value))) return false;
if (!IsNumber(*value) || !std::isinf(Object::NumberValue(*value)))
return false;
}
if (members.contains(wasm::AsmJsParser::StandardMember::kNaN)) {
members.Remove(wasm::AsmJsParser::StandardMember::kNaN);
@ -89,7 +90,7 @@ bool AreStdlibMembersValid(Isolate* isolate, Handle<JSReceiver> stdlib,
Handle<Name> name(isolate->factory()->InternalizeString( \
base::StaticCharVector(#cname))); \
Handle<Object> value = StdlibMathMember(isolate, stdlib, name); \
if (!IsNumber(*value) || Object::Number(*value) != const_value) \
if (!IsNumber(*value) || Object::NumberValue(*value) != const_value) \
return false; \
}
STDLIB_MATH_VALUE_LIST(STDLIB_MATH_CONST)

View file

@ -78,7 +78,7 @@ AsmJsParser::AsmJsParser(Zone* zone, uintptr_t stack_limit,
stack_limit_(stack_limit),
block_stack_(zone),
global_imports_(zone) {
module_builder_->SetMinMemorySize(0);
module_builder_->AddMemory(0);
InitializeStdlibTypes();
}

View file

@ -36,6 +36,7 @@
#include "src/handles/handles.h"
#include "src/numbers/conversions.h"
#include "src/objects/name.h"
#include "src/zone/zone.h"
// Ast(Raw|Cons)String and AstValueFactory are for storing strings and
// values independent of the V8 heap and internalizing them later. During
@ -234,12 +235,10 @@ using AstRawStringMap =
// For generating constants.
#define AST_STRING_CONSTANTS(F) \
F(anonymous, "anonymous") \
F(anonymous_function, "(anonymous function)") \
F(arguments, "arguments") \
F(as, "as") \
F(assert, "assert") \
F(async, "async") \
F(await, "await") \
F(bigint, "bigint") \
F(boolean, "boolean") \
F(computed, "<computed>") \
@ -261,23 +260,19 @@ using AstRawStringMap =
F(eval, "eval") \
F(from, "from") \
F(function, "function") \
F(get, "get") \
F(get_space, "get ") \
F(length, "length") \
F(let, "let") \
F(meta, "meta") \
F(name, "name") \
F(native, "native") \
F(new_target, ".new.target") \
F(next, "next") \
F(number, "number") \
F(object, "object") \
F(of, "of") \
F(private_constructor, "#constructor") \
F(proto, "__proto__") \
F(prototype, "prototype") \
F(return, "return") \
F(set, "set") \
F(set_space, "set ") \
F(string, "string") \
F(symbol, "symbol") \

15
deps/v8/src/ast/ast.h vendored
View file

@ -2609,9 +2609,6 @@ class ClassLiteral final : public Expression {
bool is_anonymous_expression() const {
return IsAnonymousExpression::decode(bit_field_);
}
bool has_private_methods() const {
return HasPrivateMethods::decode(bit_field_);
}
bool IsAnonymousFunctionDefinition() const {
return is_anonymous_expression();
}
@ -2638,8 +2635,7 @@ class ClassLiteral final : public Expression {
FunctionLiteral* instance_members_initializer_function,
int start_position, int end_position,
bool has_static_computed_names, bool is_anonymous,
bool has_private_methods, Variable* home_object,
Variable* static_home_object)
Variable* home_object, Variable* static_home_object)
: Expression(start_position, kClassLiteral),
end_position_(end_position),
scope_(scope),
@ -2653,8 +2649,7 @@ class ClassLiteral final : public Expression {
home_object_(home_object),
static_home_object_(static_home_object) {
bit_field_ |= HasStaticComputedNames::encode(has_static_computed_names) |
IsAnonymousExpression::encode(is_anonymous) |
HasPrivateMethods::encode(has_private_methods);
IsAnonymousExpression::encode(is_anonymous);
}
int end_position_;
@ -2667,7 +2662,6 @@ class ClassLiteral final : public Expression {
FunctionLiteral* instance_members_initializer_function_;
using HasStaticComputedNames = Expression::NextBitField<bool, 1>;
using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>;
using HasPrivateMethods = IsAnonymousExpression::Next<bool, 1>;
Variable* home_object_;
Variable* static_home_object_;
};
@ -3397,13 +3391,12 @@ class AstNodeFactory final {
FunctionLiteral* static_initializer,
FunctionLiteral* instance_members_initializer_function,
int start_position, int end_position, bool has_static_computed_names,
bool is_anonymous, bool has_private_methods, Variable* home_object,
Variable* static_home_object) {
bool is_anonymous, Variable* home_object, Variable* static_home_object) {
return zone_->New<ClassLiteral>(
scope, extends, constructor, public_members, private_members,
static_initializer, instance_members_initializer_function,
start_position, end_position, has_static_computed_names, is_anonymous,
has_private_methods, home_object, static_home_object);
home_object, static_home_object);
}
NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,

View file

@ -20,7 +20,7 @@ namespace internal {
CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js,
SpreadErrorInArgsHint error_in_spread_args)
: builder_(new IncrementalStringBuilder(isolate)) {
: builder_(isolate) {
isolate_ = isolate;
position_ = 0;
num_prints_ = 0;
@ -55,7 +55,7 @@ Handle<String> CallPrinter::Print(FunctionLiteral* program, int position) {
num_prints_ = 0;
position_ = position;
Find(program);
return builder_->Finish().ToHandleChecked();
return indirect_handle(builder_.Finish().ToHandleChecked(), isolate_);
}
@ -75,19 +75,19 @@ void CallPrinter::Find(AstNode* node, bool print) {
void CallPrinter::Print(char c) {
if (!found_ || done_) return;
num_prints_++;
builder_->AppendCharacter(c);
builder_.AppendCharacter(c);
}
void CallPrinter::Print(const char* str) {
if (!found_ || done_) return;
num_prints_++;
builder_->AppendCString(str);
builder_.AppendCString(str);
}
void CallPrinter::Print(Handle<String> str) {
if (!found_ || done_) return;
num_prints_++;
builder_->AppendString(str);
builder_.AppendString(str);
}
void CallPrinter::VisitBlock(Block* node) {

View file

@ -5,18 +5,15 @@
#ifndef V8_AST_PRETTYPRINTER_H_
#define V8_AST_PRETTYPRINTER_H_
#include <memory>
#include "src/ast/ast.h"
#include "src/base/compiler-specific.h"
#include "src/execution/isolate.h"
#include "src/objects/function-kind.h"
#include "src/strings/string-builder.h"
namespace v8 {
namespace internal {
class IncrementalStringBuilder; // to avoid including string-builder-inl.h
class CallPrinter final : public AstVisitor<CallPrinter> {
public:
enum class SpreadErrorInArgsHint { kErrorInArgs, kNoErrorInArgs };
@ -60,8 +57,7 @@ class CallPrinter final : public AstVisitor<CallPrinter> {
Isolate* isolate_;
int num_prints_;
// Allocate the builder on the heap simply because it's forward declared.
std::unique_ptr<IncrementalStringBuilder> builder_;
IncrementalStringBuilder builder_;
int position_; // position of ast node to print
bool found_;
bool done_;

View file

@ -372,6 +372,9 @@ void Scope::SetDefaults() {
needs_home_object_ = false;
is_block_scope_for_object_literal_ = false;
has_using_declaration_ = false;
has_await_using_declaration_ = false;
num_stack_slots_ = 0;
num_heap_slots_ = ContextHeaderLength();
@ -957,15 +960,6 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
}
}
void Scope::ReplaceOuterScope(Scope* outer) {
DCHECK_NOT_NULL(outer);
DCHECK_NOT_NULL(outer_scope_);
DCHECK(!already_resolved_);
outer_scope_->RemoveInnerScope(this);
outer->AddInnerScope(this);
outer_scope_ = outer;
}
Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
DCHECK(!scope_info_.is_null());
DCHECK(this->IsOuterScopeOf(cache));
@ -1081,14 +1075,16 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
// Private methods should be declared with ClassScope::DeclarePrivateName()
DCHECK(!IsPrivateMethodOrAccessorVariableMode(mode));
// This function handles VariableMode::kVar, VariableMode::kLet,
// VariableMode::kConst, and VariableMode::kUsing modes.
// VariableMode::kDynamic variables are introduced during variable allocation,
// and VariableMode::kTemporary variables are allocated via NewTemporary().
// VariableMode::kConst, VariableMode::kUsing, and VariableMode::kAwaitUsing
// modes. VariableMode::kDynamic variables are introduced during variable
// allocation, and VariableMode::kTemporary variables are allocated via
// NewTemporary().
DCHECK(IsDeclaredVariableMode(mode));
DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
mode == VariableMode::kVar || mode == VariableMode::kLet ||
mode == VariableMode::kConst ||
mode == VariableMode::kUsing);
mode == VariableMode::kUsing ||
mode == VariableMode::kAwaitUsing);
DCHECK(!GetDeclarationScope()->was_lazily_parsed());
Variable* var =
Declare(zone(), name, mode, kind, init_flag, kNotAssigned, was_added);
@ -2930,7 +2926,7 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) {
return nullptr;
}
DCHECK(IsConstVariableMode(lookup_result.mode));
DCHECK(IsImmutableLexicalOrPrivateVariableMode(lookup_result.mode));
DCHECK_EQ(lookup_result.init_flag, InitializationFlag::kNeedsInitialization);
DCHECK_EQ(lookup_result.maybe_assigned_flag, MaybeAssignedFlag::kNotAssigned);
@ -3076,9 +3072,10 @@ Variable* ClassScope::DeclareClassVariable(AstValueFactory* ast_value_factory,
const AstRawString* name,
int class_token_pos) {
DCHECK_NULL(class_variable_);
DCHECK_NOT_NULL(name);
bool was_added;
class_variable_ =
Declare(zone(), name == nullptr ? ast_value_factory->dot_string() : name,
Declare(zone(), name->IsEmpty() ? ast_value_factory->dot_string() : name,
VariableMode::kConst, NORMAL_VARIABLE,
InitializationFlag::kNeedsInitialization,
MaybeAssignedFlag::kMaybeAssigned, &was_added);

View file

@ -164,11 +164,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// tree and its children are reparented.
Scope* FinalizeBlockScope();
// Inserts outer_scope into this scope's scope chain (and removes this
// from the current outer_scope_'s inner scope list).
// Assumes outer_scope_ is non-null.
void ReplaceOuterScope(Scope* outer_scope);
Zone* zone() const { return variables_.zone(); }
void SetMustUsePreparseData() {
@ -380,6 +375,11 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
return private_name_lookup_skips_outer_class_;
}
bool has_using_declaration() const { return has_using_declaration_; }
bool has_await_using_declaration() const {
return has_await_using_declaration_;
}
#if V8_ENABLE_WEBASSEMBLY
bool IsAsmModule() const;
// Returns true if this scope or any inner scopes that might be eagerly
@ -651,6 +651,8 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
Variable* result = variables_.Declare(
zone, this, name, mode, kind, initialization_flag, maybe_assigned_flag,
IsStaticFlag::kNotStatic, was_added);
if (mode == VariableMode::kUsing) has_using_declaration_ = true;
if (mode == VariableMode::kAwaitUsing) has_await_using_declaration_ = true;
if (*was_added) locals_.Add(result);
return result;
}
@ -846,6 +848,10 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
bool needs_home_object_ : 1;
bool is_block_scope_for_object_literal_ : 1;
// If declarations include any `using` or `await using` declarations.
bool has_using_declaration_ : 1;
bool has_await_using_declaration_ : 1;
};
class V8_EXPORT_PRIVATE DeclarationScope : public Scope {

View file

@ -29,6 +29,7 @@ bool Variable::IsGlobalObjectProperty() const {
scope_ != nullptr && scope_->is_script_scope();
}
// TODO(rezvan): Add check and related tests for VariableMode::kUsing.
bool Variable::IsReplGlobal() const {
return scope()->is_repl_mode_scope() &&
(mode() == VariableMode::kLet || mode() == VariableMode::kConst);
@ -37,6 +38,7 @@ bool Variable::IsReplGlobal() const {
void Variable::RewriteLocationForRepl() {
DCHECK(scope_->is_repl_mode_scope());
// TODO(rezvan): Add check and related tests for VariableMode::kUsing.
if (mode() == VariableMode::kLet || mode() == VariableMode::kConst) {
DCHECK_EQ(location(), VariableLocation::CONTEXT);
bit_field_ =

View file

@ -46,7 +46,7 @@ class Variable final : public ZoneObject {
DCHECK(!(mode == VariableMode::kVar &&
initialization_flag == kNeedsInitialization));
DCHECK_IMPLIES(is_static_flag == IsStaticFlag::kStatic,
IsConstVariableMode(mode));
IsImmutableLexicalOrPrivateVariableMode(mode));
}
explicit Variable(Variable* other);
@ -92,7 +92,9 @@ class Variable final : public ZoneObject {
bit_field_ = MaybeAssignedFlagField::update(bit_field_, kNotAssigned);
}
void SetMaybeAssigned() {
if (mode() == VariableMode::kConst) return;
if (IsImmutableLexicalVariableMode(mode())) {
return;
}
// Private names are only initialized once by us.
if (name_->IsPrivateName()) {
return;
@ -105,8 +107,9 @@ class Variable final : public ZoneObject {
if (!maybe_assigned()) {
local_if_not_shadowed()->SetMaybeAssigned();
}
DCHECK_IMPLIES(local_if_not_shadowed()->mode() != VariableMode::kConst,
local_if_not_shadowed()->maybe_assigned());
DCHECK_IMPLIES(
(!IsImmutableLexicalVariableMode(local_if_not_shadowed()->mode())),
local_if_not_shadowed()->maybe_assigned());
}
set_maybe_assigned();
}

View file

@ -1,3 +1,5 @@
bikineev@chromium.org
clemensb@chromium.org
ishell@chromium.org
mlippautz@chromium.org
nicohartmann@chromium.org

View file

@ -13,21 +13,41 @@
namespace v8 {
namespace base {
// kSoft:
// - DCHECKs are turned into No-ops and as such V8 is allowed to continue
// execution.
// - CHECKs, FATAL, etc. are turned into regular exits, which allows fuzzers
// to ignore them, this is such that we can try to find useful crashes.
// kHard:
// - see definition of --hard-abort flag. DCHECKs / CHECKs are using
// IMMEDIATE_CRASH() to signal abnormal program termination.
// kDefault:
// - DHCECKs / CHECKs are using std abort() to signal abnormal program
// termination.
enum class AbortMode { kSoft, kHard, kDefault };
enum class AbortMode {
// Used for example for fuzzing when controlled crashes are harmless, such
// as for example for the sandbox. With this:
// - DCHECKs are turned into No-ops and as such V8 is allowed to continue
// execution. This way, the fuzzer can progress past them.
// - CHECKs, FATAL, etc. are turned into regular exits, which allows fuzzers
// to ignore them, as they are harmless in this context.
// - The exit code will either be zero (signaling success) or non-zero
// (signaling failure). The former is for example used in tests in which a
// controlled crash counts as success (for example in sandbox regression
// tests), the latter is typically used for fuzzing where samples that exit
// in this way should be discarded and not mutated further.
kExitWithSuccessAndIgnoreDcheckFailures,
kExitWithFailureAndIgnoreDcheckFailures,
// DCHECKs, CHECKs, etc. use IMMEDIATE_CRASH() to signal abnormal program
// termination. See the --hard-abort flag for more details.
kImmediateCrash,
// CHECKs, DCHECKs, etc. use abort() to signal abnormal program termination.
kDefault
};
V8_BASE_EXPORT extern AbortMode g_abort_mode;
V8_INLINE bool ControlledCrashesAreHarmless() {
return g_abort_mode == AbortMode::kExitWithSuccessAndIgnoreDcheckFailures ||
g_abort_mode == AbortMode::kExitWithFailureAndIgnoreDcheckFailures;
}
V8_INLINE bool DcheckFailuresAreIgnored() {
return g_abort_mode == AbortMode::kExitWithSuccessAndIgnoreDcheckFailures ||
g_abort_mode == AbortMode::kExitWithFailureAndIgnoreDcheckFailures;
}
} // namespace base
} // namespace v8

View file

@ -485,6 +485,11 @@ V8_BASE_EXPORT int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs);
// checks and returns the result.
V8_BASE_EXPORT int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs);
template <class T>
V8_BASE_EXPORT constexpr int BitWidth(T x) {
return std::numeric_limits<T>::digits - CountLeadingZeros(x);
}
} // namespace bits
} // namespace base
} // namespace v8

View file

@ -55,22 +55,31 @@ void* BoundedPageAllocator::AllocatePages(void* hint, size_t size,
}
if (address == RegionAllocator::kAllocationFailure) {
ran_out_of_reservation_ = true;
return nullptr;
}
void* ptr = reinterpret_cast<void*>(address);
// It's assumed that free regions are in kNoAccess/kNoAccessWillJitLater
// state.
if (access != PageAllocator::kNoAccess &&
access != PageAllocator::kNoAccessWillJitLater) {
if (!page_allocator_->SetPermissions(ptr, size, access)) {
// This most likely means that we ran out of memory.
CHECK_EQ(region_allocator_.FreeRegion(address), size);
return nullptr;
if (access == PageAllocator::kNoAccess ||
access == PageAllocator::kNoAccessWillJitLater) {
return ptr;
}
if (page_initialization_mode_ == PageInitializationMode::kRecommitOnly) {
if (page_allocator_->RecommitPages(ptr, size, access)) {
return ptr;
}
} else {
if (page_allocator_->SetPermissions(ptr, size, access)) {
return ptr;
}
}
return ptr;
// This most likely means that we ran out of memory.
CHECK_EQ(region_allocator_.FreeRegion(address), size);
return nullptr;
}
bool BoundedPageAllocator::AllocatePagesAt(Address address, size_t size,
@ -83,6 +92,7 @@ bool BoundedPageAllocator::AllocatePagesAt(Address address, size_t size,
DCHECK(region_allocator_.contains(address, size));
if (!region_allocator_.AllocateRegionAt(address, size)) {
ran_out_of_reservation_ = true;
return false;
}
}
@ -112,6 +122,7 @@ bool BoundedPageAllocator::ReserveForSharedMemoryMapping(void* ptr,
size_t region_size = RoundUp(size, allocate_page_size_);
if (!region_allocator_.AllocateRegionAt(
address, region_size, RegionAllocator::RegionState::kExcluded)) {
ran_out_of_reservation_ = true;
return false;
}
}
@ -125,6 +136,10 @@ bool BoundedPageAllocator::FreePages(void* raw_address, size_t size) {
Address address = reinterpret_cast<Address>(raw_address);
CHECK_EQ(size, region_allocator_.FreeRegion(address));
if (ran_out_of_reservation_) {
// Reset the flag, since some memory may become available.
ran_out_of_reservation_ = false;
}
if (page_initialization_mode_ ==
PageInitializationMode::kAllocatedPagesMustBeZeroInitialized) {
DCHECK_NE(page_freeing_mode_, PageFreeingMode::kDiscard);
@ -132,9 +147,9 @@ bool BoundedPageAllocator::FreePages(void* raw_address, size_t size) {
// pages here, which will cause any wired pages to be removed by the OS.
return page_allocator_->DecommitPages(raw_address, size);
}
DCHECK_EQ(page_initialization_mode_,
PageInitializationMode::kAllocatedPagesCanBeUninitialized);
if (page_freeing_mode_ == PageFreeingMode::kMakeInaccessible) {
DCHECK_EQ(page_initialization_mode_,
PageInitializationMode::kAllocatedPagesCanBeUninitialized);
return page_allocator_->SetPermissions(raw_address, size,
PageAllocator::kNoAccess);
}
@ -178,9 +193,9 @@ bool BoundedPageAllocator::ReleasePages(void* raw_address, size_t size,
// See comment in FreePages().
return (page_allocator_->DecommitPages(free_address, free_size));
}
DCHECK_EQ(page_initialization_mode_,
PageInitializationMode::kAllocatedPagesCanBeUninitialized);
if (page_freeing_mode_ == PageFreeingMode::kMakeInaccessible) {
DCHECK_EQ(page_initialization_mode_,
PageInitializationMode::kAllocatedPagesCanBeUninitialized);
return page_allocator_->SetPermissions(free_address, free_size,
PageAllocator::kNoAccess);
}

View file

@ -21,6 +21,9 @@ enum class PageInitializationMode {
// data. This is slightly faster as comitted pages are not decommitted
// during FreePages and ReleasePages, but only made inaccessible.
kAllocatedPagesCanBeUninitialized,
// Assume pages are in discarded state and already have the right page
// permissions. Using this mode requires PageFreeingMode::kDiscard.
kRecommitOnly,
};
// Defines how BoundedPageAllocator frees pages when FreePages or ReleasePages
@ -107,6 +110,8 @@ class V8_BASE_EXPORT BoundedPageAllocator : public v8::PageAllocator {
bool DecommitPages(void* address, size_t size) override;
bool ran_out_of_reservation() const { return ran_out_of_reservation_; }
private:
v8::base::Mutex mutex_;
const size_t allocate_page_size_;
@ -115,6 +120,7 @@ class V8_BASE_EXPORT BoundedPageAllocator : public v8::PageAllocator {
v8::base::RegionAllocator region_allocator_;
const PageInitializationMode page_initialization_mode_;
const PageFreeingMode page_freeing_mode_;
bool ran_out_of_reservation_ = false;
};
} // namespace base

View file

@ -28,13 +28,21 @@
#endif
// pthread_jit_write_protect is only available on arm64 Mac.
#if defined(V8_HOST_ARCH_ARM64) && \
(defined(V8_OS_MACOS) || (defined(V8_OS_IOS) && TARGET_OS_SIMULATOR))
#if defined(V8_HOST_ARCH_ARM64) && defined(V8_OS_MACOS)
#define V8_HAS_PTHREAD_JIT_WRITE_PROTECT 1
#else
#define V8_HAS_PTHREAD_JIT_WRITE_PROTECT 0
#endif
// BrowserEngineCore JIT write protect is only available on iOS 17.4 and later.
#if defined(V8_HOST_ARCH_ARM64) && defined(V8_OS_IOS) && \
defined(__IPHONE_17_4) && \
__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_17_4
#define V8_HAS_BECORE_JIT_WRITE_PROTECT 1
#else
#define V8_HAS_BECORE_JIT_WRITE_PROTECT 0
#endif
#if defined(V8_OS_LINUX) && defined(V8_HOST_ARCH_X64)
#define V8_HAS_PKU_JIT_WRITE_PROTECT 1
#else
@ -68,6 +76,8 @@ constexpr int kPageSizeBits = kHugePageBits;
constexpr int kPageSizeBits = 18;
#endif
constexpr int kRegularPageSize = 1 << kPageSizeBits;
// The minimal supported page size by the operation system. Any region aligned
// to that size needs to be individually protectable via
// {base::OS::SetPermission} and friends.

View file

@ -102,7 +102,7 @@
!defined(V8_TARGET_ARCH_MIPS64) && !defined(V8_TARGET_ARCH_PPC) && \
!defined(V8_TARGET_ARCH_PPC64) && !defined(V8_TARGET_ARCH_RISCV64) && \
!defined(V8_TARGET_ARCH_RISCV32)) || \
(defined(__clang__) && __cplusplus > 201300L))
defined(__clang__))
#define V8_NOEXCEPT noexcept
#else
#define V8_NOEXCEPT
@ -142,4 +142,12 @@
#define V8_DONT_STRIP_SYMBOL
#endif
#ifdef __cpp_concepts
#define HAS_CPP_CONCEPTS 1
#endif
#if __cplusplus >= 202002L
#define HAS_CPP_CLASS_TYPES_AS_TEMPLATE_ARGS 1
#endif
#endif // V8_BASE_COMPILER_SPECIFIC_H_

View file

@ -87,6 +87,30 @@ static V8_INLINE void __cpuid(int cpu_info[4], int info_type) {
#endif // defined(__i386__) && defined(__pic__)
}
static V8_INLINE void __cpuidex(int cpu_info[4], int info_type,
int sub_info_type) {
// Gather additional information about the processor.
// Set the value of the ECX register to sub_info_type before it generates the
// cpuid instruction, align with __cpuidex() of MSVC:
// https://msdn.microsoft.com/en-us/library/hskdteyh.aspx
#if defined(__i386__) && defined(__pic__)
// Make sure to preserve ebx, which contains the pointer
// to the GOT in case we're generating PIC.
__asm__ volatile(
"mov %%ebx, %%edi\n\t"
"cpuid\n\t"
"xchg %%edi, %%ebx\n\t"
: "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]),
"=d"(cpu_info[3])
: "a"(info_type), "c"(sub_info_type));
#else
__asm__ volatile("cpuid \n\t"
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]),
"=d"(cpu_info[3])
: "a"(info_type), "c"(sub_info_type));
#endif // defined(__i386__) && defined(__pic__)
}
#endif // !V8_LIBC_MSVCRT
#elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64 || V8_HOST_ARCH_MIPS64 || \
@ -359,11 +383,13 @@ bool CPU::StarboardDetectCPU() {
has_sahf_ = features.x86.has_sahf;
has_avx_ = features.x86.has_avx;
has_avx2_ = features.x86.has_avx2;
// TODO: Support AVX-VNNI on Starboard
has_fma3_ = features.x86.has_fma3;
has_bmi1_ = features.x86.has_bmi1;
has_bmi2_ = features.x86.has_bmi2;
has_lzcnt_ = features.x86.has_lzcnt;
has_popcnt_ = features.x86.has_popcnt;
has_f16c_ = features.x86.has_f16c;
break;
default:
return false;
@ -403,7 +429,9 @@ CPU::CPU()
has_osxsave_(false),
has_avx_(false),
has_avx2_(false),
has_avx_vnni_(false),
has_fma3_(false),
has_f16c_(false),
has_bmi1_(false),
has_bmi2_(false),
has_lzcnt_(false),
@ -418,6 +446,8 @@ CPU::CPU()
has_dot_prod_(false),
has_lse_(false),
has_mte_(false),
has_pmull1q_(false),
has_fp16_(false),
is_fp64_mode_(false),
has_non_stop_time_stamp_counter_(false),
is_running_in_vm_(false),
@ -452,9 +482,14 @@ CPU::CPU()
if (num_ids > 0) {
__cpuid(cpu_info, 1);
int cpu_info7[4] = {0};
int cpu_info70[4] = {0};
int cpu_info71[4] = {0};
if (num_ids >= 7) {
__cpuid(cpu_info7, 7);
__cpuid(cpu_info70, 7);
// Check the maximum input value for supported leaf 7 sub-leaves
if (cpu_info70[0] >= 1) {
__cpuidex(cpu_info71, 7, 1);
}
}
stepping_ = cpu_info[0] & 0xF;
@ -475,11 +510,13 @@ CPU::CPU()
has_popcnt_ = (cpu_info[2] & 0x00800000) != 0;
has_osxsave_ = (cpu_info[2] & 0x08000000) != 0;
has_avx_ = (cpu_info[2] & 0x10000000) != 0;
has_avx2_ = (cpu_info7[1] & 0x00000020) != 0;
has_avx2_ = (cpu_info70[1] & 0x00000020) != 0;
has_avx_vnni_ = (cpu_info71[0] & 0x00000010) != 0;
has_fma3_ = (cpu_info[2] & 0x00001000) != 0;
has_f16c_ = (cpu_info[2] & 0x20000000) != 0;
// CET shadow stack feature flag. See
// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
has_cetss_ = (cpu_info7[2] & 0x00000080) != 0;
has_cetss_ = (cpu_info70[2] & 0x00000080) != 0;
// "Hypervisor Present Bit: Bit 31 of ECX of CPUID leaf 0x1."
// See https://lwn.net/Articles/301888/
// This is checking for any hypervisor. Hypervisors may choose not to
@ -773,11 +810,21 @@ CPU::CPU()
#if !defined(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE)
constexpr int PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE = 43;
#endif
#if !defined(PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE)
constexpr int PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE = 34;
#endif
#if !defined(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)
constexpr int PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE = 30;
#endif
has_jscvt_ =
IsProcessorFeaturePresent(PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE);
has_dot_prod_ =
IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE);
has_lse_ =
IsProcessorFeaturePresent(PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE);
has_pmull1q_ =
IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
#elif V8_OS_LINUX
// Try to extract the list of CPU features from ELF hwcaps.
@ -788,6 +835,8 @@ CPU::CPU()
has_jscvt_ = (hwcaps & HWCAP_JSCVT) != 0;
has_dot_prod_ = (hwcaps & HWCAP_ASIMDDP) != 0;
has_lse_ = (hwcaps & HWCAP_ATOMICS) != 0;
has_pmull1q_ = (hwcaps & HWCAP_PMULL) != 0;
has_fp16_ = (hwcaps & HWCAP_FPHP) != 0;
} else {
// Try to fallback to "Features" CPUInfo field
CPUInfo cpu_info;
@ -795,6 +844,8 @@ CPU::CPU()
has_jscvt_ = HasListItem(features, "jscvt");
has_dot_prod_ = HasListItem(features, "asimddp");
has_lse_ = HasListItem(features, "atomics");
has_pmull1q_ = HasListItem(features, "pmull");
has_fp16_ = HasListItem(features, "half");
delete[] features;
}
#elif V8_OS_DARWIN
@ -823,11 +874,29 @@ CPU::CPU()
} else {
has_lse_ = feat_lse;
}
int64_t feat_pmull = 0;
size_t feat_pmull_size = sizeof(feat_pmull);
if (sysctlbyname("hw.optional.arm.FEAT_PMULL", &feat_pmull, &feat_pmull_size,
nullptr, 0) == -1) {
has_pmull1q_ = false;
} else {
has_pmull1q_ = feat_pmull;
}
int64_t fp16 = 0;
size_t fp16_size = sizeof(fp16);
if (sysctlbyname("hw.optional.arm.FEAT_FP16", &fp16, &fp16_size, nullptr,
0) == -1) {
has_fp16_ = false;
} else {
has_fp16_ = fp16;
}
#else
// ARM64 Macs always have JSCVT, ASIMDDP and LSE.
// ARM64 Macs always have JSCVT, ASIMDDP, FP16 and LSE.
has_jscvt_ = true;
has_dot_prod_ = true;
has_lse_ = true;
has_pmull1q_ = true;
has_fp16_ = true;
#endif // V8_OS_IOS
#endif // V8_OS_WIN
@ -914,6 +983,20 @@ CPU::CPU()
#elif V8_HOST_ARCH_RISCV64
#if V8_OS_LINUX
CPUInfo cpu_info;
#if (V8_GLIBC_PREREQ(2, 39))
#include <asm/hwprobe.h>
#include <asm/unistd.h>
riscv_hwprobe pairs[] = {{RISCV_HWPROBE_KEY_IMA_EXT_0, 0}};
if (!syscall(__NR_riscv_hwprobe, &pairs,
sizeof(pairs) / sizeof(riscv_hwprobe), 0, nullptr, 0)) {
if (pairs[0].value & RISCV_HWPROBE_IMA_V) {
has_rvv_ = true;
}
if (pairs[0].value & RISCV_HWPROBE_IMA_FD) {
has_fpu_ = true;
}
}
#else
char* features = cpu_info.ExtractField("isa");
if (HasListItem(features, "rv64imafdc")) {
@ -923,6 +1006,8 @@ CPU::CPU()
has_fpu_ = true;
has_rvv_ = true;
}
#endif
char* mmu = cpu_info.ExtractField("mmu");
if (HasListItem(mmu, "sv48")) {
riscv_mmu_ = RV_MMU_MODE::kRiscvSV48;

View file

@ -95,7 +95,9 @@ class V8_BASE_EXPORT CPU final {
bool has_osxsave() const { return has_osxsave_; }
bool has_avx() const { return has_avx_; }
bool has_avx2() const { return has_avx2_; }
bool has_avx_vnni() const { return has_avx_vnni_; }
bool has_fma3() const { return has_fma3_; }
bool has_f16c() const { return has_f16c_; }
bool has_bmi1() const { return has_bmi1_; }
bool has_bmi2() const { return has_bmi2_; }
bool has_lzcnt() const { return has_lzcnt_; }
@ -127,6 +129,8 @@ class V8_BASE_EXPORT CPU final {
bool has_dot_prod() const { return has_dot_prod_; }
bool has_lse() const { return has_lse_; }
bool has_mte() const { return has_mte_; }
bool has_pmull1q() const { return has_pmull1q_; }
bool has_fp16() const { return has_fp16_; }
// mips features
bool is_fp64_mode() const { return is_fp64_mode_; }
@ -175,7 +179,9 @@ class V8_BASE_EXPORT CPU final {
bool has_osxsave_;
bool has_avx_;
bool has_avx2_;
bool has_avx_vnni_;
bool has_fma3_;
bool has_f16c_;
bool has_bmi1_;
bool has_bmi2_;
bool has_lzcnt_;
@ -190,6 +196,8 @@ class V8_BASE_EXPORT CPU final {
bool has_dot_prod_;
bool has_lse_;
bool has_mte_;
bool has_pmull1q_;
bool has_fp16_;
bool is_fp64_mode_;
bool has_non_stop_time_stamp_counter_;
bool is_running_in_vm_;

View file

@ -23,6 +23,8 @@ void (*g_print_stack_trace)() = nullptr;
void (*g_dcheck_function)(const char*, int, const char*) = DefaultDcheckHandler;
void (*g_fatal_function)(const char*, int, const char*) = nullptr;
std::string PrettyPrintChar(int ch) {
std::ostringstream oss;
switch (ch) {
@ -71,6 +73,10 @@ void SetDcheckFunction(void (*dcheck_function)(const char*, int, const char*)) {
g_dcheck_function = dcheck_function ? dcheck_function : &DefaultDcheckHandler;
}
void SetFatalFunction(void (*fatal_function)(const char*, int, const char*)) {
g_fatal_function = fatal_function;
}
void FatalOOM(OOMType type, const char* msg) {
// Instead of directly aborting here with a message, it could make sense to
// call a global callback function that would then in turn call (the
@ -172,11 +178,15 @@ void V8_Fatal(const char* format, ...) {
FailureMessage message(format, arguments);
va_end(arguments);
if (v8::base::g_fatal_function != nullptr) {
v8::base::g_fatal_function(file, line, message.message_);
}
fflush(stdout);
fflush(stderr);
// Print the formatted message to stdout without cropping the output.
if (v8::base::g_abort_mode == v8::base::AbortMode::kSoft) {
if (v8::base::ControlledCrashesAreHarmless()) {
// In this case, instead of crashing the process will be terminated
// normally by OS::Abort. Make this clear in the output printed to stderr.
v8::base::OS::PrintError(
@ -206,7 +216,7 @@ void V8_Fatal(const char* format, ...) {
}
void V8_Dcheck(const char* file, int line, const char* message) {
if (v8::base::g_abort_mode == v8::base::AbortMode::kSoft) {
if (v8::base::DcheckFailuresAreIgnored()) {
// In this mode, DCHECK failures don't lead to process termination.
v8::base::OS::PrintError(
"# Ignoring debug check failure in %s, line %d: %s\n", file, line,

View file

@ -82,6 +82,10 @@ V8_BASE_EXPORT void SetPrintStackTrace(void (*print_stack_trace_)());
V8_BASE_EXPORT void SetDcheckFunction(void (*dcheck_Function)(const char*, int,
const char*));
// Override the default function invoked during V8_Fatal.
V8_BASE_EXPORT void SetFatalFunction(void (*fatal_Function)(const char*, int,
const char*));
enum class OOMType {
// We ran out of memory in the JavaScript heap.
kJavaScript,

View file

@ -25,20 +25,22 @@
#define OFFSET_OF(type, field) offsetof(type, field)
// A comma, to be used in macro arguments where it would otherwise be
// interpreted as separator of arguments.
#define LITERAL_COMMA ,
// The arraysize(arr) macro returns the # of elements in an array arr.
// The expression is a compile-time constant, and therefore can be
// used in defining new arrays, for example. If you use arraysize on
// a pointer by mistake, you will get a compile-time error.
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
// use its type.
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#if !V8_CC_MSVC
// That gcc wants both of these prototypes seems mysterious. VC, for
// its part, can't decide which to use (another mystery). Matching of
@ -132,6 +134,13 @@ V8_INLINE Dest bit_cast(Source const& source) {
#endif
#endif
// Define V8_USE_HWADDRESS_SANITIZER macro.
#if defined(__has_feature)
#if __has_feature(hwaddress_sanitizer)
#define V8_USE_HWADDRESS_SANITIZER 1
#endif
#endif
// Define V8_USE_MEMORY_SANITIZER macro.
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
@ -368,9 +377,9 @@ bool is_inbounds(float_t v) {
// Setup for Windows shared library export.
#define V8_EXPORT_ENUM
#ifdef BUILDING_V8_SHARED_PRIVATE
#define V8_EXPORT_PRIVATE
#define V8_EXPORT_PRIVATE __declspec(dllexport)
#elif USING_V8_SHARED_PRIVATE
#define V8_EXPORT_PRIVATE
#define V8_EXPORT_PRIVATE __declspec(dllimport)
#else
#define V8_EXPORT_PRIVATE
#endif // BUILDING_V8_SHARED
@ -380,8 +389,8 @@ bool is_inbounds(float_t v) {
// Setup for Linux shared library export.
#if V8_HAS_ATTRIBUTE_VISIBILITY
#ifdef BUILDING_V8_SHARED_PRIVATE
#define V8_EXPORT_PRIVATE
#define V8_EXPORT_ENUM
#define V8_EXPORT_PRIVATE __attribute__((visibility("default")))
#define V8_EXPORT_ENUM V8_EXPORT_PRIVATE
#else
#define V8_EXPORT_PRIVATE
#define V8_EXPORT_ENUM

View file

@ -14,8 +14,6 @@ using Address = uintptr_t;
// Memory provides an interface to 'raw' memory. It encapsulates the casts
// that typically are needed when incompatible pointer types are used.
// Note that this class currently relies on undefined behaviour. There is a
// proposal (http://wg21.link/p0593r2) to make it defined behaviour though.
template <class T>
inline T& Memory(Address addr) {
DCHECK(IsAligned(addr, alignof(T)));

View file

@ -16,7 +16,7 @@ namespace base {
// These aliases are deprecated, use std::optional directly.
template <typename T>
using Optional = std::optional<T>;
using Optional [[deprecated]] = std::optional<T>;
using std::in_place;
using std::make_optional;

View file

@ -44,7 +44,7 @@ void* PageAllocator::GetRandomMmapAddr() {
void* PageAllocator::AllocatePages(void* hint, size_t size, size_t alignment,
PageAllocator::Permission access) {
#if !V8_HAS_PTHREAD_JIT_WRITE_PROTECT
#if !V8_HAS_PTHREAD_JIT_WRITE_PROTECT && !V8_HAS_BECORE_JIT_WRITE_PROTECT
// kNoAccessWillJitLater is only used on Apple Silicon. Map it to regular
// kNoAccess on other platforms, so code doesn't have to handle both enum
// values.

View file

@ -129,10 +129,10 @@ void OS::SignalCodeMovingGC() {}
void OS::AdjustSchedulingParams() {}
std::vector<OS::MemoryRange> OS::GetFreeMemoryRangesWithin(
std::optional<OS::MemoryRange> OS::GetFirstFreeMemoryRangeWithin(
OS::Address boundary_start, OS::Address boundary_end, size_t minimum_size,
size_t alignment) {
return {};
return std::nullopt;
}
// static

View file

@ -276,10 +276,10 @@ void OS::SignalCodeMovingGC() {
void OS::AdjustSchedulingParams() {}
std::vector<OS::MemoryRange> OS::GetFreeMemoryRangesWithin(
std::optional<OS::MemoryRange> OS::GetFirstFreeMemoryRangeWithin(
OS::Address boundary_start, OS::Address boundary_end, size_t minimum_size,
size_t alignment) {
return {};
return std::nullopt;
}
} // namespace base

View file

@ -96,7 +96,7 @@ std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
#endif
if (code_ptr == nullptr) continue;
const intptr_t slide = _dyld_get_image_vmaddr_slide(i);
const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide;
const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr);
result.push_back(SharedLibraryAddress(_dyld_get_image_name(i), start,
start + size, slide));
}
@ -129,10 +129,10 @@ void OS::AdjustSchedulingParams() {
#endif
}
std::vector<OS::MemoryRange> OS::GetFreeMemoryRangesWithin(
std::optional<OS::MemoryRange> OS::GetFirstFreeMemoryRangeWithin(
OS::Address boundary_start, OS::Address boundary_end, size_t minimum_size,
size_t alignment) {
return {};
return std::nullopt;
}
// static

View file

@ -97,10 +97,10 @@ void OS::SignalCodeMovingGC() {}
void OS::AdjustSchedulingParams() {}
std::vector<OS::MemoryRange> OS::GetFreeMemoryRangesWithin(
std::optional<OS::MemoryRange> OS::GetFirstFreeMemoryRangeWithin(
OS::Address boundary_start, OS::Address boundary_end, size_t minimum_size,
size_t alignment) {
return {};
return std::nullopt;
}
// static

View file

@ -394,10 +394,10 @@ int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
void OS::AdjustSchedulingParams() {}
std::vector<OS::MemoryRange> OS::GetFreeMemoryRangesWithin(
std::optional<OS::MemoryRange> OS::GetFirstFreeMemoryRangeWithin(
OS::Address boundary_start, OS::Address boundary_end, size_t minimum_size,
size_t alignment) {
return {};
return std::nullopt;
}
Optional<AddressSpaceReservation> AddressSpaceReservation::CreateSubReservation(

View file

@ -1,22 +0,0 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/base/base-export.h"
#include "src/base/build_config.h"
// pthread_jit_write_protect_np is marked as not available in the iOS
// SDK but it is there for the iOS simulator. So we provide a thunk
// and a forward declaration in a compilation target that doesn't
// include pthread.h to avoid the compiler error.
extern "C" void pthread_jit_write_protect_np(int enable);
namespace v8::base {
#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT && defined(V8_OS_IOS)
V8_BASE_EXPORT void SetJitWriteProtected(int enable) {
pthread_jit_write_protect_np(enable);
}
#endif
} // namespace v8::base

Some files were not shown because too many files have changed in this diff Show more