deps: update V8 to 12.3.219.16
PR-URL: https://github.com/nodejs/node/pull/52293 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Richard Lau <rlau@redhat.com>
This commit is contained in:
parent
07f481cfcf
commit
1d29d81c69
12
deps/v8/.gitignore
vendored
12
deps/v8/.gitignore
vendored
@ -63,13 +63,10 @@
|
||||
/test/wasm-spec-tests/tests.tar.gz
|
||||
/third_party/*
|
||||
!/third_party/antlr4
|
||||
!/third_party/cpu_features
|
||||
/third_party/cpu_features/src
|
||||
!/third_party/inspector_protocol
|
||||
!/third_party/jsoncpp
|
||||
/third_party/jsoncpp/source
|
||||
!/third_party/colorama
|
||||
/third_party/colorama/src
|
||||
!/third_party/cpu_features
|
||||
/third_party/cpu_features/src
|
||||
!/third_party/glibc
|
||||
!/third_party/googletest
|
||||
/third_party/googletest/src/*
|
||||
@ -80,6 +77,11 @@
|
||||
!/third_party/googletest/src/googletest/include/gtest
|
||||
/third_party/googletest/src/googletest/include/gtest/*
|
||||
!/third_party/googletest/src/googletest/include/gtest/gtest_prod.h
|
||||
!/third_party/inspector_protocol
|
||||
!/third_party/jsoncpp
|
||||
/third_party/jsoncpp/source
|
||||
!/third_party/re2
|
||||
/third_party/re2/src
|
||||
!/third_party/test262-harness
|
||||
!/third_party/v8
|
||||
!/third_party/wasm-api
|
||||
|
1
deps/v8/AUTHORS
vendored
1
deps/v8/AUTHORS
vendored
@ -311,3 +311,4 @@ Zhongping Wang <kewpie.w.zp@gmail.com>
|
||||
Yang Xiang <xiangyangemail@gmail.com>
|
||||
Kotaro Ohsugi <dec4m4rk@gmail.com>
|
||||
Jing Peiyang <jingpeiyang@eswincomputing.com>
|
||||
magic-akari <akari.ccino@gmail.com>
|
||||
|
17
deps/v8/BUILD.bazel
vendored
17
deps/v8/BUILD.bazel
vendored
@ -1689,6 +1689,8 @@ filegroup(
|
||||
"src/heap/memory-balancer.h",
|
||||
"src/heap/memory-chunk.cc",
|
||||
"src/heap/memory-chunk.h",
|
||||
"src/heap/memory-chunk-header.cc",
|
||||
"src/heap/memory-chunk-header.h",
|
||||
"src/heap/memory-chunk-inl.h",
|
||||
"src/heap/memory-chunk-layout.cc",
|
||||
"src/heap/memory-chunk-layout.h",
|
||||
@ -2792,6 +2794,7 @@ filegroup(
|
||||
"src/wasm/code-space-access.cc",
|
||||
"src/wasm/code-space-access.h",
|
||||
"src/wasm/compilation-environment.h",
|
||||
"src/wasm/compilation-environment-inl.h",
|
||||
"src/wasm/constant-expression.cc",
|
||||
"src/wasm/constant-expression.h",
|
||||
"src/wasm/constant-expression-interface.cc",
|
||||
@ -2883,6 +2886,7 @@ filegroup(
|
||||
"src/wasm/wasm-value.h",
|
||||
"src/wasm/well-known-imports.cc",
|
||||
"src/wasm/well-known-imports.h",
|
||||
"src/wasm/wrappers.cc",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
@ -3011,6 +3015,8 @@ filegroup(
|
||||
"src/compiler/compiler-source-position-table.h",
|
||||
"src/compiler/constant-folding-reducer.cc",
|
||||
"src/compiler/constant-folding-reducer.h",
|
||||
"src/compiler/const-tracking-let-helpers.cc",
|
||||
"src/compiler/const-tracking-let-helpers.h",
|
||||
"src/compiler/control-equivalence.cc",
|
||||
"src/compiler/control-equivalence.h",
|
||||
"src/compiler/control-flow-optimizer.cc",
|
||||
@ -3185,7 +3191,7 @@ filegroup(
|
||||
"src/compiler/turboshaft/builtin-call-descriptors.h",
|
||||
"src/compiler/turboshaft/csa-optimize-phase.cc",
|
||||
"src/compiler/turboshaft/csa-optimize-phase.h",
|
||||
"src/compiler/turboshaft/dataview-reducer.h",
|
||||
"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/dead-code-elimination-reducer.h",
|
||||
@ -3199,7 +3205,7 @@ filegroup(
|
||||
"src/compiler/turboshaft/define-assembler-macros.inc",
|
||||
"src/compiler/turboshaft/deopt-data.h",
|
||||
"src/compiler/turboshaft/explicit-truncation-reducer.h",
|
||||
"src/compiler/turboshaft/fast-api-call-reducer.h",
|
||||
"src/compiler/turboshaft/fast-api-call-lowering-reducer.h",
|
||||
"src/compiler/turboshaft/fast-hash.h",
|
||||
"src/compiler/turboshaft/graph.cc",
|
||||
"src/compiler/turboshaft/graph.h",
|
||||
@ -3249,7 +3255,6 @@ filegroup(
|
||||
"src/compiler/turboshaft/recreate-schedule.h",
|
||||
"src/compiler/turboshaft/recreate-schedule-phase.cc",
|
||||
"src/compiler/turboshaft/recreate-schedule-phase.h",
|
||||
"src/compiler/turboshaft/reduce-args-helper.h",
|
||||
"src/compiler/turboshaft/reducer-traits.h",
|
||||
"src/compiler/turboshaft/representations.cc",
|
||||
"src/compiler/turboshaft/representations.h",
|
||||
@ -3265,7 +3270,7 @@ filegroup(
|
||||
"src/compiler/turboshaft/simplify-tf-loops.h",
|
||||
"src/compiler/turboshaft/snapshot-table.h",
|
||||
"src/compiler/turboshaft/snapshot-table-opindex.h",
|
||||
"src/compiler/turboshaft/stack-check-reducer.h",
|
||||
"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",
|
||||
@ -3374,8 +3379,8 @@ filegroup(
|
||||
"src/compiler/turboshaft/wasm-assembler-helpers.h",
|
||||
"src/compiler/turboshaft/wasm-gc-optimize-phase.cc",
|
||||
"src/compiler/turboshaft/wasm-gc-optimize-phase.h",
|
||||
"src/compiler/turboshaft/wasm-gc-type-reducer.cc",
|
||||
"src/compiler/turboshaft/wasm-gc-type-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc",
|
||||
"src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-load-elimination-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-lowering-phase.cc",
|
||||
"src/compiler/turboshaft/wasm-lowering-phase.h",
|
||||
|
68
deps/v8/BUILD.gn
vendored
68
deps/v8/BUILD.gn
vendored
@ -1149,6 +1149,9 @@ config("features") {
|
||||
if (v8_fuzzilli) {
|
||||
defines += [ "V8_FUZZILLI" ]
|
||||
}
|
||||
if (v8_enable_fuzztest) {
|
||||
defines += [ "V8_ENABLE_FUZZTEST" ]
|
||||
}
|
||||
if (v8_enable_short_builtin_calls) {
|
||||
defines += [ "V8_SHORT_BUILTIN_CALLS" ]
|
||||
}
|
||||
@ -1482,7 +1485,6 @@ config("toolchain") {
|
||||
|
||||
if (is_clang) {
|
||||
cflags += [
|
||||
"-Wmissing-field-initializers",
|
||||
"-Wunreachable-code",
|
||||
|
||||
# TODO(v8:12245): Fix shadowing instances and remove.
|
||||
@ -1496,11 +1498,6 @@ config("toolchain") {
|
||||
# warning.
|
||||
cflags += [ "-Wctad-maybe-unsupported" ]
|
||||
}
|
||||
|
||||
if (v8_current_cpu == "x64" || v8_current_cpu == "arm64" ||
|
||||
v8_current_cpu == "mips64el" || v8_current_cpu == "riscv64") {
|
||||
cflags += [ "-Wshorten-64-to-32" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_clang || !is_win) {
|
||||
@ -1700,20 +1697,6 @@ config("toolchain") {
|
||||
# Fix build with older versions of GCC
|
||||
# Ported from v8 bazel: https://crrev.com/c/3368869
|
||||
"-Wno-stringop-overflow",
|
||||
|
||||
# Fix a number of bogus errors with gcc12
|
||||
# TODO(miladfarca): re-evaluate for future gcc upgrades
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111499
|
||||
"-Wno-stringop-overread",
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104336
|
||||
"-Wno-restrict",
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
|
||||
"-Wno-array-bounds",
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108517
|
||||
"-Wno-nonnull",
|
||||
]
|
||||
}
|
||||
|
||||
@ -1723,6 +1706,17 @@ config("toolchain") {
|
||||
}
|
||||
}
|
||||
|
||||
config("strict_warnings") {
|
||||
cflags = []
|
||||
if (is_clang) {
|
||||
if (v8_current_cpu == "x64" || v8_current_cpu == "arm64" ||
|
||||
v8_current_cpu == "mips64el" || v8_current_cpu == "riscv64") {
|
||||
cflags += [ "-Wshorten-64-to-32" ]
|
||||
}
|
||||
cflags += [ "-Wmissing-field-initializers" ]
|
||||
}
|
||||
}
|
||||
|
||||
# For code that is hot during mksnapshot. In fast-mksnapshot builds, we
|
||||
# optimize some files even in debug builds to speed up mksnapshot times.
|
||||
config("always_turbofanimize") {
|
||||
@ -3304,6 +3298,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/compiler/common-operator.h",
|
||||
"src/compiler/compilation-dependencies.h",
|
||||
"src/compiler/compiler-source-position-table.h",
|
||||
"src/compiler/const-tracking-let-helpers.h",
|
||||
"src/compiler/constant-folding-reducer.h",
|
||||
"src/compiler/control-equivalence.h",
|
||||
"src/compiler/control-flow-optimizer.h",
|
||||
@ -3401,7 +3396,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/compiler/turboshaft/code-elimination-and-simplification-phase.h",
|
||||
"src/compiler/turboshaft/copying-phase.h",
|
||||
"src/compiler/turboshaft/csa-optimize-phase.h",
|
||||
"src/compiler/turboshaft/dataview-reducer.h",
|
||||
"src/compiler/turboshaft/dataview-lowering-reducer.h",
|
||||
"src/compiler/turboshaft/dead-code-elimination-reducer.h",
|
||||
"src/compiler/turboshaft/debug-feature-lowering-phase.h",
|
||||
"src/compiler/turboshaft/debug-feature-lowering-reducer.h",
|
||||
@ -3411,7 +3406,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/compiler/turboshaft/deopt-data.h",
|
||||
"src/compiler/turboshaft/duplication-optimization-reducer.h",
|
||||
"src/compiler/turboshaft/explicit-truncation-reducer.h",
|
||||
"src/compiler/turboshaft/fast-api-call-reducer.h",
|
||||
"src/compiler/turboshaft/fast-api-call-lowering-reducer.h",
|
||||
"src/compiler/turboshaft/fast-hash.h",
|
||||
"src/compiler/turboshaft/graph-builder.h",
|
||||
"src/compiler/turboshaft/graph-visualizer.h",
|
||||
@ -3440,7 +3435,6 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/compiler/turboshaft/pretenuring-propagation-reducer.h",
|
||||
"src/compiler/turboshaft/recreate-schedule-phase.h",
|
||||
"src/compiler/turboshaft/recreate-schedule.h",
|
||||
"src/compiler/turboshaft/reduce-args-helper.h",
|
||||
"src/compiler/turboshaft/reducer-traits.h",
|
||||
"src/compiler/turboshaft/representations.h",
|
||||
"src/compiler/turboshaft/required-optimization-reducer.h",
|
||||
@ -3452,7 +3446,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/compiler/turboshaft/simplify-tf-loops.h",
|
||||
"src/compiler/turboshaft/snapshot-table-opindex.h",
|
||||
"src/compiler/turboshaft/snapshot-table.h",
|
||||
"src/compiler/turboshaft/stack-check-reducer.h",
|
||||
"src/compiler/turboshaft/stack-check-lowering-reducer.h",
|
||||
"src/compiler/turboshaft/store-store-elimination-phase.h",
|
||||
"src/compiler/turboshaft/store-store-elimination-reducer.h",
|
||||
"src/compiler/turboshaft/structural-optimization-reducer.h",
|
||||
@ -3640,6 +3634,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/heap/marking.h",
|
||||
"src/heap/memory-allocator.h",
|
||||
"src/heap/memory-balancer.h",
|
||||
"src/heap/memory-chunk-header.h",
|
||||
"src/heap/memory-chunk-inl.h",
|
||||
"src/heap/memory-chunk-layout.h",
|
||||
"src/heap/memory-chunk.h",
|
||||
@ -4136,6 +4131,12 @@ v8_header_set("v8_internal_headers") {
|
||||
|
||||
if (v8_use_perfetto) {
|
||||
sources -= [ "//base/trace_event/common/trace_event_common.h" ]
|
||||
sources += [
|
||||
"src/tracing/code-data-source.h",
|
||||
"src/tracing/code-trace-context.h",
|
||||
"src/tracing/perfetto-logger.h",
|
||||
"src/tracing/perfetto-utils.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (v8_enable_sparkplug) {
|
||||
@ -4195,7 +4196,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/compiler/turboshaft/int64-lowering-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-assembler-helpers.h",
|
||||
"src/compiler/turboshaft/wasm-gc-optimize-phase.h",
|
||||
"src/compiler/turboshaft/wasm-gc-type-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-js-lowering-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-load-elimination-reducer.h",
|
||||
"src/compiler/turboshaft/wasm-lowering-phase.h",
|
||||
@ -4230,6 +4231,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/wasm/baseline/parallel-move.h",
|
||||
"src/wasm/canonical-types.h",
|
||||
"src/wasm/code-space-access.h",
|
||||
"src/wasm/compilation-environment-inl.h",
|
||||
"src/wasm/compilation-environment.h",
|
||||
"src/wasm/constant-expression-interface.h",
|
||||
"src/wasm/constant-expression.h",
|
||||
@ -4759,6 +4761,7 @@ v8_compiler_sources = [
|
||||
"src/compiler/common-operator.cc",
|
||||
"src/compiler/compilation-dependencies.cc",
|
||||
"src/compiler/compiler-source-position-table.cc",
|
||||
"src/compiler/const-tracking-let-helpers.cc",
|
||||
"src/compiler/constant-folding-reducer.cc",
|
||||
"src/compiler/control-equivalence.cc",
|
||||
"src/compiler/control-flow-optimizer.cc",
|
||||
@ -4935,7 +4938,7 @@ if (v8_enable_webassembly) {
|
||||
"src/compiler/int64-lowering.cc",
|
||||
"src/compiler/turboshaft/int64-lowering-phase.cc",
|
||||
"src/compiler/turboshaft/wasm-gc-optimize-phase.cc",
|
||||
"src/compiler/turboshaft/wasm-gc-type-reducer.cc",
|
||||
"src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc",
|
||||
"src/compiler/turboshaft/wasm-lowering-phase.cc",
|
||||
"src/compiler/turboshaft/wasm-optimize-phase.cc",
|
||||
"src/compiler/turboshaft/wasm-turboshaft-compiler.cc",
|
||||
@ -5330,6 +5333,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/heap/marking.cc",
|
||||
"src/heap/memory-allocator.cc",
|
||||
"src/heap/memory-balancer.cc",
|
||||
"src/heap/memory-chunk-header.cc",
|
||||
"src/heap/memory-chunk-layout.cc",
|
||||
"src/heap/memory-chunk.cc",
|
||||
"src/heap/memory-measurement.cc",
|
||||
@ -5651,6 +5655,14 @@ v8_source_set("v8_base_without_compiler") {
|
||||
}
|
||||
}
|
||||
|
||||
if (v8_use_perfetto) {
|
||||
sources += [
|
||||
"src/tracing/code-data-source.cc",
|
||||
"src/tracing/perfetto-logger.cc",
|
||||
"src/tracing/perfetto-utils.cc",
|
||||
]
|
||||
}
|
||||
|
||||
if (v8_enable_webassembly) {
|
||||
sources += [
|
||||
### gcmole(all) ###
|
||||
@ -5706,6 +5718,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/wasm/wasm-serialization.cc",
|
||||
"src/wasm/wasm-subtyping.cc",
|
||||
"src/wasm/well-known-imports.cc",
|
||||
"src/wasm/wrappers.cc",
|
||||
]
|
||||
}
|
||||
|
||||
@ -8131,7 +8144,6 @@ if (!build_with_chromium && v8_use_perfetto) {
|
||||
"//third_party/perfetto/src/tracing/core",
|
||||
|
||||
# TODO(skyostil): Support non-POSIX platforms.
|
||||
"//third_party/perfetto/protos/perfetto/config:cpp",
|
||||
"//third_party/perfetto/protos/perfetto/trace/track_event:zero",
|
||||
"//third_party/perfetto/src/tracing:in_process_backend",
|
||||
"//third_party/perfetto/src/tracing:platform_impl",
|
||||
@ -8139,6 +8151,8 @@ if (!build_with_chromium && v8_use_perfetto) {
|
||||
|
||||
public_deps = [
|
||||
"//third_party/perfetto/include/perfetto/trace_processor",
|
||||
"//third_party/perfetto/protos/perfetto/config:cpp",
|
||||
"//third_party/perfetto/protos/perfetto/trace/chrome:zero",
|
||||
"//third_party/perfetto/src/trace_processor:export_json",
|
||||
"//third_party/perfetto/src/tracing:client_api",
|
||||
]
|
||||
|
59
deps/v8/DEPS
vendored
59
deps/v8/DEPS
vendored
@ -27,6 +27,7 @@ vars = {
|
||||
'checkout_fuchsia_boot_images': "terminal.x64",
|
||||
'checkout_fuchsia_product_bundles': '"{checkout_fuchsia_boot_images}" != ""',
|
||||
|
||||
'checkout_centipede_deps': False,
|
||||
'checkout_instrumented_libraries': False,
|
||||
'checkout_ittapi': False,
|
||||
|
||||
@ -41,8 +42,9 @@ vars = {
|
||||
# Fetch and build V8 builtins with PGO profiles
|
||||
'checkout_v8_builtins_pgo_profiles': False,
|
||||
|
||||
'chromium_url': 'https://chromium.googlesource.com',
|
||||
'android_url': 'https://android.googlesource.com',
|
||||
'boringssl_url': 'https://boringssl.googlesource.com',
|
||||
'chromium_url': 'https://chromium.googlesource.com',
|
||||
'download_gcmole': False,
|
||||
'download_jsfunfuzz': False,
|
||||
'download_prebuilt_bazel': False,
|
||||
@ -55,7 +57,7 @@ vars = {
|
||||
'checkout_fuchsia_no_hooks': False,
|
||||
|
||||
# reclient CIPD package version
|
||||
'reclient_version': 're_client_version:0.126.0.4aaef37-gomaip',
|
||||
'reclient_version': 're_client_version:0.131.1.784ddbb-gomaip',
|
||||
|
||||
# Fetch configuration files required for the 'use_remoteexec' gn arg
|
||||
'download_remoteexec_cfg': False,
|
||||
@ -71,19 +73,19 @@ vars = {
|
||||
'build_with_chromium': False,
|
||||
|
||||
# GN CIPD package version.
|
||||
'gn_version': 'git_revision:b5adfe5f574d7110b80feb9aae6fae97c366840b',
|
||||
'gn_version': 'git_revision:0a2b8eac80f164f10b2cbc126890db0d295790cd',
|
||||
|
||||
# ninja CIPD package version
|
||||
# https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja
|
||||
'ninja_version': 'version:2@1.11.1.chromium.6',
|
||||
|
||||
# luci-go CIPD package version.
|
||||
'luci_go': 'git_revision:0d11be367258bfe14a13ff1afcf43a0bc6aedb45',
|
||||
'luci_go': 'git_revision:3df60a11d33a59614c0e8d2bccc58d8c30984901',
|
||||
|
||||
# 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:17.20240120.1.1',
|
||||
'fuchsia_version': 'version:18.20240215.1.1',
|
||||
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling android_sdk_build-tools_version
|
||||
@ -123,9 +125,9 @@ deps = {
|
||||
'base/trace_event/common':
|
||||
Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + '29ac73db520575590c3aceb0a6f1f58dda8934f6',
|
||||
'build':
|
||||
Var('chromium_url') + '/chromium/src/build.git' + '@' + '28cd6ea727d171ec990e6174308451d4178d7f8e',
|
||||
Var('chromium_url') + '/chromium/src/build.git' + '@' + 'e5cf1b3ceb3fec6aa5c57b34dede99d36cede32d',
|
||||
'buildtools':
|
||||
Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '17ce6d2f0416038de7989bc71d055c07d333ccb5',
|
||||
Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '342659133d7d0b33f4e24b640a9ad78c0c423633',
|
||||
'buildtools/linux64': {
|
||||
'packages': [
|
||||
{
|
||||
@ -171,7 +173,7 @@ 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' + '@' + 'a1ba783ca340e4bf3d80b5f5e11fa54f2ee5f1ef',
|
||||
Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + 'e4f91b6381d7694265031caad0c71d733ac132f3',
|
||||
'third_party/android_platform': {
|
||||
'url': Var('chromium_url') + '/chromium/src/third_party/android_platform.git' + '@' + 'eeb2d566f963bb66212fdc0d9bbe1dde550b4969',
|
||||
'condition': 'checkout_android',
|
||||
@ -224,8 +226,16 @@ deps = {
|
||||
'condition': 'checkout_android',
|
||||
'dep_type': 'cipd',
|
||||
},
|
||||
'third_party/boringssl': {
|
||||
'url': Var('chromium_url') + '/chromium/src/third_party/boringssl.git' + '@' + '9ead20bdbf0ecc33219d25fd3a426876c54d126e',
|
||||
'condition': "checkout_centipede_deps",
|
||||
},
|
||||
'third_party/boringssl/src': {
|
||||
'url': Var('boringssl_url') + '/boringssl.git' + '@' + '414f69504d30d0848b69f6453ea7fb5e88004cb4',
|
||||
'condition': "checkout_centipede_deps",
|
||||
},
|
||||
'third_party/catapult': {
|
||||
'url': Var('chromium_url') + '/catapult.git' + '@' + '3e413d7b62c09fda8713146714ba2146a0369d86',
|
||||
'url': Var('chromium_url') + '/catapult.git' + '@' + '3d6c15240b480da1e498a64a72ea77a61ba335e1',
|
||||
'condition': 'checkout_android',
|
||||
},
|
||||
'third_party/clang-format/script':
|
||||
@ -239,11 +249,11 @@ deps = {
|
||||
'condition': 'checkout_android',
|
||||
},
|
||||
'third_party/depot_tools':
|
||||
Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '46cb7d0aca592cd20ddc2f6cb16ee386b2abbf0d',
|
||||
Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '9d7c8e76f82ddc6a3bbc307217e31dec44a0f73a',
|
||||
'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' + '@' + '6ad82eadcb1a4404964a8d86c544fda1dab7af94',
|
||||
'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + 'fa3c41d7a15127a989111fcede8dae9265f8566b',
|
||||
'condition': 'checkout_fuchsia',
|
||||
},
|
||||
# Exists for rolling the Fuchsia SDK. Check out of the SDK should always
|
||||
@ -259,17 +269,21 @@ deps = {
|
||||
'dep_type': 'cipd',
|
||||
},
|
||||
'third_party/google_benchmark_chrome': {
|
||||
'url': Var('chromium_url') + '/chromium/src/third_party/google_benchmark.git' + '@' + '992199c3cb1076d307816e963ed4b5102df53c65',
|
||||
'url': Var('chromium_url') + '/chromium/src/third_party/google_benchmark.git' + '@' + 'c300add93460c31efe53fa71e61427fa1bc09e6a',
|
||||
},
|
||||
'third_party/google_benchmark_chrome/src': {
|
||||
'url': Var('chromium_url') + '/external/github.com/google/benchmark.git' + '@' + 'b177433f3ee2513b1075140c723d73ab8901790f',
|
||||
},
|
||||
'third_party/fuzztest':
|
||||
Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + '9fc64e5930915bfb5a593b7e12487d78283e8221',
|
||||
'third_party/fuzztest/src':
|
||||
Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + '61d95200e7ece7d121cab26f0c39fbf392e6566e',
|
||||
'third_party/googletest/src':
|
||||
Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + 'af29db7ec28d6df1c7f0f745186884091e602e07',
|
||||
'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' + '@' + '0011c28c8d35fc5093bb29631d05428932cd1206',
|
||||
Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + '0893d760101b3ddf9a2408b9d20f15ec2b80b2c1',
|
||||
'third_party/ittapi': {
|
||||
# Force checkout ittapi libraries to pass v8 header includes check on
|
||||
# bots that has check_v8_header_includes enabled.
|
||||
@ -277,19 +291,19 @@ deps = {
|
||||
'condition': "checkout_ittapi or check_v8_header_includes",
|
||||
},
|
||||
'third_party/jinja2':
|
||||
Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'e2d024354e11cc6b041b0cff032d73f0c7e43a07',
|
||||
Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'c9c77525ea20c871a1d4658f8d312b51266d4bad',
|
||||
'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' + '@' + '28aa23ffb4c7344914a5b4ac7169f12e5a12333f',
|
||||
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + '6d83791af99ea95f04986d64f111b84ce0b3c6f5',
|
||||
'third_party/libc++abi/src':
|
||||
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + 'ea028d4d2b8a901f6302f5371c68a24480766e2b',
|
||||
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + 'a7b3d968a3a923886fea64b424bd770e69dc4ea4',
|
||||
'third_party/libunwind/src':
|
||||
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + 'f400fdb561d4416b59b8f8a33d8ec8b79da60495',
|
||||
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '8bad7bd6ec30f94bce82f7cb5b58ecbd6ce02996',
|
||||
'third_party/logdog/logdog':
|
||||
Var('chromium_url') + '/infra/luci/luci-py/client/libs/logdog' + '@' + '0b2078a90f7a638d576b3a7c407d136f2fb62399',
|
||||
'third_party/markupsafe':
|
||||
Var('chromium_url') + '/chromium/src/third_party/markupsafe.git' + '@' + '0bad08bb207bbfc1d6f3bbc82b9242b0c50e5794',
|
||||
Var('chromium_url') + '/chromium/src/third_party/markupsafe.git' + '@' + 'e582d7f0edb9d67499b0f5abd6ae5550e91da7f2',
|
||||
'third_party/ninja': {
|
||||
'packages': [
|
||||
{
|
||||
@ -304,14 +318,16 @@ deps = {
|
||||
Var('android_url') + '/platform/external/perfetto.git' + '@' + '6fc824d618d2f06b5d9cd8655ba0419b6b3b366e',
|
||||
'third_party/protobuf':
|
||||
Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + '6a59a2ad1f61d9696092f79b6d74368b4d7970a3',
|
||||
'third_party/re2/src':
|
||||
Var('chromium_url') + '/external/github.com/google/re2.git' + '@' + 'd00d1e93781e6ebe415771a952689dff8f260d44',
|
||||
'third_party/requests': {
|
||||
'url': Var('chromium_url') + '/external/github.com/kennethreitz/requests.git' + '@' + 'c7e0fc087ceeadb8b4c84a0953a422c474093d6d',
|
||||
'condition': 'checkout_android',
|
||||
},
|
||||
'third_party/zlib':
|
||||
Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '63c0cec0344e6ba70f22bd690187088299baaa94',
|
||||
Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '4b5807f344182fd392849b820642457212618e5f',
|
||||
'tools/clang':
|
||||
Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'f0b1beffd512e855db0f46571958cfc83c8b05a9',
|
||||
Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'a4df104173dae7d49205ed8abefc920b7c5162d2',
|
||||
'tools/luci-go': {
|
||||
'packages': [
|
||||
{
|
||||
@ -327,7 +343,7 @@ deps = {
|
||||
'dep_type': 'cipd',
|
||||
},
|
||||
'third_party/abseil-cpp': {
|
||||
'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + '5ff8c1facf6b2e54811969ae7b90152bc1f44269',
|
||||
'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + 'f1c5751a2cb4102efbffc4110ee7551b3c54cfea',
|
||||
'condition': 'not build_with_chromium',
|
||||
}
|
||||
}
|
||||
@ -338,6 +354,7 @@ include_rules = [
|
||||
'+unicode',
|
||||
'+third_party/fdlibm',
|
||||
'+third_party/ittapi/include',
|
||||
'+third_party/fuzztest',
|
||||
# Abseil features are allow-listed. Please use your best judgement when adding
|
||||
# to this set -- if in doubt, email v8-dev@. For general guidance, refer to
|
||||
# the Chromium guidelines (though note that some requirements in V8 may be
|
||||
|
5
deps/v8/PRESUBMIT.py
vendored
5
deps/v8/PRESUBMIT.py
vendored
@ -443,10 +443,7 @@ def _CheckCommitMessageBugEntry(input_api, output_api):
|
||||
continue
|
||||
if ':' not in bug and not bug.startswith('b/'):
|
||||
try:
|
||||
if int(bug) > 10000000:
|
||||
results.append(
|
||||
'Buganizer entry requires issue tracker prefix b/{}'.format(bug))
|
||||
else:
|
||||
if int(bug) < 10000000:
|
||||
if int(bug) > 200000:
|
||||
prefix_guess = 'chromium'
|
||||
else:
|
||||
|
7
deps/v8/build_overrides/build.gni
vendored
7
deps/v8/build_overrides/build.gni
vendored
@ -6,6 +6,13 @@
|
||||
# Chromium specific targets in a client project's GN file etc.
|
||||
build_with_chromium = false
|
||||
|
||||
# Variable that can be used to support multiple build scenarios, like when
|
||||
# V8 is embedded within a target.
|
||||
build_with_v8_embedder = false
|
||||
|
||||
# Not all of V8's dependencies are available in V8's Node.js build.
|
||||
build_with_node = false
|
||||
|
||||
# Used by perfetto to distinguish from its own standalone build and the
|
||||
# chromium build.
|
||||
perfetto_build_with_embedder = true
|
||||
|
7
deps/v8/gni/v8.gni
vendored
7
deps/v8/gni/v8.gni
vendored
@ -8,6 +8,7 @@ import("//build/config/gclient_args.gni")
|
||||
import("//build/config/ios/config.gni")
|
||||
import("//build/config/sanitizers/sanitizers.gni")
|
||||
import("//build/config/v8_target_cpu.gni")
|
||||
import("//build_overrides/build.gni")
|
||||
import("release_branch_toggle.gni")
|
||||
import("split_static_library.gni")
|
||||
|
||||
@ -96,6 +97,11 @@ declare_args() {
|
||||
# Add fuzzilli fuzzer support.
|
||||
v8_fuzzilli = false
|
||||
|
||||
# Enable FuzzTest
|
||||
v8_enable_fuzztest = !build_with_v8_embedder &&
|
||||
!(defined(build_with_node) && build_with_node) &&
|
||||
!(is_win && is_component_build) && is_clang
|
||||
|
||||
# Scan the call stack conservatively during garbage collection.
|
||||
v8_enable_conservative_stack_scanning = false
|
||||
|
||||
@ -228,6 +234,7 @@ v8_remove_configs = []
|
||||
v8_add_configs = [
|
||||
v8_path_prefix + ":features",
|
||||
v8_path_prefix + ":toolchain",
|
||||
v8_path_prefix + ":strict_warnings",
|
||||
]
|
||||
|
||||
if (is_debug && !v8_optimized_debug) {
|
||||
|
@ -32,7 +32,7 @@ static constexpr uint16_t kFullyConstructedBitMask = uint16_t{1};
|
||||
|
||||
static constexpr size_t kPageSize = size_t{1} << 17;
|
||||
|
||||
#if defined(V8_TARGET_ARCH_ARM64) && defined(V8_OS_DARWIN)
|
||||
#if defined(V8_HOST_ARCH_ARM64) && defined(V8_OS_DARWIN)
|
||||
constexpr size_t kGuardPageSize = 0;
|
||||
#else
|
||||
constexpr size_t kGuardPageSize = 4096;
|
||||
|
6
deps/v8/include/v8-array-buffer.h
vendored
6
deps/v8/include/v8-array-buffer.h
vendored
@ -318,6 +318,12 @@ class V8_EXPORT ArrayBuffer : public Object {
|
||||
*/
|
||||
std::shared_ptr<BackingStore> GetBackingStore();
|
||||
|
||||
/**
|
||||
* More efficient shortcut for
|
||||
* GetBackingStore()->IsResizableByUserJavaScript().
|
||||
*/
|
||||
bool IsResizableByUserJavaScript() const;
|
||||
|
||||
/**
|
||||
* More efficient shortcut for GetBackingStore()->Data(). The returned pointer
|
||||
* is valid as long as the ArrayBuffer is alive.
|
||||
|
18
deps/v8/include/v8-callbacks.h
vendored
18
deps/v8/include/v8-callbacks.h
vendored
@ -327,10 +327,6 @@ using WasmAsyncResolvePromiseCallback = void (*)(
|
||||
using WasmLoadSourceMapCallback = Local<String> (*)(Isolate* isolate,
|
||||
const char* name);
|
||||
|
||||
// --- Callback for checking if WebAssembly GC is enabled ---
|
||||
// If the callback returns true, it will also enable Wasm stringrefs.
|
||||
using WasmGCEnabledCallback = bool (*)(Local<Context> context);
|
||||
|
||||
// --- Callback for checking if WebAssembly imported strings are enabled ---
|
||||
using WasmImportedStringsEnabledCallback = bool (*)(Local<Context> context);
|
||||
|
||||
@ -342,6 +338,9 @@ using SharedArrayBufferConstructorEnabledCallback =
|
||||
using JavaScriptCompileHintsMagicEnabledCallback =
|
||||
bool (*)(Local<Context> context);
|
||||
|
||||
// --- Callback for checking if WebAssembly JSPI is enabled ---
|
||||
using WasmJSPIEnabledCallback = bool (*)(Local<Context> context);
|
||||
|
||||
/**
|
||||
* HostImportModuleDynamicallyCallback is called when we
|
||||
* require the embedder to load a module. This is used as part of the dynamic
|
||||
@ -352,11 +351,11 @@ using JavaScriptCompileHintsMagicEnabledCallback =
|
||||
*
|
||||
* The specifier is the name of the module that should be imported.
|
||||
*
|
||||
* The import_assertions are import assertions for this request in the form:
|
||||
* The import_attributes are import attributes for this request in the form:
|
||||
* [key1, value1, key2, value2, ...] where the keys and values are of type
|
||||
* v8::String. Note, unlike the FixedArray passed to ResolveModuleCallback and
|
||||
* returned from ModuleRequest::GetImportAssertions(), this array does not
|
||||
* contain the source Locations of the assertions.
|
||||
* contain the source Locations of the attributes.
|
||||
*
|
||||
* The embedder must compile, instantiate, evaluate the Module, and
|
||||
* obtain its namespace object.
|
||||
@ -368,15 +367,10 @@ using JavaScriptCompileHintsMagicEnabledCallback =
|
||||
* fails (e.g. due to stack overflow), the embedder must propagate
|
||||
* that exception by returning an empty MaybeLocal.
|
||||
*/
|
||||
using HostImportModuleDynamicallyWithImportAssertionsCallback =
|
||||
MaybeLocal<Promise> (*)(Local<Context> context,
|
||||
Local<ScriptOrModule> referrer,
|
||||
Local<String> specifier,
|
||||
Local<FixedArray> import_assertions);
|
||||
using HostImportModuleDynamicallyCallback = MaybeLocal<Promise> (*)(
|
||||
Local<Context> context, Local<Data> host_defined_options,
|
||||
Local<Value> resource_name, Local<String> specifier,
|
||||
Local<FixedArray> import_assertions);
|
||||
Local<FixedArray> import_attributes);
|
||||
|
||||
/**
|
||||
* Callback for requesting a compile hint for a function from the embedder. The
|
||||
|
6
deps/v8/include/v8-context.h
vendored
6
deps/v8/include/v8-context.h
vendored
@ -459,12 +459,12 @@ void* Context::GetAlignedPointerFromEmbedderData(int index) {
|
||||
|
||||
template <class T>
|
||||
MaybeLocal<T> Context::GetDataFromSnapshotOnce(size_t index) {
|
||||
auto slot = GetDataFromSnapshotOnce(index);
|
||||
if (slot) {
|
||||
if (auto slot = GetDataFromSnapshotOnce(index); slot) {
|
||||
internal::PerformCastCheck(
|
||||
internal::ValueHelper::SlotAsValue<T, false>(slot));
|
||||
return Local<T>::FromSlot(slot);
|
||||
}
|
||||
return Local<T>::FromSlot(slot);
|
||||
return {};
|
||||
}
|
||||
|
||||
Context* Context::Cast(v8::Data* data) {
|
||||
|
1
deps/v8/include/v8-forward.h
vendored
1
deps/v8/include/v8-forward.h
vendored
@ -27,6 +27,7 @@ class Context;
|
||||
class DataView;
|
||||
class Data;
|
||||
class Date;
|
||||
class DictionaryTemplate;
|
||||
class Extension;
|
||||
class External;
|
||||
class FixedArray;
|
||||
|
3
deps/v8/include/v8-function-callback.h
vendored
3
deps/v8/include/v8-function-callback.h
vendored
@ -475,7 +475,8 @@ Local<Value> ReturnValue<T>::Get() const {
|
||||
#endif // V8_STATIC_ROOTS_BOOL
|
||||
return Undefined(GetIsolate());
|
||||
}
|
||||
return Local<Value>::New(GetIsolate(), reinterpret_cast<Value*>(value_));
|
||||
return Local<Value>::New(GetIsolate(),
|
||||
internal::ValueHelper::SlotAsValue<Value>(value_));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
4
deps/v8/include/v8-internal.h
vendored
4
deps/v8/include/v8-internal.h
vendored
@ -616,8 +616,6 @@ constexpr bool kAllCodeObjectsLiveInTrustedSpace =
|
||||
kRuntimeGeneratedCodeObjectsLiveInTrustedSpace &&
|
||||
kBuiltinCodeObjectsLiveInTrustedSpace;
|
||||
|
||||
constexpr bool kInterpreterDataObjectsLiveInTrustedSpace = false;
|
||||
|
||||
// {obj} must be the raw tagged pointer representation of a HeapObject
|
||||
// that's guaranteed to never be in ReadOnlySpace.
|
||||
V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject(Address obj);
|
||||
@ -781,8 +779,6 @@ class Internals {
|
||||
static const int kNodeStateMask = 0x3;
|
||||
static const int kNodeStateIsWeakValue = 2;
|
||||
|
||||
static const int kTracedNodeClassIdOffset = kApiSystemPointerSize;
|
||||
|
||||
static const int kFirstNonstringType = 0x80;
|
||||
static const int kOddballType = 0x83;
|
||||
static const int kForeignType = 0xcc;
|
||||
|
15
deps/v8/include/v8-isolate.h
vendored
15
deps/v8/include/v8-isolate.h
vendored
@ -1579,19 +1579,14 @@ class V8_EXPORT Isolate {
|
||||
|
||||
void SetWasmLoadSourceMapCallback(WasmLoadSourceMapCallback callback);
|
||||
|
||||
/**
|
||||
* Register callback to control whether Wasm GC is enabled.
|
||||
* The callback overwrites the value of the flag.
|
||||
* If the callback returns true, it will also enable Wasm stringrefs.
|
||||
*/
|
||||
void SetWasmGCEnabledCallback(WasmGCEnabledCallback callback);
|
||||
|
||||
void SetWasmImportedStringsEnabledCallback(
|
||||
WasmImportedStringsEnabledCallback callback);
|
||||
|
||||
void SetSharedArrayBufferConstructorEnabledCallback(
|
||||
SharedArrayBufferConstructorEnabledCallback callback);
|
||||
|
||||
void SetWasmJSPIEnabledCallback(WasmJSPIEnabledCallback callback);
|
||||
|
||||
/**
|
||||
* Register callback to control whether compile hints magic comments are
|
||||
* enabled.
|
||||
@ -1751,12 +1746,12 @@ uint32_t Isolate::GetNumberOfDataSlots() {
|
||||
|
||||
template <class T>
|
||||
MaybeLocal<T> Isolate::GetDataFromSnapshotOnce(size_t index) {
|
||||
auto slot = GetDataFromSnapshotOnce(index);
|
||||
if (slot) {
|
||||
if (auto slot = GetDataFromSnapshotOnce(index); slot) {
|
||||
internal::PerformCastCheck(
|
||||
internal::ValueHelper::SlotAsValue<T, false>(slot));
|
||||
return Local<T>::FromSlot(slot);
|
||||
}
|
||||
return Local<T>::FromSlot(slot);
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace v8
|
||||
|
3
deps/v8/include/v8-local-handle.h
vendored
3
deps/v8/include/v8-local-handle.h
vendored
@ -62,6 +62,7 @@ class ReturnValue;
|
||||
class String;
|
||||
template <class F>
|
||||
class Traced;
|
||||
class TypecheckWitness;
|
||||
class Utils;
|
||||
|
||||
namespace debug {
|
||||
@ -405,6 +406,8 @@ class V8_TRIVIAL_ABI Local : public LocalBase<T>,
|
||||
}
|
||||
|
||||
#ifdef V8_ENABLE_DIRECT_LOCAL
|
||||
friend class TypecheckWitness;
|
||||
|
||||
V8_INLINE static Local<T> FromAddress(internal::Address ptr) {
|
||||
return Local<T>(LocalBase<T>(ptr));
|
||||
}
|
||||
|
2
deps/v8/include/v8-persistent-handle.h
vendored
2
deps/v8/include/v8-persistent-handle.h
vendored
@ -241,7 +241,7 @@ class NonCopyablePersistentTraits {
|
||||
* This will clone the contents of storage cell, but not any of the flags, etc.
|
||||
*/
|
||||
template <class T>
|
||||
struct CopyablePersistentTraits {
|
||||
struct V8_DEPRECATED("Use v8::Global instead") CopyablePersistentTraits {
|
||||
using CopyablePersistent = Persistent<T, CopyablePersistentTraits<T>>;
|
||||
static const bool kResetInDestructor = true;
|
||||
template <class S, class M>
|
||||
|
13
deps/v8/include/v8-script.h
vendored
13
deps/v8/include/v8-script.h
vendored
@ -136,19 +136,24 @@ class V8_EXPORT ModuleRequest : public Data {
|
||||
int GetSourceOffset() const;
|
||||
|
||||
/**
|
||||
* Contains the import assertions for this request in the form:
|
||||
* Contains the import attributes for this request in the form:
|
||||
* [key1, value1, source_offset1, key2, value2, source_offset2, ...].
|
||||
* The keys and values are of type v8::String, and the source offsets are of
|
||||
* type Int32. Use Module::SourceOffsetToLocation to convert the source
|
||||
* offsets to Locations with line/column numbers.
|
||||
*
|
||||
* All assertions present in the module request will be supplied in this
|
||||
* All attributes present in the module request will be supplied in this
|
||||
* list, regardless of whether they are supported by the host. Per
|
||||
* https://tc39.es/proposal-import-attributes/#sec-hostgetsupportedimportattributes,
|
||||
* hosts are expected to throw for assertions that they do not support (as
|
||||
* hosts are expected to throw for attributes that they do not support (as
|
||||
* opposed to, for example, ignoring them).
|
||||
*/
|
||||
Local<FixedArray> GetImportAssertions() const;
|
||||
Local<FixedArray> GetImportAttributes() const;
|
||||
|
||||
V8_DEPRECATE_SOON("Use GetImportAttributes instead")
|
||||
Local<FixedArray> GetImportAssertions() const {
|
||||
return GetImportAttributes();
|
||||
}
|
||||
|
||||
V8_INLINE static ModuleRequest* Cast(Data* data);
|
||||
|
||||
|
7
deps/v8/include/v8-snapshot.h
vendored
7
deps/v8/include/v8-snapshot.h
vendored
@ -14,6 +14,10 @@ namespace v8 {
|
||||
|
||||
class Object;
|
||||
|
||||
namespace internal {
|
||||
class SnapshotCreatorImpl;
|
||||
} // namespace internal
|
||||
|
||||
class V8_EXPORT StartupData {
|
||||
public:
|
||||
/**
|
||||
@ -206,7 +210,8 @@ class V8_EXPORT SnapshotCreator {
|
||||
size_t AddData(Local<Context> context, internal::Address object);
|
||||
size_t AddData(internal::Address object);
|
||||
|
||||
void* data_;
|
||||
internal::SnapshotCreatorImpl* impl_;
|
||||
friend class internal::SnapshotCreatorImpl;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
51
deps/v8/include/v8-template.h
vendored
51
deps/v8/include/v8-template.h
vendored
@ -5,6 +5,9 @@
|
||||
#ifndef INCLUDE_V8_TEMPLATE_H_
|
||||
#define INCLUDE_V8_TEMPLATE_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <string_view>
|
||||
|
||||
#include "v8-data.h" // NOLINT(build/include_directory)
|
||||
#include "v8-function-callback.h" // NOLINT(build/include_directory)
|
||||
#include "v8-local-handle.h" // NOLINT(build/include_directory)
|
||||
@ -778,7 +781,11 @@ class V8_EXPORT ObjectTemplate : public Template {
|
||||
Isolate* isolate,
|
||||
Local<FunctionTemplate> constructor = Local<FunctionTemplate>());
|
||||
|
||||
/** Creates a new instance of this template.*/
|
||||
/**
|
||||
* Creates a new instance of this template.
|
||||
*
|
||||
* \param context The context in which the instance is created.
|
||||
*/
|
||||
V8_WARN_UNUSED_RESULT MaybeLocal<Object> NewInstance(Local<Context> context);
|
||||
|
||||
/**
|
||||
@ -950,6 +957,41 @@ class V8_EXPORT ObjectTemplate : public Template {
|
||||
friend class FunctionTemplate;
|
||||
};
|
||||
|
||||
/**
|
||||
* A template to create dictionary objects at runtime.
|
||||
*/
|
||||
class V8_EXPORT DictionaryTemplate final {
|
||||
public:
|
||||
/** Creates a new template. Also declares data properties that can be passed
|
||||
* on instantiation of the template. Properties can only be declared on
|
||||
* construction and are then immutable. The values are passed on creating the
|
||||
* object via `NewInstance()`.
|
||||
*
|
||||
* \param names the keys that can be passed on instantiation.
|
||||
*/
|
||||
static Local<DictionaryTemplate> New(
|
||||
Isolate* isolate, MemorySpan<const std::string_view> names);
|
||||
|
||||
/**
|
||||
* Creates a new instance of this template.
|
||||
*
|
||||
* \param context The context used to create the dictionary object.
|
||||
* \param property_values Values of properties that were declared using
|
||||
* `DeclareDataProperties()`. The span only passes values and expectes the
|
||||
* order to match the declaration. Non-existent properties are signaled via
|
||||
* empty `MaybeLocal`s.
|
||||
*/
|
||||
V8_WARN_UNUSED_RESULT Local<Object> NewInstance(
|
||||
Local<Context> context, MemorySpan<MaybeLocal<Value>> property_values);
|
||||
|
||||
V8_INLINE static DictionaryTemplate* Cast(Data* data);
|
||||
|
||||
private:
|
||||
static void CheckCast(Data* that);
|
||||
|
||||
DictionaryTemplate();
|
||||
};
|
||||
|
||||
/**
|
||||
* A Signature specifies which receiver is valid for a function.
|
||||
*
|
||||
@ -995,6 +1037,13 @@ ObjectTemplate* ObjectTemplate::Cast(Data* data) {
|
||||
return reinterpret_cast<ObjectTemplate*>(data);
|
||||
}
|
||||
|
||||
DictionaryTemplate* DictionaryTemplate::Cast(Data* data) {
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
CheckCast(data);
|
||||
#endif
|
||||
return reinterpret_cast<DictionaryTemplate*>(data);
|
||||
}
|
||||
|
||||
Signature* Signature::Cast(Data* data) {
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
CheckCast(data);
|
||||
|
29
deps/v8/include/v8-traced-handle.h
vendored
29
deps/v8/include/v8-traced-handle.h
vendored
@ -77,19 +77,6 @@ class TracedReferenceBase : public api_internal::IndirectHandleBase {
|
||||
return this->GetSlotThreadSafe() == nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a wrapper class ID to the handle.
|
||||
*/
|
||||
V8_DEPRECATED("Embedders need to maintain state for references themselves.")
|
||||
V8_INLINE void SetWrapperClassId(uint16_t class_id);
|
||||
|
||||
/**
|
||||
* Returns the class ID previously assigned to this handle or 0 if no class ID
|
||||
* was previously assigned.
|
||||
*/
|
||||
V8_DEPRECATED("Embedders need to maintain state for references themselves.")
|
||||
V8_INLINE uint16_t WrapperClassId() const;
|
||||
|
||||
protected:
|
||||
V8_INLINE TracedReferenceBase() = default;
|
||||
|
||||
@ -440,22 +427,6 @@ TracedReference<T>& TracedReference<T>::operator=(const TracedReference& rhs) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TracedReferenceBase::SetWrapperClassId(uint16_t class_id) {
|
||||
using I = internal::Internals;
|
||||
if (IsEmpty()) return;
|
||||
uint8_t* addr =
|
||||
reinterpret_cast<uint8_t*>(slot()) + I::kTracedNodeClassIdOffset;
|
||||
*reinterpret_cast<uint16_t*>(addr) = class_id;
|
||||
}
|
||||
|
||||
uint16_t TracedReferenceBase::WrapperClassId() const {
|
||||
using I = internal::Internals;
|
||||
if (IsEmpty()) return 0;
|
||||
uint8_t* addr =
|
||||
reinterpret_cast<uint8_t*>(slot()) + I::kTracedNodeClassIdOffset;
|
||||
return *reinterpret_cast<uint16_t*>(addr);
|
||||
}
|
||||
|
||||
} // namespace v8
|
||||
|
||||
#endif // INCLUDE_V8_TRACED_HANDLE_H_
|
||||
|
25
deps/v8/include/v8-util.h
vendored
25
deps/v8/include/v8-util.h
vendored
@ -240,8 +240,9 @@ class PersistentValueMapBase {
|
||||
: value_(other.value_) { }
|
||||
|
||||
Local<V> NewLocal(Isolate* isolate) const {
|
||||
return Local<V>::New(
|
||||
isolate, internal::ValueHelper::SlotAsValue<V>(FromVal(value_)));
|
||||
return Local<V>::New(isolate,
|
||||
internal::ValueHelper::SlotAsValue<V>(
|
||||
reinterpret_cast<internal::Address*>(value_)));
|
||||
}
|
||||
bool IsEmpty() const {
|
||||
return value_ == kPersistentContainerNotFound;
|
||||
@ -298,7 +299,8 @@ class PersistentValueMapBase {
|
||||
typename Traits::Impl* impl() { return &impl_; }
|
||||
|
||||
static V* FromVal(PersistentContainerValue v) {
|
||||
return reinterpret_cast<V*>(v);
|
||||
return internal::ValueHelper::SlotAsValue<V>(
|
||||
reinterpret_cast<internal::Address*>(v));
|
||||
}
|
||||
|
||||
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
|
||||
@ -318,7 +320,7 @@ class PersistentValueMapBase {
|
||||
*/
|
||||
static Global<V> Release(PersistentContainerValue v) {
|
||||
Global<V> p;
|
||||
p.slot() = reinterpret_cast<internal::Address*>(FromVal(v));
|
||||
p.slot() = reinterpret_cast<internal::Address*>(v);
|
||||
if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
|
||||
Traits::DisposeCallbackData(
|
||||
p.template ClearWeak<typename Traits::WeakCallbackDataType>());
|
||||
@ -328,8 +330,8 @@ class PersistentValueMapBase {
|
||||
|
||||
void RemoveWeak(const K& key) {
|
||||
Global<V> p;
|
||||
p.slot() = reinterpret_cast<internal::Address*>(
|
||||
FromVal(Traits::Remove(&impl_, key)));
|
||||
p.slot() =
|
||||
reinterpret_cast<internal::Address*>(Traits::Remove(&impl_, key));
|
||||
p.Reset();
|
||||
}
|
||||
|
||||
@ -345,8 +347,7 @@ class PersistentValueMapBase {
|
||||
PersistentContainerValue value) {
|
||||
bool hasValue = value != kPersistentContainerNotFound;
|
||||
if (hasValue) {
|
||||
returnValue->SetInternal(
|
||||
*reinterpret_cast<internal::Address*>(FromVal(value)));
|
||||
returnValue->SetInternal(*reinterpret_cast<internal::Address*>(value));
|
||||
}
|
||||
return hasValue;
|
||||
}
|
||||
@ -620,7 +621,7 @@ class V8_DEPRECATE_SOON("Use std::vector<Global<V>>.") PersistentValueVector {
|
||||
*/
|
||||
Local<V> Get(size_t index) const {
|
||||
return Local<V>::New(isolate_, internal::ValueHelper::SlotAsValue<V>(
|
||||
FromVal(Traits::Get(&impl_, index))));
|
||||
Traits::Get(&impl_, index)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -630,8 +631,7 @@ class V8_DEPRECATE_SOON("Use std::vector<Global<V>>.") PersistentValueVector {
|
||||
size_t length = Traits::Size(&impl_);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
Global<V> p;
|
||||
p.slot() =
|
||||
reinterpret_cast<internal::Address>(FromVal(Traits::Get(&impl_, i)));
|
||||
p.slot() = reinterpret_cast<internal::Address>(Traits::Get(&impl_, i));
|
||||
}
|
||||
Traits::Clear(&impl_);
|
||||
}
|
||||
@ -652,7 +652,8 @@ class V8_DEPRECATE_SOON("Use std::vector<Global<V>>.") PersistentValueVector {
|
||||
}
|
||||
|
||||
static V* FromVal(PersistentContainerValue v) {
|
||||
return reinterpret_cast<V*>(v);
|
||||
return internal::ValueHelper::SlotAsValue<V>(
|
||||
reinterpret_cast<internal::Address*>(v));
|
||||
}
|
||||
|
||||
Isolate* isolate_;
|
||||
|
6
deps/v8/include/v8-version.h
vendored
6
deps/v8/include/v8-version.h
vendored
@ -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 2
|
||||
#define V8_BUILD_NUMBER 281
|
||||
#define V8_PATCH_LEVEL 27
|
||||
#define V8_MINOR_VERSION 3
|
||||
#define V8_BUILD_NUMBER 219
|
||||
#define V8_PATCH_LEVEL 16
|
||||
|
||||
// Use 1 for candidates and 0 otherwise.
|
||||
// (Boolean macro values are not supported by all preprocessors.)
|
||||
|
2
deps/v8/infra/testing/builders.pyl
vendored
2
deps/v8/infra/testing/builders.pyl
vendored
@ -376,7 +376,6 @@
|
||||
},
|
||||
'tests': [
|
||||
{'name': 'v8testing', 'variant': 'default'},
|
||||
{'name': 'v8testing', 'variant': 'future'},
|
||||
],
|
||||
},
|
||||
'v8_linux64_coverage_rel': {
|
||||
@ -1435,7 +1434,6 @@
|
||||
},
|
||||
'tests': [
|
||||
{'name': 'v8testing', 'variant': 'default'},
|
||||
{'name': 'v8testing', 'variant': 'future'},
|
||||
],
|
||||
},
|
||||
'V8 Linux64 - custom snapshot - debug': {
|
||||
|
119
deps/v8/samples/shell.cc
vendored
119
deps/v8/samples/shell.cc
vendored
@ -48,11 +48,11 @@
|
||||
* For a more sophisticated shell, consider using the debug shell D8.
|
||||
*/
|
||||
|
||||
|
||||
v8::Local<v8::Context> CreateShellContext(v8::Isolate* isolate);
|
||||
void RunShell(v8::Local<v8::Context> context, v8::Platform* platform);
|
||||
int RunMain(v8::Isolate* isolate, v8::Platform* platform, int argc,
|
||||
char* argv[]);
|
||||
v8::Global<v8::Context> CreateShellContext(v8::Isolate* isolate);
|
||||
void RunShell(v8::Isolate* isolate, const v8::Global<v8::Context>& context,
|
||||
v8::Platform* platform);
|
||||
int RunMain(v8::Isolate* isolate, const v8::Global<v8::Context>& context,
|
||||
v8::Platform* platform, int argc, char* argv[]);
|
||||
bool ExecuteString(v8::Isolate* isolate, v8::Local<v8::String> source,
|
||||
v8::Local<v8::Value> name, bool print_result,
|
||||
bool report_exceptions);
|
||||
@ -64,10 +64,8 @@ void Version(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
v8::MaybeLocal<v8::String> ReadFile(v8::Isolate* isolate, const char* name);
|
||||
void ReportException(v8::Isolate* isolate, v8::TryCatch* handler);
|
||||
|
||||
|
||||
static bool run_shell;
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
v8::V8::InitializeICUDefaultLocation(argv[0]);
|
||||
v8::V8::InitializeExternalStartupData(argv[0]);
|
||||
@ -83,15 +81,13 @@ int main(int argc, char* argv[]) {
|
||||
int result;
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = CreateShellContext(isolate);
|
||||
v8::Global<v8::Context> context = CreateShellContext(isolate);
|
||||
if (context.IsEmpty()) {
|
||||
fprintf(stderr, "Error creating context\n");
|
||||
return 1;
|
||||
}
|
||||
v8::Context::Scope context_scope(context);
|
||||
result = RunMain(isolate, platform.get(), argc, argv);
|
||||
if (run_shell) RunShell(context, platform.get());
|
||||
result = RunMain(isolate, context, platform.get(), argc, argv);
|
||||
if (run_shell) RunShell(isolate, context, platform.get());
|
||||
}
|
||||
isolate->Dispose();
|
||||
v8::V8::Dispose();
|
||||
@ -100,16 +96,15 @@ int main(int argc, char* argv[]) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Extracts a C string from a V8 Utf8Value.
|
||||
const char* ToCString(const v8::String::Utf8Value& value) {
|
||||
return *value ? *value : "<string conversion failed>";
|
||||
}
|
||||
|
||||
|
||||
// Creates a new execution environment containing the built-in
|
||||
// functions.
|
||||
v8::Local<v8::Context> CreateShellContext(v8::Isolate* isolate) {
|
||||
v8::Global<v8::Context> CreateShellContext(v8::Isolate* isolate) {
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
// Create a template for the global object.
|
||||
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
|
||||
// Bind the global 'print' function to the C++ Print callback.
|
||||
@ -122,10 +117,11 @@ v8::Local<v8::Context> CreateShellContext(v8::Isolate* isolate) {
|
||||
global->Set(isolate, "quit", v8::FunctionTemplate::New(isolate, Quit));
|
||||
// Bind the 'version' function
|
||||
global->Set(isolate, "version", v8::FunctionTemplate::New(isolate, Version));
|
||||
return v8::Context::New(isolate, NULL, global);
|
||||
// Return the context.
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
|
||||
return v8::Global<v8::Context>(isolate, context);
|
||||
}
|
||||
|
||||
|
||||
// The callback that is invoked by v8 whenever the JavaScript 'print'
|
||||
// function is called. Prints its arguments on stdout separated by
|
||||
// spaces and ending with a newline.
|
||||
@ -155,7 +151,7 @@ void Read(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
return;
|
||||
}
|
||||
v8::String::Utf8Value file(info.GetIsolate(), info[0]);
|
||||
if (*file == NULL) {
|
||||
if (*file == nullptr) {
|
||||
info.GetIsolate()->ThrowError("Error loading file");
|
||||
return;
|
||||
}
|
||||
@ -175,7 +171,7 @@ void Load(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
for (int i = 0; i < info.Length(); i++) {
|
||||
v8::HandleScope handle_scope(info.GetIsolate());
|
||||
v8::String::Utf8Value file(info.GetIsolate(), info[i]);
|
||||
if (*file == NULL) {
|
||||
if (*file == nullptr) {
|
||||
info.GetIsolate()->ThrowError("Error loading file");
|
||||
return;
|
||||
}
|
||||
@ -203,6 +199,8 @@ void Quit(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
// The callback that is invoked by v8 whenever the JavaScript 'version'
|
||||
// function is called. Returns a string containing the current V8 version.
|
||||
void Version(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
info.GetReturnValue().Set(
|
||||
v8::String::NewFromUtf8(info.GetIsolate(), v8::V8::GetVersion())
|
||||
@ -212,7 +210,7 @@ void Version(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
// Reads a file into a v8 string.
|
||||
v8::MaybeLocal<v8::String> ReadFile(v8::Isolate* isolate, const char* name) {
|
||||
FILE* file = fopen(name, "rb");
|
||||
if (file == NULL) return v8::MaybeLocal<v8::String>();
|
||||
if (file == nullptr) return {};
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t size = ftell(file);
|
||||
@ -224,7 +222,7 @@ v8::MaybeLocal<v8::String> ReadFile(v8::Isolate* isolate, const char* name) {
|
||||
i += fread(&chars[i], 1, size - i, file);
|
||||
if (ferror(file)) {
|
||||
fclose(file);
|
||||
return v8::MaybeLocal<v8::String>();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
@ -234,10 +232,9 @@ v8::MaybeLocal<v8::String> ReadFile(v8::Isolate* isolate, const char* name) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Process remaining command line arguments and execute files
|
||||
int RunMain(v8::Isolate* isolate, v8::Platform* platform, int argc,
|
||||
char* argv[]) {
|
||||
int RunMain(v8::Isolate* isolate, const v8::Global<v8::Context>& context,
|
||||
v8::Platform* platform, int argc, char* argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
const char* str = argv[i];
|
||||
if (strcmp(str, "--shell") == 0) {
|
||||
@ -251,25 +248,41 @@ int RunMain(v8::Isolate* isolate, v8::Platform* platform, int argc,
|
||||
"Warning: unknown flag %s.\nTry --help for options\n", str);
|
||||
} else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
|
||||
// Execute argument given to -e option directly.
|
||||
v8::Local<v8::String> file_name =
|
||||
v8::String::NewFromUtf8Literal(isolate, "unnamed");
|
||||
v8::Local<v8::String> source;
|
||||
if (!v8::String::NewFromUtf8(isolate, argv[++i]).ToLocal(&source)) {
|
||||
return 1;
|
||||
bool success;
|
||||
{
|
||||
// Enter the execution environment before evaluating any code.
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Context::Scope context_scope(context.Get(isolate));
|
||||
v8::Local<v8::String> file_name =
|
||||
v8::String::NewFromUtf8Literal(isolate, "unnamed");
|
||||
v8::Local<v8::String> source;
|
||||
if (!v8::String::NewFromUtf8(isolate, argv[++i]).ToLocal(&source)) {
|
||||
return 1;
|
||||
}
|
||||
success = ExecuteString(isolate, source, file_name, false, true);
|
||||
}
|
||||
bool success = ExecuteString(isolate, source, file_name, false, true);
|
||||
// It is important not to pump the message loop when there are v8::Local
|
||||
// handles on the stack, as this may trigger a stackless GC.
|
||||
while (v8::platform::PumpMessageLoop(platform, isolate)) continue;
|
||||
if (!success) return 1;
|
||||
} else {
|
||||
// Use all other arguments as names of files to load and run.
|
||||
v8::Local<v8::String> file_name =
|
||||
v8::String::NewFromUtf8(isolate, str).ToLocalChecked();
|
||||
v8::Local<v8::String> source;
|
||||
if (!ReadFile(isolate, str).ToLocal(&source)) {
|
||||
fprintf(stderr, "Error reading '%s'\n", str);
|
||||
continue;
|
||||
bool success;
|
||||
{
|
||||
// Enter the execution environment before evaluating any code.
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Context::Scope context_scope(context.Get(isolate));
|
||||
v8::Local<v8::String> file_name =
|
||||
v8::String::NewFromUtf8(isolate, str).ToLocalChecked();
|
||||
v8::Local<v8::String> source;
|
||||
if (!ReadFile(isolate, str).ToLocal(&source)) {
|
||||
fprintf(stderr, "Error reading '%s'\n", str);
|
||||
continue;
|
||||
}
|
||||
success = ExecuteString(isolate, source, file_name, false, true);
|
||||
}
|
||||
bool success = ExecuteString(isolate, source, file_name, false, true);
|
||||
// It is important not to pump the message loop when there are v8::Local
|
||||
// handles on the stack, as this may trigger a stackless GC.
|
||||
while (v8::platform::PumpMessageLoop(platform, isolate)) continue;
|
||||
if (!success) return 1;
|
||||
}
|
||||
@ -277,32 +290,33 @@ int RunMain(v8::Isolate* isolate, v8::Platform* platform, int argc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// The read-eval-execute loop of the shell.
|
||||
void RunShell(v8::Local<v8::Context> context, v8::Platform* platform) {
|
||||
void RunShell(v8::Isolate* isolate, const v8::Global<v8::Context>& context,
|
||||
v8::Platform* platform) {
|
||||
fprintf(stderr, "V8 version %s [sample shell]\n", v8::V8::GetVersion());
|
||||
static const int kBufferSize = 256;
|
||||
// Enter the execution environment before evaluating any code.
|
||||
v8::Context::Scope context_scope(context);
|
||||
v8::Local<v8::String> name(
|
||||
v8::String::NewFromUtf8Literal(context->GetIsolate(), "(shell)"));
|
||||
while (true) {
|
||||
char buffer[kBufferSize];
|
||||
fprintf(stderr, "> ");
|
||||
char* str = fgets(buffer, kBufferSize, stdin);
|
||||
if (str == NULL) break;
|
||||
v8::HandleScope handle_scope(context->GetIsolate());
|
||||
ExecuteString(
|
||||
context->GetIsolate(),
|
||||
v8::String::NewFromUtf8(context->GetIsolate(), str).ToLocalChecked(),
|
||||
name, true, true);
|
||||
while (v8::platform::PumpMessageLoop(platform, context->GetIsolate()))
|
||||
continue;
|
||||
if (str == nullptr) break;
|
||||
{
|
||||
// Enter the execution environment before evaluating any code.
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Context::Scope context_scope(context.Get(isolate));
|
||||
v8::Local<v8::String> name(
|
||||
v8::String::NewFromUtf8Literal(isolate, "(shell)"));
|
||||
ExecuteString(isolate,
|
||||
v8::String::NewFromUtf8(isolate, str).ToLocalChecked(),
|
||||
name, true, true);
|
||||
}
|
||||
// It is important not to pump the message loop when there are v8::Local
|
||||
// handles on the stack, as this may trigger a stackless GC.
|
||||
while (v8::platform::PumpMessageLoop(platform, isolate)) continue;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
// Executes a string within the current v8 context.
|
||||
bool ExecuteString(v8::Isolate* isolate, v8::Local<v8::String> source,
|
||||
v8::Local<v8::Value> name, bool print_result,
|
||||
@ -339,7 +353,6 @@ bool ExecuteString(v8::Isolate* isolate, v8::Local<v8::String> source,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReportException(v8::Isolate* isolate, v8::TryCatch* try_catch) {
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::String::Utf8Value exception(isolate, try_catch->Exception());
|
||||
|
7
deps/v8/src/DEPS
vendored
7
deps/v8/src/DEPS
vendored
@ -39,6 +39,7 @@ include_rules = [
|
||||
# TODO(v8:10496): Don't expose memory chunk outside of heap/.
|
||||
"+src/heap/memory-chunk.h",
|
||||
"+src/heap/memory-chunk-inl.h",
|
||||
"+src/heap/memory-chunk-header.h",
|
||||
"+src/heap/paged-spaces-inl.h",
|
||||
"+src/heap/parked-scope-inl.h",
|
||||
"+src/heap/parked-scope.h",
|
||||
@ -107,6 +108,12 @@ specific_include_rules = {
|
||||
"external-pointer-table\.cc": [
|
||||
"+src/heap/read-only-spaces.h",
|
||||
],
|
||||
# keep the includes to a minimum since this header will be included via write barriers.
|
||||
"memory-chunk-header\.h": [
|
||||
"-src",
|
||||
"+src/base/build_config.h",
|
||||
"+src/flags/flags.h",
|
||||
],
|
||||
"script\.h": [
|
||||
"+src/heap/factory.h",
|
||||
"+src/heap/factory-base.h",
|
||||
|
4
deps/v8/src/api/api-inl.h
vendored
4
deps/v8/src/api/api-inl.h
vendored
@ -179,7 +179,7 @@ class V8_NODISCARD CallDepthScope {
|
||||
CallDepthScope(i::Isolate* isolate, Local<Context> context)
|
||||
: isolate_(isolate), saved_context_(isolate->context(), isolate_) {
|
||||
isolate_->thread_local_top()->IncrementCallDepth<do_callback>(this);
|
||||
i::Tagged<i::NativeContext> env = *Utils::OpenHandle(*context);
|
||||
i::Tagged<i::NativeContext> env = *Utils::OpenDirectHandle(*context);
|
||||
isolate->set_context(env);
|
||||
|
||||
if (do_callback) isolate_->FireBeforeCallEnteredCallback();
|
||||
@ -304,7 +304,7 @@ bool CopyAndConvertArrayToCppBuffer(Local<Array> src, T* dst,
|
||||
}
|
||||
|
||||
i::DisallowGarbageCollection no_gc;
|
||||
i::Tagged<i::JSArray> obj = *Utils::OpenHandle(*src);
|
||||
i::Tagged<i::JSArray> obj = *Utils::OpenDirectHandle(*src);
|
||||
if (i::Object::IterationHasObservableEffects(obj)) {
|
||||
// The array has a custom iterator.
|
||||
return false;
|
||||
|
157
deps/v8/src/api/api.cc
vendored
157
deps/v8/src/api/api.cc
vendored
@ -24,6 +24,7 @@
|
||||
#include "include/v8-primitive-object.h"
|
||||
#include "include/v8-profiler.h"
|
||||
#include "include/v8-source-location.h"
|
||||
#include "include/v8-template.h"
|
||||
#include "include/v8-unwinder-state.h"
|
||||
#include "include/v8-util.h"
|
||||
#include "include/v8-wasm.h"
|
||||
@ -86,6 +87,7 @@
|
||||
#include "src/objects/js-array-buffer-inl.h"
|
||||
#include "src/objects/js-array-inl.h"
|
||||
#include "src/objects/js-collection-inl.h"
|
||||
#include "src/objects/js-objects.h"
|
||||
#include "src/objects/js-promise-inl.h"
|
||||
#include "src/objects/js-regexp-inl.h"
|
||||
#include "src/objects/js-weak-refs-inl.h"
|
||||
@ -101,6 +103,7 @@
|
||||
#include "src/objects/shared-function-info.h"
|
||||
#include "src/objects/slots.h"
|
||||
#include "src/objects/smi.h"
|
||||
#include "src/objects/string.h"
|
||||
#include "src/objects/synthetic-module-inl.h"
|
||||
#include "src/objects/templates.h"
|
||||
#include "src/objects/value-serializer.h"
|
||||
@ -537,7 +540,7 @@ SnapshotCreator::SnapshotCreator(Isolate* v8_isolate,
|
||||
const intptr_t* external_references,
|
||||
const StartupData* existing_snapshot,
|
||||
bool owns_isolate)
|
||||
: data_(new i::SnapshotCreatorImpl(
|
||||
: impl_(new i::SnapshotCreatorImpl(
|
||||
reinterpret_cast<i::Isolate*>(v8_isolate), external_references,
|
||||
existing_snapshot, owns_isolate)) {}
|
||||
|
||||
@ -546,50 +549,43 @@ SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
|
||||
: SnapshotCreator(nullptr, external_references, existing_snapshot) {}
|
||||
|
||||
SnapshotCreator::SnapshotCreator(const v8::Isolate::CreateParams& params)
|
||||
: data_(new i::SnapshotCreatorImpl(params)) {}
|
||||
: impl_(new i::SnapshotCreatorImpl(params)) {}
|
||||
|
||||
SnapshotCreator::SnapshotCreator(v8::Isolate* isolate,
|
||||
const v8::Isolate::CreateParams& params)
|
||||
: data_(new i::SnapshotCreatorImpl(reinterpret_cast<i::Isolate*>(isolate),
|
||||
: impl_(new i::SnapshotCreatorImpl(reinterpret_cast<i::Isolate*>(isolate),
|
||||
params)) {}
|
||||
|
||||
SnapshotCreator::~SnapshotCreator() {
|
||||
DCHECK_NOT_NULL(data_);
|
||||
auto impl = static_cast<i::SnapshotCreatorImpl*>(data_);
|
||||
delete impl;
|
||||
DCHECK_NOT_NULL(impl_);
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
Isolate* SnapshotCreator::GetIsolate() {
|
||||
auto impl = static_cast<i::SnapshotCreatorImpl*>(data_);
|
||||
return reinterpret_cast<v8::Isolate*>(impl->isolate());
|
||||
return reinterpret_cast<v8::Isolate*>(impl_->isolate());
|
||||
}
|
||||
|
||||
void SnapshotCreator::SetDefaultContext(
|
||||
Local<Context> context, SerializeInternalFieldsCallback callback) {
|
||||
auto impl = static_cast<i::SnapshotCreatorImpl*>(data_);
|
||||
impl->SetDefaultContext(Utils::OpenHandle(*context), callback);
|
||||
impl_->SetDefaultContext(Utils::OpenHandle(*context), callback);
|
||||
}
|
||||
|
||||
size_t SnapshotCreator::AddContext(Local<Context> context,
|
||||
SerializeInternalFieldsCallback callback) {
|
||||
auto impl = static_cast<i::SnapshotCreatorImpl*>(data_);
|
||||
return impl->AddContext(Utils::OpenHandle(*context), callback);
|
||||
return impl_->AddContext(Utils::OpenHandle(*context), callback);
|
||||
}
|
||||
|
||||
size_t SnapshotCreator::AddData(i::Address object) {
|
||||
auto impl = static_cast<i::SnapshotCreatorImpl*>(data_);
|
||||
return impl->AddData(object);
|
||||
return impl_->AddData(object);
|
||||
}
|
||||
|
||||
size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
|
||||
auto impl = static_cast<i::SnapshotCreatorImpl*>(data_);
|
||||
return impl->AddData(Utils::OpenHandle(*context), object);
|
||||
return impl_->AddData(Utils::OpenHandle(*context), object);
|
||||
}
|
||||
|
||||
StartupData SnapshotCreator::CreateBlob(
|
||||
SnapshotCreator::FunctionCodeHandling function_code_handling) {
|
||||
auto impl = static_cast<i::SnapshotCreatorImpl*>(data_);
|
||||
return impl->CreateBlob(function_code_handling);
|
||||
return impl_->CreateBlob(function_code_handling);
|
||||
}
|
||||
|
||||
bool StartupData::CanBeRehashed() const {
|
||||
@ -1949,6 +1945,24 @@ void ObjectTemplate::SetCodeLike() {
|
||||
self->set_code_like(true);
|
||||
}
|
||||
|
||||
Local<DictionaryTemplate> DictionaryTemplate::New(
|
||||
Isolate* isolate, MemorySpan<const std::string_view> names) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
API_RCS_SCOPE(i_isolate, DictionaryTemplate, New);
|
||||
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
|
||||
return Utils::ToLocal(i::DictionaryTemplateInfo::Create(i_isolate, names));
|
||||
}
|
||||
|
||||
Local<Object> DictionaryTemplate::NewInstance(
|
||||
Local<Context> context, MemorySpan<MaybeLocal<Value>> property_values) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
|
||||
API_RCS_SCOPE(i_isolate, DictionaryTemplate, NewInstance);
|
||||
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
|
||||
auto self = Utils::OpenDirectHandle(this);
|
||||
return ToApiHandle<Object>(i::DictionaryTemplateInfo::NewInstance(
|
||||
Utils::OpenHandle(*context), self, property_values));
|
||||
}
|
||||
|
||||
// --- S c r i p t s ---
|
||||
|
||||
// Internally, UnboundScript and UnboundModuleScript are SharedFunctionInfos,
|
||||
@ -2294,11 +2308,11 @@ int ModuleRequest::GetSourceOffset() const {
|
||||
return Utils::OpenDirectHandle(this)->position();
|
||||
}
|
||||
|
||||
Local<FixedArray> ModuleRequest::GetImportAssertions() const {
|
||||
Local<FixedArray> ModuleRequest::GetImportAttributes() const {
|
||||
auto self = Utils::OpenDirectHandle(this);
|
||||
i::Isolate* i_isolate = self->GetIsolate();
|
||||
return ToApiHandle<FixedArray>(
|
||||
i::direct_handle(self->import_assertions(), i_isolate), i_isolate);
|
||||
i::direct_handle(self->import_attributes(), i_isolate), i_isolate);
|
||||
}
|
||||
|
||||
Module::Status Module::GetStatus() const {
|
||||
@ -3866,7 +3880,7 @@ bool Value::IsInt32() const {
|
||||
}
|
||||
|
||||
bool Value::IsUint32() const {
|
||||
auto obj = *Utils::OpenHandle(this);
|
||||
auto obj = *Utils::OpenDirectHandle(this);
|
||||
if (i::IsSmi(obj)) return i::Smi::ToInt(obj) >= 0;
|
||||
if (i::IsNumber(obj)) {
|
||||
double value = i::Object::Number(obj);
|
||||
@ -4271,6 +4285,10 @@ void* v8::ArrayBuffer::Data() const {
|
||||
return Utils::OpenDirectHandle(this)->backing_store();
|
||||
}
|
||||
|
||||
bool v8::ArrayBuffer::IsResizableByUserJavaScript() const {
|
||||
return Utils::OpenDirectHandle(this)->is_resizable_by_js();
|
||||
}
|
||||
|
||||
std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() {
|
||||
auto self = Utils::OpenDirectHandle(this);
|
||||
std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
|
||||
@ -4306,7 +4324,7 @@ void v8::TypedArray::CheckCast(Value* that) {
|
||||
|
||||
#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype) \
|
||||
void v8::Type##Array::CheckCast(Value* that) { \
|
||||
auto obj = *Utils::OpenHandle(that); \
|
||||
auto obj = *Utils::OpenDirectHandle(that); \
|
||||
Utils::ApiCheck( \
|
||||
i::IsJSTypedArray(obj) && \
|
||||
i::JSTypedArray::cast(obj)->type() == i::kExternal##Type##Array, \
|
||||
@ -5359,6 +5377,30 @@ bool v8::Object::IsUndetectable() const {
|
||||
return i::IsUndetectable(*self);
|
||||
}
|
||||
|
||||
namespace {
|
||||
#ifdef V8_ENABLE_DIRECT_LOCAL
|
||||
// A newly allocated vector is required to convert from an array of direct
|
||||
// locals to an array of indirect handles.
|
||||
std::vector<i::Handle<i::Object>> PrepareArguments(int argc,
|
||||
Local<Value> argv[]) {
|
||||
std::vector<i::Handle<i::Object>> args(argc);
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
args[i] = Utils::OpenHandle(*argv[i]);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
#else // !V8_ENABLE_DIRECT_LOCAL
|
||||
// A simple cast is used to convert from an array of indirect locals to an
|
||||
// array of indirect handles. A MemorySpan object is returned, as no
|
||||
// deallocation is necessary.
|
||||
v8::MemorySpan<i::Handle<i::Object>> PrepareArguments(int argc,
|
||||
Local<Value> argv[]) {
|
||||
return {reinterpret_cast<i::Handle<i::Object>*>(argv),
|
||||
static_cast<size_t>(argc)};
|
||||
}
|
||||
#endif // V8_ENABLE_DIRECT_LOCAL
|
||||
} // namespace
|
||||
|
||||
MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
|
||||
Local<Value> recv, int argc,
|
||||
Local<Value> argv[]) {
|
||||
@ -5371,10 +5413,11 @@ MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
|
||||
auto self = Utils::OpenHandle(this);
|
||||
auto recv_obj = Utils::OpenHandle(*recv);
|
||||
static_assert(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
|
||||
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
|
||||
auto args = PrepareArguments(argc, argv);
|
||||
Local<Value> result;
|
||||
has_exception = !ToLocal<Value>(
|
||||
i::Execution::Call(i_isolate, self, recv_obj, argc, args), &result);
|
||||
i::Execution::Call(i_isolate, self, recv_obj, argc, args.data()),
|
||||
&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Value);
|
||||
RETURN_ESCAPED(result);
|
||||
}
|
||||
@ -5390,10 +5433,10 @@ MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
|
||||
i_isolate);
|
||||
auto self = Utils::OpenHandle(this);
|
||||
static_assert(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
|
||||
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
|
||||
auto args = PrepareArguments(argc, argv);
|
||||
Local<Value> result;
|
||||
has_exception = !ToLocal<Value>(
|
||||
i::Execution::New(i_isolate, self, self, argc, args), &result);
|
||||
i::Execution::New(i_isolate, self, self, argc, args.data()), &result);
|
||||
RETURN_ON_FAILED_EXECUTION(Value);
|
||||
RETURN_ESCAPED(result);
|
||||
}
|
||||
@ -5446,10 +5489,10 @@ MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
|
||||
}
|
||||
}
|
||||
}
|
||||
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
|
||||
auto args = PrepareArguments(argc, argv);
|
||||
Local<Object> result;
|
||||
has_exception = !ToLocal<Object>(
|
||||
i::Execution::New(i_isolate, self, self, argc, args), &result);
|
||||
i::Execution::New(i_isolate, self, self, argc, args.data()), &result);
|
||||
RETURN_ON_FAILED_EXECUTION(Object);
|
||||
RETURN_ESCAPED(result);
|
||||
}
|
||||
@ -5468,19 +5511,11 @@ MaybeLocal<v8::Value> Function::Call(Local<Context> context,
|
||||
"Function to be called is a null pointer");
|
||||
auto recv_obj = Utils::OpenHandle(*recv);
|
||||
static_assert(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
|
||||
|
||||
#ifdef V8_ENABLE_DIRECT_LOCAL
|
||||
i::Handle<i::Object>* args = new i::Handle<i::Object>[argc];
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
args[i] = Utils::OpenHandle(*argv[i]);
|
||||
}
|
||||
#else // !V8_ENABLE_DIRECT_LOCAL
|
||||
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
|
||||
#endif // V8_ENABLE_DIRECT_LOCAL
|
||||
|
||||
auto args = PrepareArguments(argc, argv);
|
||||
Local<Value> result;
|
||||
has_exception = !ToLocal<Value>(
|
||||
i::Execution::Call(i_isolate, self, recv_obj, argc, args), &result);
|
||||
i::Execution::Call(i_isolate, self, recv_obj, argc, args.data()),
|
||||
&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Value);
|
||||
RETURN_ESCAPED(result);
|
||||
}
|
||||
@ -7328,6 +7363,13 @@ void v8::ObjectTemplate::CheckCast(Data* that) {
|
||||
"Value is not an ObjectTemplate");
|
||||
}
|
||||
|
||||
void v8::DictionaryTemplate::CheckCast(Data* that) {
|
||||
auto obj = Utils::OpenDirectHandle(that);
|
||||
Utils::ApiCheck(i::IsDictionaryTemplateInfo(*obj),
|
||||
"v8::DictionaryTemplate::Cast",
|
||||
"Value is not an DictionaryTemplate");
|
||||
}
|
||||
|
||||
void v8::FunctionTemplate::CheckCast(Data* that) {
|
||||
auto obj = Utils::OpenDirectHandle(that);
|
||||
Utils::ApiCheck(i::IsFunctionTemplateInfo(*obj), "v8::FunctionTemplate::Cast",
|
||||
@ -8087,7 +8129,7 @@ uint32_t GetLength(Tagged<JSArray> array) {
|
||||
} // namespace internal
|
||||
|
||||
uint32_t v8::Array::Length() const {
|
||||
return i::GetLength(*Utils::OpenHandle(this));
|
||||
return i::GetLength(*Utils::OpenDirectHandle(this));
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
@ -8259,13 +8301,27 @@ Maybe<void> v8::Array::Iterate(Local<Context> context,
|
||||
}
|
||||
|
||||
v8::TypecheckWitness::TypecheckWitness(Isolate* isolate)
|
||||
#ifdef V8_ENABLE_DIRECT_LOCAL
|
||||
// An empty local suffices.
|
||||
: cached_map_()
|
||||
#else
|
||||
// We need to reserve a handle that we can patch later.
|
||||
// TODO(13270): When we switch to CSS, we can use a direct pointer
|
||||
// instead of a handle.
|
||||
: cached_map_(v8::Number::New(isolate, 1)) {}
|
||||
// We initialize it with something that cannot compare equal to any map.
|
||||
: cached_map_(v8::Number::New(isolate, 1))
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
void v8::TypecheckWitness::Update(Local<Value> baseline) {
|
||||
i::Tagged<i::Object> obj = *Utils::OpenDirectHandle(*baseline);
|
||||
#ifdef V8_ENABLE_DIRECT_LOCAL
|
||||
if (IsSmi(obj)) {
|
||||
cached_map_ = Local<Data>();
|
||||
} else {
|
||||
i::Tagged<i::HeapObject> map = i::HeapObject::cast(obj)->map();
|
||||
cached_map_ = Local<Data>::FromAddress(map->ptr());
|
||||
}
|
||||
#else
|
||||
i::Tagged<i::Object> map = i::Smi::zero();
|
||||
if (!IsSmi(obj)) map = i::HeapObject::cast(obj)->map();
|
||||
// Design overview: in the {TypecheckWitness} constructor, we create
|
||||
@ -8274,12 +8330,12 @@ void v8::TypecheckWitness::Update(Local<Value> baseline) {
|
||||
// to allow having short-lived HandleScopes (e.g. in {FastIterateArray}
|
||||
// above) while a {TypecheckWitness} is alive: it therefore cannot hold
|
||||
// on to one of the short-lived handles.
|
||||
// Calling {OpenHandle} on the {cached_map_} only serves to "reinterpret_cast"
|
||||
// it to an {i::Handle} on which we can call {PatchValue}.
|
||||
// TODO(13270): When we switch to CSS, this can become simpler: we can
|
||||
// then simply overwrite the direct pointer.
|
||||
// Calling {OpenIndirectHandle} on the {cached_map_} only serves to
|
||||
// "reinterpret_cast" it to an {i::IndirectHandle} on which we can call
|
||||
// {PatchValue}.
|
||||
auto cache = Utils::OpenIndirectHandle(*cached_map_);
|
||||
cache.PatchValue(map);
|
||||
#endif
|
||||
}
|
||||
|
||||
Local<v8::Map> v8::Map::New(Isolate* v8_isolate) {
|
||||
@ -10384,13 +10440,13 @@ CALLBACK_SETTER(WasmAsyncResolvePromiseCallback,
|
||||
CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
|
||||
wasm_load_source_map_callback)
|
||||
|
||||
CALLBACK_SETTER(WasmGCEnabledCallback, WasmGCEnabledCallback,
|
||||
wasm_gc_enabled_callback)
|
||||
|
||||
CALLBACK_SETTER(WasmImportedStringsEnabledCallback,
|
||||
WasmImportedStringsEnabledCallback,
|
||||
wasm_imported_strings_enabled_callback)
|
||||
|
||||
CALLBACK_SETTER(WasmJSPIEnabledCallback, WasmJSPIEnabledCallback,
|
||||
wasm_jspi_enabled_callback)
|
||||
|
||||
CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
|
||||
SharedArrayBufferConstructorEnabledCallback,
|
||||
sharedarraybuffer_constructor_enabled_callback)
|
||||
@ -10410,6 +10466,7 @@ void Isolate::InstallConditionalFeatures(Local<Context> context) {
|
||||
i::WasmJs::InstallConditionalFeatures(i_isolate,
|
||||
Utils::OpenHandle(*context));
|
||||
}
|
||||
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
}
|
||||
|
||||
|
181
deps/v8/src/api/api.h
vendored
181
deps/v8/src/api/api.h
vendored
@ -30,6 +30,7 @@
|
||||
|
||||
namespace v8 {
|
||||
|
||||
class DictionaryTemplate;
|
||||
class Extension;
|
||||
class Signature;
|
||||
class Template;
|
||||
@ -96,97 +97,99 @@ class RegisteredExtension {
|
||||
static RegisteredExtension* first_extension_;
|
||||
};
|
||||
|
||||
#define TO_LOCAL_LIST(V) \
|
||||
V(ToLocal, AccessorPair, debug::AccessorPair) \
|
||||
V(ToLocal, NativeContext, Context) \
|
||||
V(ToLocal, Object, Value) \
|
||||
V(ToLocal, Module, Module) \
|
||||
V(ToLocal, Name, Name) \
|
||||
V(ToLocal, String, String) \
|
||||
V(ToLocal, Symbol, Symbol) \
|
||||
V(ToLocal, JSRegExp, RegExp) \
|
||||
V(ToLocal, JSReceiver, Object) \
|
||||
V(ToLocal, JSObject, Object) \
|
||||
V(ToLocal, JSFunction, Function) \
|
||||
V(ToLocal, JSArray, Array) \
|
||||
V(ToLocal, JSMap, Map) \
|
||||
V(ToLocal, JSSet, Set) \
|
||||
V(ToLocal, JSProxy, Proxy) \
|
||||
V(ToLocal, JSArrayBuffer, ArrayBuffer) \
|
||||
V(ToLocal, JSArrayBufferView, ArrayBufferView) \
|
||||
V(ToLocal, JSDataView, DataView) \
|
||||
V(ToLocal, JSRabGsabDataView, DataView) \
|
||||
V(ToLocal, JSTypedArray, TypedArray) \
|
||||
V(ToLocalShared, JSArrayBuffer, SharedArrayBuffer) \
|
||||
V(ToLocal, FunctionTemplateInfo, FunctionTemplate) \
|
||||
V(ToLocal, ObjectTemplateInfo, ObjectTemplate) \
|
||||
V(SignatureToLocal, FunctionTemplateInfo, Signature) \
|
||||
V(MessageToLocal, Object, Message) \
|
||||
V(PromiseToLocal, JSObject, Promise) \
|
||||
V(StackTraceToLocal, FixedArray, StackTrace) \
|
||||
V(StackFrameToLocal, StackFrameInfo, StackFrame) \
|
||||
V(NumberToLocal, Object, Number) \
|
||||
V(IntegerToLocal, Object, Integer) \
|
||||
V(Uint32ToLocal, Object, Uint32) \
|
||||
V(ToLocal, BigInt, BigInt) \
|
||||
V(ExternalToLocal, JSObject, External) \
|
||||
V(CallableToLocal, JSReceiver, Function) \
|
||||
V(ToLocalPrimitive, Object, Primitive) \
|
||||
V(FixedArrayToLocal, FixedArray, FixedArray) \
|
||||
V(PrimitiveArrayToLocal, FixedArray, PrimitiveArray) \
|
||||
#define TO_LOCAL_LIST(V) \
|
||||
V(ToLocal, AccessorPair, debug::AccessorPair) \
|
||||
V(ToLocal, NativeContext, Context) \
|
||||
V(ToLocal, Object, Value) \
|
||||
V(ToLocal, Module, Module) \
|
||||
V(ToLocal, Name, Name) \
|
||||
V(ToLocal, String, String) \
|
||||
V(ToLocal, Symbol, Symbol) \
|
||||
V(ToLocal, JSRegExp, RegExp) \
|
||||
V(ToLocal, JSReceiver, Object) \
|
||||
V(ToLocal, JSObject, Object) \
|
||||
V(ToLocal, JSFunction, Function) \
|
||||
V(ToLocal, JSArray, Array) \
|
||||
V(ToLocal, JSMap, Map) \
|
||||
V(ToLocal, JSSet, Set) \
|
||||
V(ToLocal, JSProxy, Proxy) \
|
||||
V(ToLocal, JSArrayBuffer, ArrayBuffer) \
|
||||
V(ToLocal, JSArrayBufferView, ArrayBufferView) \
|
||||
V(ToLocal, JSDataView, DataView) \
|
||||
V(ToLocal, JSRabGsabDataView, DataView) \
|
||||
V(ToLocal, JSTypedArray, TypedArray) \
|
||||
V(ToLocalShared, JSArrayBuffer, SharedArrayBuffer) \
|
||||
V(ToLocal, FunctionTemplateInfo, FunctionTemplate) \
|
||||
V(ToLocal, ObjectTemplateInfo, ObjectTemplate) \
|
||||
V(ToLocal, DictionaryTemplateInfo, DictionaryTemplate) \
|
||||
V(SignatureToLocal, FunctionTemplateInfo, Signature) \
|
||||
V(MessageToLocal, Object, Message) \
|
||||
V(PromiseToLocal, JSObject, Promise) \
|
||||
V(StackTraceToLocal, FixedArray, StackTrace) \
|
||||
V(StackFrameToLocal, StackFrameInfo, StackFrame) \
|
||||
V(NumberToLocal, Object, Number) \
|
||||
V(IntegerToLocal, Object, Integer) \
|
||||
V(Uint32ToLocal, Object, Uint32) \
|
||||
V(ToLocal, BigInt, BigInt) \
|
||||
V(ExternalToLocal, JSObject, External) \
|
||||
V(CallableToLocal, JSReceiver, Function) \
|
||||
V(ToLocalPrimitive, Object, Primitive) \
|
||||
V(FixedArrayToLocal, FixedArray, FixedArray) \
|
||||
V(PrimitiveArrayToLocal, FixedArray, PrimitiveArray) \
|
||||
V(ToLocal, ScriptOrModule, ScriptOrModule)
|
||||
|
||||
#define OPEN_HANDLE_LIST(V) \
|
||||
V(Template, TemplateInfo) \
|
||||
V(FunctionTemplate, FunctionTemplateInfo) \
|
||||
V(ObjectTemplate, ObjectTemplateInfo) \
|
||||
V(Signature, FunctionTemplateInfo) \
|
||||
V(Data, Object) \
|
||||
V(RegExp, JSRegExp) \
|
||||
V(Object, JSReceiver) \
|
||||
V(Array, JSArray) \
|
||||
V(Map, JSMap) \
|
||||
V(Set, JSSet) \
|
||||
V(ArrayBuffer, JSArrayBuffer) \
|
||||
V(ArrayBufferView, JSArrayBufferView) \
|
||||
V(TypedArray, JSTypedArray) \
|
||||
V(Uint8Array, JSTypedArray) \
|
||||
V(Uint8ClampedArray, JSTypedArray) \
|
||||
V(Int8Array, JSTypedArray) \
|
||||
V(Uint16Array, JSTypedArray) \
|
||||
V(Int16Array, JSTypedArray) \
|
||||
V(Uint32Array, JSTypedArray) \
|
||||
V(Int32Array, JSTypedArray) \
|
||||
V(Float32Array, JSTypedArray) \
|
||||
V(Float64Array, JSTypedArray) \
|
||||
V(DataView, JSDataViewOrRabGsabDataView) \
|
||||
V(SharedArrayBuffer, JSArrayBuffer) \
|
||||
V(Name, Name) \
|
||||
V(String, String) \
|
||||
V(Symbol, Symbol) \
|
||||
V(Script, JSFunction) \
|
||||
V(UnboundModuleScript, SharedFunctionInfo) \
|
||||
V(UnboundScript, SharedFunctionInfo) \
|
||||
V(Module, Module) \
|
||||
V(Function, JSReceiver) \
|
||||
V(Message, JSMessageObject) \
|
||||
V(Context, NativeContext) \
|
||||
V(External, Object) \
|
||||
V(StackTrace, FixedArray) \
|
||||
V(StackFrame, StackFrameInfo) \
|
||||
V(Proxy, JSProxy) \
|
||||
V(debug::GeneratorObject, JSGeneratorObject) \
|
||||
V(debug::ScriptSource, HeapObject) \
|
||||
V(debug::Script, Script) \
|
||||
V(debug::EphemeronTable, EphemeronHashTable) \
|
||||
V(debug::AccessorPair, AccessorPair) \
|
||||
V(Promise, JSPromise) \
|
||||
V(Primitive, Object) \
|
||||
V(PrimitiveArray, FixedArray) \
|
||||
V(BigInt, BigInt) \
|
||||
V(ScriptOrModule, ScriptOrModule) \
|
||||
V(FixedArray, FixedArray) \
|
||||
V(ModuleRequest, ModuleRequest) \
|
||||
#define OPEN_HANDLE_LIST(V) \
|
||||
V(Template, TemplateInfo) \
|
||||
V(FunctionTemplate, FunctionTemplateInfo) \
|
||||
V(ObjectTemplate, ObjectTemplateInfo) \
|
||||
V(DictionaryTemplate, DictionaryTemplateInfo) \
|
||||
V(Signature, FunctionTemplateInfo) \
|
||||
V(Data, Object) \
|
||||
V(RegExp, JSRegExp) \
|
||||
V(Object, JSReceiver) \
|
||||
V(Array, JSArray) \
|
||||
V(Map, JSMap) \
|
||||
V(Set, JSSet) \
|
||||
V(ArrayBuffer, JSArrayBuffer) \
|
||||
V(ArrayBufferView, JSArrayBufferView) \
|
||||
V(TypedArray, JSTypedArray) \
|
||||
V(Uint8Array, JSTypedArray) \
|
||||
V(Uint8ClampedArray, JSTypedArray) \
|
||||
V(Int8Array, JSTypedArray) \
|
||||
V(Uint16Array, JSTypedArray) \
|
||||
V(Int16Array, JSTypedArray) \
|
||||
V(Uint32Array, JSTypedArray) \
|
||||
V(Int32Array, JSTypedArray) \
|
||||
V(Float32Array, JSTypedArray) \
|
||||
V(Float64Array, JSTypedArray) \
|
||||
V(DataView, JSDataViewOrRabGsabDataView) \
|
||||
V(SharedArrayBuffer, JSArrayBuffer) \
|
||||
V(Name, Name) \
|
||||
V(String, String) \
|
||||
V(Symbol, Symbol) \
|
||||
V(Script, JSFunction) \
|
||||
V(UnboundModuleScript, SharedFunctionInfo) \
|
||||
V(UnboundScript, SharedFunctionInfo) \
|
||||
V(Module, Module) \
|
||||
V(Function, JSReceiver) \
|
||||
V(Message, JSMessageObject) \
|
||||
V(Context, NativeContext) \
|
||||
V(External, Object) \
|
||||
V(StackTrace, FixedArray) \
|
||||
V(StackFrame, StackFrameInfo) \
|
||||
V(Proxy, JSProxy) \
|
||||
V(debug::GeneratorObject, JSGeneratorObject) \
|
||||
V(debug::ScriptSource, HeapObject) \
|
||||
V(debug::Script, Script) \
|
||||
V(debug::EphemeronTable, EphemeronHashTable) \
|
||||
V(debug::AccessorPair, AccessorPair) \
|
||||
V(Promise, JSPromise) \
|
||||
V(Primitive, Object) \
|
||||
V(PrimitiveArray, FixedArray) \
|
||||
V(BigInt, BigInt) \
|
||||
V(ScriptOrModule, ScriptOrModule) \
|
||||
V(FixedArray, FixedArray) \
|
||||
V(ModuleRequest, ModuleRequest) \
|
||||
IF_WASM(V, WasmMemoryObject, WasmMemoryObject)
|
||||
|
||||
class Utils {
|
||||
|
34
deps/v8/src/ast/ast-source-ranges.h
vendored
34
deps/v8/src/ast/ast-source-ranges.h
vendored
@ -46,6 +46,7 @@ struct SourceRange {
|
||||
V(BinaryOperation) \
|
||||
V(Block) \
|
||||
V(CaseClause) \
|
||||
V(ConditionalChain) \
|
||||
V(Conditional) \
|
||||
V(Expression) \
|
||||
V(FunctionLiteral) \
|
||||
@ -142,6 +143,39 @@ class CaseClauseSourceRanges final : public AstNodeSourceRanges {
|
||||
SourceRange body_range_;
|
||||
};
|
||||
|
||||
class ConditionalChainSourceRanges final : public AstNodeSourceRanges {
|
||||
public:
|
||||
explicit ConditionalChainSourceRanges(Zone* zone)
|
||||
: then_ranges_(zone), else_ranges_(zone) {}
|
||||
|
||||
SourceRange GetRangeAtIndex(SourceRangeKind kind, size_t index) {
|
||||
if (kind == SourceRangeKind::kThen) {
|
||||
DCHECK_LT(index, then_ranges_.size());
|
||||
return then_ranges_[index];
|
||||
}
|
||||
DCHECK_EQ(kind, SourceRangeKind::kElse);
|
||||
DCHECK_LT(index, else_ranges_.size());
|
||||
return else_ranges_[index];
|
||||
}
|
||||
|
||||
void AddThenRanges(const SourceRange& range) {
|
||||
then_ranges_.push_back(range);
|
||||
}
|
||||
|
||||
void AddElseRange(const SourceRange& else_range) {
|
||||
else_ranges_.push_back(else_range);
|
||||
}
|
||||
|
||||
size_t RangeCount() const { return then_ranges_.size(); }
|
||||
|
||||
SourceRange GetRange(SourceRangeKind kind) override { UNREACHABLE(); }
|
||||
bool HasRange(SourceRangeKind kind) override { return false; }
|
||||
|
||||
private:
|
||||
ZoneVector<SourceRange> then_ranges_;
|
||||
ZoneVector<SourceRange> else_ranges_;
|
||||
};
|
||||
|
||||
class ConditionalSourceRanges final : public AstNodeSourceRanges {
|
||||
public:
|
||||
explicit ConditionalSourceRanges(const SourceRange& then_range,
|
||||
|
15
deps/v8/src/ast/ast-traversal-visitor.h
vendored
15
deps/v8/src/ast/ast-traversal-visitor.h
vendored
@ -295,6 +295,17 @@ void AstTraversalVisitor<Subclass>::VisitNativeFunctionLiteral(
|
||||
PROCESS_EXPRESSION(expr);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitConditionalChain(
|
||||
ConditionalChain* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
for (size_t i = 0; i < expr->conditional_chain_length(); ++i) {
|
||||
RECURSE_EXPRESSION(Visit(expr->condition_at(i)));
|
||||
RECURSE_EXPRESSION(Visit(expr->then_expression_at(i)));
|
||||
}
|
||||
RECURSE(Visit(expr->else_expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitConditional(Conditional* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
@ -561,8 +572,8 @@ void AstTraversalVisitor<Subclass>::VisitImportCallExpression(
|
||||
ImportCallExpression* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->specifier()));
|
||||
if (expr->import_assertions()) {
|
||||
RECURSE_EXPRESSION(Visit(expr->import_assertions()));
|
||||
if (expr->import_options()) {
|
||||
RECURSE_EXPRESSION(Visit(expr->import_options()));
|
||||
}
|
||||
}
|
||||
|
||||
|
2
deps/v8/src/ast/ast-value-factory.cc
vendored
2
deps/v8/src/ast/ast-value-factory.cc
vendored
@ -60,7 +60,7 @@ class OneByteStringStream {
|
||||
template <typename IsolateT>
|
||||
void AstRawString::Internalize(IsolateT* isolate) {
|
||||
DCHECK(!has_string_);
|
||||
if (literal_bytes_.length() == 0) {
|
||||
if (literal_bytes_.empty()) {
|
||||
set_string(isolate->factory()->empty_string());
|
||||
} else if (is_one_byte()) {
|
||||
OneByteStringKey key(raw_hash_field_, literal_bytes_);
|
||||
|
31
deps/v8/src/ast/ast.cc
vendored
31
deps/v8/src/ast/ast.cc
vendored
@ -847,8 +847,8 @@ template EXPORT_TEMPLATE_DEFINE(V8_BASE_EXPORT)
|
||||
|
||||
static bool IsCommutativeOperationWithSmiLiteral(Token::Value op) {
|
||||
// Add is not commutative due to potential for string addition.
|
||||
return op == Token::MUL || op == Token::BIT_AND || op == Token::BIT_OR ||
|
||||
op == Token::BIT_XOR;
|
||||
return op == Token::kMul || op == Token::kBitAnd || op == Token::kBitOr ||
|
||||
op == Token::kBitXor;
|
||||
}
|
||||
|
||||
// Check for the pattern: x + 1.
|
||||
@ -869,32 +869,9 @@ bool BinaryOperation::IsSmiLiteralOperation(Expression** subexpr,
|
||||
MatchSmiLiteralOperation(right_, left_, subexpr, literal));
|
||||
}
|
||||
|
||||
static bool IsTypeof(Expression* expr) {
|
||||
UnaryOperation* maybe_unary = expr->AsUnaryOperation();
|
||||
return maybe_unary != nullptr && maybe_unary->op() == Token::TYPEOF;
|
||||
}
|
||||
|
||||
// Check for the pattern: typeof <expression> equals <string literal>.
|
||||
static bool MatchLiteralCompareTypeof(Expression* left, Token::Value op,
|
||||
Expression* right, Expression** expr,
|
||||
Literal** literal) {
|
||||
if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
|
||||
*expr = left->AsUnaryOperation()->expression();
|
||||
*literal = right->AsLiteral();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
|
||||
Literal** literal) {
|
||||
return MatchLiteralCompareTypeof(left_, op(), right_, expr, literal) ||
|
||||
MatchLiteralCompareTypeof(right_, op(), left_, expr, literal);
|
||||
}
|
||||
|
||||
static bool IsVoidOfLiteral(Expression* expr) {
|
||||
UnaryOperation* maybe_unary = expr->AsUnaryOperation();
|
||||
return maybe_unary != nullptr && maybe_unary->op() == Token::VOID &&
|
||||
return maybe_unary != nullptr && maybe_unary->op() == Token::kVoid &&
|
||||
maybe_unary->expression()->IsLiteral();
|
||||
}
|
||||
|
||||
@ -902,7 +879,7 @@ static bool MatchLiteralStrictCompareBoolean(Expression* left, Token::Value op,
|
||||
Expression* right,
|
||||
Expression** expr,
|
||||
Literal** literal) {
|
||||
if (left->IsBooleanLiteral() && op == Token::EQ_STRICT) {
|
||||
if (left->IsBooleanLiteral() && op == Token::kEqStrict) {
|
||||
*expr = right;
|
||||
*literal = left->AsLiteral();
|
||||
return true;
|
||||
|
97
deps/v8/src/ast/ast.h
vendored
97
deps/v8/src/ast/ast.h
vendored
@ -91,6 +91,7 @@ namespace internal {
|
||||
V(ClassLiteral) \
|
||||
V(CompareOperation) \
|
||||
V(CompoundAssignment) \
|
||||
V(ConditionalChain) \
|
||||
V(Conditional) \
|
||||
V(CountOperation) \
|
||||
V(EmptyParentheses) \
|
||||
@ -1938,7 +1939,7 @@ class NaryOperation final : public Expression {
|
||||
subsequent_(zone) {
|
||||
bit_field_ |= OperatorField::encode(op);
|
||||
DCHECK(Token::IsBinaryOp(op));
|
||||
DCHECK_NE(op, Token::EXP);
|
||||
DCHECK_NE(op, Token::kExp);
|
||||
subsequent_.reserve(initial_subsequent_size);
|
||||
}
|
||||
|
||||
@ -2002,7 +2003,6 @@ class CompareOperation final : public Expression {
|
||||
Expression* right() const { return right_; }
|
||||
|
||||
// Match special cases.
|
||||
bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
|
||||
bool IsLiteralStrictCompareBoolean(Expression** expr, Literal** literal);
|
||||
bool IsLiteralCompareUndefined(Expression** expr);
|
||||
bool IsLiteralCompareNull(Expression** expr);
|
||||
@ -2045,6 +2045,77 @@ class Spread final : public Expression {
|
||||
Expression* expression_;
|
||||
};
|
||||
|
||||
class ConditionalChain : public Expression {
|
||||
public:
|
||||
Expression* condition_at(size_t index) const {
|
||||
return conditional_chain_entries_[index].condition;
|
||||
}
|
||||
Expression* then_expression_at(size_t index) const {
|
||||
return conditional_chain_entries_[index].then_expression;
|
||||
}
|
||||
int condition_position_at(size_t index) const {
|
||||
return conditional_chain_entries_[index].condition_position;
|
||||
}
|
||||
size_t conditional_chain_length() const {
|
||||
return conditional_chain_entries_.size();
|
||||
}
|
||||
Expression* else_expression() const { return else_expression_; }
|
||||
void set_else_expression(Expression* s) { else_expression_ = s; }
|
||||
|
||||
void AddChainEntry(Expression* cond, Expression* then, int pos) {
|
||||
conditional_chain_entries_.emplace_back(cond, then, pos);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class AstNodeFactory;
|
||||
friend Zone;
|
||||
|
||||
ConditionalChain(Zone* zone, size_t initial_size, int pos)
|
||||
: Expression(pos, kConditionalChain),
|
||||
conditional_chain_entries_(zone),
|
||||
else_expression_(nullptr) {
|
||||
conditional_chain_entries_.reserve(initial_size);
|
||||
}
|
||||
|
||||
// Conditional Chain Expression stores the conditional chain entries out of
|
||||
// line, along with their operation's position. The else expression is stored
|
||||
// inline. This Expression is reserved for ternary operations that have more
|
||||
// than one conditional chain entry. For ternary operations with only one
|
||||
// conditional chain entry, the Conditional Expression is used instead.
|
||||
//
|
||||
// So an conditional chain:
|
||||
//
|
||||
// cond ? then : cond ? then : cond ? then : else
|
||||
//
|
||||
// is stored as:
|
||||
//
|
||||
// [(cond, then), (cond, then),...] else
|
||||
// '-----------------------------' '----'
|
||||
// conditional chain entries else
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// Expression: v1 == 1 ? "a" : v2 == 2 ? "b" : "c"
|
||||
//
|
||||
// conditionat_chain_entries_: [(v1 == 1, "a", 0), (v2 == 2, "b", 14)]
|
||||
// else_expression_: "c"
|
||||
//
|
||||
// Example of a _not_ expected expression (only one chain entry):
|
||||
//
|
||||
// Expression: v1 == 1 ? "a" : "b"
|
||||
//
|
||||
|
||||
struct ConditionalChainEntry {
|
||||
Expression* condition;
|
||||
Expression* then_expression;
|
||||
int condition_position;
|
||||
ConditionalChainEntry(Expression* cond, Expression* then, int pos)
|
||||
: condition(cond), then_expression(then), condition_position(pos) {}
|
||||
};
|
||||
ZoneVector<ConditionalChainEntry> conditional_chain_entries_;
|
||||
Expression* else_expression_;
|
||||
};
|
||||
|
||||
class Conditional final : public Expression {
|
||||
public:
|
||||
Expression* condition() const { return condition_; }
|
||||
@ -2666,7 +2737,7 @@ class SuperCallReference final : public Expression {
|
||||
class ImportCallExpression final : public Expression {
|
||||
public:
|
||||
Expression* specifier() const { return specifier_; }
|
||||
Expression* import_assertions() const { return import_assertions_; }
|
||||
Expression* import_options() const { return import_options_; }
|
||||
|
||||
private:
|
||||
friend class AstNodeFactory;
|
||||
@ -2675,16 +2746,16 @@ class ImportCallExpression final : public Expression {
|
||||
ImportCallExpression(Expression* specifier, int pos)
|
||||
: Expression(pos, kImportCallExpression),
|
||||
specifier_(specifier),
|
||||
import_assertions_(nullptr) {}
|
||||
import_options_(nullptr) {}
|
||||
|
||||
ImportCallExpression(Expression* specifier, Expression* import_assertions,
|
||||
ImportCallExpression(Expression* specifier, Expression* import_options,
|
||||
int pos)
|
||||
: Expression(pos, kImportCallExpression),
|
||||
specifier_(specifier),
|
||||
import_assertions_(import_assertions) {}
|
||||
import_options_(import_options) {}
|
||||
|
||||
Expression* specifier_;
|
||||
Expression* import_assertions_;
|
||||
Expression* import_options_;
|
||||
};
|
||||
|
||||
// This class is produced when parsing the () in arrow functions without any
|
||||
@ -3216,6 +3287,10 @@ class AstNodeFactory final {
|
||||
return zone_->New<Spread>(expression, pos, expr_pos);
|
||||
}
|
||||
|
||||
ConditionalChain* NewConditionalChain(size_t initial_size, int pos) {
|
||||
return zone_->New<ConditionalChain>(zone_, initial_size, pos);
|
||||
}
|
||||
|
||||
Conditional* NewConditional(Expression* condition,
|
||||
Expression* then_expression,
|
||||
Expression* else_expression,
|
||||
@ -3232,11 +3307,11 @@ class AstNodeFactory final {
|
||||
DCHECK_NOT_NULL(target);
|
||||
DCHECK_NOT_NULL(value);
|
||||
|
||||
if (op != Token::INIT && target->IsVariableProxy()) {
|
||||
if (op != Token::kInit && target->IsVariableProxy()) {
|
||||
target->AsVariableProxy()->set_is_assigned();
|
||||
}
|
||||
|
||||
if (op == Token::ASSIGN || op == Token::INIT) {
|
||||
if (op == Token::kAssign || op == Token::kInit) {
|
||||
return zone_->New<Assignment>(AstNode::kAssignment, op, target, value,
|
||||
pos);
|
||||
} else {
|
||||
@ -3371,9 +3446,9 @@ class AstNodeFactory final {
|
||||
}
|
||||
|
||||
ImportCallExpression* NewImportCallExpression(Expression* specifier,
|
||||
Expression* import_assertions,
|
||||
Expression* import_options,
|
||||
int pos) {
|
||||
return zone_->New<ImportCallExpression>(specifier, import_assertions, pos);
|
||||
return zone_->New<ImportCallExpression>(specifier, import_options, pos);
|
||||
}
|
||||
|
||||
InitializeClassMembersStatement* NewInitializeClassMembersStatement(
|
||||
|
58
deps/v8/src/ast/modules.cc
vendored
58
deps/v8/src/ast/modules.cc
vendored
@ -27,10 +27,10 @@ bool SourceTextModuleDescriptor::ModuleRequestComparer::operator()(
|
||||
return specifier_comparison < 0;
|
||||
}
|
||||
|
||||
auto lhsIt = lhs->import_assertions()->cbegin();
|
||||
auto rhsIt = rhs->import_assertions()->cbegin();
|
||||
for (; lhsIt != lhs->import_assertions()->cend() &&
|
||||
rhsIt != rhs->import_assertions()->cend();
|
||||
auto lhsIt = lhs->import_attributes()->cbegin();
|
||||
auto rhsIt = rhs->import_attributes()->cbegin();
|
||||
for (; lhsIt != lhs->import_attributes()->cend() &&
|
||||
rhsIt != rhs->import_attributes()->cend();
|
||||
++lhsIt, ++rhsIt) {
|
||||
if (int assertion_key_comparison =
|
||||
AstRawString::Compare(lhsIt->first, rhsIt->first)) {
|
||||
@ -43,9 +43,9 @@ bool SourceTextModuleDescriptor::ModuleRequestComparer::operator()(
|
||||
}
|
||||
}
|
||||
|
||||
if (lhs->import_assertions()->size() != rhs->import_assertions()->size()) {
|
||||
return (lhs->import_assertions()->size() <
|
||||
rhs->import_assertions()->size());
|
||||
if (lhs->import_attributes()->size() != rhs->import_attributes()->size()) {
|
||||
return (lhs->import_attributes()->size() <
|
||||
rhs->import_attributes()->size());
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -54,32 +54,32 @@ bool SourceTextModuleDescriptor::ModuleRequestComparer::operator()(
|
||||
void SourceTextModuleDescriptor::AddImport(
|
||||
const AstRawString* import_name, const AstRawString* local_name,
|
||||
const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions, const Scanner::Location loc,
|
||||
const ImportAttributes* import_attributes, const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone) {
|
||||
Entry* entry = zone->New<Entry>(loc);
|
||||
entry->local_name = local_name;
|
||||
entry->import_name = import_name;
|
||||
entry->module_request =
|
||||
AddModuleRequest(module_request, import_assertions, specifier_loc, zone);
|
||||
AddModuleRequest(module_request, import_attributes, specifier_loc, zone);
|
||||
AddRegularImport(entry);
|
||||
}
|
||||
|
||||
void SourceTextModuleDescriptor::AddStarImport(
|
||||
const AstRawString* local_name, const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions, const Scanner::Location loc,
|
||||
const ImportAttributes* import_attributes, const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone) {
|
||||
Entry* entry = zone->New<Entry>(loc);
|
||||
entry->local_name = local_name;
|
||||
entry->module_request =
|
||||
AddModuleRequest(module_request, import_assertions, specifier_loc, zone);
|
||||
AddModuleRequest(module_request, import_attributes, specifier_loc, zone);
|
||||
AddNamespaceImport(entry, zone);
|
||||
}
|
||||
|
||||
void SourceTextModuleDescriptor::AddEmptyImport(
|
||||
const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions,
|
||||
const ImportAttributes* import_attributes,
|
||||
const Scanner::Location specifier_loc, Zone* zone) {
|
||||
AddModuleRequest(module_request, import_assertions, specifier_loc, zone);
|
||||
AddModuleRequest(module_request, import_attributes, specifier_loc, zone);
|
||||
}
|
||||
|
||||
void SourceTextModuleDescriptor::AddExport(const AstRawString* local_name,
|
||||
@ -94,7 +94,7 @@ void SourceTextModuleDescriptor::AddExport(const AstRawString* local_name,
|
||||
void SourceTextModuleDescriptor::AddExport(
|
||||
const AstRawString* import_name, const AstRawString* export_name,
|
||||
const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions, const Scanner::Location loc,
|
||||
const ImportAttributes* import_attributes, const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone) {
|
||||
DCHECK_NOT_NULL(import_name);
|
||||
DCHECK_NOT_NULL(export_name);
|
||||
@ -102,17 +102,17 @@ void SourceTextModuleDescriptor::AddExport(
|
||||
entry->export_name = export_name;
|
||||
entry->import_name = import_name;
|
||||
entry->module_request =
|
||||
AddModuleRequest(module_request, import_assertions, specifier_loc, zone);
|
||||
AddModuleRequest(module_request, import_attributes, specifier_loc, zone);
|
||||
AddSpecialExport(entry, zone);
|
||||
}
|
||||
|
||||
void SourceTextModuleDescriptor::AddStarExport(
|
||||
const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions, const Scanner::Location loc,
|
||||
const ImportAttributes* import_attributes, const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone) {
|
||||
Entry* entry = zone->New<Entry>(loc);
|
||||
entry->module_request =
|
||||
AddModuleRequest(module_request, import_assertions, specifier_loc, zone);
|
||||
AddModuleRequest(module_request, import_attributes, specifier_loc, zone);
|
||||
AddSpecialExport(entry, zone);
|
||||
}
|
||||
|
||||
@ -128,28 +128,28 @@ Handle<PrimitiveHeapObject> ToStringOrUndefined(IsolateT* isolate,
|
||||
template <typename IsolateT>
|
||||
Handle<ModuleRequest> SourceTextModuleDescriptor::AstModuleRequest::Serialize(
|
||||
IsolateT* isolate) const {
|
||||
// The import assertions will be stored in this array in the form:
|
||||
// The import attributes will be stored in this array in the form:
|
||||
// [key1, value1, location1, key2, value2, location2, ...]
|
||||
Handle<FixedArray> import_assertions_array =
|
||||
Handle<FixedArray> import_attributes_array =
|
||||
isolate->factory()->NewFixedArray(
|
||||
static_cast<int>(import_assertions()->size() *
|
||||
ModuleRequest::kAssertionEntrySize),
|
||||
static_cast<int>(import_attributes()->size() *
|
||||
ModuleRequest::kAttributeEntrySize),
|
||||
AllocationType::kOld);
|
||||
{
|
||||
DisallowGarbageCollection no_gc;
|
||||
Tagged<FixedArray> raw_import_assertions = *import_assertions_array;
|
||||
Tagged<FixedArray> raw_import_attributes = *import_attributes_array;
|
||||
int i = 0;
|
||||
for (auto iter = import_assertions()->cbegin();
|
||||
iter != import_assertions()->cend();
|
||||
++iter, i += ModuleRequest::kAssertionEntrySize) {
|
||||
raw_import_assertions->set(i, *iter->first->string());
|
||||
raw_import_assertions->set(i + 1, *iter->second.first->string());
|
||||
raw_import_assertions->set(i + 2,
|
||||
for (auto iter = import_attributes()->cbegin();
|
||||
iter != import_attributes()->cend();
|
||||
++iter, i += ModuleRequest::kAttributeEntrySize) {
|
||||
raw_import_attributes->set(i, *iter->first->string());
|
||||
raw_import_attributes->set(i + 1, *iter->second.first->string());
|
||||
raw_import_attributes->set(i + 2,
|
||||
Smi::FromInt(iter->second.second.beg_pos));
|
||||
}
|
||||
}
|
||||
return v8::internal::ModuleRequest::New(isolate, specifier()->string(),
|
||||
import_assertions_array, position());
|
||||
import_attributes_array, position());
|
||||
}
|
||||
template Handle<ModuleRequest>
|
||||
SourceTextModuleDescriptor::AstModuleRequest::Serialize(Isolate* isolate) const;
|
||||
|
24
deps/v8/src/ast/modules.h
vendored
24
deps/v8/src/ast/modules.h
vendored
@ -38,14 +38,14 @@ class SourceTextModuleDescriptor : public ZoneObject {
|
||||
void AddImport(const AstRawString* import_name,
|
||||
const AstRawString* local_name,
|
||||
const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions,
|
||||
const ImportAttributes* import_attributes,
|
||||
const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone);
|
||||
|
||||
// import * as x from "foo.js";
|
||||
void AddStarImport(const AstRawString* local_name,
|
||||
const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions,
|
||||
const ImportAttributes* import_attributes,
|
||||
const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone);
|
||||
|
||||
@ -53,7 +53,7 @@ class SourceTextModuleDescriptor : public ZoneObject {
|
||||
// import {} from "foo.js";
|
||||
// export {} from "foo.js"; (sic!)
|
||||
void AddEmptyImport(const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions,
|
||||
const ImportAttributes* import_attributes,
|
||||
const Scanner::Location specifier_loc, Zone* zone);
|
||||
|
||||
// export {x};
|
||||
@ -70,13 +70,13 @@ class SourceTextModuleDescriptor : public ZoneObject {
|
||||
void AddExport(const AstRawString* export_name,
|
||||
const AstRawString* import_name,
|
||||
const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions,
|
||||
const ImportAttributes* import_attributes,
|
||||
const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone);
|
||||
|
||||
// export * from "foo.js";
|
||||
void AddStarExport(const AstRawString* module_request,
|
||||
const ImportAssertions* import_assertions,
|
||||
const ImportAttributes* import_attributes,
|
||||
const Scanner::Location loc,
|
||||
const Scanner::Location specifier_loc, Zone* zone);
|
||||
|
||||
@ -125,10 +125,10 @@ class SourceTextModuleDescriptor : public ZoneObject {
|
||||
class AstModuleRequest : public ZoneObject {
|
||||
public:
|
||||
AstModuleRequest(const AstRawString* specifier,
|
||||
const ImportAssertions* import_assertions, int position,
|
||||
const ImportAttributes* import_attributes, int position,
|
||||
int index)
|
||||
: specifier_(specifier),
|
||||
import_assertions_(import_assertions),
|
||||
import_attributes_(import_attributes),
|
||||
position_(position),
|
||||
index_(index) {}
|
||||
|
||||
@ -136,8 +136,8 @@ class SourceTextModuleDescriptor : public ZoneObject {
|
||||
Handle<v8::internal::ModuleRequest> Serialize(IsolateT* isolate) const;
|
||||
|
||||
const AstRawString* specifier() const { return specifier_; }
|
||||
const ImportAssertions* import_assertions() const {
|
||||
return import_assertions_;
|
||||
const ImportAttributes* import_attributes() const {
|
||||
return import_attributes_;
|
||||
}
|
||||
|
||||
int position() const { return position_; }
|
||||
@ -145,7 +145,7 @@ class SourceTextModuleDescriptor : public ZoneObject {
|
||||
|
||||
private:
|
||||
const AstRawString* specifier_;
|
||||
const ImportAssertions* import_assertions_;
|
||||
const ImportAttributes* import_attributes_;
|
||||
|
||||
// The JS source code position of the request, used for reporting errors.
|
||||
int position_;
|
||||
@ -264,13 +264,13 @@ class SourceTextModuleDescriptor : public ZoneObject {
|
||||
void AssignCellIndices();
|
||||
|
||||
int AddModuleRequest(const AstRawString* specifier,
|
||||
const ImportAssertions* import_assertions,
|
||||
const ImportAttributes* import_attributes,
|
||||
Scanner::Location specifier_loc, Zone* zone) {
|
||||
DCHECK_NOT_NULL(specifier);
|
||||
int module_requests_count = static_cast<int>(module_requests_.size());
|
||||
auto it = module_requests_
|
||||
.insert(zone->New<AstModuleRequest>(
|
||||
specifier, import_assertions, specifier_loc.beg_pos,
|
||||
specifier, import_attributes, specifier_loc.beg_pos,
|
||||
module_requests_count))
|
||||
.first;
|
||||
return (*it)->index();
|
||||
|
28
deps/v8/src/ast/prettyprinter.cc
vendored
28
deps/v8/src/ast/prettyprinter.cc
vendored
@ -256,6 +256,13 @@ void CallPrinter::VisitInitializeClassStaticElementsStatement(
|
||||
|
||||
void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
|
||||
|
||||
void CallPrinter::VisitConditionalChain(ConditionalChain* node) {
|
||||
for (size_t i = 0; i < node->conditional_chain_length(); ++i) {
|
||||
Find(node->condition_at(i));
|
||||
Find(node->then_expression_at(i));
|
||||
}
|
||||
Find(node->else_expression());
|
||||
}
|
||||
|
||||
void CallPrinter::VisitConditional(Conditional* node) {
|
||||
Find(node->condition());
|
||||
@ -500,7 +507,7 @@ void CallPrinter::VisitSuperCallForwardArgs(SuperCallForwardArgs* node) {
|
||||
void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
|
||||
Token::Value op = node->op();
|
||||
bool needsSpace =
|
||||
op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
|
||||
op == Token::kDelete || op == Token::kTypeOf || op == Token::kVoid;
|
||||
Print("(");
|
||||
Print(Token::String(op));
|
||||
if (needsSpace) Print(" ");
|
||||
@ -572,8 +579,8 @@ void CallPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
|
||||
void CallPrinter::VisitImportCallExpression(ImportCallExpression* node) {
|
||||
Print("ImportCall(");
|
||||
Find(node->specifier(), true);
|
||||
if (node->import_assertions()) {
|
||||
Find(node->import_assertions(), true);
|
||||
if (node->import_options()) {
|
||||
Find(node->import_options(), true);
|
||||
}
|
||||
Print(")");
|
||||
}
|
||||
@ -1176,6 +1183,17 @@ void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
|
||||
PrintLiteralIndented("NAME", node->raw_name(), false);
|
||||
}
|
||||
|
||||
void AstPrinter::VisitConditionalChain(ConditionalChain* node) {
|
||||
IndentedScope indent(this, "CONDITIONAL_CHAIN", node->position());
|
||||
PrintIndentedVisit("CONDITION", node->condition_at(0));
|
||||
PrintIndentedVisit("THEN", node->then_expression_at(0));
|
||||
for (size_t i = 1; i < node->conditional_chain_length(); ++i) {
|
||||
IndentedScope indent(this, "ELSE IF", node->condition_position_at(i));
|
||||
PrintIndentedVisit("CONDITION", node->condition_at(i));
|
||||
PrintIndentedVisit("THEN", node->then_expression_at(i));
|
||||
}
|
||||
PrintIndentedVisit("ELSE", node->else_expression());
|
||||
}
|
||||
|
||||
void AstPrinter::VisitConditional(Conditional* node) {
|
||||
IndentedScope indent(this, "CONDITIONAL", node->position());
|
||||
@ -1471,8 +1489,8 @@ void AstPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
|
||||
void AstPrinter::VisitImportCallExpression(ImportCallExpression* node) {
|
||||
IndentedScope indent(this, "IMPORT-CALL", node->position());
|
||||
Visit(node->specifier());
|
||||
if (node->import_assertions()) {
|
||||
Visit(node->import_assertions());
|
||||
if (node->import_options()) {
|
||||
Visit(node->import_options());
|
||||
}
|
||||
}
|
||||
|
||||
|
13
deps/v8/src/ast/scopes.cc
vendored
13
deps/v8/src/ast/scopes.cc
vendored
@ -679,7 +679,7 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
|
||||
DCHECK(is_being_lazily_parsed_);
|
||||
bool was_added;
|
||||
Variable* var = DeclareVariableName(name, VariableMode::kVar, &was_added);
|
||||
if (sloppy_block_function->init() == Token::ASSIGN) {
|
||||
if (sloppy_block_function->init() == Token::kAssign) {
|
||||
var->SetMaybeAssigned();
|
||||
}
|
||||
}
|
||||
@ -1077,14 +1077,15 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
|
||||
DCHECK(!already_resolved_);
|
||||
// Private methods should be declared with ClassScope::DeclarePrivateName()
|
||||
DCHECK(!IsPrivateMethodOrAccessorVariableMode(mode));
|
||||
// This function handles VariableMode::kVar, VariableMode::kLet, and
|
||||
// VariableMode::kConst modes. VariableMode::kDynamic variables are
|
||||
// introduced during variable allocation, and VariableMode::kTemporary
|
||||
// variables are allocated via NewTemporary().
|
||||
// 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().
|
||||
DCHECK(IsDeclaredVariableMode(mode));
|
||||
DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
|
||||
mode == VariableMode::kVar || mode == VariableMode::kLet ||
|
||||
mode == VariableMode::kConst);
|
||||
mode == VariableMode::kConst ||
|
||||
mode == VariableMode::kUsing);
|
||||
DCHECK(!GetDeclarationScope()->was_lazily_parsed());
|
||||
Variable* var =
|
||||
Declare(zone(), name, mode, kind, init_flag, kNotAssigned, was_added);
|
||||
|
1
deps/v8/src/ast/scopes.h
vendored
1
deps/v8/src/ast/scopes.h
vendored
@ -486,6 +486,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
|
||||
switch (scope_type_) {
|
||||
case MODULE_SCOPE:
|
||||
case WITH_SCOPE: // DebugEvaluateContext as well
|
||||
case SCRIPT_SCOPE: // Side data for const tracking let.
|
||||
return true;
|
||||
default:
|
||||
DCHECK_IMPLIES(sloppy_eval_can_extend_vars_,
|
||||
|
14
deps/v8/src/base/bounds.h
vendored
14
deps/v8/src/base/bounds.h
vendored
@ -25,6 +25,20 @@ inline constexpr bool IsInRange(T value, U lower_limit, U higher_limit) {
|
||||
static_cast<unsigned_T>(lower_limit));
|
||||
}
|
||||
|
||||
// Like IsInRange but for the half-open range [lower_limit, higher_limit).
|
||||
template <typename T, typename U>
|
||||
inline constexpr bool IsInHalfOpenRange(T value, U lower_limit,
|
||||
U higher_limit) {
|
||||
DCHECK_LE(lower_limit, higher_limit);
|
||||
static_assert(sizeof(U) <= sizeof(T));
|
||||
using unsigned_T = typename std::make_unsigned<T>::type;
|
||||
// Use static_cast to support enum classes.
|
||||
return static_cast<unsigned_T>(static_cast<unsigned_T>(value) -
|
||||
static_cast<unsigned_T>(lower_limit)) <
|
||||
static_cast<unsigned_T>(static_cast<unsigned_T>(higher_limit) -
|
||||
static_cast<unsigned_T>(lower_limit));
|
||||
}
|
||||
|
||||
// Checks if [index, index+length) is in range [0, max). Note that this check
|
||||
// works even if {index+length} would wrap around.
|
||||
template <typename T,
|
||||
|
8
deps/v8/src/base/macros.h
vendored
8
deps/v8/src/base/macros.h
vendored
@ -368,9 +368,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 +380,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
|
||||
|
867
deps/v8/src/base/optional.h
vendored
867
deps/v8/src/base/optional.h
vendored
@ -9,872 +9,19 @@
|
||||
#ifndef V8_BASE_OPTIONAL_H_
|
||||
#define V8_BASE_OPTIONAL_H_
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "src/base/logging.h"
|
||||
#include <optional>
|
||||
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
|
||||
// Specification:
|
||||
// http://en.cppreference.com/w/cpp/utility/optional/in_place_t
|
||||
struct in_place_t {};
|
||||
|
||||
// Specification:
|
||||
// http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
|
||||
struct nullopt_t {
|
||||
constexpr explicit nullopt_t(int) {}
|
||||
};
|
||||
|
||||
// Specification:
|
||||
// http://en.cppreference.com/w/cpp/utility/optional/in_place
|
||||
constexpr in_place_t in_place = {};
|
||||
|
||||
// Specification:
|
||||
// http://en.cppreference.com/w/cpp/utility/optional/nullopt
|
||||
constexpr nullopt_t nullopt(0);
|
||||
|
||||
// Forward declaration, which is referred by following helpers.
|
||||
// These aliases are deprecated, use std::optional directly.
|
||||
template <typename T>
|
||||
class Optional;
|
||||
using Optional [[deprecated]] = std::optional<T>;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename T, bool = std::is_trivially_destructible<T>::value>
|
||||
struct OptionalStorageBase {
|
||||
// Initializing |empty_| here instead of using default member initializing
|
||||
// to avoid errors in g++ 4.8.
|
||||
constexpr OptionalStorageBase() : empty_('\0') {}
|
||||
|
||||
template <class... Args>
|
||||
constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
|
||||
: is_populated_(true), value_(std::forward<Args>(args)...) {}
|
||||
|
||||
// When T is not trivially destructible we must call its
|
||||
// destructor before deallocating its memory.
|
||||
// Note that this hides the (implicitly declared) move constructor, which
|
||||
// would be used for constexpr move constructor in OptionalStorage<T>.
|
||||
// It is needed iff T is trivially move constructible. However, the current
|
||||
// is_trivially_{copy,move}_constructible implementation requires
|
||||
// is_trivially_destructible (which looks a bug, cf:
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
|
||||
// http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
|
||||
// necessary for this case at the moment. Please see also the destructor
|
||||
// comment in "is_trivially_destructible = true" specialization below.
|
||||
~OptionalStorageBase() {
|
||||
if (is_populated_) value_.~T();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void Init(Args&&... args) {
|
||||
DCHECK(!is_populated_);
|
||||
::new (&value_) T(std::forward<Args>(args)...);
|
||||
is_populated_ = true;
|
||||
}
|
||||
|
||||
bool is_populated_ = false;
|
||||
union {
|
||||
// |empty_| exists so that the union will always be initialized, even when
|
||||
// it doesn't contain a value. Union members must be initialized for the
|
||||
// constructor to be 'constexpr'.
|
||||
char empty_;
|
||||
T value_;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct OptionalStorageBase<T, true /* trivially destructible */> {
|
||||
// Initializing |empty_| here instead of using default member initializing
|
||||
// to avoid errors in g++ 4.8.
|
||||
constexpr OptionalStorageBase() : empty_('\0') {}
|
||||
|
||||
template <class... Args>
|
||||
constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
|
||||
: is_populated_(true), value_(std::forward<Args>(args)...) {}
|
||||
|
||||
// When T is trivially destructible (i.e. its destructor does nothing) there
|
||||
// is no need to call it. Implicitly defined destructor is trivial, because
|
||||
// both members (bool and union containing only variants which are trivially
|
||||
// destructible) are trivially destructible.
|
||||
// Explicitly-defaulted destructor is also trivial, but do not use it here,
|
||||
// because it hides the implicit move constructor. It is needed to implement
|
||||
// constexpr move constructor in OptionalStorage iff T is trivially move
|
||||
// constructible. Note that, if T is trivially move constructible, the move
|
||||
// constructor of OptionalStorageBase<T> is also implicitly defined and it is
|
||||
// trivially move constructor. If T is not trivially move constructible,
|
||||
// "not declaring move constructor without destructor declaration" here means
|
||||
// "delete move constructor", which works because any move constructor of
|
||||
// OptionalStorage will not refer to it in that case.
|
||||
|
||||
template <class... Args>
|
||||
void Init(Args&&... args) {
|
||||
DCHECK(!is_populated_);
|
||||
::new (&value_) T(std::forward<Args>(args)...);
|
||||
is_populated_ = true;
|
||||
}
|
||||
|
||||
bool is_populated_ = false;
|
||||
union {
|
||||
// |empty_| exists so that the union will always be initialized, even when
|
||||
// it doesn't contain a value. Union members must be initialized for the
|
||||
// constructor to be 'constexpr'.
|
||||
char empty_;
|
||||
T value_;
|
||||
};
|
||||
};
|
||||
|
||||
// Implement conditional constexpr copy and move constructors. These are
|
||||
// constexpr if is_trivially_{copy,move}_constructible<T>::value is true
|
||||
// respectively. If each is true, the corresponding constructor is defined as
|
||||
// "= default;", which generates a constexpr constructor (In this case,
|
||||
// the condition of constexpr-ness is satisfied because the base class also has
|
||||
// compiler generated constexpr {copy,move} constructors). Note that
|
||||
// placement-new is prohibited in constexpr.
|
||||
template <typename T, bool = std::is_trivially_copy_constructible<T>::value,
|
||||
bool = std::is_trivially_move_constructible<T>::value>
|
||||
struct OptionalStorage : OptionalStorageBase<T> {
|
||||
// This is no trivially {copy,move} constructible case. Other cases are
|
||||
// defined below as specializations.
|
||||
|
||||
// Accessing the members of template base class requires explicit
|
||||
// declaration.
|
||||
using OptionalStorageBase<T>::is_populated_;
|
||||
using OptionalStorageBase<T>::value_;
|
||||
using OptionalStorageBase<T>::Init;
|
||||
|
||||
// Inherit constructors (specifically, the in_place constructor).
|
||||
using OptionalStorageBase<T>::OptionalStorageBase;
|
||||
|
||||
// User defined constructor deletes the default constructor.
|
||||
// Define it explicitly.
|
||||
OptionalStorage() = default;
|
||||
|
||||
OptionalStorage(const OptionalStorage& other) V8_NOEXCEPT {
|
||||
if (other.is_populated_) Init(other.value_);
|
||||
}
|
||||
|
||||
OptionalStorage(OptionalStorage&& other) V8_NOEXCEPT {
|
||||
if (other.is_populated_) Init(std::move(other.value_));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct OptionalStorage<T, true /* trivially copy constructible */,
|
||||
false /* trivially move constructible */>
|
||||
: OptionalStorageBase<T> {
|
||||
using OptionalStorageBase<T>::is_populated_;
|
||||
using OptionalStorageBase<T>::value_;
|
||||
using OptionalStorageBase<T>::Init;
|
||||
using OptionalStorageBase<T>::OptionalStorageBase;
|
||||
|
||||
OptionalStorage() = default;
|
||||
OptionalStorage(const OptionalStorage& other) V8_NOEXCEPT = default;
|
||||
|
||||
OptionalStorage(OptionalStorage&& other) V8_NOEXCEPT {
|
||||
if (other.is_populated_) Init(std::move(other.value_));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct OptionalStorage<T, false /* trivially copy constructible */,
|
||||
true /* trivially move constructible */>
|
||||
: OptionalStorageBase<T> {
|
||||
using OptionalStorageBase<T>::is_populated_;
|
||||
using OptionalStorageBase<T>::value_;
|
||||
using OptionalStorageBase<T>::Init;
|
||||
using OptionalStorageBase<T>::OptionalStorageBase;
|
||||
|
||||
OptionalStorage() = default;
|
||||
OptionalStorage(OptionalStorage&& other) V8_NOEXCEPT = default;
|
||||
|
||||
OptionalStorage(const OptionalStorage& other) V8_NOEXCEPT {
|
||||
if (other.is_populated_) Init(other.value_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct OptionalStorage<T, true /* trivially copy constructible */,
|
||||
true /* trivially move constructible */>
|
||||
: OptionalStorageBase<T> {
|
||||
// If both trivially {copy,move} constructible are true, it is not necessary
|
||||
// to use user-defined constructors. So, just inheriting constructors
|
||||
// from the base class works.
|
||||
using OptionalStorageBase<T>::OptionalStorageBase;
|
||||
};
|
||||
|
||||
// Base class to support conditionally usable copy-/move- constructors
|
||||
// and assign operators.
|
||||
template <typename T>
|
||||
class OptionalBase {
|
||||
// This class provides implementation rather than public API, so everything
|
||||
// should be hidden. Often we use composition, but we cannot in this case
|
||||
// because of C++ language restriction.
|
||||
protected:
|
||||
constexpr OptionalBase() = default;
|
||||
constexpr OptionalBase(const OptionalBase& other) V8_NOEXCEPT = default;
|
||||
constexpr OptionalBase(OptionalBase&& other) V8_NOEXCEPT = default;
|
||||
|
||||
template <class... Args>
|
||||
constexpr explicit OptionalBase(in_place_t, Args&&... args)
|
||||
: storage_(in_place, std::forward<Args>(args)...) {}
|
||||
|
||||
// Implementation of converting constructors.
|
||||
template <typename U>
|
||||
explicit OptionalBase(const OptionalBase<U>& other) V8_NOEXCEPT {
|
||||
if (other.storage_.is_populated_) storage_.Init(other.storage_.value_);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
explicit OptionalBase(OptionalBase<U>&& other) V8_NOEXCEPT {
|
||||
if (other.storage_.is_populated_)
|
||||
storage_.Init(std::move(other.storage_.value_));
|
||||
}
|
||||
|
||||
~OptionalBase() = default;
|
||||
|
||||
OptionalBase& operator=(const OptionalBase& other) V8_NOEXCEPT {
|
||||
CopyAssign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OptionalBase& operator=(OptionalBase&& other) V8_NOEXCEPT {
|
||||
MoveAssign(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void CopyAssign(const OptionalBase<U>& other) {
|
||||
if (other.storage_.is_populated_)
|
||||
InitOrAssign(other.storage_.value_);
|
||||
else
|
||||
FreeIfNeeded();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void MoveAssign(OptionalBase<U>&& other) {
|
||||
if (other.storage_.is_populated_)
|
||||
InitOrAssign(std::move(other.storage_.value_));
|
||||
else
|
||||
FreeIfNeeded();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void InitOrAssign(U&& value) {
|
||||
if (storage_.is_populated_)
|
||||
storage_.value_ = std::forward<U>(value);
|
||||
else
|
||||
storage_.Init(std::forward<U>(value));
|
||||
}
|
||||
|
||||
void FreeIfNeeded() {
|
||||
if (!storage_.is_populated_) return;
|
||||
storage_.value_.~T();
|
||||
storage_.is_populated_ = false;
|
||||
}
|
||||
|
||||
// For implementing conversion, allow access to other typed OptionalBase
|
||||
// class.
|
||||
template <typename U>
|
||||
friend class OptionalBase;
|
||||
|
||||
OptionalStorage<T> storage_;
|
||||
};
|
||||
|
||||
// The following {Copy,Move}{Constructible,Assignable} structs are helpers to
|
||||
// implement constructor/assign-operator overloading. Specifically, if T is
|
||||
// is not movable but copyable, Optional<T>'s move constructor should not
|
||||
// participate in overload resolution. This inheritance trick implements that.
|
||||
template <bool is_copy_constructible>
|
||||
struct CopyConstructible {};
|
||||
|
||||
template <>
|
||||
struct CopyConstructible<false> {
|
||||
constexpr CopyConstructible() = default;
|
||||
constexpr CopyConstructible(const CopyConstructible&) V8_NOEXCEPT = delete;
|
||||
constexpr CopyConstructible(CopyConstructible&&) V8_NOEXCEPT = default;
|
||||
CopyConstructible& operator=(const CopyConstructible&) V8_NOEXCEPT = default;
|
||||
CopyConstructible& operator=(CopyConstructible&&) V8_NOEXCEPT = default;
|
||||
};
|
||||
|
||||
template <bool is_move_constructible>
|
||||
struct MoveConstructible {};
|
||||
|
||||
template <>
|
||||
struct MoveConstructible<false> {
|
||||
constexpr MoveConstructible() = default;
|
||||
constexpr MoveConstructible(const MoveConstructible&) V8_NOEXCEPT = default;
|
||||
constexpr MoveConstructible(MoveConstructible&&) V8_NOEXCEPT = delete;
|
||||
MoveConstructible& operator=(const MoveConstructible&) V8_NOEXCEPT = default;
|
||||
MoveConstructible& operator=(MoveConstructible&&) V8_NOEXCEPT = default;
|
||||
};
|
||||
|
||||
template <bool is_copy_assignable>
|
||||
struct CopyAssignable {};
|
||||
|
||||
template <>
|
||||
struct CopyAssignable<false> {
|
||||
constexpr CopyAssignable() = default;
|
||||
constexpr CopyAssignable(const CopyAssignable&) V8_NOEXCEPT = default;
|
||||
constexpr CopyAssignable(CopyAssignable&&) V8_NOEXCEPT = default;
|
||||
CopyAssignable& operator=(const CopyAssignable&) V8_NOEXCEPT = delete;
|
||||
CopyAssignable& operator=(CopyAssignable&&) V8_NOEXCEPT = default;
|
||||
};
|
||||
|
||||
template <bool is_move_assignable>
|
||||
struct MoveAssignable {};
|
||||
|
||||
template <>
|
||||
struct MoveAssignable<false> {
|
||||
constexpr MoveAssignable() = default;
|
||||
constexpr MoveAssignable(const MoveAssignable&) V8_NOEXCEPT = default;
|
||||
constexpr MoveAssignable(MoveAssignable&&) V8_NOEXCEPT = default;
|
||||
MoveAssignable& operator=(const MoveAssignable&) V8_NOEXCEPT = default;
|
||||
MoveAssignable& operator=(MoveAssignable&&) V8_NOEXCEPT = delete;
|
||||
};
|
||||
|
||||
// Helper to conditionally enable converting constructors and assign operators.
|
||||
template <typename T, typename U>
|
||||
struct IsConvertibleFromOptional
|
||||
: std::integral_constant<
|
||||
bool, std::is_constructible<T, Optional<U>&>::value ||
|
||||
std::is_constructible<T, const Optional<U>&>::value ||
|
||||
std::is_constructible<T, Optional<U>&&>::value ||
|
||||
std::is_constructible<T, const Optional<U>&&>::value ||
|
||||
std::is_convertible<Optional<U>&, T>::value ||
|
||||
std::is_convertible<const Optional<U>&, T>::value ||
|
||||
std::is_convertible<Optional<U>&&, T>::value ||
|
||||
std::is_convertible<const Optional<U>&&, T>::value> {};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct IsAssignableFromOptional
|
||||
: std::integral_constant<
|
||||
bool, IsConvertibleFromOptional<T, U>::value ||
|
||||
std::is_assignable<T&, Optional<U>&>::value ||
|
||||
std::is_assignable<T&, const Optional<U>&>::value ||
|
||||
std::is_assignable<T&, Optional<U>&&>::value ||
|
||||
std::is_assignable<T&, const Optional<U>&&>::value> {};
|
||||
|
||||
// Forward compatibility for C++17.
|
||||
// Introduce one more deeper nested namespace to avoid leaking using std::swap.
|
||||
namespace swappable_impl {
|
||||
using std::swap;
|
||||
|
||||
struct IsSwappableImpl {
|
||||
// Tests if swap can be called. Check<T&>(0) returns true_type iff swap
|
||||
// is available for T. Otherwise, Check's overload resolution falls back
|
||||
// to Check(...) declared below thanks to SFINAE, so returns false_type.
|
||||
template <typename T>
|
||||
static auto Check(int i)
|
||||
-> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
|
||||
|
||||
template <typename T>
|
||||
static std::false_type Check(...);
|
||||
};
|
||||
} // namespace swappable_impl
|
||||
|
||||
template <typename T>
|
||||
struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
|
||||
|
||||
// Forward compatibility for C++20.
|
||||
template <typename T>
|
||||
using RemoveCvRefT =
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// On Windows, by default, empty-base class optimization does not work,
|
||||
// which means even if the base class is empty struct, it still consumes one
|
||||
// byte for its body. __declspec(empty_bases) enables the optimization.
|
||||
// cf)
|
||||
// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
|
||||
#ifdef OS_WIN
|
||||
#define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
|
||||
#else
|
||||
#define OPTIONAL_DECLSPEC_EMPTY_BASES
|
||||
#endif
|
||||
|
||||
// base::Optional is a Chromium version of the C++17 optional class:
|
||||
// std::optional documentation:
|
||||
// http://en.cppreference.com/w/cpp/utility/optional
|
||||
// Chromium documentation:
|
||||
// https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
|
||||
//
|
||||
// These are the differences between the specification and the implementation:
|
||||
// - Constructors do not use 'constexpr' as it is a C++14 extension.
|
||||
// - 'constexpr' might be missing in some places for reasons specified locally.
|
||||
// - No exceptions are thrown, because they are banned from Chromium.
|
||||
// All copy/move constructors or assignment operators are marked V8_NOEXCEPT.
|
||||
// - All the non-members are in the 'base' namespace instead of 'std'.
|
||||
//
|
||||
// Note that T cannot have a constructor T(Optional<T>) etc. Optional<T> checks
|
||||
// T's constructor (specifically via IsConvertibleFromOptional), and in the
|
||||
// check whether T can be constructible from Optional<T>, which is recursive
|
||||
// so it does not work. As of Feb 2018, std::optional C++17 implementation in
|
||||
// both clang and gcc has same limitation. MSVC SFINAE looks to have different
|
||||
// behavior, but anyway it reports an error, too.
|
||||
template <typename T>
|
||||
class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
|
||||
: public internal::OptionalBase<T>,
|
||||
public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
|
||||
public internal::MoveConstructible<std::is_move_constructible<T>::value>,
|
||||
public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
|
||||
std::is_copy_assignable<T>::value>,
|
||||
public internal::MoveAssignable<std::is_move_constructible<T>::value &&
|
||||
std::is_move_assignable<T>::value> {
|
||||
public:
|
||||
#undef OPTIONAL_DECLSPEC_EMPTY_BASES
|
||||
using value_type = T;
|
||||
|
||||
// Defer default/copy/move constructor implementation to OptionalBase.
|
||||
constexpr Optional() = default;
|
||||
constexpr Optional(const Optional& other) V8_NOEXCEPT = default;
|
||||
constexpr Optional(Optional&& other) V8_NOEXCEPT = default;
|
||||
|
||||
constexpr Optional(nullopt_t) {} // NOLINT(runtime/explicit)
|
||||
|
||||
// Converting copy constructor. "explicit" only if
|
||||
// std::is_convertible<const U&, T>::value is false. It is implemented by
|
||||
// declaring two almost same constructors, but that condition in enable_if
|
||||
// is different, so that either one is chosen, thanks to SFINAE.
|
||||
template <typename U,
|
||||
typename std::enable_if<
|
||||
std::is_constructible<T, const U&>::value &&
|
||||
!internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
std::is_convertible<const U&, T>::value,
|
||||
bool>::type = false>
|
||||
Optional(const Optional<U>& other) V8_NOEXCEPT
|
||||
: internal::OptionalBase<T>(other) {}
|
||||
|
||||
template <typename U,
|
||||
typename std::enable_if<
|
||||
std::is_constructible<T, const U&>::value &&
|
||||
!internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
!std::is_convertible<const U&, T>::value,
|
||||
bool>::type = false>
|
||||
explicit Optional(const Optional<U>& other) V8_NOEXCEPT
|
||||
: internal::OptionalBase<T>(other) {}
|
||||
|
||||
// Converting move constructor. Similar to converting copy constructor,
|
||||
// declaring two (explicit and non-explicit) constructors.
|
||||
template <typename U,
|
||||
typename std::enable_if<
|
||||
std::is_constructible<T, U&&>::value &&
|
||||
!internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
std::is_convertible<U&&, T>::value,
|
||||
bool>::type = false>
|
||||
Optional(Optional<U>&& other) V8_NOEXCEPT
|
||||
: internal::OptionalBase<T>(std::move(other)) {}
|
||||
|
||||
template <typename U,
|
||||
typename std::enable_if<
|
||||
std::is_constructible<T, U&&>::value &&
|
||||
!internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
!std::is_convertible<U&&, T>::value,
|
||||
bool>::type = false>
|
||||
explicit Optional(Optional<U>&& other) V8_NOEXCEPT
|
||||
: internal::OptionalBase<T>(std::move(other)) {}
|
||||
|
||||
template <class... Args>
|
||||
constexpr explicit Optional(in_place_t, Args&&... args)
|
||||
: internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
|
||||
|
||||
template <class U, class... Args,
|
||||
class = typename std::enable_if<std::is_constructible<
|
||||
value_type, std::initializer_list<U>&, Args...>::value>::type>
|
||||
constexpr explicit Optional(in_place_t, std::initializer_list<U> il,
|
||||
Args&&... args)
|
||||
: internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
|
||||
|
||||
// Forward value constructor. Similar to converting constructors,
|
||||
// conditionally explicit.
|
||||
template <
|
||||
typename U = value_type,
|
||||
typename std::enable_if<
|
||||
std::is_constructible<T, U&&>::value &&
|
||||
!std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
|
||||
!std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
|
||||
std::is_convertible<U&&, T>::value,
|
||||
bool>::type = false>
|
||||
constexpr Optional(U&& value) // NOLINT(runtime/explicit)
|
||||
: internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
|
||||
|
||||
template <
|
||||
typename U = value_type,
|
||||
typename std::enable_if<
|
||||
std::is_constructible<T, U&&>::value &&
|
||||
!std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
|
||||
!std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
|
||||
!std::is_convertible<U&&, T>::value,
|
||||
bool>::type = false>
|
||||
constexpr explicit Optional(U&& value)
|
||||
: internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
|
||||
|
||||
~Optional() = default;
|
||||
|
||||
// Defer copy-/move- assign operator implementation to OptionalBase.
|
||||
Optional& operator=(const Optional& other) V8_NOEXCEPT = default;
|
||||
Optional& operator=(Optional&& other) V8_NOEXCEPT = default;
|
||||
|
||||
Optional& operator=(nullopt_t) {
|
||||
FreeIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Perfect-forwarded assignment.
|
||||
template <typename U>
|
||||
typename std::enable_if<
|
||||
!std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
|
||||
std::is_constructible<T, U>::value &&
|
||||
std::is_assignable<T&, U>::value &&
|
||||
(!std::is_scalar<T>::value ||
|
||||
!std::is_same<typename std::decay<U>::type, T>::value),
|
||||
Optional&>::type
|
||||
operator=(U&& value) V8_NOEXCEPT {
|
||||
InitOrAssign(std::forward<U>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy assign the state of other.
|
||||
template <typename U>
|
||||
typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
|
||||
std::is_constructible<T, const U&>::value &&
|
||||
std::is_assignable<T&, const U&>::value,
|
||||
Optional&>::type
|
||||
operator=(const Optional<U>& other) V8_NOEXCEPT {
|
||||
CopyAssign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move assign the state of other.
|
||||
template <typename U>
|
||||
typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
|
||||
std::is_constructible<T, U>::value &&
|
||||
std::is_assignable<T&, U>::value,
|
||||
Optional&>::type
|
||||
operator=(Optional<U>&& other) V8_NOEXCEPT {
|
||||
MoveAssign(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr const T* operator->() const {
|
||||
DCHECK(storage_.is_populated_);
|
||||
return &storage_.value_;
|
||||
}
|
||||
|
||||
constexpr T* operator->() {
|
||||
DCHECK(storage_.is_populated_);
|
||||
return &storage_.value_;
|
||||
}
|
||||
|
||||
constexpr const T& operator*() const& {
|
||||
DCHECK(storage_.is_populated_);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
constexpr T& operator*() & {
|
||||
DCHECK(storage_.is_populated_);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
constexpr const T&& operator*() const&& {
|
||||
DCHECK(storage_.is_populated_);
|
||||
return std::move(storage_.value_);
|
||||
}
|
||||
|
||||
constexpr T&& operator*() && {
|
||||
DCHECK(storage_.is_populated_);
|
||||
return std::move(storage_.value_);
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const { return storage_.is_populated_; }
|
||||
|
||||
constexpr bool has_value() const { return storage_.is_populated_; }
|
||||
|
||||
T& value() & {
|
||||
CHECK(storage_.is_populated_);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
const T& value() const & {
|
||||
CHECK(storage_.is_populated_);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
CHECK(storage_.is_populated_);
|
||||
return std::move(storage_.value_);
|
||||
}
|
||||
|
||||
const T&& value() const && {
|
||||
CHECK(storage_.is_populated_);
|
||||
return std::move(storage_.value_);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
constexpr T value_or(U&& default_value) const & {
|
||||
// TODO(mlamouri): add the following assert when possible:
|
||||
// static_assert(std::is_copy_constructible<T>::value,
|
||||
// "T must be copy constructible");
|
||||
static_assert(std::is_convertible<U, T>::value,
|
||||
"U must be convertible to T");
|
||||
return storage_.is_populated_
|
||||
? storage_.value_
|
||||
: static_cast<T>(std::forward<U>(default_value));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
constexpr T value_or(U&& default_value) && {
|
||||
// TODO(mlamouri): add the following assert when possible:
|
||||
// static_assert(std::is_move_constructible<T>::value,
|
||||
// "T must be move constructible");
|
||||
static_assert(std::is_convertible<U, T>::value,
|
||||
"U must be convertible to T");
|
||||
return storage_.is_populated_
|
||||
? std::move(storage_.value_)
|
||||
: static_cast<T>(std::forward<U>(default_value));
|
||||
}
|
||||
|
||||
void swap(Optional& other) {
|
||||
if (!storage_.is_populated_ && !other.storage_.is_populated_) return;
|
||||
|
||||
if (storage_.is_populated_ != other.storage_.is_populated_) {
|
||||
if (storage_.is_populated_) {
|
||||
other.storage_.Init(std::move(storage_.value_));
|
||||
FreeIfNeeded();
|
||||
} else {
|
||||
storage_.Init(std::move(other.storage_.value_));
|
||||
other.FreeIfNeeded();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
|
||||
using std::swap;
|
||||
swap(**this, *other);
|
||||
}
|
||||
|
||||
void reset() { FreeIfNeeded(); }
|
||||
|
||||
template <class... Args>
|
||||
T& emplace(Args&&... args) {
|
||||
FreeIfNeeded();
|
||||
storage_.Init(std::forward<Args>(args)...);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
template <class U, class... Args>
|
||||
typename std::enable_if<
|
||||
std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
|
||||
T&>::type
|
||||
emplace(std::initializer_list<U> il, Args&&... args) {
|
||||
FreeIfNeeded();
|
||||
storage_.Init(il, std::forward<Args>(args)...);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Accessing template base class's protected member needs explicit
|
||||
// declaration to do so.
|
||||
using internal::OptionalBase<T>::CopyAssign;
|
||||
using internal::OptionalBase<T>::FreeIfNeeded;
|
||||
using internal::OptionalBase<T>::InitOrAssign;
|
||||
using internal::OptionalBase<T>::MoveAssign;
|
||||
using internal::OptionalBase<T>::storage_;
|
||||
};
|
||||
|
||||
// Here after defines comparation operators. The definition follows
|
||||
// http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
|
||||
// while bool() casting is replaced by has_value() to meet the chromium
|
||||
// style guide.
|
||||
template <class T, class U>
|
||||
bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
|
||||
if (lhs.has_value() != rhs.has_value()) return false;
|
||||
if (!lhs.has_value()) return true;
|
||||
return *lhs == *rhs;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
|
||||
if (lhs.has_value() != rhs.has_value()) return true;
|
||||
if (!lhs.has_value()) return false;
|
||||
return *lhs != *rhs;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
|
||||
if (!rhs.has_value()) return false;
|
||||
if (!lhs.has_value()) return true;
|
||||
return *lhs < *rhs;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
|
||||
if (!lhs.has_value()) return true;
|
||||
if (!rhs.has_value()) return false;
|
||||
return *lhs <= *rhs;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
|
||||
if (!lhs.has_value()) return false;
|
||||
if (!rhs.has_value()) return true;
|
||||
return *lhs > *rhs;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
|
||||
if (!rhs.has_value()) return true;
|
||||
if (!lhs.has_value()) return false;
|
||||
return *lhs >= *rhs;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
|
||||
return !opt;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
|
||||
return !opt;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
|
||||
return opt.has_value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
|
||||
return opt.has_value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator<(const Optional<T>& opt, nullopt_t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
|
||||
return opt.has_value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
|
||||
return !opt;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator<=(nullopt_t, const Optional<T>& opt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
|
||||
return opt.has_value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator>(nullopt_t, const Optional<T>& opt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator>=(const Optional<T>& opt, nullopt_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
|
||||
return !opt;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator==(const Optional<T>& opt, const U& value) {
|
||||
return opt.has_value() ? *opt == value : false;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator==(const U& value, const Optional<T>& opt) {
|
||||
return opt.has_value() ? value == *opt : false;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator!=(const Optional<T>& opt, const U& value) {
|
||||
return opt.has_value() ? *opt != value : true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator!=(const U& value, const Optional<T>& opt) {
|
||||
return opt.has_value() ? value != *opt : true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator<(const Optional<T>& opt, const U& value) {
|
||||
return opt.has_value() ? *opt < value : true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator<(const U& value, const Optional<T>& opt) {
|
||||
return opt.has_value() ? value < *opt : false;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator<=(const Optional<T>& opt, const U& value) {
|
||||
return opt.has_value() ? *opt <= value : true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator<=(const U& value, const Optional<T>& opt) {
|
||||
return opt.has_value() ? value <= *opt : false;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator>(const Optional<T>& opt, const U& value) {
|
||||
return opt.has_value() ? *opt > value : false;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator>(const U& value, const Optional<T>& opt) {
|
||||
return opt.has_value() ? value > *opt : true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator>=(const Optional<T>& opt, const U& value) {
|
||||
return opt.has_value() ? *opt >= value : false;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr bool operator>=(const U& value, const Optional<T>& opt) {
|
||||
return opt.has_value() ? value >= *opt : true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
|
||||
return Optional<typename std::decay<T>::type>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
template <class T, class... Args>
|
||||
constexpr Optional<T> make_optional(Args&&... args) {
|
||||
return Optional<T>(in_place, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class U, class... Args>
|
||||
constexpr Optional<T> make_optional(std::initializer_list<U> il,
|
||||
Args&&... args) {
|
||||
return Optional<T>(in_place, il, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Partial specialization for a function template is not allowed. Also, it is
|
||||
// not allowed to add overload function to std namespace, while it is allowed
|
||||
// to specialize the template in std. Thus, swap() (kind of) overloading is
|
||||
// defined in base namespace, instead.
|
||||
template <class T>
|
||||
typename std::enable_if<std::is_move_constructible<T>::value &&
|
||||
internal::IsSwappable<T>::value>::type
|
||||
swap(Optional<T>& lhs, Optional<T>& rhs) {
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
using std::in_place;
|
||||
using std::make_optional;
|
||||
using std::nullopt;
|
||||
using std::nullopt_t;
|
||||
|
||||
} // namespace base
|
||||
} // namespace v8
|
||||
|
@ -190,7 +190,7 @@ void ConditionVariable::Wait(Mutex* mutex) {
|
||||
}
|
||||
|
||||
bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
|
||||
SbTime microseconds = static_cast<SbTime>(rel_time.InMicroseconds());
|
||||
int64_t microseconds = static_cast<int64_t>(rel_time.InMicroseconds());
|
||||
SbConditionVariableResult result = SbConditionVariableWaitTimed(
|
||||
&native_handle_, &mutex->native_handle(), microseconds);
|
||||
DCHECK(result != kSbConditionVariableFailed);
|
||||
|
4
deps/v8/src/base/platform/memory.h
vendored
4
deps/v8/src/base/platform/memory.h
vendored
@ -83,8 +83,6 @@ inline void* AlignedAlloc(size_t size, size_t alignment) {
|
||||
// posix_memalign is not exposed in some Android versions, so we fall back to
|
||||
// memalign. See http://code.google.com/p/android/issues/detail?id=35391.
|
||||
return memalign(alignment, size);
|
||||
#elif V8_OS_STARBOARD
|
||||
return SbMemoryAllocateAligned(alignment, size);
|
||||
#else // POSIX
|
||||
void* ptr;
|
||||
if (posix_memalign(&ptr, alignment, size)) ptr = nullptr;
|
||||
@ -95,8 +93,6 @@ inline void* AlignedAlloc(size_t size, size_t alignment) {
|
||||
inline void AlignedFree(void* ptr) {
|
||||
#if V8_OS_WIN
|
||||
_aligned_free(ptr);
|
||||
#elif V8_OS_STARBOARD
|
||||
SbMemoryFreeAligned(ptr);
|
||||
#else
|
||||
// Using regular Free() is not correct in general. For most platforms,
|
||||
// including V8_LIBC_BIONIC, it is though.
|
||||
|
1
deps/v8/src/base/platform/platform-posix.cc
vendored
1
deps/v8/src/base/platform/platform-posix.cc
vendored
@ -967,6 +967,7 @@ void OS::PrintError(const char* format, ...) {
|
||||
va_start(args, format);
|
||||
VPrintError(format, args);
|
||||
va_end(args);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
|
||||
|
66
deps/v8/src/base/platform/platform-starboard.cc
vendored
66
deps/v8/src/base/platform/platform-starboard.cc
vendored
@ -6,6 +6,9 @@
|
||||
// abstraction layer for Cobalt, an HTML5 container used mainly by YouTube
|
||||
// apps in the living room.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "src/base/lazy-instance.h"
|
||||
#include "src/base/macros.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
@ -16,10 +19,9 @@
|
||||
#include "starboard/common/condition_variable.h"
|
||||
#include "starboard/common/log.h"
|
||||
#include "starboard/common/string.h"
|
||||
#include "starboard/common/time.h"
|
||||
#include "starboard/configuration.h"
|
||||
#include "starboard/configuration_constants.h"
|
||||
#include "starboard/memory.h"
|
||||
#include "starboard/time.h"
|
||||
#include "starboard/time_zone.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -82,18 +84,11 @@ void OS::Initialize(AbortMode abort_mode, const char* const gc_fake_mmap) {
|
||||
}
|
||||
|
||||
int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
|
||||
#if SB_API_VERSION >= 12
|
||||
if (!SbTimeIsTimeThreadNowSupported()) return -1;
|
||||
#endif
|
||||
|
||||
#if SB_API_VERSION >= 12 || SB_HAS(TIME_THREAD_NOW)
|
||||
SbTimeMonotonic thread_now = SbTimeGetMonotonicThreadNow();
|
||||
*secs = thread_now / kSbTimeSecond;
|
||||
*usecs = thread_now % kSbTimeSecond;
|
||||
const int64_t us_time = starboard::CurrentMonotonicThreadTime();
|
||||
if (us_time == 0) return -1;
|
||||
*secs = us_time / TimeConstants::kMicroSecondsPerSecond;
|
||||
*usecs = us_time % TimeConstants::kMicroSecondsPerSecond;
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
double OS::TimeCurrentMillis() { return Time::Now().ToJsTime(); }
|
||||
@ -130,13 +125,13 @@ void OS::SetRandomMmapSeed(int64_t seed) { SB_NOTIMPLEMENTED(); }
|
||||
void* OS::GetRandomMmapAddr() { return nullptr; }
|
||||
|
||||
void* Allocate(void* address, size_t size, OS::MemoryPermission access) {
|
||||
SbMemoryMapFlags sb_flags;
|
||||
int prot_flags;
|
||||
switch (access) {
|
||||
case OS::MemoryPermission::kNoAccess:
|
||||
sb_flags = SbMemoryMapFlags(0);
|
||||
prot_flags = PROT_NONE;
|
||||
break;
|
||||
case OS::MemoryPermission::kReadWrite:
|
||||
sb_flags = SbMemoryMapFlags(kSbMemoryMapProtectReadWrite);
|
||||
prot_flags = PROT_READ | PROT_WRITE;
|
||||
break;
|
||||
default:
|
||||
SB_LOG(ERROR) << "The requested memory allocation access is not"
|
||||
@ -144,8 +139,8 @@ void* Allocate(void* address, size_t size, OS::MemoryPermission access) {
|
||||
<< static_cast<int>(access);
|
||||
return nullptr;
|
||||
}
|
||||
void* result = SbMemoryMap(size, sb_flags, "v8::Base::Allocate");
|
||||
if (result == SB_MEMORY_MAP_FAILED) {
|
||||
void* result = mmap(nullptr, size, prot_flags, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
if (result == MAP_FAILED) {
|
||||
return nullptr;
|
||||
}
|
||||
return result;
|
||||
@ -188,30 +183,29 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
|
||||
// static
|
||||
void OS::Free(void* address, const size_t size) {
|
||||
CHECK(SbMemoryUnmap(address, size));
|
||||
CHECK_EQ(munmap(address, size), 0);
|
||||
}
|
||||
|
||||
// static
|
||||
void OS::Release(void* address, size_t size) {
|
||||
CHECK(SbMemoryUnmap(address, size));
|
||||
CHECK_EQ(munmap(address, size), 0);
|
||||
}
|
||||
|
||||
// static
|
||||
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
|
||||
SbMemoryMapFlags new_protection;
|
||||
int new_protection;
|
||||
switch (access) {
|
||||
case OS::MemoryPermission::kNoAccess:
|
||||
new_protection = SbMemoryMapFlags(0);
|
||||
new_protection = PROT_NONE;
|
||||
break;
|
||||
case OS::MemoryPermission::kRead:
|
||||
new_protection = SbMemoryMapFlags(kSbMemoryMapProtectRead);
|
||||
new_protection = PROT_READ;
|
||||
case OS::MemoryPermission::kReadWrite:
|
||||
new_protection = SbMemoryMapFlags(kSbMemoryMapProtectReadWrite);
|
||||
new_protection = PROT_READ | PROT_WRITE;
|
||||
break;
|
||||
case OS::MemoryPermission::kReadExecute:
|
||||
#if SB_CAN(MAP_EXECUTABLE_MEMORY)
|
||||
new_protection =
|
||||
SbMemoryMapFlags(kSbMemoryMapProtectRead | kSbMemoryMapProtectExec);
|
||||
new_protection = PROT_READ | PROT_EXEC;
|
||||
#else
|
||||
UNREACHABLE();
|
||||
#endif
|
||||
@ -220,7 +214,7 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
|
||||
// All other types are not supported by Starboard.
|
||||
return false;
|
||||
}
|
||||
return SbMemoryProtect(address, size, new_protection);
|
||||
return mprotect(address, size, new_protection) == 0;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -348,7 +342,7 @@ int OS::SNPrintF(char* str, int length, const char* format, ...) {
|
||||
}
|
||||
|
||||
int OS::VSNPrintF(char* str, int length, const char* format, va_list args) {
|
||||
int n = SbStringFormat(str, length, format, args);
|
||||
int n = vsnprintf(str, length, format, args);
|
||||
if (n < 0 || n >= length) {
|
||||
// If the length is zero, the assignment fails.
|
||||
if (length > 0) str[length - 1] = '\0';
|
||||
@ -363,7 +357,7 @@ int OS::VSNPrintF(char* str, int length, const char* format, va_list args) {
|
||||
//
|
||||
|
||||
void OS::StrNCpy(char* dest, int length, const char* src, size_t n) {
|
||||
SbStringCopy(dest, src, n);
|
||||
strncpy(dest, src, n);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -448,14 +442,18 @@ class StarboardDefaultTimezoneCache : public StarboardTimezoneCache {
|
||||
return SbTimeZoneGetName();
|
||||
}
|
||||
double LocalTimeOffset(double time_ms, bool is_utc) override {
|
||||
// SbTimeZOneGetCurrent returns an offset west of Greenwich, which has the
|
||||
// SbTimeZoneGetCurrent returns an offset west of Greenwich, which has the
|
||||
// opposite sign V8 expects.
|
||||
// The starboard function returns offset in minutes. We convert to return
|
||||
// value in milliseconds.
|
||||
return SbTimeZoneGetCurrent() * 60.0 * msPerSecond * (-1);
|
||||
}
|
||||
double DaylightSavingsOffset(double time_ms) override {
|
||||
EzTimeValue value = EzTimeValueFromSbTime(SbTimeGetNow());
|
||||
int64_t posix_microseconds = starboard::CurrentPosixTime();
|
||||
EzTimeValue value = {
|
||||
posix_microseconds / TimeConstants::kMicroSecondsPerSecond,
|
||||
(int32_t)(posix_microseconds % TimeConstants::kMicroSecondsPerSecond)
|
||||
};
|
||||
EzTimeExploded ez_exploded;
|
||||
bool result =
|
||||
EzTimeValueExplode(&value, kEzTimeZoneLocal, &ez_exploded, NULL);
|
||||
@ -489,6 +487,12 @@ bool OS::DiscardSystemPages(void* address, size_t size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
Stack::StackSlot Stack::GetStackStart() {
|
||||
SB_NOTIMPLEMENTED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
Stack::StackSlot Stack::GetCurrentStackPosition() {
|
||||
void* addresses[kStackSize];
|
||||
|
1
deps/v8/src/base/platform/platform-win32.cc
vendored
1
deps/v8/src/base/platform/platform-win32.cc
vendored
@ -702,6 +702,7 @@ void OS::PrintError(const char* format, ...) {
|
||||
va_start(args, format);
|
||||
VPrintError(format, args);
|
||||
va_end(args);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
|
||||
|
2
deps/v8/src/base/platform/semaphore.cc
vendored
2
deps/v8/src/base/platform/semaphore.cc
vendored
@ -170,7 +170,7 @@ void Semaphore::Signal() { native_handle_.Put(); }
|
||||
void Semaphore::Wait() { native_handle_.Take(); }
|
||||
|
||||
bool Semaphore::WaitFor(const TimeDelta& rel_time) {
|
||||
SbTime microseconds = rel_time.InMicroseconds();
|
||||
int64_t microseconds = rel_time.InMicroseconds();
|
||||
return native_handle_.TakeWait(microseconds);
|
||||
}
|
||||
|
||||
|
37
deps/v8/src/base/platform/time.cc
vendored
37
deps/v8/src/base/platform/time.cc
vendored
@ -22,6 +22,10 @@
|
||||
#include <zircon/threads.h>
|
||||
#endif
|
||||
|
||||
#if V8_OS_STARBOARD
|
||||
#include <sys/time.h>
|
||||
#endif // V8_OS_STARBOARD
|
||||
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
|
||||
@ -41,7 +45,7 @@
|
||||
#include "src/base/platform/platform.h"
|
||||
|
||||
#if V8_OS_STARBOARD
|
||||
#include "starboard/time.h"
|
||||
#include "starboard/common/time.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@ -402,7 +406,7 @@ FILETIME Time::ToFiletime() const {
|
||||
return ft;
|
||||
}
|
||||
|
||||
#elif V8_OS_POSIX
|
||||
#elif V8_OS_POSIX || V8_OS_STARBOARD
|
||||
|
||||
Time Time::Now() {
|
||||
struct timeval tv;
|
||||
@ -482,13 +486,7 @@ struct timeval Time::ToTimeval() const {
|
||||
return tv;
|
||||
}
|
||||
|
||||
#elif V8_OS_STARBOARD
|
||||
|
||||
Time Time::Now() { return Time(SbTimeToPosix(SbTimeGetNow())); }
|
||||
|
||||
Time Time::NowFromSystemTime() { return Now(); }
|
||||
|
||||
#endif // V8_OS_STARBOARD
|
||||
#endif // V8_OS_POSIX || V8_OS_STARBOARD
|
||||
|
||||
Time Time::FromJsTime(double ms_since_epoch) {
|
||||
// The epoch is a valid time, so this constructor doesn't interpret
|
||||
@ -753,7 +751,7 @@ TimeTicks TimeTicks::Now() {
|
||||
#elif V8_OS_POSIX
|
||||
ticks = ClockNow(CLOCK_MONOTONIC);
|
||||
#elif V8_OS_STARBOARD
|
||||
ticks = SbTimeGetMonotonicNow();
|
||||
ticks = starboard::CurrentMonotonicTime();
|
||||
#else
|
||||
#error platform does not implement TimeTicks::Now.
|
||||
#endif // V8_OS_DARWIN
|
||||
@ -780,13 +778,7 @@ bool TimeTicks::IsHighResolution() {
|
||||
|
||||
bool ThreadTicks::IsSupported() {
|
||||
#if V8_OS_STARBOARD
|
||||
#if SB_API_VERSION >= 12
|
||||
return SbTimeIsTimeThreadNowSupported();
|
||||
#elif SB_HAS(TIME_THREAD_NOW)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return starboard::CurrentMonotonicThreadTime() != 0;
|
||||
#elif defined(__PASE__)
|
||||
// Thread CPU time accounting is unavailable in PASE
|
||||
return false;
|
||||
@ -803,15 +795,10 @@ bool ThreadTicks::IsSupported() {
|
||||
|
||||
ThreadTicks ThreadTicks::Now() {
|
||||
#if V8_OS_STARBOARD
|
||||
#if SB_API_VERSION >= 12
|
||||
if (SbTimeIsTimeThreadNowSupported())
|
||||
return ThreadTicks(SbTimeGetMonotonicThreadNow());
|
||||
const int64_t now = starboard::CurrentMonotonicThreadTime();
|
||||
if (now != 0)
|
||||
return ThreadTicks(now);
|
||||
UNREACHABLE();
|
||||
#elif SB_HAS(TIME_THREAD_NOW)
|
||||
return ThreadTicks(SbTimeGetMonotonicThreadNow());
|
||||
#else
|
||||
UNREACHABLE();
|
||||
#endif
|
||||
#elif V8_OS_DARWIN
|
||||
return ThreadTicks(ComputeThreadTicks());
|
||||
#elif V8_OS_FUCHSIA
|
||||
|
29
deps/v8/src/baseline/baseline-compiler.cc
vendored
29
deps/v8/src/baseline/baseline-compiler.cc
vendored
@ -422,6 +422,9 @@ Tagged<Smi> BaselineCompiler::IndexAsSmi(int operand_index) {
|
||||
Tagged<Smi> BaselineCompiler::IntAsSmi(int operand_index) {
|
||||
return Smi::FromInt(Int(operand_index));
|
||||
}
|
||||
Tagged<Smi> BaselineCompiler::UintAsSmi(int operand_index) {
|
||||
return Smi::FromInt(Uint(operand_index));
|
||||
}
|
||||
Tagged<Smi> BaselineCompiler::Flag8AsSmi(int operand_index) {
|
||||
return Smi::FromInt(Flag8(operand_index));
|
||||
}
|
||||
@ -647,6 +650,8 @@ constexpr static bool BuiltinMayDeopt(Builtin id) {
|
||||
case Builtin::kBaselineOutOfLinePrologue:
|
||||
case Builtin::kIncBlockCounter:
|
||||
case Builtin::kToObject:
|
||||
case Builtin::kStoreScriptContextSlotBaseline:
|
||||
case Builtin::kStoreCurrentScriptContextSlotBaseline:
|
||||
// This one explicitly skips the construct if the debugger is enabled.
|
||||
case Builtin::kFindNonDefaultConstructorOrConstruct:
|
||||
return false;
|
||||
@ -812,6 +817,30 @@ void BaselineCompiler::VisitStaCurrentContextSlot() {
|
||||
context, Context::OffsetOfElementAt(Index(0)), value);
|
||||
}
|
||||
|
||||
void BaselineCompiler::VisitStaScriptContextSlot() {
|
||||
Register value = WriteBarrierDescriptor::ValueRegister();
|
||||
Register context = WriteBarrierDescriptor::ObjectRegister();
|
||||
DCHECK(!AreAliased(value, context, kInterpreterAccumulatorRegister));
|
||||
__ Move(value, kInterpreterAccumulatorRegister);
|
||||
LoadRegister(context, 0);
|
||||
SaveAccumulatorScope accumulator_scope(this, &basm_);
|
||||
CallBuiltin<Builtin::kStoreScriptContextSlotBaseline>(
|
||||
context, // context
|
||||
value, // value
|
||||
IndexAsSmi(1), // slot
|
||||
UintAsTagged(2)); // depth
|
||||
}
|
||||
|
||||
void BaselineCompiler::VisitStaCurrentScriptContextSlot() {
|
||||
Register value = WriteBarrierDescriptor::ValueRegister();
|
||||
DCHECK(!AreAliased(value, kInterpreterAccumulatorRegister));
|
||||
SaveAccumulatorScope accumulator_scope(this, &basm_);
|
||||
__ Move(value, kInterpreterAccumulatorRegister);
|
||||
CallBuiltin<Builtin::kStoreCurrentScriptContextSlotBaseline>(
|
||||
value, // value
|
||||
IndexAsSmi(0)); // slot
|
||||
}
|
||||
|
||||
void BaselineCompiler::VisitLdaLookupSlot() {
|
||||
CallRuntime(Runtime::kLoadLookupSlot, Constant<Name>(0));
|
||||
}
|
||||
|
1
deps/v8/src/baseline/baseline-compiler.h
vendored
1
deps/v8/src/baseline/baseline-compiler.h
vendored
@ -91,6 +91,7 @@ class BaselineCompiler {
|
||||
Tagged<TaggedIndex> UintAsTagged(int operand_index);
|
||||
Tagged<Smi> IndexAsSmi(int operand_index);
|
||||
Tagged<Smi> IntAsSmi(int operand_index);
|
||||
Tagged<Smi> UintAsSmi(int operand_index);
|
||||
Tagged<Smi> Flag8AsSmi(int operand_index);
|
||||
Tagged<Smi> Flag16AsSmi(int operand_index);
|
||||
|
||||
|
14
deps/v8/src/builtins/accessors.cc
vendored
14
deps/v8/src/builtins/accessors.cc
vendored
@ -151,7 +151,8 @@ void Accessors::ArrayLengthGetter(
|
||||
RCS_SCOPE(isolate, RuntimeCallCounterId::kArrayLengthGetter);
|
||||
DisallowGarbageCollection no_gc;
|
||||
HandleScope scope(isolate);
|
||||
Tagged<JSArray> holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
|
||||
Tagged<JSArray> holder =
|
||||
JSArray::cast(*Utils::OpenDirectHandle(*info.Holder()));
|
||||
Tagged<Object> result = holder->length();
|
||||
info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
|
||||
}
|
||||
@ -163,7 +164,7 @@ void Accessors::ArrayLengthSetter(
|
||||
RCS_SCOPE(isolate, RuntimeCallCounterId::kArrayLengthSetter);
|
||||
HandleScope scope(isolate);
|
||||
|
||||
DCHECK(Object::SameValue(*Utils::OpenHandle(*name),
|
||||
DCHECK(Object::SameValue(*Utils::OpenDirectHandle(*name),
|
||||
ReadOnlyRoots(isolate).length_string()));
|
||||
|
||||
Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder());
|
||||
@ -233,7 +234,7 @@ void Accessors::ModuleNamespaceEntryGetter(
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
|
||||
HandleScope scope(isolate);
|
||||
Tagged<JSModuleNamespace> holder =
|
||||
JSModuleNamespace::cast(*Utils::OpenHandle(*info.Holder()));
|
||||
JSModuleNamespace::cast(*Utils::OpenDirectHandle(*info.Holder()));
|
||||
Handle<Object> result;
|
||||
if (holder->GetExport(isolate, Handle<String>::cast(Utils::OpenHandle(*name)))
|
||||
.ToHandle(&result)) {
|
||||
@ -281,12 +282,13 @@ void Accessors::StringLengthGetter(
|
||||
// v8::Object, but internally we have callbacks on entities which are higher
|
||||
// in the hierarchy, in this case for String values.
|
||||
|
||||
Tagged<Object> value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
|
||||
Tagged<Object> value =
|
||||
*Utils::OpenDirectHandle(*v8::Local<v8::Value>(info.This()));
|
||||
if (!IsString(value)) {
|
||||
// Not a string value. That means that we either got a String wrapper or
|
||||
// a Value with a String wrapper in its prototype chain.
|
||||
value =
|
||||
JSPrimitiveWrapper::cast(*Utils::OpenHandle(*info.Holder()))->value();
|
||||
value = JSPrimitiveWrapper::cast(*Utils::OpenDirectHandle(*info.Holder()))
|
||||
->value();
|
||||
}
|
||||
Tagged<Object> result = Smi::FromInt(String::cast(value)->length());
|
||||
info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
|
||||
|
8
deps/v8/src/builtins/arm/builtins-arm.cc
vendored
8
deps/v8/src/builtins/arm/builtins-arm.cc
vendored
@ -930,7 +930,7 @@ void ResetFeedbackVectorOsrUrgency(MacroAssembler* masm,
|
||||
void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
|
||||
UseScratchRegisterScope temps(masm);
|
||||
// Need a few extra registers
|
||||
temps.Include({r4, r8, r9});
|
||||
temps.Include({r4, r5, r8, r9});
|
||||
|
||||
auto descriptor =
|
||||
Builtins::CallInterfaceDescriptorFor(Builtin::kBaselineOutOfLinePrologue);
|
||||
@ -943,7 +943,11 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
|
||||
FieldMemOperand(closure, JSFunction::kFeedbackCellOffset));
|
||||
__ ldr(feedback_vector,
|
||||
FieldMemOperand(feedback_cell, FeedbackCell::kValueOffset));
|
||||
__ AssertFeedbackVector(feedback_vector);
|
||||
{
|
||||
UseScratchRegisterScope temps(masm);
|
||||
Register temporary = temps.Acquire();
|
||||
__ AssertFeedbackVector(feedback_vector, temporary);
|
||||
}
|
||||
|
||||
// Check the tiering state.
|
||||
Label flags_need_processing;
|
||||
|
19
deps/v8/src/builtins/arm64/builtins-arm64.cc
vendored
19
deps/v8/src/builtins/arm64/builtins-arm64.cc
vendored
@ -491,9 +491,8 @@ static void GetSharedFunctionInfoBytecodeOrBaseline(
|
||||
&done);
|
||||
}
|
||||
|
||||
__ LoadTrustedPointerField(
|
||||
bytecode, FieldMemOperand(data, InterpreterData::kBytecodeArrayOffset),
|
||||
kBytecodeArrayIndirectPointerTag);
|
||||
__ LoadProtectedPointerField(
|
||||
bytecode, FieldMemOperand(data, InterpreterData::kBytecodeArrayOffset));
|
||||
|
||||
__ Bind(&done);
|
||||
__ IsObjectType(bytecode, scratch1, scratch1, BYTECODE_ARRAY_TYPE);
|
||||
@ -1557,7 +1556,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(
|
||||
__ Move(x2, kInterpreterBytecodeArrayRegister);
|
||||
static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch");
|
||||
__ ReplaceClosureCodeWithOptimizedCode(x2, closure);
|
||||
__ JumpCodeObject(x2);
|
||||
__ JumpCodeObject(x2, kJSEntrypointTag);
|
||||
|
||||
__ bind(&install_baseline_code);
|
||||
__ GenerateTailCallToReturnedCode(Runtime::kInstallBaselineCode);
|
||||
@ -2026,9 +2025,9 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
kInterpreterDispatchTableRegister, INTERPRETER_DATA_TYPE);
|
||||
__ B(ne, &builtin_trampoline);
|
||||
|
||||
__ LoadCodePointerField(
|
||||
__ LoadProtectedPointerField(
|
||||
x1, FieldMemOperand(x1, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ LoadCodeInstructionStart(x1, x1);
|
||||
__ LoadCodeInstructionStart(x1, x1, kJSEntrypointTag);
|
||||
__ B(&trampoline_loaded);
|
||||
|
||||
__ Bind(&builtin_trampoline);
|
||||
@ -2280,17 +2279,17 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
|
||||
|
||||
// Load deoptimization data from the code object.
|
||||
// <deopt_data> = <code>[#deoptimization_data_offset]
|
||||
__ LoadTaggedField(
|
||||
__ LoadProtectedPointerField(
|
||||
x1,
|
||||
FieldMemOperand(x0, Code::kDeoptimizationDataOrInterpreterDataOffset));
|
||||
|
||||
// Load the OSR entrypoint offset from the deoptimization data.
|
||||
// <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
|
||||
__ SmiUntagField(
|
||||
x1, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(
|
||||
x1, FieldMemOperand(x1, TrustedFixedArray::OffsetOfElementAt(
|
||||
DeoptimizationData::kOsrPcOffsetIndex)));
|
||||
|
||||
__ LoadCodeInstructionStart(x0, x0);
|
||||
__ LoadCodeInstructionStart(x0, x0, kJSEntrypointTag);
|
||||
|
||||
// Compute the target address = code_entry + osr_offset
|
||||
// <entry_addr> = <code_entry> + <osr_offset>
|
||||
@ -5509,7 +5508,7 @@ void Generate_BaselineOrInterpreterEntry(MacroAssembler* masm,
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ CallCFunction(get_baseline_pc, 3, 0);
|
||||
}
|
||||
__ LoadCodeInstructionStart(code_obj, code_obj);
|
||||
__ LoadCodeInstructionStart(code_obj, code_obj, kJSEntrypointTag);
|
||||
__ Add(code_obj, code_obj, kReturnRegister0);
|
||||
__ Pop(kInterpreterAccumulatorRegister, padreg);
|
||||
|
||||
|
7
deps/v8/src/builtins/base.tq
vendored
7
deps/v8/src/builtins/base.tq
vendored
@ -243,7 +243,10 @@ type IndirectPointer
|
||||
generates 'TNode<IndirectPointerHandleT>'
|
||||
constexpr 'IndirectPointerHandle';
|
||||
// TODO(saelo): implement accessors and type checkers for these fields.
|
||||
type IndirectPointer<To: type> extends IndirectPointer;
|
||||
type IndirectPointer<To : type extends ExposedTrustedObject> extends
|
||||
IndirectPointer;
|
||||
type ProtectedPointer extends Tagged;
|
||||
type ProtectedPointer<To : type extends TrustedObject> extends ProtectedPointer;
|
||||
extern class InstructionStream extends TrustedObject;
|
||||
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
|
||||
|
||||
@ -419,6 +422,7 @@ extern enum MessageTemplate {
|
||||
kTypedArraySetOffsetOutOfBounds,
|
||||
kInvalidArgument,
|
||||
kInvalidRegExpExecResult,
|
||||
kInvalidSizeValue,
|
||||
kRegExpNonRegExp,
|
||||
kRegExpNonObject,
|
||||
kPromiseNonCallable,
|
||||
@ -477,6 +481,7 @@ extern enum MessageTemplate {
|
||||
kIteratorResultNotAnObject,
|
||||
kFlattenPastSafeLength,
|
||||
kStrictReadOnlyProperty,
|
||||
kInvalidUsingInForInLoop,
|
||||
...
|
||||
}
|
||||
|
||||
|
@ -413,8 +413,10 @@ TF_BUILTIN(AsyncGeneratorAwaitResolveClosure, AsyncGeneratorBuiltinsAssembler) {
|
||||
TF_BUILTIN(AsyncGeneratorAwaitRejectClosure, AsyncGeneratorBuiltinsAssembler) {
|
||||
auto value = Parameter<Object>(Descriptor::kValue);
|
||||
auto context = Parameter<Context>(Descriptor::kContext);
|
||||
// Restart in Rethrow mode, as this exception was already thrown and we don't
|
||||
// want to trigger a second debug break event or change the message location.
|
||||
AsyncGeneratorAwaitResumeClosure(context, value,
|
||||
JSAsyncGeneratorObject::kThrow);
|
||||
JSAsyncGeneratorObject::kRethrow);
|
||||
}
|
||||
|
||||
TF_BUILTIN(AsyncGeneratorAwaitUncaught, AsyncGeneratorBuiltinsAssembler) {
|
||||
|
@ -2782,9 +2782,10 @@ TNode<Word32T> WeakCollectionsBuiltinsAssembler::ShouldShrink(
|
||||
|
||||
TNode<IntPtrT> WeakCollectionsBuiltinsAssembler::ValueIndexFromKeyIndex(
|
||||
TNode<IntPtrT> key_index) {
|
||||
return IntPtrAdd(key_index,
|
||||
IntPtrConstant(EphemeronHashTable::ShapeT::kEntryValueIndex -
|
||||
EphemeronHashTable::kEntryKeyIndex));
|
||||
return IntPtrAdd(
|
||||
key_index,
|
||||
IntPtrConstant(EphemeronHashTable::TodoShape::kEntryValueIndex -
|
||||
EphemeronHashTable::kEntryKeyIndex));
|
||||
}
|
||||
|
||||
TF_BUILTIN(WeakMapConstructor, WeakCollectionsBuiltinsAssembler) {
|
||||
|
@ -373,12 +373,8 @@ TNode<JSObject> ConstructorBuiltinsAssembler::FastNewObject(
|
||||
}
|
||||
BIND(&allocate_properties);
|
||||
{
|
||||
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
properties =
|
||||
AllocateSwissNameDictionary(SwissNameDictionary::kInitialCapacity);
|
||||
} else {
|
||||
properties = AllocateNameDictionary(NameDictionary::kInitialCapacity);
|
||||
}
|
||||
properties =
|
||||
AllocatePropertyDictionary(PropertyDictionary::kInitialCapacity);
|
||||
Goto(&instantiate_map);
|
||||
}
|
||||
|
||||
|
30
deps/v8/src/builtins/builtins-definitions.h
vendored
30
deps/v8/src/builtins/builtins-definitions.h
vendored
@ -665,7 +665,9 @@ namespace internal {
|
||||
TFH(StoreGlobalICTrampoline, StoreGlobal) \
|
||||
TFH(StoreGlobalICBaseline, StoreGlobalBaseline) \
|
||||
TFH(StoreIC, StoreWithVector) \
|
||||
TFH(StoreIC_Megamorphic, StoreWithVector) \
|
||||
TFH(StoreICTrampoline, Store) \
|
||||
TFH(StoreICTrampoline_Megamorphic, Store) \
|
||||
TFH(StoreICBaseline, StoreBaseline) \
|
||||
TFH(DefineNamedOwnIC, StoreWithVector) \
|
||||
TFH(DefineNamedOwnICTrampoline, Store) \
|
||||
@ -892,8 +894,8 @@ namespace internal {
|
||||
kMatchInfo) \
|
||||
TFS(RegExpExecInternal, NeedsContext::kYes, kRegExp, kString, kLastIndex, \
|
||||
kMatchInfo) \
|
||||
ASM(RegExpInterpreterTrampoline, CCall) \
|
||||
ASM(RegExpExperimentalTrampoline, CCall) \
|
||||
ASM(RegExpInterpreterTrampoline, RegExpTrampoline) \
|
||||
ASM(RegExpExperimentalTrampoline, RegExpTrampoline) \
|
||||
\
|
||||
/* Set */ \
|
||||
TFS(FindOrderedHashSetEntry, NeedsContext::kYes, kTable, kKey) \
|
||||
@ -2029,14 +2031,6 @@ namespace internal {
|
||||
BUILTIN_LIST(V, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
|
||||
|
||||
#define BUILTIN_LIST_A(V) \
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, V)
|
||||
|
||||
#define BUILTIN_LIST_TFS(V) \
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, V, \
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
|
||||
|
||||
#define BUILTIN_LIST_TFJ(V) \
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, V, IGNORE_BUILTIN, IGNORE_BUILTIN, \
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
|
||||
@ -2045,6 +2039,22 @@ namespace internal {
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, V, IGNORE_BUILTIN, \
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
|
||||
|
||||
#define BUILTIN_LIST_TFS(V) \
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, V, \
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
|
||||
|
||||
#define BUILTIN_LIST_TFH(V) \
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
|
||||
V, IGNORE_BUILTIN, IGNORE_BUILTIN)
|
||||
|
||||
#define BUILTIN_LIST_BCH(V) \
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
|
||||
IGNORE_BUILTIN, V, IGNORE_BUILTIN)
|
||||
|
||||
#define BUILTIN_LIST_A(V) \
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, V)
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -106,6 +106,9 @@ void GeneratorBuiltinsAssembler::InnerResume(
|
||||
case JSGeneratorObject::kThrow:
|
||||
builtin_result = CallRuntime(Runtime::kThrow, context, value);
|
||||
break;
|
||||
case JSGeneratorObject::kRethrow:
|
||||
// Currently only async generators use this mode.
|
||||
UNREACHABLE();
|
||||
}
|
||||
args->PopAndReturn(builtin_result);
|
||||
}
|
||||
|
10
deps/v8/src/builtins/builtins-ic-gen.cc
vendored
10
deps/v8/src/builtins/builtins-ic-gen.cc
vendored
@ -101,10 +101,20 @@ void Builtins::Generate_StoreIC(compiler::CodeAssemblerState* state) {
|
||||
AccessorAssembler assembler(state);
|
||||
assembler.GenerateStoreIC();
|
||||
}
|
||||
void Builtins::Generate_StoreIC_Megamorphic(
|
||||
compiler::CodeAssemblerState* state) {
|
||||
AccessorAssembler assembler(state);
|
||||
assembler.GenerateStoreIC_Megamorphic();
|
||||
}
|
||||
void Builtins::Generate_StoreICTrampoline(compiler::CodeAssemblerState* state) {
|
||||
AccessorAssembler assembler(state);
|
||||
assembler.GenerateStoreICTrampoline();
|
||||
}
|
||||
void Builtins::Generate_StoreICTrampoline_Megamorphic(
|
||||
compiler::CodeAssemblerState* state) {
|
||||
AccessorAssembler assembler(state);
|
||||
assembler.GenerateStoreICTrampoline_Megamorphic();
|
||||
}
|
||||
void Builtins::Generate_StoreICBaseline(compiler::CodeAssemblerState* state) {
|
||||
AccessorAssembler assembler(state);
|
||||
assembler.GenerateStoreICBaseline();
|
||||
|
24
deps/v8/src/builtins/builtins-internal-gen.cc
vendored
24
deps/v8/src/builtins/builtins-internal-gen.cc
vendored
@ -137,10 +137,10 @@ class WriteBarrierCodeStubAssembler : public CodeStubAssembler {
|
||||
}
|
||||
|
||||
TNode<BoolT> IsPageFlagSet(TNode<IntPtrT> object, int mask) {
|
||||
TNode<IntPtrT> page = PageFromAddress(object);
|
||||
TNode<IntPtrT> header = PageHeaderFromAddress(object);
|
||||
TNode<IntPtrT> flags = UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::Pointer(), page,
|
||||
IntPtrConstant(BasicMemoryChunk::kFlagsOffset)));
|
||||
Load(MachineType::Pointer(), header,
|
||||
IntPtrConstant(MemoryChunkLayout::kFlagsOffset)));
|
||||
return WordNotEqual(WordAnd(flags, IntPtrConstant(mask)),
|
||||
IntPtrConstant(0));
|
||||
}
|
||||
@ -156,8 +156,8 @@ class WriteBarrierCodeStubAssembler : public CodeStubAssembler {
|
||||
void GetMarkBit(TNode<IntPtrT> object, TNode<IntPtrT>* cell,
|
||||
TNode<IntPtrT>* mask) {
|
||||
TNode<IntPtrT> page = PageFromAddress(object);
|
||||
TNode<IntPtrT> bitmap =
|
||||
IntPtrAdd(page, IntPtrConstant(MemoryChunk::kMarkingBitmapOffset));
|
||||
TNode<IntPtrT> bitmap = IntPtrAdd(
|
||||
page, IntPtrConstant(MemoryChunkLayout::kMarkingBitmapOffset));
|
||||
|
||||
{
|
||||
// Temp variable to calculate cell offset in bitmap.
|
||||
@ -165,8 +165,10 @@ class WriteBarrierCodeStubAssembler : public CodeStubAssembler {
|
||||
int shift = MarkingBitmap::kBitsPerCellLog2 + kTaggedSizeLog2 -
|
||||
MarkingBitmap::kBytesPerCellLog2;
|
||||
r0 = WordShr(object, IntPtrConstant(shift));
|
||||
r0 = WordAnd(r0, IntPtrConstant((kPageAlignmentMask >> shift) &
|
||||
~(MarkingBitmap::kBytesPerCell - 1)));
|
||||
r0 = WordAnd(
|
||||
r0, IntPtrConstant(
|
||||
(MemoryChunkHeader::GetAlignmentMaskForAssembler() >> shift) &
|
||||
~(MarkingBitmap::kBytesPerCell - 1)));
|
||||
*cell = IntPtrAdd(bitmap, Signed(r0));
|
||||
}
|
||||
{
|
||||
@ -185,11 +187,12 @@ class WriteBarrierCodeStubAssembler : public CodeStubAssembler {
|
||||
void InsertIntoRememberedSet(TNode<IntPtrT> object, TNode<IntPtrT> slot,
|
||||
SaveFPRegsMode fp_mode) {
|
||||
Label slow_path(this), next(this);
|
||||
TNode<IntPtrT> page = PageFromAddress(object);
|
||||
TNode<IntPtrT> page_header = PageHeaderFromAddress(object);
|
||||
TNode<IntPtrT> page = PageFromPageHeader(page_header);
|
||||
|
||||
// Load address of SlotSet
|
||||
TNode<IntPtrT> slot_set = LoadSlotSet(page, &slow_path);
|
||||
TNode<IntPtrT> slot_offset = IntPtrSub(slot, page);
|
||||
TNode<IntPtrT> slot_offset = IntPtrSub(slot, page_header);
|
||||
|
||||
// Load bucket
|
||||
TNode<IntPtrT> bucket = LoadBucket(slot_set, slot_offset, &slow_path);
|
||||
@ -1423,7 +1426,8 @@ void Builtins::Generate_MaglevOptimizeCodeOrTailCallOptimizedCodeSlot(
|
||||
using D = MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor;
|
||||
Register flags = D::GetRegisterParameter(D::kFlags);
|
||||
Register feedback_vector = D::GetRegisterParameter(D::kFeedbackVector);
|
||||
masm->AssertFeedbackVector(feedback_vector);
|
||||
Register temporary = D::GetRegisterParameter(D::kTemporary);
|
||||
masm->AssertFeedbackVector(feedback_vector, temporary);
|
||||
masm->OptimizeCodeOrTailCallOptimizedCodeSlot(flags, feedback_vector);
|
||||
masm->Trap();
|
||||
}
|
||||
|
14
deps/v8/src/builtins/builtins-object-gen.cc
vendored
14
deps/v8/src/builtins/builtins-object-gen.cc
vendored
@ -1072,13 +1072,8 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) {
|
||||
BIND(&null_proto);
|
||||
{
|
||||
map = LoadSlowObjectWithNullPrototypeMap(native_context);
|
||||
if constexpr (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
new_properties =
|
||||
AllocateSwissNameDictionary(SwissNameDictionary::kInitialCapacity);
|
||||
} else {
|
||||
new_properties =
|
||||
AllocateNameDictionary(NameDictionary::kInitialCapacity);
|
||||
}
|
||||
new_properties =
|
||||
AllocatePropertyDictionary(PropertyDictionary::kInitialCapacity);
|
||||
Goto(&instantiate_map);
|
||||
}
|
||||
|
||||
@ -1419,10 +1414,7 @@ TNode<JSObject> ObjectBuiltinsAssembler::FromPropertyDescriptor(
|
||||
native_context, Context::SLOW_OBJECT_WITH_OBJECT_PROTOTYPE_MAP));
|
||||
// We want to preallocate the slots for value, writable, get, set,
|
||||
// enumerable and configurable - a total of 6
|
||||
TNode<HeapObject> properties =
|
||||
V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
|
||||
? TNode<HeapObject>(AllocateSwissNameDictionary(6))
|
||||
: AllocateNameDictionary(6);
|
||||
TNode<HeapObject> properties = AllocatePropertyDictionary(6);
|
||||
TNode<JSObject> js_desc = AllocateJSObjectFromMap(map, properties);
|
||||
|
||||
Label bailout(this, Label::kDeferred);
|
||||
|
10
deps/v8/src/builtins/builtins-object.cc
vendored
10
deps/v8/src/builtins/builtins-object.cc
vendored
@ -115,10 +115,9 @@ Tagged<Object> ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
|
||||
LookupIterator it(isolate, object, lookup_key,
|
||||
LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
|
||||
|
||||
for (; it.IsFound(); it.Next()) {
|
||||
for (;; it.Next()) {
|
||||
switch (it.state()) {
|
||||
case LookupIterator::INTERCEPTOR:
|
||||
case LookupIterator::NOT_FOUND:
|
||||
case LookupIterator::TRANSITION:
|
||||
UNREACHABLE();
|
||||
|
||||
@ -151,8 +150,9 @@ Tagged<Object> ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
|
||||
return ObjectLookupAccessor(isolate, prototype, key, component);
|
||||
}
|
||||
case LookupIterator::WASM_OBJECT:
|
||||
case LookupIterator::INTEGER_INDEXED_EXOTIC:
|
||||
case LookupIterator::TYPED_ARRAY_INDEX_NOT_FOUND:
|
||||
case LookupIterator::DATA:
|
||||
case LookupIterator::NOT_FOUND:
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
|
||||
case LookupIterator::ACCESSOR: {
|
||||
@ -165,11 +165,11 @@ Tagged<Object> ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
|
||||
isolate, holder_realm, Handle<AccessorPair>::cast(maybe_pair),
|
||||
component);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
39
deps/v8/src/builtins/builtins-regexp-gen.cc
vendored
39
deps/v8/src/builtins/builtins-regexp-gen.cc
vendored
@ -312,19 +312,45 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
|
||||
// implementation of CreateDataProperty instead.
|
||||
|
||||
// At this point the spec says to call CreateDataProperty. However, we can
|
||||
// skip most of the steps and go straight to adding a dictionary entry
|
||||
// because we know a bunch of useful facts:
|
||||
// skip most of the steps and go straight to adding/updating a dictionary
|
||||
// entry because we know a bunch of useful facts:
|
||||
// - All keys are non-numeric internalized strings
|
||||
// - No keys repeat
|
||||
// - Receiver has no prototype
|
||||
// - Receiver isn't used as a prototype
|
||||
// - Receiver isn't any special object like a Promise intrinsic object
|
||||
// - Receiver is extensible
|
||||
// - Receiver has no interceptors
|
||||
Label add_dictionary_property_slow(this, Label::kDeferred);
|
||||
AddToDictionary<PropertyDictionary>(CAST(properties), name, capture,
|
||||
&add_dictionary_property_slow);
|
||||
TVARIABLE(IntPtrT, var_name_index);
|
||||
Label add_name_entry_find_index(this),
|
||||
add_name_entry_known_index(this, &var_name_index),
|
||||
duplicate_name(this, &var_name_index), next(this);
|
||||
NameDictionaryLookup<PropertyDictionary>(
|
||||
CAST(properties), name, &duplicate_name, &var_name_index,
|
||||
&add_name_entry_find_index, kFindExisting,
|
||||
&add_name_entry_known_index);
|
||||
BIND(&duplicate_name);
|
||||
GotoIf(IsUndefined(capture), &next);
|
||||
CSA_DCHECK(this,
|
||||
TaggedEqual(LoadValueByKeyIndex<PropertyDictionary>(
|
||||
CAST(properties), var_name_index.value()),
|
||||
UndefinedConstant()));
|
||||
StoreValueByKeyIndex<PropertyDictionary>(CAST(properties),
|
||||
var_name_index.value(), capture);
|
||||
Goto(&next);
|
||||
|
||||
BIND(&add_name_entry_find_index);
|
||||
FindInsertionEntry<PropertyDictionary>(CAST(properties), name,
|
||||
&var_name_index);
|
||||
Goto(&add_name_entry_known_index);
|
||||
|
||||
BIND(&add_name_entry_known_index);
|
||||
AddToDictionary<PropertyDictionary>(CAST(properties), name, capture,
|
||||
&add_dictionary_property_slow,
|
||||
var_name_index.value());
|
||||
Goto(&next);
|
||||
|
||||
BIND(&next);
|
||||
var_i = i_plus_2;
|
||||
Branch(IntPtrGreaterThanOrEqual(var_i.value(), names_length),
|
||||
&maybe_build_indices, &inner_loop);
|
||||
@ -578,7 +604,8 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
|
||||
// instead of referencing the CodeWrapper object, we could directly load
|
||||
// the entrypoint from that via LoadCodeEntrypointViaCodePointerField. This
|
||||
// will save an indirection when the sandbox is enabled.
|
||||
TNode<RawPtrT> code_entry = LoadCodeInstructionStart(code);
|
||||
TNode<RawPtrT> code_entry =
|
||||
LoadCodeInstructionStart(code, kRegExpEntrypointTag);
|
||||
|
||||
// AIX uses function descriptors on CFunction calls. code_entry in this case
|
||||
// may also point to a Regex interpreter entry trampoline which does not
|
||||
|
22
deps/v8/src/builtins/builtins.cc
vendored
22
deps/v8/src/builtins/builtins.cc
vendored
@ -462,6 +462,28 @@ bool Builtins::IsCpp(Builtin builtin) {
|
||||
return Builtins::KindOf(builtin) == CPP;
|
||||
}
|
||||
|
||||
// static
|
||||
CodeEntrypointTag Builtins::EntrypointTagFor(Builtin builtin) {
|
||||
if (builtin == Builtin::kNoBuiltinId) {
|
||||
// Special case needed for example for tests.
|
||||
return kDefaultCodeEntrypointTag;
|
||||
}
|
||||
|
||||
Kind kind = Builtins::KindOf(builtin);
|
||||
switch (kind) {
|
||||
case BCH:
|
||||
return kBytecodeHandlerEntrypointTag;
|
||||
case TFH:
|
||||
return kICHandlerEntrypointTag;
|
||||
case ASM:
|
||||
// TODO(saelo) consider using this approach for the other kinds as well.
|
||||
return CallInterfaceDescriptorFor(builtin).tag();
|
||||
default:
|
||||
// TODO(saelo): use more fine-grained tags here.
|
||||
return kDefaultCodeEntrypointTag;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool Builtins::AllowDynamicFunction(Isolate* isolate, Handle<JSFunction> target,
|
||||
Handle<JSObject> target_global_proxy) {
|
||||
|
4
deps/v8/src/builtins/builtins.h
vendored
4
deps/v8/src/builtins/builtins.h
vendored
@ -9,6 +9,7 @@
|
||||
#include "src/builtins/builtins-definitions.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/objects/type-hints.h"
|
||||
#include "src/sandbox/code-entrypoint-tag.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -193,6 +194,9 @@ class Builtins {
|
||||
static Kind KindOf(Builtin builtin);
|
||||
static const char* KindNameOf(Builtin builtin);
|
||||
|
||||
// The tag for the builtins entrypoint.
|
||||
V8_EXPORT_PRIVATE static CodeEntrypointTag EntrypointTagFor(Builtin builtin);
|
||||
|
||||
static bool IsCpp(Builtin builtin);
|
||||
|
||||
// True, iff the given code object is a builtin. Note that this does not
|
||||
|
15
deps/v8/src/builtins/collections.tq
vendored
15
deps/v8/src/builtins/collections.tq
vendored
@ -288,21 +288,26 @@ transitioning macro GetSetRecord(
|
||||
// 6. Let intSize be ! ToIntegerOrInfinity(numSize).
|
||||
const intSize = ToInteger_Inline(numSize);
|
||||
|
||||
// 7. Let has be ? Get(obj, "has").
|
||||
// 7. If intSize < 0, throw a RangeError exception.
|
||||
if (intSize < 0) {
|
||||
ThrowRangeError(MessageTemplate::kInvalidSizeValue, intSize);
|
||||
}
|
||||
|
||||
// 8. Let has be ? Get(obj, "has").
|
||||
let has = GetProperty(obj, kHasString);
|
||||
|
||||
// 8. If IsCallable(has) is false, throw a TypeError exception.
|
||||
// 9. If IsCallable(has) is false, throw a TypeError exception.
|
||||
has = Cast<Callable>(has)
|
||||
otherwise ThrowCalledNonCallable(kHasString);
|
||||
|
||||
// 9. Let keys be ? Get(obj, "keys").
|
||||
// 10. Let keys be ? Get(obj, "keys").
|
||||
let keys = GetProperty(obj, kKeysString);
|
||||
|
||||
// 10. If IsCallable(keys) is false, throw a TypeError exception.
|
||||
// 11. If IsCallable(keys) is false, throw a TypeError exception.
|
||||
keys = Cast<Callable>(keys)
|
||||
otherwise ThrowCalledNonCallable(kKeysString);
|
||||
|
||||
// 11. Return a new Set Record { [[Set]]: obj, [[Size]]: intSize, [[Has]]:
|
||||
// 12. Return a new Set Record { [[Set]]: obj, [[Size]]: intSize, [[Has]]:
|
||||
// has, [[Keys]]: keys }.
|
||||
return SetRecord{object: obj, size: intSize, has: has, keys: keys};
|
||||
}
|
||||
|
9
deps/v8/src/builtins/js-to-js.tq
vendored
9
deps/v8/src/builtins/js-to-js.tq
vendored
@ -42,6 +42,8 @@ macro ConvertToAndFromWasm(context: Context, wasmType: int32, value: JSAny):
|
||||
} else if (wasmType == kWasmF64Type) {
|
||||
return Convert<Number>(WasmTaggedToFloat64(value));
|
||||
} else {
|
||||
const wasmKind = wasmType & kValueTypeKindBitsMask;
|
||||
dcheck(wasmKind == ValueKind::kRef || wasmKind == ValueKind::kRefNull);
|
||||
if (value == Null) {
|
||||
// At the moment it is not possible to define non-nullable types for
|
||||
// WebAssembly.Functions.
|
||||
@ -61,6 +63,13 @@ macro ConvertToAndFromWasm(context: Context, wasmType: int32, value: JSAny):
|
||||
}
|
||||
}
|
||||
|
||||
extern runtime WasmThrowJSTypeError(Context): never;
|
||||
|
||||
transitioning javascript builtin JSToJSWrapperInvalidSig(
|
||||
js-implicit context: NativeContext)(): JSAny {
|
||||
runtime::WasmThrowJSTypeError(context);
|
||||
}
|
||||
|
||||
transitioning javascript builtin JSToJSWrapper(
|
||||
js-implicit context: NativeContext, receiver: JSAny, target: JSFunction)(
|
||||
...arguments): JSAny {
|
||||
|
4
deps/v8/src/builtins/js-to-wasm.tq
vendored
4
deps/v8/src/builtins/js-to-wasm.tq
vendored
@ -504,6 +504,8 @@ macro JSToWasmWrapperHelper(
|
||||
} else if (retType == kWasmF64Type) {
|
||||
allocator.AllocFP64();
|
||||
} else {
|
||||
const retKind = retType & kValueTypeKindBitsMask;
|
||||
dcheck(retKind == ValueKind::kRef || retKind == ValueKind::kRefNull);
|
||||
// Also check if there are any reference return values, as this allows
|
||||
// us to skip code when we process return values.
|
||||
hasRefReturns = true;
|
||||
@ -600,6 +602,8 @@ macro JSToWasmWrapperHelper(
|
||||
*toHighRef = Signed(pair.high);
|
||||
}
|
||||
} else {
|
||||
const paramKind = paramType & kValueTypeKindBitsMask;
|
||||
dcheck(paramKind == ValueKind::kRef || paramKind == ValueKind::kRefNull);
|
||||
// The byte array where we store converted parameters is not GC-safe.
|
||||
// Therefore we can only copy references into this array once no GC can
|
||||
// happen anymore. Any conversion of a primitive type can execute
|
||||
|
@ -305,6 +305,7 @@ macro CreatePromiseCapability(
|
||||
struct PromiseResolvingFunctions {
|
||||
resolve: JSFunction;
|
||||
reject: JSFunction;
|
||||
context: Context;
|
||||
}
|
||||
|
||||
@export
|
||||
@ -322,7 +323,11 @@ macro CreatePromiseResolvingFunctions(
|
||||
const rejectInfo = PromiseCapabilityDefaultRejectSharedFunConstant();
|
||||
const reject: JSFunction =
|
||||
AllocateFunctionWithMapAndContext(map, rejectInfo, promiseContext);
|
||||
return PromiseResolvingFunctions{resolve: resolve, reject: reject};
|
||||
return PromiseResolvingFunctions{
|
||||
resolve: resolve,
|
||||
reject: reject,
|
||||
context: promiseContext
|
||||
};
|
||||
}
|
||||
|
||||
transitioning macro InnerNewPromiseCapability(
|
||||
|
7
deps/v8/src/builtins/promise-constructor.tq
vendored
7
deps/v8/src/builtins/promise-constructor.tq
vendored
@ -82,6 +82,13 @@ transitioning javascript builtin PromiseConstructor(
|
||||
try {
|
||||
Call(context, UnsafeCast<Callable>(executor), Undefined, resolve, reject);
|
||||
} catch (e, _message) {
|
||||
// We need to disable the debug event, as we have already paused on this
|
||||
// exception.
|
||||
const promiseContext =
|
||||
%RawDownCast<PromiseResolvingFunctionContext>(funcs.context);
|
||||
*ContextSlot(
|
||||
promiseContext, PromiseResolvingFunctionContextSlot::kDebugEventSlot) =
|
||||
False;
|
||||
Call(context, reject, Undefined, e);
|
||||
}
|
||||
|
||||
|
5
deps/v8/src/builtins/riscv/builtins-riscv.cc
vendored
5
deps/v8/src/builtins/riscv/builtins-riscv.cc
vendored
@ -3028,7 +3028,10 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
|
||||
|
||||
// Check result for exception sentinel.
|
||||
Label exception_returned;
|
||||
__ Branch(&exception_returned, eq, a0, RootIndex::kException);
|
||||
// The returned value may be a trusted object, living outside of the main
|
||||
// pointer compression cage, so we need to use full pointer comparison here.
|
||||
__ CompareRootAndBranch(a0, RootIndex::kException, eq, &exception_returned,
|
||||
ComparisonMode::kFullPointer);
|
||||
|
||||
// Check that there is no exception, otherwise we
|
||||
// should have returned the exception sentinel.
|
||||
|
10
deps/v8/src/builtins/wasm-strings.tq
vendored
10
deps/v8/src/builtins/wasm-strings.tq
vendored
@ -63,6 +63,16 @@ transitioning javascript builtin WebAssemblyStringIntoUtf8Array(
|
||||
}
|
||||
}
|
||||
|
||||
transitioning javascript builtin WebAssemblyStringToUtf8Array(
|
||||
js-implicit context: Context)(...arguments): JSAny {
|
||||
try {
|
||||
const string = Cast<String>(arguments[0]) otherwise goto IllegalCast;
|
||||
return runtime::WasmStringToUtf8Array(context, string);
|
||||
} label IllegalCast deferred {
|
||||
Trap(context, MessageTemplate::kWasmTrapIllegalCast);
|
||||
}
|
||||
}
|
||||
|
||||
transitioning javascript builtin WebAssemblyStringToWtf16Array(
|
||||
js-implicit context: Context)(...arguments): JSAny {
|
||||
try {
|
||||
|
3
deps/v8/src/builtins/wasm-to-js.tq
vendored
3
deps/v8/src/builtins/wasm-to-js.tq
vendored
@ -81,6 +81,7 @@ transitioning macro WasmToJSWrapper(ref: WasmApiFunctionRef): WasmToJSResult {
|
||||
const returnCount =
|
||||
Convert<intptr>(*torque_internal::unsafe::NewReference<int32>(
|
||||
serializedSig.object, serializedSig.offset));
|
||||
dcheck(returnCount < serializedSig.length);
|
||||
const paramCount: intptr = serializedSig.length - returnCount - 1;
|
||||
const returnTypes = Subslice(serializedSig, Convert<intptr>(1), returnCount)
|
||||
otherwise unreachable;
|
||||
@ -261,6 +262,8 @@ transitioning macro WasmToJSWrapper(ref: WasmApiFunctionRef): WasmToJSResult {
|
||||
*toHighRef = Signed(pair.high);
|
||||
}
|
||||
} else {
|
||||
const retKind = retType & kValueTypeKindBitsMask;
|
||||
dcheck(retKind == ValueKind::kRef || retKind == ValueKind::kRefNull);
|
||||
dcheck(ref.instance == Undefined || Is<WasmInstanceObject>(ref.instance));
|
||||
const trustedData = ref.instance == Undefined ?
|
||||
Undefined :
|
||||
|
4
deps/v8/src/builtins/wasm.tq
vendored
4
deps/v8/src/builtins/wasm.tq
vendored
@ -62,6 +62,7 @@ extern runtime WasmStringEncodeWtf8(
|
||||
Context, WasmTrustedInstanceData, Smi, Smi, String, Number): Number;
|
||||
extern runtime WasmStringEncodeWtf8Array(
|
||||
Context, Smi, String, WasmArray, Number): Number;
|
||||
extern runtime WasmStringToUtf8Array(Context, String): WasmArray;
|
||||
extern runtime WasmStringEncodeWtf16(
|
||||
Context, WasmTrustedInstanceData, Smi, String, Number, Smi, Smi): JSAny;
|
||||
extern runtime WasmStringAsWtf8(Context, String): ByteArray;
|
||||
@ -995,6 +996,9 @@ builtin WasmStringEncodeWtf8Array(
|
||||
WasmUint32ToNumber(start));
|
||||
return ChangeNumberToUint32(result);
|
||||
}
|
||||
builtin WasmStringToUtf8Array(string: String): WasmArray {
|
||||
return runtime::WasmStringToUtf8Array(LoadContextFromFrame(), string);
|
||||
}
|
||||
builtin WasmStringEncodeWtf16(string: String, offset: uint32, memory: Smi):
|
||||
uint32 {
|
||||
const trustedData = LoadInstanceDataFromFrame();
|
||||
|
27
deps/v8/src/builtins/x64/builtins-x64.cc
vendored
27
deps/v8/src/builtins/x64/builtins-x64.cc
vendored
@ -759,9 +759,8 @@ static void GetSharedFunctionInfoBytecodeOrBaseline(
|
||||
&done);
|
||||
}
|
||||
|
||||
__ LoadTrustedPointerField(
|
||||
bytecode, FieldOperand(data, InterpreterData::kBytecodeArrayOffset),
|
||||
kBytecodeArrayIndirectPointerTag, scratch1);
|
||||
__ LoadProtectedPointerField(
|
||||
bytecode, FieldOperand(data, InterpreterData::kBytecodeArrayOffset));
|
||||
|
||||
__ bind(&done);
|
||||
__ IsObjectType(bytecode, BYTECODE_ARRAY_TYPE, scratch1);
|
||||
@ -1298,7 +1297,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(
|
||||
__ ReplaceClosureCodeWithOptimizedCode(
|
||||
rcx, closure, kInterpreterBytecodeArrayRegister,
|
||||
WriteBarrierDescriptor::SlotAddressRegister());
|
||||
__ JumpCodeObject(rcx);
|
||||
__ JumpCodeObject(rcx, kJSEntrypointTag);
|
||||
|
||||
__ bind(&install_baseline_code);
|
||||
__ GenerateTailCallToReturnedCode(Runtime::kInstallBaselineCode);
|
||||
@ -1707,11 +1706,9 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
GetSharedFunctionInfoData(masm, rbx, shared_function_info, kScratchRegister);
|
||||
__ IsObjectType(rbx, INTERPRETER_DATA_TYPE, kScratchRegister);
|
||||
__ j(not_equal, &builtin_trampoline, Label::kNear);
|
||||
|
||||
__ LoadCodePointerField(
|
||||
rbx, FieldOperand(rbx, InterpreterData::kInterpreterTrampolineOffset),
|
||||
kScratchRegister);
|
||||
__ LoadCodeInstructionStart(rbx, rbx);
|
||||
__ LoadProtectedPointerField(
|
||||
rbx, FieldOperand(rbx, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ LoadCodeInstructionStart(rbx, rbx, kJSEntrypointTag);
|
||||
__ jmp(&trampoline_loaded, Label::kNear);
|
||||
|
||||
__ bind(&builtin_trampoline);
|
||||
@ -1841,7 +1838,7 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
|
||||
FieldOperand(closure, JSFunction::kFeedbackCellOffset));
|
||||
__ LoadTaggedField(feedback_vector,
|
||||
FieldOperand(feedback_cell, FeedbackCell::kValueOffset));
|
||||
__ AssertFeedbackVector(feedback_vector);
|
||||
__ AssertFeedbackVector(feedback_vector, kScratchRegister);
|
||||
|
||||
// Check the tiering state.
|
||||
Label flags_need_processing;
|
||||
@ -2935,18 +2932,18 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
|
||||
}
|
||||
|
||||
// Load deoptimization data from the code object.
|
||||
const TaggedRegister deopt_data(rbx);
|
||||
__ LoadTaggedField(
|
||||
const Register deopt_data(rbx);
|
||||
__ LoadProtectedPointerField(
|
||||
deopt_data,
|
||||
FieldOperand(rax, Code::kDeoptimizationDataOrInterpreterDataOffset));
|
||||
|
||||
// Load the OSR entrypoint offset from the deoptimization data.
|
||||
__ SmiUntagField(
|
||||
rbx,
|
||||
FieldOperand(deopt_data, FixedArray::OffsetOfElementAt(
|
||||
FieldOperand(deopt_data, TrustedFixedArray::OffsetOfElementAt(
|
||||
DeoptimizationData::kOsrPcOffsetIndex)));
|
||||
|
||||
__ LoadCodeInstructionStart(rax, rax);
|
||||
__ LoadCodeInstructionStart(rax, rax, kJSEntrypointTag);
|
||||
|
||||
// Compute the target address = code_entry + osr_offset
|
||||
__ addq(rax, rbx);
|
||||
@ -4990,7 +4987,7 @@ void Generate_BaselineOrInterpreterEntry(MacroAssembler* masm,
|
||||
__ movq(kCArgRegs[2], kInterpreterBytecodeArrayRegister);
|
||||
__ CallCFunction(get_baseline_pc, 3);
|
||||
}
|
||||
__ LoadCodeInstructionStart(code_obj, code_obj);
|
||||
__ LoadCodeInstructionStart(code_obj, code_obj, kJSEntrypointTag);
|
||||
__ addq(code_obj, kReturnRegister0);
|
||||
__ popq(kInterpreterAccumulatorRegister);
|
||||
|
||||
|
16
deps/v8/src/codegen/arm/assembler-arm.cc
vendored
16
deps/v8/src/codegen/arm/assembler-arm.cc
vendored
@ -1250,7 +1250,7 @@ void Assembler::AddrMode1(Instr instr, Register rd, Register rn,
|
||||
// pool only for a MOV instruction which does not set the flags.
|
||||
DCHECK(!rn.is_valid());
|
||||
Move32BitImmediate(rd, x, cond);
|
||||
} else if ((opcode == ADD) && !set_flags && (rd == rn) &&
|
||||
} else if ((opcode == ADD || opcode == SUB) && !set_flags && (rd == rn) &&
|
||||
!temps.CanAcquire()) {
|
||||
// Split the operation into a sequence of additions if we cannot use a
|
||||
// scratch register. In this case, we cannot re-use rn and the assembler
|
||||
@ -1266,10 +1266,20 @@ void Assembler::AddrMode1(Instr instr, Register rd, Register rn,
|
||||
// immediate allows us to more efficiently split it:
|
||||
int trailing_zeroes = base::bits::CountTrailingZeros(imm) & ~1u;
|
||||
uint32_t mask = (0xFF << trailing_zeroes);
|
||||
add(rd, rd, Operand(imm & mask), LeaveCC, cond);
|
||||
if (opcode == ADD) {
|
||||
add(rd, rd, Operand(imm & mask), LeaveCC, cond);
|
||||
} else {
|
||||
DCHECK_EQ(opcode, SUB);
|
||||
sub(rd, rd, Operand(imm & mask), LeaveCC, cond);
|
||||
}
|
||||
imm = imm & ~mask;
|
||||
} while (!ImmediateFitsAddrMode1Instruction(imm));
|
||||
add(rd, rd, Operand(imm), LeaveCC, cond);
|
||||
if (opcode == ADD) {
|
||||
add(rd, rd, Operand(imm), LeaveCC, cond);
|
||||
} else {
|
||||
DCHECK_EQ(opcode, SUB);
|
||||
sub(rd, rd, Operand(imm), LeaveCC, cond);
|
||||
}
|
||||
} else {
|
||||
// The immediate operand cannot be encoded as a shifter operand, so load
|
||||
// it first to a scratch register and change the original instruction to
|
||||
|
@ -164,6 +164,11 @@ constexpr Register MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor::
|
||||
FeedbackVectorRegister() {
|
||||
return r5;
|
||||
}
|
||||
// static
|
||||
constexpr Register
|
||||
MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor::TemporaryRegister() {
|
||||
return r4;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallTrampolineDescriptor::registers() {
|
||||
|
65
deps/v8/src/codegen/arm/macro-assembler-arm.cc
vendored
65
deps/v8/src/codegen/arm/macro-assembler-arm.cc
vendored
@ -363,7 +363,8 @@ void MacroAssembler::TailCallBuiltin(Builtin builtin, Condition cond) {
|
||||
}
|
||||
|
||||
void MacroAssembler::LoadCodeInstructionStart(Register destination,
|
||||
Register code_object) {
|
||||
Register code_object,
|
||||
CodeEntrypointTag tag) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
ldr(destination, FieldMemOperand(code_object, Code::kInstructionStartOffset));
|
||||
}
|
||||
@ -2006,10 +2007,8 @@ void MacroAssembler::AssertFeedbackCell(Register object, Register scratch) {
|
||||
Assert(eq, AbortReason::kExpectedFeedbackCell);
|
||||
}
|
||||
}
|
||||
void MacroAssembler::AssertFeedbackVector(Register object) {
|
||||
void MacroAssembler::AssertFeedbackVector(Register object, Register scratch) {
|
||||
if (v8_flags.debug_code) {
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register scratch = temps.Acquire();
|
||||
CompareObjectType(object, scratch, scratch, FEEDBACK_VECTOR_TYPE);
|
||||
Assert(eq, AbortReason::kExpectedFeedbackVector);
|
||||
}
|
||||
@ -2729,20 +2728,22 @@ void MacroAssembler::MovToFloatParameters(DwVfpRegister src1,
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_reg_arguments,
|
||||
int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
int MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_reg_arguments,
|
||||
int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_label) {
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register scratch = temps.Acquire();
|
||||
Move(scratch, function);
|
||||
CallCFunction(scratch, num_reg_arguments, num_double_arguments,
|
||||
set_isolate_data_slots);
|
||||
return CallCFunction(scratch, num_reg_arguments, num_double_arguments,
|
||||
set_isolate_data_slots, return_label);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(Register function, int num_reg_arguments,
|
||||
int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
int MacroAssembler::CallCFunction(Register function, int num_reg_arguments,
|
||||
int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_label) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
DCHECK_LE(num_reg_arguments + num_double_arguments, kMaxCParameters);
|
||||
DCHECK(has_frame());
|
||||
@ -2767,13 +2768,19 @@ void MacroAssembler::CallCFunction(Register function, int num_reg_arguments,
|
||||
}
|
||||
#endif
|
||||
|
||||
Label get_pc;
|
||||
|
||||
if (set_isolate_data_slots == SetIsolateDataSlots::kYes) {
|
||||
Register pc_scratch = r5;
|
||||
Push(pc_scratch);
|
||||
GetLabelAddress(pc_scratch, &get_pc);
|
||||
|
||||
// Save the frame pointer and PC so that the stack layout remains iterable,
|
||||
// even without an ExitFrame which normally exists between JS and C frames.
|
||||
// See x64 code for reasoning about how to address the isolate data fields.
|
||||
if (root_array_available()) {
|
||||
str(pc, MemOperand(kRootRegister,
|
||||
IsolateData::fast_c_call_caller_pc_offset()));
|
||||
str(pc_scratch, MemOperand(kRootRegister,
|
||||
IsolateData::fast_c_call_caller_pc_offset()));
|
||||
str(fp, MemOperand(kRootRegister,
|
||||
IsolateData::fast_c_call_caller_fp_offset()));
|
||||
} else {
|
||||
@ -2783,19 +2790,24 @@ void MacroAssembler::CallCFunction(Register function, int num_reg_arguments,
|
||||
|
||||
Move(addr_scratch,
|
||||
ExternalReference::fast_c_call_caller_pc_address(isolate()));
|
||||
str(pc, MemOperand(addr_scratch));
|
||||
str(pc_scratch, MemOperand(addr_scratch));
|
||||
Move(addr_scratch,
|
||||
ExternalReference::fast_c_call_caller_fp_address(isolate()));
|
||||
str(fp, MemOperand(addr_scratch));
|
||||
|
||||
Pop(addr_scratch);
|
||||
}
|
||||
|
||||
Pop(pc_scratch);
|
||||
}
|
||||
|
||||
// Just call directly. The function called cannot cause a GC, or
|
||||
// allow preemption, so the return address in the link register
|
||||
// stays correct.
|
||||
Call(function);
|
||||
int call_pc_offset = pc_offset();
|
||||
bind(&get_pc);
|
||||
if (return_label) bind(return_label);
|
||||
|
||||
if (set_isolate_data_slots == SetIsolateDataSlots::kYes) {
|
||||
// We don't unset the PC; the FP is the source of truth.
|
||||
@ -2827,17 +2839,22 @@ void MacroAssembler::CallCFunction(Register function, int num_reg_arguments,
|
||||
} else {
|
||||
add(sp, sp, Operand(stack_passed_arguments * kPointerSize));
|
||||
}
|
||||
|
||||
return call_pc_offset;
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
CallCFunction(function, num_arguments, 0, set_isolate_data_slots);
|
||||
int MacroAssembler::CallCFunction(ExternalReference function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_label) {
|
||||
return CallCFunction(function, num_arguments, 0, set_isolate_data_slots,
|
||||
return_label);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
CallCFunction(function, num_arguments, 0, set_isolate_data_slots);
|
||||
int MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_label) {
|
||||
return CallCFunction(function, num_arguments, 0, set_isolate_data_slots,
|
||||
return_label);
|
||||
}
|
||||
|
||||
void MacroAssembler::CheckPageFlag(Register object, int mask, Condition cc,
|
||||
@ -2848,7 +2865,7 @@ void MacroAssembler::CheckPageFlag(Register object, int mask, Condition cc,
|
||||
DCHECK(!AreAliased(object, scratch));
|
||||
DCHECK(cc == eq || cc == ne);
|
||||
Bfc(scratch, object, 0, kPageSizeBits);
|
||||
ldr(scratch, MemOperand(scratch, BasicMemoryChunk::kFlagsOffset));
|
||||
ldr(scratch, MemOperand(scratch, MemoryChunkLayout::kFlagsOffset));
|
||||
tst(scratch, Operand(mask));
|
||||
b(cc, condition_met);
|
||||
}
|
||||
|
31
deps/v8/src/codegen/arm/macro-assembler-arm.h
vendored
31
deps/v8/src/codegen/arm/macro-assembler-arm.h
vendored
@ -252,23 +252,23 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
|
||||
// garbage collection, since that might move the code and invalidate the
|
||||
// return address (unless this is somehow accounted for by the called
|
||||
// function).
|
||||
enum class SetIsolateDataSlots {
|
||||
kNo,
|
||||
kYes,
|
||||
};
|
||||
void CallCFunction(
|
||||
int CallCFunction(
|
||||
ExternalReference function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
void CallCFunction(
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_label = nullptr);
|
||||
int CallCFunction(
|
||||
Register function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
void CallCFunction(
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_label = nullptr);
|
||||
int CallCFunction(
|
||||
ExternalReference function, int num_reg_arguments,
|
||||
int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
void CallCFunction(
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_label = nullptr);
|
||||
int CallCFunction(
|
||||
Register function, int num_reg_arguments, int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_label = nullptr);
|
||||
|
||||
void MovFromFloatParameter(DwVfpRegister dst);
|
||||
void MovFromFloatResult(DwVfpRegister dst);
|
||||
@ -337,7 +337,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
|
||||
void TailCallBuiltin(Builtin builtin, Condition cond = al);
|
||||
|
||||
// Load the code entry point from the Code object.
|
||||
void LoadCodeInstructionStart(Register destination, Register code_object);
|
||||
void LoadCodeInstructionStart(
|
||||
Register destination, Register code_object,
|
||||
CodeEntrypointTag tag = kDefaultCodeEntrypointTag);
|
||||
void CallCodeObject(Register code_object);
|
||||
void JumpCodeObject(Register code_object,
|
||||
JumpMode jump_mode = JumpMode::kJump);
|
||||
@ -875,7 +877,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
|
||||
// Tiering support.
|
||||
void AssertFeedbackCell(Register object,
|
||||
Register scratch) NOOP_UNLESS_DEBUG_CODE;
|
||||
void AssertFeedbackVector(Register object) NOOP_UNLESS_DEBUG_CODE;
|
||||
void AssertFeedbackVector(Register object,
|
||||
Register scratch) NOOP_UNLESS_DEBUG_CODE;
|
||||
void ReplaceClosureCodeWithOptimizedCode(Register optimized_code,
|
||||
Register closure);
|
||||
void GenerateTailCallToReturnedCode(Runtime::FunctionId function_id);
|
||||
|
@ -154,6 +154,11 @@ constexpr Register MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor::
|
||||
FeedbackVectorRegister() {
|
||||
return x9;
|
||||
}
|
||||
// static
|
||||
constexpr Register
|
||||
MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor::TemporaryRegister() {
|
||||
return x4;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto TypeofDescriptor::registers() { return RegisterArray(x0); }
|
||||
|
@ -1440,7 +1440,7 @@ void TailCallOptimizedCodeSlot(MacroAssembler* masm,
|
||||
__ ReplaceClosureCodeWithOptimizedCode(optimized_code_entry, closure);
|
||||
static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch");
|
||||
__ Move(x2, optimized_code_entry);
|
||||
__ JumpCodeObject(x2);
|
||||
__ JumpCodeObject(x2, kJSEntrypointTag);
|
||||
|
||||
// Optimized code slot contains deoptimized code or code is cleared and
|
||||
// optimized code marker isn't updated. Evict the code, update the marker
|
||||
@ -1507,7 +1507,7 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
|
||||
}
|
||||
|
||||
static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch");
|
||||
JumpCodeObject(x2);
|
||||
JumpCodeObject(x2, kJSEntrypointTag);
|
||||
}
|
||||
|
||||
// Read off the flags in the feedback vector and check if there
|
||||
@ -2061,31 +2061,37 @@ int MacroAssembler::ActivationFrameAlignment() {
|
||||
#endif // V8_HOST_ARCH_ARM64
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_of_reg_args,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
CallCFunction(function, num_of_reg_args, 0, set_isolate_data_slots);
|
||||
int MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_of_reg_args,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_location) {
|
||||
return CallCFunction(function, num_of_reg_args, 0, set_isolate_data_slots,
|
||||
return_location);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_of_reg_args, int num_of_double_args,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
int MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_of_reg_args, int num_of_double_args,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_location) {
|
||||
// Note: The "CallCFunction" code comment will be generated by the other
|
||||
// CallCFunction method called below.
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register temp = temps.AcquireX();
|
||||
Mov(temp, function);
|
||||
CallCFunction(temp, num_of_reg_args, num_of_double_args,
|
||||
set_isolate_data_slots);
|
||||
return CallCFunction(temp, num_of_reg_args, num_of_double_args,
|
||||
set_isolate_data_slots, return_location);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(Register function, int num_of_reg_args,
|
||||
int num_of_double_args,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
int MacroAssembler::CallCFunction(Register function, int num_of_reg_args,
|
||||
int num_of_double_args,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_location) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
DCHECK_LE(num_of_reg_args + num_of_double_args, kMaxCParameters);
|
||||
DCHECK(has_frame());
|
||||
|
||||
Label get_pc;
|
||||
|
||||
if (set_isolate_data_slots == SetIsolateDataSlots::kYes) {
|
||||
// Save the frame pointer and PC so that the stack layout remains iterable,
|
||||
// even without an ExitFrame which normally exists between JS and C frames.
|
||||
@ -2093,8 +2099,6 @@ void MacroAssembler::CallCFunction(Register function, int num_of_reg_args,
|
||||
Register addr_scratch = x5;
|
||||
Push(pc_scratch, addr_scratch);
|
||||
|
||||
Label get_pc;
|
||||
Bind(&get_pc);
|
||||
Adr(pc_scratch, &get_pc);
|
||||
|
||||
// See x64 code for reasoning about how to address the isolate data fields.
|
||||
@ -2119,6 +2123,9 @@ void MacroAssembler::CallCFunction(Register function, int num_of_reg_args,
|
||||
// Call directly. The function called cannot cause a GC, or allow preemption,
|
||||
// so the return address in the link register stays correct.
|
||||
Call(function);
|
||||
int call_pc_offset = pc_offset();
|
||||
bind(&get_pc);
|
||||
if (return_location) bind(return_location);
|
||||
|
||||
if (set_isolate_data_slots == SetIsolateDataSlots::kYes) {
|
||||
// We don't unset the PC; the FP is the source of truth.
|
||||
@ -2148,6 +2155,8 @@ void MacroAssembler::CallCFunction(Register function, int num_of_reg_args,
|
||||
RoundUp(num_of_double_args - kFPRegisterPassedArguments, 2);
|
||||
Drop(claim_slots);
|
||||
}
|
||||
|
||||
return call_pc_offset;
|
||||
}
|
||||
|
||||
void MacroAssembler::LoadFromConstantsTable(Register destination,
|
||||
@ -2459,27 +2468,30 @@ void MacroAssembler::TailCallBuiltin(Builtin builtin, Condition cond) {
|
||||
}
|
||||
|
||||
void MacroAssembler::LoadCodeInstructionStart(Register destination,
|
||||
Register code_object) {
|
||||
Register code_object,
|
||||
CodeEntrypointTag tag) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
LoadCodeEntrypointViaCodePointer(
|
||||
destination,
|
||||
FieldMemOperand(code_object, Code::kSelfIndirectPointerOffset));
|
||||
FieldMemOperand(code_object, Code::kSelfIndirectPointerOffset), tag);
|
||||
#else
|
||||
Ldr(destination, FieldMemOperand(code_object, Code::kInstructionStartOffset));
|
||||
#endif
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCodeObject(Register code_object) {
|
||||
void MacroAssembler::CallCodeObject(Register code_object,
|
||||
CodeEntrypointTag tag) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
LoadCodeInstructionStart(code_object, code_object);
|
||||
LoadCodeInstructionStart(code_object, code_object, tag);
|
||||
Call(code_object);
|
||||
}
|
||||
|
||||
void MacroAssembler::JumpCodeObject(Register code_object, JumpMode jump_mode) {
|
||||
void MacroAssembler::JumpCodeObject(Register code_object, CodeEntrypointTag tag,
|
||||
JumpMode jump_mode) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
DCHECK_EQ(JumpMode::kJump, jump_mode);
|
||||
LoadCodeInstructionStart(code_object, code_object);
|
||||
LoadCodeInstructionStart(code_object, code_object, tag);
|
||||
// We jump through x17 here because for Branch Identification (BTI) we use
|
||||
// "Call" (`bti c`) rather than "Jump" (`bti j`) landing pads for tail-called
|
||||
// code. See TailCallBuiltin for more information.
|
||||
@ -2496,12 +2508,13 @@ void MacroAssembler::CallJSFunction(Register function_object) {
|
||||
// from the code pointer table instead of going through the Code object. In
|
||||
// this way, we avoid one memory load on this code path.
|
||||
LoadCodeEntrypointViaCodePointer(
|
||||
code, FieldMemOperand(function_object, JSFunction::kCodeOffset));
|
||||
code, FieldMemOperand(function_object, JSFunction::kCodeOffset),
|
||||
kJSEntrypointTag);
|
||||
Call(code);
|
||||
#else
|
||||
LoadTaggedField(code,
|
||||
FieldMemOperand(function_object, JSFunction::kCodeOffset));
|
||||
CallCodeObject(code);
|
||||
CallCodeObject(code, kJSEntrypointTag);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2513,7 +2526,8 @@ void MacroAssembler::JumpJSFunction(Register function_object,
|
||||
// from the code pointer table instead of going through the Code object. In
|
||||
// this way, we avoid one memory load on this code path.
|
||||
LoadCodeEntrypointViaCodePointer(
|
||||
code, FieldMemOperand(function_object, JSFunction::kCodeOffset));
|
||||
code, FieldMemOperand(function_object, JSFunction::kCodeOffset),
|
||||
kJSEntrypointTag);
|
||||
DCHECK_EQ(jump_mode, JumpMode::kJump);
|
||||
// We jump through x17 here because for Branch Identification (BTI) we use
|
||||
// "Call" (`bti c`) rather than "Jump" (`bti j`) landing pads for tail-called
|
||||
@ -2524,7 +2538,7 @@ void MacroAssembler::JumpJSFunction(Register function_object,
|
||||
#else
|
||||
LoadTaggedField(code,
|
||||
FieldMemOperand(function_object, JSFunction::kCodeOffset));
|
||||
JumpCodeObject(code, jump_mode);
|
||||
JumpCodeObject(code, kJSEntrypointTag, jump_mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -3479,8 +3493,8 @@ void MacroAssembler::CheckPageFlag(const Register& object, int mask,
|
||||
ASM_CODE_COMMENT(this);
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register scratch = temps.AcquireX();
|
||||
And(scratch, object, ~kPageAlignmentMask);
|
||||
Ldr(scratch, MemOperand(scratch, BasicMemoryChunk::kFlagsOffset));
|
||||
And(scratch, object, ~MemoryChunkHeader::GetAlignmentMaskForAssembler());
|
||||
Ldr(scratch, MemOperand(scratch, MemoryChunkLayout::kFlagsOffset));
|
||||
if (cc == ne) {
|
||||
TestAndBranchIfAnySet(scratch, mask, condition_met);
|
||||
} else {
|
||||
@ -3705,17 +3719,23 @@ void MacroAssembler::ResolveCodePointerHandle(Register destination,
|
||||
Orr(destination, destination, Immediate(kHeapObjectTag));
|
||||
}
|
||||
|
||||
void MacroAssembler::LoadCodeEntrypointViaCodePointer(
|
||||
Register destination, MemOperand field_operand) {
|
||||
void MacroAssembler::LoadCodeEntrypointViaCodePointer(Register destination,
|
||||
MemOperand field_operand,
|
||||
CodeEntrypointTag tag) {
|
||||
DCHECK_NE(tag, kInvalidEntrypointTag);
|
||||
ASM_CODE_COMMENT(this);
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register table = temps.AcquireX();
|
||||
Mov(table, ExternalReference::code_pointer_table_address());
|
||||
Register scratch = temps.AcquireX();
|
||||
Mov(scratch, ExternalReference::code_pointer_table_address());
|
||||
Ldr(destination.W(), field_operand);
|
||||
// TODO(saelo): can the offset computation be done more efficiently?
|
||||
Mov(destination, Operand(destination, LSR, kCodePointerHandleShift));
|
||||
Mov(destination, Operand(destination, LSL, kCodePointerTableEntrySizeLog2));
|
||||
Ldr(destination, MemOperand(table, destination));
|
||||
Ldr(destination, MemOperand(scratch, destination));
|
||||
if (tag != 0) {
|
||||
Mov(scratch, Immediate(tag));
|
||||
Eor(destination, destination, scratch);
|
||||
}
|
||||
}
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
|
||||
|
@ -1063,9 +1063,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
|
||||
void TailCallBuiltin(Builtin builtin, Condition cond = al);
|
||||
|
||||
// Load code entry point from the Code object.
|
||||
void LoadCodeInstructionStart(Register destination, Register code_object);
|
||||
void CallCodeObject(Register code_object);
|
||||
void JumpCodeObject(Register code_object,
|
||||
void LoadCodeInstructionStart(Register destination, Register code_object,
|
||||
CodeEntrypointTag tag);
|
||||
void CallCodeObject(Register code_object, CodeEntrypointTag tag);
|
||||
void JumpCodeObject(Register code_object, CodeEntrypointTag tag,
|
||||
JumpMode jump_mode = JumpMode::kJump);
|
||||
|
||||
// Convenience functions to call/jmp to the code of a JSFunction object.
|
||||
@ -1083,25 +1084,24 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
|
||||
DeoptimizeKind kind, Label* ret,
|
||||
Label* jump_deoptimization_entry_label);
|
||||
|
||||
// Calls a C function.
|
||||
// The called function is not allowed to trigger a
|
||||
// Calls a C function and cleans up the space for arguments allocated
|
||||
// by PrepareCallCFunction. The called function is not allowed to trigger a
|
||||
// garbage collection, since that might move the code and invalidate the
|
||||
// return address (unless this is somehow accounted for by the called
|
||||
// function).
|
||||
enum class SetIsolateDataSlots {
|
||||
kNo,
|
||||
kYes,
|
||||
};
|
||||
void CallCFunction(
|
||||
int CallCFunction(
|
||||
ExternalReference function, int num_reg_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
void CallCFunction(
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_location = nullptr);
|
||||
int CallCFunction(
|
||||
ExternalReference function, int num_reg_arguments,
|
||||
int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
void CallCFunction(
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_location = nullptr);
|
||||
int CallCFunction(
|
||||
Register function, int num_reg_arguments, int num_double_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_location = nullptr);
|
||||
|
||||
// Performs a truncating conversion of a floating point number as used by
|
||||
// the JS bitwise operations. See ECMA-262 9.5: ToInt32.
|
||||
@ -1632,7 +1632,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
|
||||
// Only available when the sandbox is enabled as it requires the code pointer
|
||||
// table.
|
||||
void LoadCodeEntrypointViaCodePointer(Register destination,
|
||||
MemOperand field_operand);
|
||||
MemOperand field_operand,
|
||||
CodeEntrypointTag tag);
|
||||
#endif
|
||||
|
||||
// Load a protected pointer field.
|
||||
|
277
deps/v8/src/codegen/code-stub-assembler.cc
vendored
277
deps/v8/src/codegen/code-stub-assembler.cc
vendored
@ -1842,12 +1842,12 @@ void CodeStubAssembler::StoreExternalPointerToObject(TNode<HeapObject> object,
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
}
|
||||
|
||||
TNode<HeapObject> CodeStubAssembler::LoadTrustedPointerFromObject(
|
||||
TNode<TrustedObject> CodeStubAssembler::LoadTrustedPointerFromObject(
|
||||
TNode<HeapObject> object, int field_offset, IndirectPointerTag tag) {
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
return LoadIndirectPointerFromObject(object, field_offset, tag);
|
||||
#else
|
||||
return LoadObjectField<HeapObject>(object, field_offset);
|
||||
return LoadObjectField<TrustedObject>(object, field_offset);
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
}
|
||||
|
||||
@ -1858,7 +1858,7 @@ TNode<Code> CodeStubAssembler::LoadCodePointerFromObject(
|
||||
}
|
||||
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
TNode<HeapObject> CodeStubAssembler::LoadIndirectPointerFromObject(
|
||||
TNode<TrustedObject> CodeStubAssembler::LoadIndirectPointerFromObject(
|
||||
TNode<HeapObject> object, int field_offset, IndirectPointerTag tag) {
|
||||
TNode<IndirectPointerHandleT> handle =
|
||||
LoadObjectField<IndirectPointerHandleT>(object, field_offset);
|
||||
@ -1871,13 +1871,13 @@ TNode<BoolT> CodeStubAssembler::IsTrustedPointerHandle(
|
||||
Int32Constant(0));
|
||||
}
|
||||
|
||||
TNode<HeapObject> CodeStubAssembler::ResolveIndirectPointerHandle(
|
||||
TNode<TrustedObject> CodeStubAssembler::ResolveIndirectPointerHandle(
|
||||
TNode<IndirectPointerHandleT> handle, IndirectPointerTag tag) {
|
||||
// The tag implies which pointer table to use.
|
||||
if (tag == kUnknownIndirectPointerTag) {
|
||||
// In this case we have to rely on the handle marking to determine which
|
||||
// pointer table to use.
|
||||
return Select<HeapObject>(
|
||||
return Select<TrustedObject>(
|
||||
IsTrustedPointerHandle(handle),
|
||||
[=] { return ResolveTrustedPointerHandle(handle, tag); },
|
||||
[=] { return ResolveCodePointerHandle(handle); });
|
||||
@ -1903,7 +1903,7 @@ TNode<Code> CodeStubAssembler::ResolveCodePointerHandle(
|
||||
return UncheckedCast<Code>(BitcastWordToTagged(value));
|
||||
}
|
||||
|
||||
TNode<HeapObject> CodeStubAssembler::ResolveTrustedPointerHandle(
|
||||
TNode<TrustedObject> CodeStubAssembler::ResolveTrustedPointerHandle(
|
||||
TNode<IndirectPointerHandleT> handle, IndirectPointerTag tag) {
|
||||
TNode<RawPtrT> table = ExternalConstant(
|
||||
ExternalReference::trusted_pointer_table_base_address(isolate()));
|
||||
@ -1919,7 +1919,7 @@ TNode<HeapObject> CodeStubAssembler::ResolveTrustedPointerHandle(
|
||||
// to set it using a bitwise OR as it may or may not be set.
|
||||
value =
|
||||
UncheckedCast<UintPtrT>(WordOr(value, UintPtrConstant(kHeapObjectTag)));
|
||||
return UncheckedCast<HeapObject>(BitcastWordToTagged(value));
|
||||
return UncheckedCast<TrustedObject>(BitcastWordToTagged(value));
|
||||
}
|
||||
|
||||
TNode<UintPtrT> CodeStubAssembler::ComputeCodePointerTableEntryOffset(
|
||||
@ -1935,16 +1935,36 @@ TNode<UintPtrT> CodeStubAssembler::ComputeCodePointerTableEntryOffset(
|
||||
}
|
||||
|
||||
TNode<RawPtrT> CodeStubAssembler::LoadCodeEntrypointViaCodePointerField(
|
||||
TNode<HeapObject> object, TNode<IntPtrT> field_offset) {
|
||||
TNode<HeapObject> object, TNode<IntPtrT> field_offset,
|
||||
CodeEntrypointTag tag) {
|
||||
TNode<IndirectPointerHandleT> handle =
|
||||
LoadObjectField<IndirectPointerHandleT>(object, field_offset);
|
||||
TNode<RawPtrT> table =
|
||||
ExternalConstant(ExternalReference::code_pointer_table_address());
|
||||
TNode<UintPtrT> offset = ComputeCodePointerTableEntryOffset(handle);
|
||||
return Load<RawPtrT>(table, offset);
|
||||
TNode<UintPtrT> entry = Load<UintPtrT>(table, offset);
|
||||
if (tag != 0) {
|
||||
entry = UncheckedCast<UintPtrT>(WordXor(entry, UintPtrConstant(tag)));
|
||||
}
|
||||
return UncheckedCast<RawPtrT>(UncheckedCast<WordT>(entry));
|
||||
}
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
|
||||
TNode<TrustedObject> CodeStubAssembler::LoadProtectedPointerFromObject(
|
||||
TNode<TrustedObject> object, int offset) {
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
TNode<RawPtrT> trusted_cage_base = LoadPointerFromRootRegister(
|
||||
IntPtrConstant(IsolateData::trusted_cage_base_offset()));
|
||||
TNode<UintPtrT> offset_from_cage_base =
|
||||
ChangeUint32ToWord(LoadObjectField<Uint32T>(object, offset));
|
||||
TNode<UintPtrT> pointer =
|
||||
UncheckedCast<UintPtrT>(WordOr(trusted_cage_base, offset_from_cage_base));
|
||||
return UncheckedCast<TrustedObject>(BitcastWordToTagged(pointer));
|
||||
#else
|
||||
return LoadObjectField<TrustedObject>(object, offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
TNode<Object> CodeStubAssembler::LoadFromParentFrame(int offset) {
|
||||
TNode<RawPtrT> frame_pointer = LoadParentFramePointer();
|
||||
return LoadFullTagged(frame_pointer, IntPtrConstant(offset));
|
||||
@ -2099,13 +2119,8 @@ TNode<HeapObject> CodeStubAssembler::LoadSlowProperties(
|
||||
};
|
||||
NodeGenerator<HeapObject> cast_properties = [=] {
|
||||
TNode<HeapObject> dict = CAST(properties);
|
||||
if constexpr (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
CSA_DCHECK(this, Word32Or(IsSwissNameDictionary(dict),
|
||||
IsGlobalDictionary(dict)));
|
||||
} else {
|
||||
CSA_DCHECK(this,
|
||||
Word32Or(IsNameDictionary(dict), IsGlobalDictionary(dict)));
|
||||
}
|
||||
CSA_DCHECK(this,
|
||||
Word32Or(IsPropertyDictionary(dict), IsGlobalDictionary(dict)));
|
||||
return dict;
|
||||
};
|
||||
return Select<HeapObject>(TaggedIsSmi(properties), make_empty,
|
||||
@ -2640,6 +2655,12 @@ TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(
|
||||
return LoadAndUntagWeakFixedArrayLength(array);
|
||||
}
|
||||
|
||||
template <>
|
||||
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(
|
||||
TNode<TrustedFixedArray> array) {
|
||||
return SmiUntag(LoadArrayCapacity(array));
|
||||
}
|
||||
|
||||
template <typename Array, typename TIndex, typename TValue>
|
||||
TNode<TValue> CodeStubAssembler::LoadArrayElement(TNode<Array> array,
|
||||
int array_header_size,
|
||||
@ -2673,6 +2694,9 @@ template V8_EXPORT_PRIVATE TNode<Smi> CodeStubAssembler::LoadArrayElement<
|
||||
template V8_EXPORT_PRIVATE TNode<Context>
|
||||
CodeStubAssembler::LoadArrayElement<ScriptContextTable, IntPtrT>(
|
||||
TNode<ScriptContextTable>, int, TNode<IntPtrT>, int);
|
||||
template V8_EXPORT_PRIVATE TNode<MaybeObject>
|
||||
CodeStubAssembler::LoadArrayElement<TrustedFixedArray, IntPtrT>(
|
||||
TNode<TrustedFixedArray>, int, TNode<IntPtrT>, int);
|
||||
|
||||
template <typename TIndex>
|
||||
TNode<Object> CodeStubAssembler::LoadFixedArrayElement(
|
||||
@ -3468,27 +3492,17 @@ TNode<BytecodeArray> CodeStubAssembler::LoadSharedFunctionInfoBytecodeArray(
|
||||
this, Word32Equal(DecodeWord32<Code::KindField>(code_flags),
|
||||
Int32Constant(static_cast<int>(CodeKind::BASELINE))));
|
||||
#endif // DEBUG
|
||||
TNode<HeapObject> baseline_data = LoadObjectField<HeapObject>(
|
||||
TNode<HeapObject> baseline_data = LoadProtectedPointerFromObject(
|
||||
code, Code::kDeoptimizationDataOrInterpreterDataOffset);
|
||||
var_result = baseline_data;
|
||||
// As long as InterpreterData objects still live inside the sandbox, Code
|
||||
// references BytecodeArrays through their in-sandbox wrapper object.
|
||||
static_assert(!kInterpreterDataObjectsLiveInTrustedSpace);
|
||||
GotoIfNot(HasInstanceType(var_result.value(), BYTECODE_WRAPPER_TYPE),
|
||||
&check_for_interpreter_data);
|
||||
TNode<HeapObject> bytecode = LoadTrustedPointerFromObject(
|
||||
var_result.value(), BytecodeWrapper::kBytecodeOffset,
|
||||
kBytecodeArrayIndirectPointerTag);
|
||||
var_result = bytecode;
|
||||
Goto(&done);
|
||||
}
|
||||
Goto(&check_for_interpreter_data);
|
||||
|
||||
BIND(&check_for_interpreter_data);
|
||||
|
||||
GotoIfNot(HasInstanceType(var_result.value(), INTERPRETER_DATA_TYPE), &done);
|
||||
TNode<BytecodeArray> bytecode_array = CAST(LoadTrustedPointerFromObject(
|
||||
var_result.value(), InterpreterData::kBytecodeArrayOffset,
|
||||
kBytecodeArrayIndirectPointerTag));
|
||||
TNode<BytecodeArray> bytecode_array = CAST(LoadProtectedPointerFromObject(
|
||||
CAST(var_result.value()), InterpreterData::kBytecodeArrayOffset));
|
||||
var_result = bytecode_array;
|
||||
Goto(&done);
|
||||
|
||||
@ -4229,6 +4243,40 @@ TNode<NameDictionary> CodeStubAssembler::AllocateNameDictionaryWithCapacity(
|
||||
return result;
|
||||
}
|
||||
|
||||
TNode<PropertyDictionary> CodeStubAssembler::AllocatePropertyDictionary(
|
||||
int at_least_space_for) {
|
||||
TNode<HeapObject> dict;
|
||||
if constexpr (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
dict = AllocateSwissNameDictionary(at_least_space_for);
|
||||
} else {
|
||||
dict = AllocateNameDictionary(at_least_space_for);
|
||||
}
|
||||
return TNode<PropertyDictionary>::UncheckedCast(dict);
|
||||
}
|
||||
|
||||
TNode<PropertyDictionary> CodeStubAssembler::AllocatePropertyDictionary(
|
||||
TNode<IntPtrT> at_least_space_for, AllocationFlags flags) {
|
||||
TNode<HeapObject> dict;
|
||||
if constexpr (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
dict = AllocateSwissNameDictionary(at_least_space_for);
|
||||
} else {
|
||||
dict = AllocateNameDictionary(at_least_space_for, flags);
|
||||
}
|
||||
return TNode<PropertyDictionary>::UncheckedCast(dict);
|
||||
}
|
||||
|
||||
TNode<PropertyDictionary>
|
||||
CodeStubAssembler::AllocatePropertyDictionaryWithCapacity(
|
||||
TNode<IntPtrT> capacity, AllocationFlags flags) {
|
||||
TNode<HeapObject> dict;
|
||||
if constexpr (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
dict = AllocateSwissNameDictionaryWithCapacity(capacity);
|
||||
} else {
|
||||
dict = AllocateNameDictionaryWithCapacity(capacity, flags);
|
||||
}
|
||||
return TNode<PropertyDictionary>::UncheckedCast(dict);
|
||||
}
|
||||
|
||||
TNode<NameDictionary> CodeStubAssembler::CopyNameDictionary(
|
||||
TNode<NameDictionary> dictionary, Label* large_object_fallback) {
|
||||
Comment("Copy boilerplate property dict");
|
||||
@ -4423,9 +4471,8 @@ void CodeStubAssembler::InitializeJSObjectFromMap(
|
||||
StoreObjectFieldRoot(object, JSObject::kPropertiesOrHashOffset,
|
||||
RootIndex::kEmptyFixedArray);
|
||||
} else {
|
||||
CSA_DCHECK(this, Word32Or(Word32Or(Word32Or(IsPropertyArray(*properties),
|
||||
IsNameDictionary(*properties)),
|
||||
IsSwissNameDictionary(*properties)),
|
||||
CSA_DCHECK(this, Word32Or(Word32Or(IsPropertyArray(*properties),
|
||||
IsPropertyDictionary(*properties)),
|
||||
IsEmptyFixedArray(*properties)));
|
||||
StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOrHashOffset,
|
||||
*properties);
|
||||
@ -5013,9 +5060,9 @@ TNode<FixedArray> CodeStubAssembler::ExtractToFixedArray(
|
||||
#ifndef V8_ENABLE_SINGLE_GENERATION
|
||||
#ifdef DEBUG
|
||||
TNode<IntPtrT> object_word = BitcastTaggedToWord(to_elements);
|
||||
TNode<IntPtrT> object_page = PageFromAddress(object_word);
|
||||
TNode<IntPtrT> page_flags =
|
||||
Load<IntPtrT>(object_page, IntPtrConstant(Page::kFlagsOffset));
|
||||
TNode<IntPtrT> object_page_header = PageHeaderFromAddress(object_word);
|
||||
TNode<IntPtrT> page_flags = Load<IntPtrT>(
|
||||
object_page_header, IntPtrConstant(MemoryChunkLayout::kFlagsOffset));
|
||||
CSA_DCHECK(
|
||||
this,
|
||||
WordNotEqual(
|
||||
@ -5414,9 +5461,10 @@ void CodeStubAssembler::JumpIfPointersFromHereAreInteresting(
|
||||
TNode<Object> object, Label* interesting) {
|
||||
Label finished(this);
|
||||
TNode<IntPtrT> object_word = BitcastTaggedToWord(object);
|
||||
TNode<IntPtrT> object_page = PageFromAddress(object_word);
|
||||
TNode<IntPtrT> page_flags = UncheckedCast<IntPtrT>(Load(
|
||||
MachineType::IntPtr(), object_page, IntPtrConstant(Page::kFlagsOffset)));
|
||||
TNode<IntPtrT> object_page_header = PageHeaderFromAddress(object_word);
|
||||
TNode<IntPtrT> page_flags = UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::IntPtr(), object_page_header,
|
||||
IntPtrConstant(MemoryChunkLayout::kFlagsOffset)));
|
||||
Branch(
|
||||
WordEqual(WordAnd(page_flags,
|
||||
IntPtrConstant(
|
||||
@ -7617,19 +7665,15 @@ TNode<BoolT> CodeStubAssembler::IsEphemeronHashTable(TNode<HeapObject> object) {
|
||||
return HasInstanceType(object, EPHEMERON_HASH_TABLE_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsNameDictionary(TNode<HeapObject> object) {
|
||||
return HasInstanceType(object, NAME_DICTIONARY_TYPE);
|
||||
TNode<BoolT> CodeStubAssembler::IsPropertyDictionary(TNode<HeapObject> object) {
|
||||
return HasInstanceType(object, PROPERTY_DICTIONARY_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsOrderedNameDictionary(
|
||||
TNode<HeapObject> object) {
|
||||
return HasInstanceType(object, ORDERED_NAME_DICTIONARY_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsSwissNameDictionary(
|
||||
TNode<HeapObject> object) {
|
||||
return HasInstanceType(object, SWISS_NAME_DICTIONARY_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsGlobalDictionary(TNode<HeapObject> object) {
|
||||
return HasInstanceType(object, GLOBAL_DICTIONARY_TYPE);
|
||||
}
|
||||
@ -7823,10 +7867,10 @@ TNode<BoolT> CodeStubAssembler::IsNumberArrayIndex(TNode<Number> number) {
|
||||
TNode<IntPtrT> CodeStubAssembler::LoadBasicMemoryChunkFlags(
|
||||
TNode<HeapObject> object) {
|
||||
TNode<IntPtrT> object_word = BitcastTaggedToWord(object);
|
||||
TNode<IntPtrT> page = PageFromAddress(object_word);
|
||||
TNode<IntPtrT> page_header = PageHeaderFromAddress(object_word);
|
||||
return UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::Pointer(), page,
|
||||
IntPtrConstant(BasicMemoryChunk::kFlagsOffset)));
|
||||
Load(MachineType::Pointer(), page_header,
|
||||
IntPtrConstant(MemoryChunkLayout::kFlagsOffset)));
|
||||
}
|
||||
|
||||
template <typename TIndex>
|
||||
@ -9410,7 +9454,8 @@ TNode<IntPtrT> CodeStubAssembler::NameToIndexHashTableLookup(
|
||||
template <typename Dictionary>
|
||||
void CodeStubAssembler::NameDictionaryLookup(
|
||||
TNode<Dictionary> dictionary, TNode<Name> unique_name, Label* if_found,
|
||||
TVariable<IntPtrT>* var_name_index, Label* if_not_found, LookupMode mode) {
|
||||
TVariable<IntPtrT>* var_name_index, Label* if_not_found_no_insertion_index,
|
||||
LookupMode mode, Label* if_not_found_with_insertion_index) {
|
||||
static_assert(std::is_same<Dictionary, NameDictionary>::value ||
|
||||
std::is_same<Dictionary, GlobalDictionary>::value ||
|
||||
std::is_same<Dictionary, NameToIndexHashTable>::value,
|
||||
@ -9418,8 +9463,13 @@ void CodeStubAssembler::NameDictionaryLookup(
|
||||
DCHECK_IMPLIES(var_name_index != nullptr,
|
||||
MachineType::PointerRepresentation() == var_name_index->rep());
|
||||
DCHECK_IMPLIES(mode == kFindInsertionIndex, if_found == nullptr);
|
||||
DCHECK_IMPLIES(if_not_found_with_insertion_index != nullptr,
|
||||
var_name_index != nullptr);
|
||||
Comment("NameDictionaryLookup");
|
||||
CSA_DCHECK(this, IsUniqueName(unique_name));
|
||||
if (if_not_found_with_insertion_index == nullptr) {
|
||||
if_not_found_with_insertion_index = if_not_found_no_insertion_index;
|
||||
}
|
||||
|
||||
Label if_not_computed(this, Label::kDeferred);
|
||||
|
||||
@ -9453,16 +9503,17 @@ void CodeStubAssembler::NameDictionaryLookup(
|
||||
|
||||
TNode<HeapObject> current =
|
||||
CAST(UnsafeLoadFixedArrayElement(dictionary, index));
|
||||
GotoIf(TaggedEqual(current, undefined), if_not_found);
|
||||
GotoIf(TaggedEqual(current, undefined), if_not_found_with_insertion_index);
|
||||
if (mode == kFindExisting) {
|
||||
if (Dictionary::ShapeT::kMatchNeedsHoleCheck) {
|
||||
if (Dictionary::TodoShape::kMatchNeedsHoleCheck) {
|
||||
GotoIf(TaggedEqual(current, TheHoleConstant()), &next_probe);
|
||||
}
|
||||
current = LoadName<Dictionary>(current);
|
||||
GotoIf(TaggedEqual(current, unique_name), if_found);
|
||||
} else {
|
||||
DCHECK_EQ(kFindInsertionIndex, mode);
|
||||
GotoIf(TaggedEqual(current, TheHoleConstant()), if_not_found);
|
||||
GotoIf(TaggedEqual(current, TheHoleConstant()),
|
||||
if_not_found_with_insertion_index);
|
||||
}
|
||||
Goto(&next_probe);
|
||||
|
||||
@ -9507,14 +9558,19 @@ void CodeStubAssembler::NameDictionaryLookup(
|
||||
std::make_pair(MachineType::Pointer(), isolate_ptr),
|
||||
std::make_pair(MachineType::TaggedPointer(), dictionary),
|
||||
std::make_pair(MachineType::TaggedPointer(), unique_name)));
|
||||
|
||||
if (var_name_index) *var_name_index = EntryToIndex<Dictionary>(entry);
|
||||
if (mode == kFindExisting) {
|
||||
GotoIf(IntPtrEqual(entry,
|
||||
IntPtrConstant(InternalIndex::NotFound().raw_value())),
|
||||
if_not_found);
|
||||
if_not_found_no_insertion_index);
|
||||
Goto(if_found);
|
||||
} else {
|
||||
Goto(if_not_found);
|
||||
CSA_DCHECK(
|
||||
this,
|
||||
WordNotEqual(entry,
|
||||
IntPtrConstant(InternalIndex::NotFound().raw_value())));
|
||||
Goto(if_not_found_with_insertion_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9524,10 +9580,11 @@ template V8_EXPORT_PRIVATE void
|
||||
CodeStubAssembler::NameDictionaryLookup<NameDictionary>(TNode<NameDictionary>,
|
||||
TNode<Name>, Label*,
|
||||
TVariable<IntPtrT>*,
|
||||
Label*, LookupMode);
|
||||
Label*, LookupMode,
|
||||
Label*);
|
||||
template V8_EXPORT_PRIVATE void CodeStubAssembler::NameDictionaryLookup<
|
||||
GlobalDictionary>(TNode<GlobalDictionary>, TNode<Name>, Label*,
|
||||
TVariable<IntPtrT>*, Label*, LookupMode);
|
||||
TVariable<IntPtrT>*, Label*, LookupMode, Label*);
|
||||
|
||||
TNode<Word32T> CodeStubAssembler::ComputeSeededHash(TNode<IntPtrT> key) {
|
||||
const TNode<ExternalReference> function_addr =
|
||||
@ -9547,10 +9604,13 @@ TNode<Word32T> CodeStubAssembler::ComputeSeededHash(TNode<IntPtrT> key) {
|
||||
template <>
|
||||
void CodeStubAssembler::NameDictionaryLookup(
|
||||
TNode<SwissNameDictionary> dictionary, TNode<Name> unique_name,
|
||||
Label* if_found, TVariable<IntPtrT>* var_name_index, Label* if_not_found,
|
||||
LookupMode mode) {
|
||||
Label* if_found, TVariable<IntPtrT>* var_name_index,
|
||||
Label* if_not_found_no_insertion_index, LookupMode mode,
|
||||
Label* if_not_found_with_insertion_index) {
|
||||
// TODO(pthier): Support path for not found with valid insertion index for
|
||||
// SwissNameDictionary.
|
||||
SwissNameDictionaryFindEntry(dictionary, unique_name, if_found,
|
||||
var_name_index, if_not_found);
|
||||
var_name_index, if_not_found_no_insertion_index);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::NumberDictionaryLookup(
|
||||
@ -9707,9 +9767,9 @@ void CodeStubAssembler::InsertEntry<GlobalDictionary>(
|
||||
}
|
||||
|
||||
template <class Dictionary>
|
||||
void CodeStubAssembler::AddToDictionary(TNode<Dictionary> dictionary,
|
||||
TNode<Name> key, TNode<Object> value,
|
||||
Label* bailout) {
|
||||
void CodeStubAssembler::AddToDictionary(
|
||||
TNode<Dictionary> dictionary, TNode<Name> key, TNode<Object> value,
|
||||
Label* bailout, base::Optional<TNode<IntPtrT>> insertion_index) {
|
||||
CSA_DCHECK(this, Word32BinaryNot(IsEmptyPropertyDictionary(dictionary)));
|
||||
TNode<Smi> capacity = GetCapacity<Dictionary>(dictionary);
|
||||
TNode<Smi> nof = GetNumberOfElements<Dictionary>(dictionary);
|
||||
@ -9737,16 +9797,21 @@ void CodeStubAssembler::AddToDictionary(TNode<Dictionary> dictionary,
|
||||
SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index);
|
||||
SetNumberOfElements<Dictionary>(dictionary, new_nof);
|
||||
|
||||
TVARIABLE(IntPtrT, var_key_index);
|
||||
FindInsertionEntry<Dictionary>(dictionary, key, &var_key_index);
|
||||
InsertEntry<Dictionary>(dictionary, key, value, var_key_index.value(),
|
||||
enum_index);
|
||||
if (insertion_index.has_value()) {
|
||||
InsertEntry<Dictionary>(dictionary, key, value, *insertion_index,
|
||||
enum_index);
|
||||
} else {
|
||||
TVARIABLE(IntPtrT, var_key_index);
|
||||
FindInsertionEntry<Dictionary>(dictionary, key, &var_key_index);
|
||||
InsertEntry<Dictionary>(dictionary, key, value, var_key_index.value(),
|
||||
enum_index);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void CodeStubAssembler::AddToDictionary(TNode<SwissNameDictionary> dictionary,
|
||||
TNode<Name> key, TNode<Object> value,
|
||||
Label* bailout) {
|
||||
void CodeStubAssembler::AddToDictionary(
|
||||
TNode<SwissNameDictionary> dictionary, TNode<Name> key, TNode<Object> value,
|
||||
Label* bailout, base::Optional<TNode<IntPtrT>> insertion_index) {
|
||||
PropertyDetails d(PropertyKind::kData, NONE,
|
||||
PropertyDetails::kConstIfDictConstnessTracking);
|
||||
|
||||
@ -9765,11 +9830,13 @@ void CodeStubAssembler::AddToDictionary(TNode<SwissNameDictionary> dictionary,
|
||||
Goto(¬_private);
|
||||
|
||||
BIND(¬_private);
|
||||
// TODO(pthier): Use insertion_index if it was provided.
|
||||
SwissNameDictionaryAdd(dictionary, key, value, var_details.value(), bailout);
|
||||
}
|
||||
|
||||
template void CodeStubAssembler::AddToDictionary<NameDictionary>(
|
||||
TNode<NameDictionary>, TNode<Name>, TNode<Object>, Label*);
|
||||
TNode<NameDictionary>, TNode<Name>, TNode<Object>, Label*,
|
||||
base::Optional<TNode<IntPtrT>>);
|
||||
|
||||
template <class Dictionary>
|
||||
TNode<Smi> CodeStubAssembler::GetNumberOfElements(
|
||||
@ -11083,9 +11150,9 @@ TNode<Object> CodeStubAssembler::GetInterestingProperty(
|
||||
TNode<Object> properties =
|
||||
LoadObjectField(holder, JSObject::kPropertiesOrHashOffset);
|
||||
CSA_DCHECK(this, TaggedIsNotSmi(properties));
|
||||
CSA_DCHECK(this, IsPropertyDictionary(CAST(properties)));
|
||||
// TODO(pthier): Support swiss dictionaries.
|
||||
if constexpr (!V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
CSA_DCHECK(this, IsNameDictionary(CAST(properties)));
|
||||
TNode<Smi> flags =
|
||||
GetNameDictionaryFlags<NameDictionary>(CAST(properties));
|
||||
GotoIf(IsSetSmi(flags,
|
||||
@ -12748,10 +12815,10 @@ void CodeStubAssembler::TrapAllocationMemento(TNode<JSObject> object,
|
||||
TNode<IntPtrT> object_word = BitcastTaggedToWord(object);
|
||||
// TODO(v8:11641): Skip TrapAllocationMemento when allocation-site
|
||||
// tracking is disabled.
|
||||
TNode<IntPtrT> object_page = PageFromAddress(object_word);
|
||||
TNode<IntPtrT> object_page_header = PageHeaderFromAddress(object_word);
|
||||
{
|
||||
TNode<IntPtrT> page_flags =
|
||||
Load<IntPtrT>(object_page, IntPtrConstant(Page::kFlagsOffset));
|
||||
TNode<IntPtrT> page_flags = Load<IntPtrT>(
|
||||
object_page_header, IntPtrConstant(MemoryChunkLayout::kFlagsOffset));
|
||||
GotoIf(WordEqual(
|
||||
WordAnd(page_flags,
|
||||
IntPtrConstant(MemoryChunk::kIsInYoungGenerationMask)),
|
||||
@ -12767,20 +12834,23 @@ void CodeStubAssembler::TrapAllocationMemento(TNode<JSObject> object,
|
||||
|
||||
TNode<IntPtrT> memento_last_word = IntPtrAdd(
|
||||
object_word, IntPtrConstant(kMementoLastWordOffset - kHeapObjectTag));
|
||||
TNode<IntPtrT> memento_last_word_page = PageFromAddress(memento_last_word);
|
||||
TNode<IntPtrT> memento_last_word_page_header =
|
||||
PageHeaderFromAddress(memento_last_word);
|
||||
|
||||
TNode<IntPtrT> new_space_top = Load<IntPtrT>(new_space_top_address);
|
||||
TNode<IntPtrT> new_space_top_page = PageFromAddress(new_space_top);
|
||||
TNode<IntPtrT> new_space_top_page_header =
|
||||
PageHeaderFromAddress(new_space_top);
|
||||
|
||||
// If the object is in new space, we need to check whether respective
|
||||
// potential memento object is on the same page as the current top.
|
||||
GotoIf(WordEqual(memento_last_word_page, new_space_top_page), &top_check);
|
||||
GotoIf(WordEqual(memento_last_word_page_header, new_space_top_page_header),
|
||||
&top_check);
|
||||
|
||||
// The object is on a different page than allocation top. Bail out if the
|
||||
// object sits on the page boundary as no memento can follow and we cannot
|
||||
// touch the memory following it.
|
||||
Branch(WordEqual(object_page, memento_last_word_page), &map_check,
|
||||
&no_memento_found);
|
||||
Branch(WordEqual(object_page_header, memento_last_word_page_header),
|
||||
&map_check, &no_memento_found);
|
||||
|
||||
// If top is on the same page as the current object, we need to check whether
|
||||
// we are below top.
|
||||
@ -12804,9 +12874,22 @@ void CodeStubAssembler::TrapAllocationMemento(TNode<JSObject> object,
|
||||
Comment("] TrapAllocationMemento");
|
||||
}
|
||||
|
||||
TNode<IntPtrT> CodeStubAssembler::PageHeaderFromAddress(
|
||||
TNode<IntPtrT> address) {
|
||||
DCHECK(!V8_ENABLE_THIRD_PARTY_HEAP_BOOL);
|
||||
return WordAnd(
|
||||
address,
|
||||
IntPtrConstant(~MemoryChunkHeader::GetAlignmentMaskForAssembler()));
|
||||
}
|
||||
|
||||
TNode<IntPtrT> CodeStubAssembler::PageFromPageHeader(TNode<IntPtrT> address) {
|
||||
DCHECK(!V8_ENABLE_THIRD_PARTY_HEAP_BOOL);
|
||||
return address;
|
||||
}
|
||||
|
||||
TNode<IntPtrT> CodeStubAssembler::PageFromAddress(TNode<IntPtrT> address) {
|
||||
DCHECK(!V8_ENABLE_THIRD_PARTY_HEAP_BOOL);
|
||||
return WordAnd(address, IntPtrConstant(~kPageAlignmentMask));
|
||||
return PageFromPageHeader(PageHeaderFromAddress(address));
|
||||
}
|
||||
|
||||
TNode<AllocationSite> CodeStubAssembler::CreateAllocationSiteInFeedbackVector(
|
||||
@ -13230,6 +13313,18 @@ TNode<Context> CodeStubAssembler::GotoIfHasContextExtensionUpToDepth(
|
||||
Goto(&context_search);
|
||||
BIND(&context_search);
|
||||
{
|
||||
#if DEBUG
|
||||
// Const tracking let data is stored in the extension slot of a
|
||||
// ScriptContext - however, it's unrelated to the sloppy eval variable
|
||||
// extension. We should never iterate through a ScriptContext here.
|
||||
auto scope_info = LoadScopeInfo(cur_context.value());
|
||||
TNode<Int32T> flags =
|
||||
LoadAndUntagToWord32ObjectField(scope_info, ScopeInfo::kFlagsOffset);
|
||||
auto scope_type = DecodeWord32<ScopeInfo::ScopeTypeBits>(flags);
|
||||
CSA_DCHECK(this, Word32NotEqual(scope_type,
|
||||
Int32Constant(ScopeType::SCRIPT_SCOPE)));
|
||||
#endif
|
||||
|
||||
// Check if context has an extension slot.
|
||||
TNode<BoolT> has_extension =
|
||||
LoadScopeInfoHasExtensionField(LoadScopeInfo(cur_context.value()));
|
||||
@ -16301,8 +16396,8 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
|
||||
CSA_DCHECK(this,
|
||||
Word32Equal(data_type, Int32Constant(INTERPRETER_DATA_TYPE)));
|
||||
{
|
||||
TNode<Code> trampoline = LoadCodePointerFromObject(
|
||||
CAST(sfi_data), InterpreterData::kInterpreterTrampolineOffset);
|
||||
TNode<Code> trampoline = CAST(LoadProtectedPointerFromObject(
|
||||
CAST(sfi_data), InterpreterData::kInterpreterTrampolineOffset));
|
||||
sfi_code = trampoline;
|
||||
}
|
||||
Goto(&done);
|
||||
@ -16329,12 +16424,13 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
|
||||
return sfi_code.value();
|
||||
}
|
||||
|
||||
TNode<RawPtrT> CodeStubAssembler::LoadCodeInstructionStart(TNode<Code> code) {
|
||||
TNode<RawPtrT> CodeStubAssembler::LoadCodeInstructionStart(
|
||||
TNode<Code> code, CodeEntrypointTag tag) {
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
// In this case, the entrypoint is stored in the code pointer table entry
|
||||
// referenced via the Code object's 'self' indirect pointer.
|
||||
return LoadCodeEntrypointViaCodePointerField(
|
||||
code, Code::kSelfIndirectPointerOffset);
|
||||
code, Code::kSelfIndirectPointerOffset, tag);
|
||||
#else
|
||||
return LoadObjectField<RawPtrT>(code, Code::kInstructionStartOffset);
|
||||
#endif
|
||||
@ -16439,15 +16535,14 @@ TNode<Map> CodeStubAssembler::CheckEnumCache(TNode<JSReceiver> receiver,
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85149
|
||||
// TODO(miladfarca): Use `if constexpr` once all compilers handle this
|
||||
// properly.
|
||||
CSA_DCHECK(this, Word32Or(IsPropertyDictionary(properties),
|
||||
IsGlobalDictionary(properties)));
|
||||
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
|
||||
CSA_DCHECK(this, Word32Or(IsSwissNameDictionary(properties),
|
||||
IsGlobalDictionary(properties)));
|
||||
|
||||
length = Select<Smi>(
|
||||
IsSwissNameDictionary(properties),
|
||||
IsPropertyDictionary(properties),
|
||||
[=] {
|
||||
return GetNumberOfElements(
|
||||
UncheckedCast<SwissNameDictionary>(properties));
|
||||
UncheckedCast<PropertyDictionary>(properties));
|
||||
},
|
||||
[=] {
|
||||
return GetNumberOfElements(
|
||||
@ -16455,8 +16550,6 @@ TNode<Map> CodeStubAssembler::CheckEnumCache(TNode<JSReceiver> receiver,
|
||||
});
|
||||
|
||||
} else {
|
||||
CSA_DCHECK(this, Word32Or(IsNameDictionary(properties),
|
||||
IsGlobalDictionary(properties)));
|
||||
static_assert(static_cast<int>(NameDictionary::kNumberOfElementsIndex) ==
|
||||
static_cast<int>(GlobalDictionary::kNumberOfElementsIndex));
|
||||
length = GetNumberOfElements(UncheckedCast<HashTableBase>(properties));
|
||||
|
96
deps/v8/src/codegen/code-stub-assembler.h
vendored
96
deps/v8/src/codegen/code-stub-assembler.h
vendored
@ -18,6 +18,7 @@
|
||||
#include "src/objects/arguments.h"
|
||||
#include "src/objects/bigint.h"
|
||||
#include "src/objects/cell.h"
|
||||
#include "src/objects/dictionary.h"
|
||||
#include "src/objects/feedback-vector.h"
|
||||
#include "src/objects/heap-number.h"
|
||||
#include "src/objects/hole.h"
|
||||
@ -358,6 +359,14 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
|
||||
#define CSA_SLOW_DCHECK(csa, ...) ((void)0)
|
||||
#endif
|
||||
|
||||
// Similar to SBXCHECK in C++, these become a CSA_CHECK in sandbox-enabled
|
||||
// builds, otherwise a CSA_DCHECK.
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
#define CSA_SBXCHECK(csa, ...) CSA_CHECK(csa, __VA_ARGS__)
|
||||
#else
|
||||
#define CSA_SBXCHECK(csa, ...) CSA_DCHECK(csa, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Provides JavaScript-specific "macro-assembler" functionality on top of the
|
||||
// CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler,
|
||||
// it's possible to add JavaScript-specific useful CodeAssembler "macros"
|
||||
@ -922,7 +931,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
void FastCheck(TNode<BoolT> condition);
|
||||
|
||||
TNode<RawPtrT> LoadCodeInstructionStart(TNode<Code> code);
|
||||
TNode<RawPtrT> LoadCodeInstructionStart(TNode<Code> code,
|
||||
CodeEntrypointTag tag);
|
||||
TNode<BoolT> IsMarkedForDeoptimization(TNode<Code> code);
|
||||
|
||||
// The following Call wrappers call an object according to the semantics that
|
||||
@ -1193,9 +1203,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Load a trusted pointer field.
|
||||
// When the sandbox is enabled, these are indirect pointers using the trusted
|
||||
// pointer table. Otherwise they are regular tagged fields.
|
||||
TNode<HeapObject> LoadTrustedPointerFromObject(TNode<HeapObject> object,
|
||||
int offset,
|
||||
IndirectPointerTag tag);
|
||||
TNode<TrustedObject> LoadTrustedPointerFromObject(TNode<HeapObject> object,
|
||||
int offset,
|
||||
IndirectPointerTag tag);
|
||||
|
||||
// Load a code pointer field.
|
||||
// These are special versions of trusted pointers that, when the sandbox is
|
||||
@ -1204,9 +1214,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
// Load an indirect pointer field.
|
||||
TNode<HeapObject> LoadIndirectPointerFromObject(TNode<HeapObject> object,
|
||||
int offset,
|
||||
IndirectPointerTag tag);
|
||||
TNode<TrustedObject> LoadIndirectPointerFromObject(TNode<HeapObject> object,
|
||||
int offset,
|
||||
IndirectPointerTag tag);
|
||||
|
||||
// Determines whether the given indirect pointer handle is a trusted pointer
|
||||
// handle or a code pointer handle.
|
||||
@ -1214,14 +1224,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
// Retrieve the heap object referenced by the given indirect pointer handle,
|
||||
// which can either be a trusted pointer handle or a code pointer handle.
|
||||
TNode<HeapObject> ResolveIndirectPointerHandle(
|
||||
TNode<TrustedObject> ResolveIndirectPointerHandle(
|
||||
TNode<IndirectPointerHandleT> handle, IndirectPointerTag tag);
|
||||
|
||||
// Retrieve the Code object referenced by the given trusted pointer handle.
|
||||
TNode<Code> ResolveCodePointerHandle(TNode<IndirectPointerHandleT> handle);
|
||||
|
||||
// Retrieve the heap object referenced by the given trusted pointer handle.
|
||||
TNode<HeapObject> ResolveTrustedPointerHandle(
|
||||
TNode<TrustedObject> ResolveTrustedPointerHandle(
|
||||
TNode<IndirectPointerHandleT> handle, IndirectPointerTag tag);
|
||||
|
||||
// Helper function to compute the offset into the code pointer table from a
|
||||
@ -1233,14 +1243,19 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Only available when the sandbox is enabled as it requires the code pointer
|
||||
// table.
|
||||
TNode<RawPtrT> LoadCodeEntrypointViaCodePointerField(TNode<HeapObject> object,
|
||||
int offset) {
|
||||
return LoadCodeEntrypointViaCodePointerField(object,
|
||||
IntPtrConstant(offset));
|
||||
int offset,
|
||||
CodeEntrypointTag tag) {
|
||||
return LoadCodeEntrypointViaCodePointerField(object, IntPtrConstant(offset),
|
||||
tag);
|
||||
}
|
||||
TNode<RawPtrT> LoadCodeEntrypointViaCodePointerField(TNode<HeapObject> object,
|
||||
TNode<IntPtrT> offset);
|
||||
TNode<IntPtrT> offset,
|
||||
CodeEntrypointTag tag);
|
||||
#endif
|
||||
|
||||
TNode<TrustedObject> LoadProtectedPointerFromObject(
|
||||
TNode<TrustedObject> object, int offset);
|
||||
|
||||
TNode<RawPtrT> LoadForeignForeignAddressPtr(TNode<Foreign> object) {
|
||||
return LoadExternalPointerFromObject(object, Foreign::kForeignAddressOffset,
|
||||
kForeignForeignAddressTag);
|
||||
@ -1289,11 +1304,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<WasmInternalFunction> object) {
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
return LoadCodeEntrypointViaCodePointerField(
|
||||
object, WasmInternalFunction::kCodeOffset);
|
||||
object, WasmInternalFunction::kCodeOffset, kWasmEntrypointTag);
|
||||
#else
|
||||
TNode<Code> code =
|
||||
LoadObjectField<Code>(object, WasmInternalFunction::kCodeOffset);
|
||||
return LoadCodeInstructionStart(code);
|
||||
return LoadCodeInstructionStart(code, kWasmEntrypointTag);
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
}
|
||||
|
||||
@ -2192,6 +2207,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
AllocationFlags = AllocationFlag::kNone);
|
||||
TNode<NameDictionary> AllocateNameDictionaryWithCapacity(
|
||||
TNode<IntPtrT> capacity, AllocationFlags = AllocationFlag::kNone);
|
||||
|
||||
TNode<PropertyDictionary> AllocatePropertyDictionary(int at_least_space_for);
|
||||
TNode<PropertyDictionary> AllocatePropertyDictionary(
|
||||
TNode<IntPtrT> at_least_space_for,
|
||||
AllocationFlags = AllocationFlag::kNone);
|
||||
TNode<PropertyDictionary> AllocatePropertyDictionaryWithCapacity(
|
||||
TNode<IntPtrT> capacity, AllocationFlags = AllocationFlag::kNone);
|
||||
|
||||
TNode<NameDictionary> CopyNameDictionary(TNode<NameDictionary> dictionary,
|
||||
Label* large_object_fallback);
|
||||
|
||||
@ -2865,7 +2888,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<BoolT> IsConstructorMap(TNode<Map> map);
|
||||
TNode<BoolT> IsConstructor(TNode<HeapObject> object);
|
||||
TNode<BoolT> IsDeprecatedMap(TNode<Map> map);
|
||||
TNode<BoolT> IsNameDictionary(TNode<HeapObject> object);
|
||||
TNode<BoolT> IsPropertyDictionary(TNode<HeapObject> object);
|
||||
TNode<BoolT> IsOrderedNameDictionary(TNode<HeapObject> object);
|
||||
TNode<BoolT> IsGlobalDictionary(TNode<HeapObject> object);
|
||||
TNode<BoolT> IsExtensibleMap(TNode<Map> map);
|
||||
@ -2978,7 +3001,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<BoolT> IsStringInstanceType(TNode<Int32T> instance_type);
|
||||
TNode<BoolT> IsString(TNode<HeapObject> object);
|
||||
TNode<BoolT> IsSeqOneByteString(TNode<HeapObject> object);
|
||||
TNode<BoolT> IsSwissNameDictionary(TNode<HeapObject> object);
|
||||
|
||||
TNode<BoolT> IsSymbolInstanceType(TNode<Int32T> instance_type);
|
||||
TNode<BoolT> IsInternalizedStringInstanceType(TNode<Int32T> instance_type);
|
||||
@ -3511,24 +3533,40 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
template <class Dictionary>
|
||||
void SetNameDictionaryFlags(TNode<Dictionary>, TNode<Smi> flags);
|
||||
|
||||
// Looks up an entry in a NameDictionaryBase successor. If the entry is found
|
||||
// control goes to {if_found} and {var_name_index} contains an index of the
|
||||
// key field of the entry found. If the key is not found control goes to
|
||||
// {if_not_found}.
|
||||
enum LookupMode { kFindExisting, kFindInsertionIndex };
|
||||
|
||||
template <typename Dictionary>
|
||||
TNode<HeapObject> LoadName(TNode<HeapObject> key);
|
||||
|
||||
// Looks up an entry in a NameDictionaryBase successor.
|
||||
// For {mode} == kFindExisting:
|
||||
// If the entry is found control goes to {if_found} and {var_name_index}
|
||||
// contains an index of the key field of the entry found.
|
||||
// If the key is not found and {if_not_found_with_insertion_index} is
|
||||
// provided, control goes to {if_not_found_with_insertion_index} and
|
||||
// {var_name_index} contains the index of the key field to insert the given
|
||||
// name at.
|
||||
// Otherwise control goes to {if_not_found_no_insertion_index}.
|
||||
// For {mode} == kFindInsertionIndex:
|
||||
// {if_not_found_no_insertion_index} and {if_not_found_with_insertion_index}
|
||||
// are treated equally. If {if_not_found_with_insertion_index} is provided,
|
||||
// control goes to {if_not_found_with_insertion_index}, otherwise control
|
||||
// goes to {if_not_found_no_insertion_index}. In both cases {var_name_index}
|
||||
// contains the index of the key field to insert the given name at.
|
||||
template <typename Dictionary>
|
||||
void NameDictionaryLookup(TNode<Dictionary> dictionary,
|
||||
TNode<Name> unique_name, Label* if_found,
|
||||
TVariable<IntPtrT>* var_name_index,
|
||||
Label* if_not_found,
|
||||
LookupMode mode = kFindExisting);
|
||||
Label* if_not_found_no_insertion_index,
|
||||
LookupMode mode = kFindExisting,
|
||||
Label* if_not_found_with_insertion_index = nullptr);
|
||||
|
||||
TNode<Word32T> ComputeSeededHash(TNode<IntPtrT> key);
|
||||
|
||||
// Looks up an entry in a NameDictionaryBase successor. If the entry is found
|
||||
// control goes to {if_found} and {var_name_index} contains an index of the
|
||||
// key field of the entry found. If the key is not found control goes to
|
||||
// {if_not_found}.
|
||||
void NumberDictionaryLookup(TNode<NumberDictionary> dictionary,
|
||||
TNode<IntPtrT> intptr_index, Label* if_found,
|
||||
TVariable<IntPtrT>* var_entry,
|
||||
@ -3548,8 +3586,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<Smi> enum_index);
|
||||
|
||||
template <class Dictionary>
|
||||
void AddToDictionary(TNode<Dictionary> dictionary, TNode<Name> key,
|
||||
TNode<Object> value, Label* bailout);
|
||||
void AddToDictionary(
|
||||
TNode<Dictionary> dictionary, TNode<Name> key, TNode<Object> value,
|
||||
Label* bailout,
|
||||
base::Optional<TNode<IntPtrT>> insertion_index = base::nullopt);
|
||||
|
||||
// Tries to check if {object} has own {unique_name} property.
|
||||
void TryHasOwnProperty(TNode<HeapObject> object, TNode<Map> map,
|
||||
@ -3875,6 +3915,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
void TrapAllocationMemento(TNode<JSObject> object, Label* memento_found);
|
||||
|
||||
// Helpers to look up MemoryChunk/Page metadata for a given address.
|
||||
// Equivalent to MemoryChunkHeader::FromAddress().
|
||||
TNode<IntPtrT> PageHeaderFromAddress(TNode<IntPtrT> address);
|
||||
// Equivalent to MemoryChunkHeader::MemoryChunk().
|
||||
TNode<IntPtrT> PageFromPageHeader(TNode<IntPtrT> address);
|
||||
// Equivalent to BasicMemoryChunk::FromAddress().
|
||||
TNode<IntPtrT> PageFromAddress(TNode<IntPtrT> address);
|
||||
|
||||
// Store a weak in-place reference into the FeedbackVector.
|
||||
|
65
deps/v8/src/codegen/compiler.cc
vendored
65
deps/v8/src/codegen/compiler.cc
vendored
@ -1720,8 +1720,10 @@ BackgroundCompileTask::BackgroundCompileTask(
|
||||
|
||||
BackgroundCompileTask::~BackgroundCompileTask() = default;
|
||||
|
||||
namespace {
|
||||
|
||||
void SetScriptFieldsFromDetails(Isolate* isolate, Tagged<Script> script,
|
||||
const ScriptDetails& script_details,
|
||||
ScriptDetails script_details,
|
||||
DisallowGarbageCollection* no_gc) {
|
||||
Handle<Object> script_name;
|
||||
if (script_details.name_obj.ToHandle(&script_name)) {
|
||||
@ -1747,8 +1749,6 @@ void SetScriptFieldsFromDetails(Isolate* isolate, Tagged<Script> script,
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef ENABLE_SLOW_DCHECKS
|
||||
|
||||
// A class which traverses the object graph for a newly compiled Script and
|
||||
@ -2032,34 +2032,44 @@ class ConstantPoolPointerForwarder {
|
||||
for (Handle<BytecodeArray> bytecode_array : bytecode_arrays_to_update_) {
|
||||
local_heap_->Safepoint();
|
||||
DisallowGarbageCollection no_gc;
|
||||
Tagged<FixedArray> constant_pool = bytecode_array->constant_pool();
|
||||
IterateConstantPool(constant_pool);
|
||||
IterateConstantPool(bytecode_array->constant_pool());
|
||||
}
|
||||
}
|
||||
|
||||
bool HasAnythingToForward() const { return !forwarding_table_.empty(); }
|
||||
|
||||
private:
|
||||
void IterateConstantPool(Tagged<FixedArray> constant_pool) {
|
||||
for (int i = 0, length = constant_pool->length(); i < length; ++i) {
|
||||
Tagged<Object> obj = constant_pool->get(i);
|
||||
if (IsSmi(obj)) continue;
|
||||
Tagged<HeapObject> heap_obj = HeapObject::cast(obj);
|
||||
if (IsFixedArray(heap_obj, cage_base_)) {
|
||||
// Constant pools can have nested fixed arrays, but such relationships
|
||||
// are acyclic and never more than a few layers deep, so recursion is
|
||||
// fine here.
|
||||
IterateConstantPool(FixedArray::cast(heap_obj));
|
||||
} else if (IsSharedFunctionInfo(heap_obj, cage_base_)) {
|
||||
auto it = forwarding_table_.find(
|
||||
SharedFunctionInfo::cast(heap_obj)->function_literal_id());
|
||||
if (it != forwarding_table_.end()) {
|
||||
constant_pool->set(i, *it->second);
|
||||
}
|
||||
template <typename TArray>
|
||||
void IterateConstantPoolEntry(Tagged<TArray> constant_pool, int i) {
|
||||
Tagged<Object> obj = constant_pool->get(i);
|
||||
if (IsSmi(obj)) return;
|
||||
Tagged<HeapObject> heap_obj = HeapObject::cast(obj);
|
||||
if (IsFixedArray(heap_obj, cage_base_)) {
|
||||
// Constant pools can have nested fixed arrays, but such relationships
|
||||
// are acyclic and never more than a few layers deep, so recursion is
|
||||
// fine here.
|
||||
IterateConstantPoolNestedArray(FixedArray::cast(heap_obj));
|
||||
} else if (IsSharedFunctionInfo(heap_obj, cage_base_)) {
|
||||
auto it = forwarding_table_.find(
|
||||
SharedFunctionInfo::cast(heap_obj)->function_literal_id());
|
||||
if (it != forwarding_table_.end()) {
|
||||
constant_pool->set(i, *it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IterateConstantPool(Tagged<TrustedFixedArray> constant_pool) {
|
||||
for (int i = 0, length = constant_pool->length(); i < length; ++i) {
|
||||
IterateConstantPoolEntry(constant_pool, i);
|
||||
}
|
||||
}
|
||||
|
||||
void IterateConstantPoolNestedArray(Tagged<FixedArray> nested_array) {
|
||||
for (int i = 0, length = nested_array->length(); i < length; ++i) {
|
||||
IterateConstantPoolEntry(nested_array, i);
|
||||
}
|
||||
}
|
||||
|
||||
PtrComprCageBase cage_base_;
|
||||
LocalHeap* local_heap_;
|
||||
std::vector<Handle<BytecodeArray>> bytecode_arrays_to_update_;
|
||||
@ -2450,10 +2460,10 @@ void BackgroundDeserializeTask::MergeWithExistingScript() {
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> BackgroundDeserializeTask::Finish(
|
||||
Isolate* isolate, Handle<String> source,
|
||||
const ScriptDetails& script_details) {
|
||||
ScriptOriginOptions origin_options) {
|
||||
return CodeSerializer::FinishOffThreadDeserialize(
|
||||
isolate, std::move(off_thread_data_), &cached_data_, source,
|
||||
script_details, &background_merge_task_);
|
||||
origin_options, &background_merge_task_);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -3630,8 +3640,8 @@ MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
|
||||
"V8.CompileDeserialize");
|
||||
if (deserialize_task) {
|
||||
// If there's a cache consume task, finish it.
|
||||
maybe_result =
|
||||
deserialize_task->Finish(isolate, source, script_details);
|
||||
maybe_result = deserialize_task->Finish(isolate, source,
|
||||
script_details.origin_options);
|
||||
// It is possible at this point that there is a Script object for this
|
||||
// script in the compilation cache (held in the variable maybe_script),
|
||||
// which does not match maybe_result->script(). This could happen any of
|
||||
@ -3652,7 +3662,8 @@ MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
|
||||
// would be non-trivial.
|
||||
} else {
|
||||
maybe_result = CodeSerializer::Deserialize(
|
||||
isolate, cached_data, source, script_details, maybe_script);
|
||||
isolate, cached_data, source, script_details.origin_options,
|
||||
maybe_script);
|
||||
}
|
||||
|
||||
bool consuming_code_cache_succeeded = false;
|
||||
@ -3828,7 +3839,7 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.CompileDeserialize");
|
||||
maybe_result = CodeSerializer::Deserialize(isolate, cached_data, source,
|
||||
script_details);
|
||||
script_details.origin_options);
|
||||
bool consuming_code_cache_succeeded = false;
|
||||
if (maybe_result.ToHandle(&result)) {
|
||||
is_compiled_scope = result->is_compiled_scope(isolate);
|
||||
|
2
deps/v8/src/codegen/compiler.h
vendored
2
deps/v8/src/codegen/compiler.h
vendored
@ -682,7 +682,7 @@ class V8_EXPORT_PRIVATE BackgroundDeserializeTask {
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> Finish(Isolate* isolate,
|
||||
Handle<String> source,
|
||||
const ScriptDetails& script_details);
|
||||
ScriptOriginOptions origin_options);
|
||||
|
||||
bool rejected() const { return cached_data_.rejected(); }
|
||||
|
||||
|
29
deps/v8/src/codegen/external-reference-table.cc
vendored
29
deps/v8/src/codegen/external-reference-table.cc
vendored
@ -288,26 +288,19 @@ void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
|
||||
kIsolateAddressReferenceCount,
|
||||
*index);
|
||||
|
||||
StubCache* load_stub_cache = isolate->load_stub_cache();
|
||||
|
||||
// Stub cache tables
|
||||
Add(load_stub_cache->key_reference(StubCache::kPrimary).address(), index);
|
||||
Add(load_stub_cache->value_reference(StubCache::kPrimary).address(), index);
|
||||
Add(load_stub_cache->map_reference(StubCache::kPrimary).address(), index);
|
||||
Add(load_stub_cache->key_reference(StubCache::kSecondary).address(), index);
|
||||
Add(load_stub_cache->value_reference(StubCache::kSecondary).address(), index);
|
||||
Add(load_stub_cache->map_reference(StubCache::kSecondary).address(), index);
|
||||
std::array<StubCache*, 3> stub_caches{isolate->load_stub_cache(),
|
||||
isolate->store_stub_cache(),
|
||||
isolate->define_own_stub_cache()};
|
||||
|
||||
StubCache* store_stub_cache = isolate->store_stub_cache();
|
||||
|
||||
// Stub cache tables
|
||||
Add(store_stub_cache->key_reference(StubCache::kPrimary).address(), index);
|
||||
Add(store_stub_cache->value_reference(StubCache::kPrimary).address(), index);
|
||||
Add(store_stub_cache->map_reference(StubCache::kPrimary).address(), index);
|
||||
Add(store_stub_cache->key_reference(StubCache::kSecondary).address(), index);
|
||||
Add(store_stub_cache->value_reference(StubCache::kSecondary).address(),
|
||||
index);
|
||||
Add(store_stub_cache->map_reference(StubCache::kSecondary).address(), index);
|
||||
for (StubCache* stub_cache : stub_caches) {
|
||||
Add(stub_cache->key_reference(StubCache::kPrimary).address(), index);
|
||||
Add(stub_cache->value_reference(StubCache::kPrimary).address(), index);
|
||||
Add(stub_cache->map_reference(StubCache::kPrimary).address(), index);
|
||||
Add(stub_cache->key_reference(StubCache::kSecondary).address(), index);
|
||||
Add(stub_cache->value_reference(StubCache::kSecondary).address(), index);
|
||||
Add(stub_cache->map_reference(StubCache::kSecondary).address(), index);
|
||||
}
|
||||
|
||||
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
|
||||
kIsolateAddressReferenceCount + kStubCacheReferenceCount,
|
||||
|
@ -38,7 +38,7 @@ class ExternalReferenceTable {
|
||||
Accessors::kAccessorInfoCount + Accessors::kAccessorGetterCount +
|
||||
Accessors::kAccessorSetterCount + Accessors::kAccessorCallbackCount;
|
||||
// The number of stub cache external references, see AddStubCache.
|
||||
static constexpr int kStubCacheReferenceCount = 12;
|
||||
static constexpr int kStubCacheReferenceCount = 6 * 3; // 3 stub caches
|
||||
static constexpr int kStatsCountersReferenceCount =
|
||||
#define SC(...) +1
|
||||
STATS_COUNTER_NATIVE_CODE_LIST(SC);
|
||||
|
50
deps/v8/src/codegen/ia32/macro-assembler-ia32.cc
vendored
50
deps/v8/src/codegen/ia32/macro-assembler-ia32.cc
vendored
@ -1948,18 +1948,20 @@ void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(ExternalReference function,
|
||||
int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
int MacroAssembler::CallCFunction(ExternalReference function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_location) {
|
||||
// Note: The "CallCFunction" code comment will be generated by the other
|
||||
// CallCFunction method called below.
|
||||
// Trashing eax is ok as it will be the return value.
|
||||
Move(eax, Immediate(function));
|
||||
CallCFunction(eax, num_arguments);
|
||||
return CallCFunction(eax, num_arguments, set_isolate_data_slots,
|
||||
return_location);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots) {
|
||||
int MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots,
|
||||
Label* return_location) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
DCHECK_LE(num_arguments, kMaxCParameters);
|
||||
DCHECK(has_frame());
|
||||
@ -1968,6 +1970,8 @@ void MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
CheckStackAlignment();
|
||||
}
|
||||
|
||||
Label get_pc;
|
||||
|
||||
if (set_isolate_data_slots == SetIsolateDataSlots::kYes) {
|
||||
// Save the frame pointer and PC so that the stack layout remains iterable,
|
||||
// even without an ExitFrame which normally exists between JS and C frames.
|
||||
@ -1976,8 +1980,7 @@ void MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
Register scratch = ecx;
|
||||
if (function == eax) pc_scratch = edx;
|
||||
if (function == ecx) scratch = edx;
|
||||
PushPC();
|
||||
pop(pc_scratch);
|
||||
LoadLabelAddress(pc_scratch, &get_pc);
|
||||
|
||||
// See x64 code for reasoning about how to address the isolate data fields.
|
||||
DCHECK_IMPLIES(!root_array_available(), isolate() != nullptr);
|
||||
@ -1998,6 +2001,9 @@ void MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
}
|
||||
|
||||
call(function);
|
||||
int call_pc_offset = pc_offset();
|
||||
bind(&get_pc);
|
||||
if (return_location) bind(return_location);
|
||||
|
||||
if (set_isolate_data_slots == SetIsolateDataSlots::kYes) {
|
||||
// We don't unset the PC; the FP is the source of truth.
|
||||
@ -2016,6 +2022,8 @@ void MacroAssembler::CallCFunction(Register function, int num_arguments,
|
||||
} else {
|
||||
add(esp, Immediate(num_arguments * kSystemPointerSize));
|
||||
}
|
||||
|
||||
return call_pc_offset;
|
||||
}
|
||||
|
||||
void MacroAssembler::PushPC() {
|
||||
@ -2112,7 +2120,8 @@ Operand MacroAssembler::EntryFromBuiltinAsOperand(Builtin builtin) {
|
||||
}
|
||||
|
||||
void MacroAssembler::LoadCodeInstructionStart(Register destination,
|
||||
Register code_object) {
|
||||
Register code_object,
|
||||
CodeEntrypointTag tag) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
mov(destination, FieldOperand(code_object, Code::kInstructionStartOffset));
|
||||
}
|
||||
@ -2185,21 +2194,28 @@ void MacroAssembler::LoadLabelAddress(Register dst, Label* lbl) {
|
||||
DCHECK(pc_offset() - kStart == kInsDelta);
|
||||
}
|
||||
|
||||
void MacroAssembler::MemoryChunkHeaderFromObject(Register object,
|
||||
Register header) {
|
||||
constexpr intptr_t alignment_mask =
|
||||
MemoryChunkHeader::GetAlignmentMaskForAssembler();
|
||||
if (header == object) {
|
||||
and_(header, Immediate(~alignment_mask));
|
||||
} else {
|
||||
mov(header, Immediate(~alignment_mask));
|
||||
and_(header, object);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::CheckPageFlag(Register object, Register scratch, int mask,
|
||||
Condition cc, Label* condition_met,
|
||||
Label::Distance condition_met_distance) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
DCHECK(cc == zero || cc == not_zero);
|
||||
if (scratch == object) {
|
||||
and_(scratch, Immediate(~kPageAlignmentMask));
|
||||
} else {
|
||||
mov(scratch, Immediate(~kPageAlignmentMask));
|
||||
and_(scratch, object);
|
||||
}
|
||||
MemoryChunkHeaderFromObject(object, scratch);
|
||||
if (mask < (1 << kBitsPerByte)) {
|
||||
test_b(Operand(scratch, BasicMemoryChunk::kFlagsOffset), Immediate(mask));
|
||||
test_b(Operand(scratch, MemoryChunkLayout::kFlagsOffset), Immediate(mask));
|
||||
} else {
|
||||
test(Operand(scratch, BasicMemoryChunk::kFlagsOffset), Immediate(mask));
|
||||
test(Operand(scratch, MemoryChunkLayout::kFlagsOffset), Immediate(mask));
|
||||
}
|
||||
j(cc, condition_met, condition_met_distance);
|
||||
}
|
||||
|
18
deps/v8/src/codegen/ia32/macro-assembler-ia32.h
vendored
18
deps/v8/src/codegen/ia32/macro-assembler-ia32.h
vendored
@ -74,6 +74,7 @@ class V8_EXPORT_PRIVATE MacroAssembler
|
||||
public:
|
||||
using SharedMacroAssembler<MacroAssembler>::SharedMacroAssembler;
|
||||
|
||||
void MemoryChunkHeaderFromObject(Register object, Register header);
|
||||
void CheckPageFlag(Register object, Register scratch, int mask, Condition cc,
|
||||
Label* condition_met,
|
||||
Label::Distance condition_met_distance = Label::kFar);
|
||||
@ -162,7 +163,8 @@ class V8_EXPORT_PRIVATE MacroAssembler
|
||||
void TailCallBuiltin(Builtin builtin);
|
||||
|
||||
// Load the code entry point from the Code object.
|
||||
void LoadCodeInstructionStart(Register destination, Register code_object);
|
||||
void LoadCodeInstructionStart(Register destination, Register code_object,
|
||||
CodeEntrypointTag = kDefaultCodeEntrypointTag);
|
||||
void CallCodeObject(Register code_object);
|
||||
void JumpCodeObject(Register code_object,
|
||||
JumpMode jump_mode = JumpMode::kJump);
|
||||
@ -234,16 +236,14 @@ class V8_EXPORT_PRIVATE MacroAssembler
|
||||
// garbage collection, since that might move the code and invalidate the
|
||||
// return address (unless this is somehow accounted for by the called
|
||||
// function).
|
||||
enum class SetIsolateDataSlots {
|
||||
kNo,
|
||||
kYes,
|
||||
};
|
||||
void CallCFunction(
|
||||
int CallCFunction(
|
||||
ExternalReference function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
void CallCFunction(
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_location = nullptr);
|
||||
int CallCFunction(
|
||||
Register function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes,
|
||||
Label* return_location = nullptr);
|
||||
|
||||
void ShlPair(Register high, Register low, uint8_t imm8);
|
||||
void ShlPair_cl(Register high, Register low);
|
||||
|
11
deps/v8/src/codegen/interface-descriptors-inl.h
vendored
11
deps/v8/src/codegen/interface-descriptors-inl.h
vendored
@ -115,8 +115,8 @@ void StaticCallInterfaceDescriptor<DerivedDescriptor>::Initialize(
|
||||
DCHECK_GE(return_registers.size(), DerivedDescriptor::kReturnCount);
|
||||
DCHECK_GE(return_double_registers.size(), DerivedDescriptor::kReturnCount);
|
||||
data->InitializeRegisters(
|
||||
DerivedDescriptor::flags(), DerivedDescriptor::kReturnCount,
|
||||
DerivedDescriptor::GetParameterCount(),
|
||||
DerivedDescriptor::flags(), DerivedDescriptor::kEntrypointTag,
|
||||
DerivedDescriptor::kReturnCount, DerivedDescriptor::GetParameterCount(),
|
||||
DerivedDescriptor::kStackArgumentOrder,
|
||||
DerivedDescriptor::GetRegisterParameterCount(), registers.data(),
|
||||
double_registers.data(), return_registers.data(),
|
||||
@ -138,7 +138,7 @@ StaticCallInterfaceDescriptor<DerivedDescriptor>::GetReturnCount() {
|
||||
static_assert(
|
||||
DerivedDescriptor::kReturnCount >= 0,
|
||||
"DerivedDescriptor subclass should override return count with a value "
|
||||
"that is greater than 0");
|
||||
"that is greater than or equal to 0");
|
||||
|
||||
return DerivedDescriptor::kReturnCount;
|
||||
}
|
||||
@ -150,7 +150,7 @@ StaticCallInterfaceDescriptor<DerivedDescriptor>::GetParameterCount() {
|
||||
static_assert(
|
||||
DerivedDescriptor::kParameterCount >= 0,
|
||||
"DerivedDescriptor subclass should override parameter count with a "
|
||||
"value that is greater than 0");
|
||||
"value that is greater than or equal to 0");
|
||||
|
||||
return DerivedDescriptor::kParameterCount;
|
||||
}
|
||||
@ -502,7 +502,8 @@ constexpr auto OnStackReplacementDescriptor::registers() {
|
||||
constexpr auto
|
||||
MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor::registers() {
|
||||
#ifdef V8_ENABLE_MAGLEV
|
||||
return RegisterArray(FlagsRegister(), FeedbackVectorRegister());
|
||||
return RegisterArray(FlagsRegister(), FeedbackVectorRegister(),
|
||||
TemporaryRegister());
|
||||
#else
|
||||
return DefaultRegisterArray();
|
||||
#endif
|
||||
|
3
deps/v8/src/codegen/interface-descriptors.cc
vendored
3
deps/v8/src/codegen/interface-descriptors.cc
vendored
@ -37,7 +37,7 @@ void CheckRegisterConfiguration(int count, const Register* registers,
|
||||
#endif
|
||||
|
||||
void CallInterfaceDescriptorData::InitializeRegisters(
|
||||
Flags flags, int return_count, int parameter_count,
|
||||
Flags flags, CodeEntrypointTag tag, int return_count, int parameter_count,
|
||||
StackArgumentOrder stack_order, int register_parameter_count,
|
||||
const Register* registers, const DoubleRegister* double_registers,
|
||||
const Register* return_registers,
|
||||
@ -52,6 +52,7 @@ void CallInterfaceDescriptorData::InitializeRegisters(
|
||||
#endif
|
||||
|
||||
flags_ = flags;
|
||||
tag_ = tag;
|
||||
stack_order_ = stack_order;
|
||||
return_count_ = return_count;
|
||||
param_count_ = parameter_count;
|
||||
|
74
deps/v8/src/codegen/interface-descriptors.h
vendored
74
deps/v8/src/codegen/interface-descriptors.h
vendored
@ -53,6 +53,8 @@ namespace internal {
|
||||
V(CallWithSpread) \
|
||||
V(CallWithSpread_Baseline) \
|
||||
V(CallWithSpread_WithFeedback) \
|
||||
V(CCall) \
|
||||
V(CEntryDummy) \
|
||||
V(CEntry1ArgvOnStack) \
|
||||
V(CloneObjectBaseline) \
|
||||
V(CloneObjectWithVector) \
|
||||
@ -117,6 +119,7 @@ namespace internal {
|
||||
V(NewHeapNumber) \
|
||||
V(NoContext) \
|
||||
V(OnStackReplacement) \
|
||||
V(RegExpTrampoline) \
|
||||
V(RestartFrameTrampoline) \
|
||||
V(ResumeGenerator) \
|
||||
V(ResumeGeneratorBaseline) \
|
||||
@ -141,6 +144,7 @@ namespace internal {
|
||||
V(UnaryOp_Baseline) \
|
||||
V(UnaryOp_WithFeedback) \
|
||||
V(Void) \
|
||||
V(WasmDummy) \
|
||||
V(WasmFloat32ToNumber) \
|
||||
V(WasmFloat64ToTagged) \
|
||||
V(WasmJSToWasmWrapper) \
|
||||
@ -191,8 +195,8 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
|
||||
// The passed registers are owned by the caller, and their lifetime is
|
||||
// expected to exceed that of this data. In practice, they are expected to
|
||||
// be in a static local.
|
||||
void InitializeRegisters(Flags flags, int return_count, int parameter_count,
|
||||
StackArgumentOrder stack_order,
|
||||
void InitializeRegisters(Flags flags, CodeEntrypointTag tag, int return_count,
|
||||
int parameter_count, StackArgumentOrder stack_order,
|
||||
int register_parameter_count,
|
||||
const Register* registers,
|
||||
const DoubleRegister* double_registers,
|
||||
@ -217,6 +221,7 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
|
||||
}
|
||||
|
||||
Flags flags() const { return flags_; }
|
||||
CodeEntrypointTag tag() const { return tag_; }
|
||||
int return_count() const { return return_count_; }
|
||||
int param_count() const { return param_count_; }
|
||||
int register_param_count() const { return register_param_count_; }
|
||||
@ -271,6 +276,7 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
|
||||
int return_count_ = kUninitializedCount;
|
||||
int param_count_ = kUninitializedCount;
|
||||
Flags flags_ = kNoFlags;
|
||||
CodeEntrypointTag tag_ = kDefaultCodeEntrypointTag;
|
||||
StackArgumentOrder stack_order_ = StackArgumentOrder::kDefault;
|
||||
|
||||
// Specifying the set of registers that could be used by the register
|
||||
@ -354,6 +360,8 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
|
||||
|
||||
Flags flags() const { return data()->flags(); }
|
||||
|
||||
CodeEntrypointTag tag() const { return data()->tag(); }
|
||||
|
||||
bool HasContextParameter() const {
|
||||
return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
|
||||
}
|
||||
@ -474,6 +482,9 @@ class StaticCallInterfaceDescriptor : public CallInterfaceDescriptor {
|
||||
static constexpr bool kNoContext = false;
|
||||
static constexpr bool kAllowVarArgs = false;
|
||||
static constexpr bool kNoStackScan = false;
|
||||
// TODO(saelo): we should not have a default value here to force all interface
|
||||
// descriptors to define a (unique) tag.
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kDefaultCodeEntrypointTag;
|
||||
static constexpr auto kStackArgumentOrder = StackArgumentOrder::kDefault;
|
||||
|
||||
// The set of registers available to the parameters, as a
|
||||
@ -752,6 +763,7 @@ constexpr EmptyDoubleRegisterArray DoubleRegisterArray() { return {}; }
|
||||
class V8_EXPORT_PRIVATE VoidDescriptor
|
||||
: public StaticCallInterfaceDescriptor<VoidDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kInvalidEntrypointTag;
|
||||
// The void descriptor could (and indeed probably should) also be NO_CONTEXT,
|
||||
// but this breaks some code assembler unittests.
|
||||
DEFINE_PARAMETERS()
|
||||
@ -761,10 +773,6 @@ class V8_EXPORT_PRIVATE VoidDescriptor
|
||||
static constexpr auto registers();
|
||||
};
|
||||
|
||||
// Dummy descriptor that marks builtins with C calling convention.
|
||||
// TODO(jgruber): Define real descriptors for C calling conventions.
|
||||
using CCallDescriptor = VoidDescriptor;
|
||||
|
||||
// Marks deoptimization entry builtins. Precise calling conventions currently
|
||||
// differ based on the platform.
|
||||
// TODO(jgruber): Once this is unified, we could create a better description
|
||||
@ -777,15 +785,39 @@ using JSEntryDescriptor = VoidDescriptor;
|
||||
|
||||
// TODO(jgruber): Consider filling in the details here; however, this doesn't
|
||||
// make too much sense as long as the descriptor isn't used or verified.
|
||||
using CEntryDummyDescriptor = VoidDescriptor;
|
||||
using ContinueToBuiltinDescriptor = VoidDescriptor;
|
||||
|
||||
// Dummy descriptor that marks builtins with C calling convention.
|
||||
// TODO(jgruber): Define real descriptors for C calling conventions.
|
||||
class CCallDescriptor : public StaticCallInterfaceDescriptor<CCallDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kDefaultCodeEntrypointTag;
|
||||
DEFINE_PARAMETERS()
|
||||
DEFINE_PARAMETER_TYPES()
|
||||
DECLARE_DESCRIPTOR(CCallDescriptor)
|
||||
};
|
||||
|
||||
// TODO(jgruber): Consider filling in the details here; however, this doesn't
|
||||
// make too much sense as long as the descriptor isn't used or verified.
|
||||
using ContinueToBuiltinDescriptor = VoidDescriptor;
|
||||
class CEntryDummyDescriptor
|
||||
: public StaticCallInterfaceDescriptor<CEntryDummyDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kDefaultCodeEntrypointTag;
|
||||
DEFINE_PARAMETERS()
|
||||
DEFINE_PARAMETER_TYPES()
|
||||
DECLARE_DESCRIPTOR(CEntryDummyDescriptor)
|
||||
};
|
||||
|
||||
// TODO(wasm): Consider filling in details / defining real descriptors for all
|
||||
// builtins still using this placeholder descriptor.
|
||||
using WasmDummyDescriptor = VoidDescriptor;
|
||||
class WasmDummyDescriptor
|
||||
: public StaticCallInterfaceDescriptor<WasmDummyDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kWasmEntrypointTag;
|
||||
DEFINE_PARAMETERS()
|
||||
DEFINE_PARAMETER_TYPES()
|
||||
DECLARE_DESCRIPTOR(WasmDummyDescriptor)
|
||||
};
|
||||
|
||||
class AllocateDescriptor
|
||||
: public StaticCallInterfaceDescriptor<AllocateDescriptor> {
|
||||
@ -819,6 +851,17 @@ class JSTrampolineDescriptor
|
||||
DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor)
|
||||
};
|
||||
|
||||
// Descriptor used for code using the RegExp calling convention, in particular
|
||||
// the RegExp interpreter trampolines.
|
||||
class RegExpTrampolineDescriptor
|
||||
: public StaticCallInterfaceDescriptor<RegExpTrampolineDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kRegExpEntrypointTag;
|
||||
DEFINE_PARAMETERS()
|
||||
DEFINE_PARAMETER_TYPES()
|
||||
DECLARE_DESCRIPTOR(RegExpTrampolineDescriptor)
|
||||
};
|
||||
|
||||
class ContextOnlyDescriptor
|
||||
: public StaticCallInterfaceDescriptor<ContextOnlyDescriptor> {
|
||||
public:
|
||||
@ -953,14 +996,17 @@ class MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor
|
||||
: public StaticCallInterfaceDescriptor<
|
||||
MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor> {
|
||||
public:
|
||||
DEFINE_PARAMETERS_NO_CONTEXT(kFlags, kFeedbackVector)
|
||||
DEFINE_PARAMETERS_NO_CONTEXT(kFlags, kFeedbackVector, kTemporary)
|
||||
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kFlags
|
||||
MachineType::TaggedPointer()) // kFeedbackVector
|
||||
MachineType::TaggedPointer(), // kFeedbackVector
|
||||
MachineType::AnyTagged()) // kTemporary
|
||||
DECLARE_DESCRIPTOR(MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor)
|
||||
|
||||
static constexpr inline Register FlagsRegister();
|
||||
static constexpr inline Register FeedbackVectorRegister();
|
||||
|
||||
static constexpr inline Register TemporaryRegister();
|
||||
|
||||
static constexpr inline auto registers();
|
||||
};
|
||||
|
||||
@ -1009,6 +1055,8 @@ class StoreBaselineDescriptor
|
||||
class StoreTransitionDescriptor
|
||||
: public StaticCallInterfaceDescriptor<StoreTransitionDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kICHandlerEntrypointTag;
|
||||
|
||||
DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
|
||||
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
|
||||
MachineType::AnyTagged(), // kName
|
||||
@ -1026,6 +1074,8 @@ class StoreTransitionDescriptor
|
||||
class StoreWithVectorDescriptor
|
||||
: public StaticCallInterfaceDescriptor<StoreWithVectorDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kICHandlerEntrypointTag;
|
||||
|
||||
DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
|
||||
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
|
||||
MachineType::AnyTagged(), // kName
|
||||
@ -1127,6 +1177,8 @@ class DefineKeyedOwnWithVectorDescriptor
|
||||
class LoadWithVectorDescriptor
|
||||
: public StaticCallInterfaceDescriptor<LoadWithVectorDescriptor> {
|
||||
public:
|
||||
static constexpr CodeEntrypointTag kEntrypointTag = kICHandlerEntrypointTag;
|
||||
|
||||
// TODO(v8:9497): Revert the Machine type for kSlot to the
|
||||
// TaggedSigned once Torque can emit better call descriptors
|
||||
DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
|
||||
|
@ -4555,8 +4555,9 @@ void MacroAssembler::CheckPageFlag(Register object, int mask, Condition cc,
|
||||
UseScratchRegisterScope temps(this);
|
||||
temps.Include(t8);
|
||||
Register scratch = temps.Acquire();
|
||||
And(scratch, object, Operand(~kPageAlignmentMask));
|
||||
Ld_d(scratch, MemOperand(scratch, BasicMemoryChunk::kFlagsOffset));
|
||||
And(scratch, object,
|
||||
Operand(~MemoryChunkHeader::GetAlignmentMaskForAssembler()));
|
||||
Ld_d(scratch, MemOperand(scratch, MemoryChunkLayout::kFlagsOffset));
|
||||
And(scratch, scratch, Operand(mask));
|
||||
Branch(condition_met, cc, scratch, Operand(zero_reg));
|
||||
}
|
||||
|
@ -518,10 +518,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
|
||||
// garbage collection, since that might move the code and invalidate the
|
||||
// return address (unless this is somehow accounted for by the called
|
||||
// function).
|
||||
enum class SetIsolateDataSlots {
|
||||
kNo,
|
||||
kYes,
|
||||
};
|
||||
void CallCFunction(
|
||||
ExternalReference function, int num_arguments,
|
||||
SetIsolateDataSlots set_isolate_data_slots = SetIsolateDataSlots::kYes);
|
||||
|
5
deps/v8/src/codegen/macro-assembler.h
vendored
5
deps/v8/src/codegen/macro-assembler.h
vendored
@ -45,6 +45,11 @@ enum class ComparisonMode {
|
||||
kFullPointer,
|
||||
};
|
||||
|
||||
enum class SetIsolateDataSlots {
|
||||
kNo,
|
||||
kYes,
|
||||
};
|
||||
|
||||
// This is the only place allowed to include the platform-specific headers.
|
||||
#define INCLUDED_FROM_MACRO_ASSEMBLER_H
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
|
@ -6172,8 +6172,9 @@ void MacroAssembler::CallCFunctionHelper(
|
||||
void MacroAssembler::CheckPageFlag(Register object, Register scratch, int mask,
|
||||
Condition cc, Label* condition_met) {
|
||||
ASM_CODE_COMMENT(this);
|
||||
And(scratch, object, Operand(~kPageAlignmentMask));
|
||||
Ld(scratch, MemOperand(scratch, BasicMemoryChunk::kFlagsOffset));
|
||||
And(scratch, object,
|
||||
Operand(~MemoryChunkHeader::GetAlignmentMaskForAssembler()));
|
||||
Ld(scratch, MemOperand(scratch, MemoryChunkLayout::kFlagsOffset));
|
||||
And(scratch, scratch, Operand(mask));
|
||||
Branch(condition_met, cc, scratch, Operand(zero_reg));
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user