diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index ce47fa36103f45..6a9bbd67997311 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -52,6 +52,8 @@ /test/test262/data /test/test262/harness /test/wasm-js/data +/test/wasm-js/tests +/test/wasm-js/tests.tar.gz /test/wasm-spec-tests/tests /test/wasm-spec-tests/tests.tar.gz /third_party/* diff --git a/deps/v8/.gn b/deps/v8/.gn index 328778fb46bcdf..d4ad959954845f 100644 --- a/deps/v8/.gn +++ b/deps/v8/.gn @@ -16,4 +16,5 @@ check_targets = [] # These are the list of GN files that run exec_script. This whitelist exists # to force additional review for new uses of exec_script, which is strongly # discouraged except for gypi_to_gn calls. -exec_script_whitelist = build_dotfile_settings.exec_script_whitelist + [] +exec_script_whitelist = build_dotfile_settings.exec_script_whitelist + + [ "//build_overrides/build.gni" ] diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 827d124b0dcf0d..1198de8f358fbc 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -39,6 +39,7 @@ Vewd Software AS <*@vewd.com> Groupon <*@groupon.com> Meteor Development Group <*@meteor.com> Cloudflare, Inc. <*@cloudflare.com> +Julia Computing, Inc. <*@juliacomputing.com> Aaron Bieber Abdulla Kamar @@ -74,6 +75,7 @@ Colin Ihrig Daniel Andersson Daniel Bevenius Daniel James +David Carlier Deepak Mohan Deon Dior Dominic Farolini @@ -163,6 +165,7 @@ Rob Wu Robert Meijer Robert Mustacchi Robert Nagy +Rong Wang Ross Kirsling Ruben Bridgewater Ryan Dahl diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index efca4a626f1633..c486f1a1c86abc 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -91,7 +91,7 @@ declare_args() { # Enable embedded builtins. v8_enable_embedded_builtins = true - # Enable the registration of unwinding info for Windows/x64. + # Enable the registration of unwinding info for Windows x64 and ARM64. v8_win64_unwinding_info = true # Enable code comments for builtins in the snapshot (impacts performance). @@ -187,15 +187,21 @@ declare_args() { # Enable sharing read-only space across isolates. # Sets -DV8_SHARED_RO_HEAP. v8_enable_shared_ro_heap = "" -} -# We reuse the snapshot toolchain for building torque and other generators to -# avoid building v8_libbase on the host more than once. On mips with big endian, -# the snapshot toolchain is the target toolchain and, hence, can't be used. -v8_generator_toolchain = v8_snapshot_toolchain -if (host_cpu == "x64" && - (v8_current_cpu == "mips" || v8_current_cpu == "mips64")) { - v8_generator_toolchain = "//build/toolchain/linux:clang_x64" + # Enable lazy source positions by default. + v8_enable_lazy_source_positions = true + + # Disable write barriers when GCs are non-incremental and + # heap has single generation. + v8_disable_write_barriers = false + + # Redirect allocation in young generation so that there will be + # only one single generation. + v8_enable_single_generation = "" + + # Use token threaded dispatch for the regular expression interpreter. + # Use switch-based dispatch if this is false + v8_enable_regexp_interpreter_threaded_dispatch = true } # Derived defaults. @@ -231,6 +237,13 @@ if (v8_enable_fast_torque == "") { v8_enable_fast_torque = v8_enable_fast_mksnapshot } +if (v8_enable_single_generation == "") { + v8_enable_single_generation = v8_disable_write_barriers +} + +assert(!v8_disable_write_barriers || v8_enable_single_generation, + "Disabling write barriers works only with single generation") + assert(v8_current_cpu != "x86" || !v8_untrusted_code_mitigations, "Untrusted code mitigations are unsupported on ia32") @@ -424,12 +437,21 @@ config("features") { defines += [ "V8_SNAPSHOT_NATIVE_CODE_COUNTERS" ] } } + if (v8_enable_single_generation) { + defines += [ "V8_ENABLE_SINGLE_GENERATION" ] + } + if (v8_disable_write_barriers) { + defines += [ "V8_DISABLE_WRITE_BARRIERS" ] + } if (v8_use_external_startup_data) { defines += [ "V8_USE_EXTERNAL_STARTUP_DATA" ] } if (v8_enable_concurrent_marking) { defines += [ "V8_CONCURRENT_MARKING" ] } + if (v8_enable_lazy_source_positions) { + defines += [ "V8_ENABLE_LAZY_SOURCE_POSITIONS" ] + } if (v8_check_microtasks_scopes_consistency) { defines += [ "V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY" ] } @@ -451,6 +473,9 @@ config("features") { if (v8_win64_unwinding_info) { defines += [ "V8_WIN64_UNWINDING_INFO" ] } + if (v8_enable_regexp_interpreter_threaded_dispatch) { + defines += [ "V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH" ] + } } config("toolchain") { @@ -968,16 +993,21 @@ torque_files = [ "src/builtins/proxy-set-prototype-of.tq", "src/builtins/proxy.tq", "src/builtins/reflect.tq", + "src/builtins/regexp-match.tq", "src/builtins/regexp-replace.tq", + "src/builtins/regexp-source.tq", + "src/builtins/regexp-test.tq", "src/builtins/regexp.tq", "src/builtins/string.tq", "src/builtins/string-endswith.tq", "src/builtins/string-html.tq", "src/builtins/string-iterator.tq", + "src/builtins/string-pad.tq", "src/builtins/string-repeat.tq", "src/builtins/string-slice.tq", "src/builtins/string-startswith.tq", "src/builtins/string-substring.tq", + "src/builtins/torque-internal.tq", "src/builtins/typed-array-createtypedarray.tq", "src/builtins/typed-array-every.tq", "src/builtins/typed-array-filter.tq", @@ -1002,6 +1032,7 @@ if (!v8_enable_i18n_support) { action("run_torque") { visibility = [ ":*", + "tools/debug_helper/:*", "tools/gcmole/:*", "test/cctest/:*", ] @@ -1023,6 +1054,8 @@ action("run_torque") { "$target_gen_dir/torque-generated/class-definitions-tq.cc", "$target_gen_dir/torque-generated/class-definitions-tq-inl.h", "$target_gen_dir/torque-generated/class-definitions-tq.h", + "$target_gen_dir/torque-generated/class-debug-readers-tq.cc", + "$target_gen_dir/torque-generated/class-debug-readers-tq.h", "$target_gen_dir/torque-generated/exported-macros-assembler-tq.cc", "$target_gen_dir/torque-generated/exported-macros-assembler-tq.h", "$target_gen_dir/torque-generated/csa-types-tq.h", @@ -1752,6 +1785,8 @@ v8_compiler_sources = [ "src/compiler/escape-analysis-reducer.h", "src/compiler/escape-analysis.cc", "src/compiler/escape-analysis.h", + "src/compiler/feedback-source.cc", + "src/compiler/feedback-source.h", "src/compiler/frame-states.cc", "src/compiler/frame-states.h", "src/compiler/frame.cc", @@ -1892,8 +1927,6 @@ v8_compiler_sources = [ "src/compiler/types.h", "src/compiler/value-numbering-reducer.cc", "src/compiler/value-numbering-reducer.h", - "src/compiler/vector-slot-pair.cc", - "src/compiler/vector-slot-pair.h", "src/compiler/verifier.cc", "src/compiler/verifier.h", "src/compiler/wasm-compiler.cc", @@ -2031,7 +2064,6 @@ v8_source_set("v8_base_without_compiler") { "src/builtins/builtins-internal.cc", "src/builtins/builtins-intl.cc", "src/builtins/builtins-json.cc", - "src/builtins/builtins-math.cc", "src/builtins/builtins-number.cc", "src/builtins/builtins-object.cc", "src/builtins/builtins-promise.cc", @@ -2095,6 +2127,7 @@ v8_source_set("v8_base_without_compiler") { "src/codegen/register-arch.h", "src/codegen/register-configuration.cc", "src/codegen/register-configuration.h", + "src/codegen/register.cc", "src/codegen/register.h", "src/codegen/reglist.h", "src/codegen/reloc-info.cc", @@ -2194,6 +2227,9 @@ v8_source_set("v8_base_without_compiler") { "src/execution/messages.h", "src/execution/microtask-queue.cc", "src/execution/microtask-queue.h", + "src/execution/protectors-inl.h", + "src/execution/protectors.cc", + "src/execution/protectors.h", "src/execution/runtime-profiler.cc", "src/execution/runtime-profiler.h", "src/execution/simulator-base.cc", @@ -2758,7 +2794,6 @@ v8_source_set("v8_base_without_compiler") { "src/runtime/runtime-typedarray.cc", "src/runtime/runtime-utils.h", "src/runtime/runtime-wasm.cc", - "src/runtime/runtime-weak-refs.cc", "src/runtime/runtime.cc", "src/runtime/runtime.h", "src/sanitizer/asan.h", @@ -2922,6 +2957,8 @@ v8_source_set("v8_base_without_compiler") { "src/wasm/wasm-memory.h", "src/wasm/wasm-module-builder.cc", "src/wasm/wasm-module-builder.h", + "src/wasm/wasm-module-sourcemap.cc", + "src/wasm/wasm-module-sourcemap.h", "src/wasm/wasm-module.cc", "src/wasm/wasm-module.h", "src/wasm/wasm-objects-inl.h", @@ -3109,6 +3146,7 @@ v8_source_set("v8_base_without_compiler") { "src/diagnostics/arm64/eh-frame-arm64.cc", "src/execution/arm64/frame-constants-arm64.cc", "src/execution/arm64/frame-constants-arm64.h", + "src/execution/arm64/pointer-auth-arm64.cc", "src/execution/arm64/simulator-arm64.cc", "src/execution/arm64/simulator-arm64.h", "src/execution/arm64/simulator-logic-arm64.cc", @@ -3116,6 +3154,12 @@ v8_source_set("v8_base_without_compiler") { "src/regexp/arm64/regexp-macro-assembler-arm64.h", "src/wasm/baseline/arm64/liftoff-assembler-arm64.h", ] + if (is_win) { + sources += [ + "src/diagnostics/unwinding-info-win64.cc", + "src/diagnostics/unwinding-info-win64.h", + ] + } jumbo_excluded_sources += [ # TODO(mostynb@vewd.com): fix this code so it doesn't need # to be excluded, see the comments inside. @@ -3325,6 +3369,7 @@ v8_source_set("torque_base") { "src/torque/ast.h", "src/torque/cfg.cc", "src/torque/cfg.h", + "src/torque/class-debug-reader-generator.cc", "src/torque/constants.h", "src/torque/contextual.h", "src/torque/csa-generator.cc", @@ -3351,6 +3396,8 @@ v8_source_set("torque_base") { "src/torque/torque-compiler.h", "src/torque/torque-parser.cc", "src/torque/torque-parser.h", + "src/torque/type-inference.cc", + "src/torque/type-inference.h", "src/torque/type-oracle.cc", "src/torque/type-oracle.h", "src/torque/type-visitor.cc", diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 27afc18a5117cd..be6a58859c5394 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,1453 @@ +2019-09-04: Version 7.8.279 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.278 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.277 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.276 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.275 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.274 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.273 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.272 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.271 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.270 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.269 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.268 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.267 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.266 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.265 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.264 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.263 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.262 + + Performance and stability improvements on all platforms. + + +2019-09-03: Version 7.8.261 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.260 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.259 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.258 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.257 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.256 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.255 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.254 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.253 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.252 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.251 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.250 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.249 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.248 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.247 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.246 + + Performance and stability improvements on all platforms. + + +2019-09-02: Version 7.8.245 + + Performance and stability improvements on all platforms. + + +2019-09-01: Version 7.8.244 + + Performance and stability improvements on all platforms. + + +2019-08-31: Version 7.8.243 + + Performance and stability improvements on all platforms. + + +2019-08-31: Version 7.8.242 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.241 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.240 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.239 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.238 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.237 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.236 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.235 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.234 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.233 + + Performance and stability improvements on all platforms. + + +2019-08-30: Version 7.8.232 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.231 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.230 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.229 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.228 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.227 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.226 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.225 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.224 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.223 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.222 + + Performance and stability improvements on all platforms. + + +2019-08-29: Version 7.8.221 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.220 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.219 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.218 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.217 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.216 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.215 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.214 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.213 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.212 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.211 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.210 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.209 + + Performance and stability improvements on all platforms. + + +2019-08-28: Version 7.8.208 + + Performance and stability improvements on all platforms. + + +2019-08-27: Version 7.8.207 + + Performance and stability improvements on all platforms. + + +2019-08-27: Version 7.8.206 + + Performance and stability improvements on all platforms. + + +2019-08-27: Version 7.8.205 + + Performance and stability improvements on all platforms. + + +2019-08-27: Version 7.8.204 + + Performance and stability improvements on all platforms. + + +2019-08-27: Version 7.8.203 + + Performance and stability improvements on all platforms. + + +2019-08-27: Version 7.8.202 + + Performance and stability improvements on all platforms. + + +2019-08-27: Version 7.8.201 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.200 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.199 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.198 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.197 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.196 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.195 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.194 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.193 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.192 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.191 + + Performance and stability improvements on all platforms. + + +2019-08-26: Version 7.8.190 + + Performance and stability improvements on all platforms. + + +2019-08-25: Version 7.8.189 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.188 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.187 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.186 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.185 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.184 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.183 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.182 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.181 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.180 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.179 + + Performance and stability improvements on all platforms. + + +2019-08-23: Version 7.8.178 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.177 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.176 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.175 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.174 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.173 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.172 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.171 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.170 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.169 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.168 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.167 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.166 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.165 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.164 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.163 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.162 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.161 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.160 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.159 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.158 + + Performance and stability improvements on all platforms. + + +2019-08-22: Version 7.8.157 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.156 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.155 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.154 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.153 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.152 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.151 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.150 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.149 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.148 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.147 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.146 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.145 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.144 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.143 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.142 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.141 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.140 + + Performance and stability improvements on all platforms. + + +2019-08-21: Version 7.8.139 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.138 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.137 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.136 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.135 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.134 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.133 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.132 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.131 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.130 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.129 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.128 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.127 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.126 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.125 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.124 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.123 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.122 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.121 + + Performance and stability improvements on all platforms. + + +2019-08-20: Version 7.8.120 + + Performance and stability improvements on all platforms. + + +2019-08-19: Version 7.8.119 + + Performance and stability improvements on all platforms. + + +2019-08-19: Version 7.8.118 + + Performance and stability improvements on all platforms. + + +2019-08-19: Version 7.8.117 + + Performance and stability improvements on all platforms. + + +2019-08-19: Version 7.8.116 + + Performance and stability improvements on all platforms. + + +2019-08-19: Version 7.8.115 + + Performance and stability improvements on all platforms. + + +2019-08-19: Version 7.8.114 + + Performance and stability improvements on all platforms. + + +2019-08-16: Version 7.8.113 + + Performance and stability improvements on all platforms. + + +2019-08-15: Version 7.8.112 + + Performance and stability improvements on all platforms. + + +2019-08-14: Version 7.8.111 + + Performance and stability improvements on all platforms. + + +2019-08-14: Version 7.8.110 + + Performance and stability improvements on all platforms. + + +2019-08-14: Version 7.8.109 + + Performance and stability improvements on all platforms. + + +2019-08-14: Version 7.8.108 + + Performance and stability improvements on all platforms. + + +2019-08-14: Version 7.8.107 + + Performance and stability improvements on all platforms. + + +2019-08-14: Version 7.8.106 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.105 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.104 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.103 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.102 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.101 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.100 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.99 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.98 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.97 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.96 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.95 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.94 + + Performance and stability improvements on all platforms. + + +2019-08-13: Version 7.8.93 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.92 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.91 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.90 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.89 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.88 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.87 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.86 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.85 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.84 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.83 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.82 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.81 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.80 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.79 + + Performance and stability improvements on all platforms. + + +2019-08-12: Version 7.8.78 + + Performance and stability improvements on all platforms. + + +2019-08-09: Version 7.8.77 + + Performance and stability improvements on all platforms. + + +2019-08-09: Version 7.8.76 + + Performance and stability improvements on all platforms. + + +2019-08-09: Version 7.8.75 + + Performance and stability improvements on all platforms. + + +2019-08-09: Version 7.8.74 + + Performance and stability improvements on all platforms. + + +2019-08-09: Version 7.8.73 + + Performance and stability improvements on all platforms. + + +2019-08-09: Version 7.8.72 + + Performance and stability improvements on all platforms. + + +2019-08-08: Version 7.8.71 + + Performance and stability improvements on all platforms. + + +2019-08-08: Version 7.8.70 + + Performance and stability improvements on all platforms. + + +2019-08-08: Version 7.8.69 + + Performance and stability improvements on all platforms. + + +2019-08-08: Version 7.8.68 + + Performance and stability improvements on all platforms. + + +2019-08-07: Version 7.8.67 + + Performance and stability improvements on all platforms. + + +2019-08-07: Version 7.8.66 + + Performance and stability improvements on all platforms. + + +2019-08-07: Version 7.8.65 + + Performance and stability improvements on all platforms. + + +2019-08-06: Version 7.8.64 + + Performance and stability improvements on all platforms. + + +2019-08-06: Version 7.8.63 + + Performance and stability improvements on all platforms. + + +2019-08-06: Version 7.8.62 + + Performance and stability improvements on all platforms. + + +2019-08-05: Version 7.8.61 + + Performance and stability improvements on all platforms. + + +2019-08-05: Version 7.8.60 + + Performance and stability improvements on all platforms. + + +2019-08-04: Version 7.8.59 + + Performance and stability improvements on all platforms. + + +2019-08-02: Version 7.8.58 + + Performance and stability improvements on all platforms. + + +2019-08-02: Version 7.8.57 + + Performance and stability improvements on all platforms. + + +2019-08-02: Version 7.8.56 + + Performance and stability improvements on all platforms. + + +2019-08-02: Version 7.8.55 + + Performance and stability improvements on all platforms. + + +2019-08-02: Version 7.8.54 + + Performance and stability improvements on all platforms. + + +2019-08-02: Version 7.8.53 + + Performance and stability improvements on all platforms. + + +2019-08-01: Version 7.8.52 + + Performance and stability improvements on all platforms. + + +2019-08-01: Version 7.8.51 + + Performance and stability improvements on all platforms. + + +2019-08-01: Version 7.8.50 + + Performance and stability improvements on all platforms. + + +2019-08-01: Version 7.8.49 + + Performance and stability improvements on all platforms. + + +2019-08-01: Version 7.8.48 + + Performance and stability improvements on all platforms. + + +2019-08-01: Version 7.8.47 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.46 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.45 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.44 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.43 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.42 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.41 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.40 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.39 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.38 + + Performance and stability improvements on all platforms. + + +2019-07-31: Version 7.8.37 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.36 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.35 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.34 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.33 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.32 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.31 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.30 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.29 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.28 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.27 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.26 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.25 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.24 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.23 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.22 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.21 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.20 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.19 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.18 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.17 + + Performance and stability improvements on all platforms. + + +2019-07-30: Version 7.8.16 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.15 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.14 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.13 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.12 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.11 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.10 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.9 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.8 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.7 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.6 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.5 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.4 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.3 + + Performance and stability improvements on all platforms. + + +2019-07-29: Version 7.8.2 + + Performance and stability improvements on all platforms. + + +2019-07-28: Version 7.8.1 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.310 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.309 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.308 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.307 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.306 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.305 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.304 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.303 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.302 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.301 + + Performance and stability improvements on all platforms. + + +2019-07-24: Version 7.7.300 + + Performance and stability improvements on all platforms. + + 2019-07-23: Version 7.7.299 Performance and stability improvements on all platforms. diff --git a/deps/v8/DEPS b/deps/v8/DEPS index 986264356f99cc..a7d4081edb856c 100644 --- a/deps/v8/DEPS +++ b/deps/v8/DEPS @@ -3,6 +3,21 @@ # all paths in here must match this assumption. vars = { + # Fetches only the SDK boot images which match at least one of the whitelist + # entries in a comma-separated list. + # + # Only the X64 and ARM64 QEMU images are downloaded by default. Developers + # that need to boot on other target architectures or devices can opt to + # download more boot images. Example of images include: + # + # Emulation: + # qemu.x64, qemu.arm64 + # Hardware: + # generic.x64, generic.arm64 + # + # Wildcards are supported (e.g. "qemu.*"). + 'checkout_fuchsia_boot_images': "qemu.x64,qemu.arm64", + 'checkout_instrumented_libraries': False, 'chromium_url': 'https://chromium.googlesource.com', 'android_url': 'https://android.googlesource.com', @@ -12,7 +27,7 @@ vars = { 'check_v8_header_includes': False, # GN CIPD package version. - 'gn_version': 'git_revision:972ed755f8e6d31cae9ba15fcd08136ae1a7886f', + 'gn_version': 'git_revision:152c5144ceed9592c20f0c8fd55769646077569b', # luci-go CIPD package version. 'luci_go': 'git_revision:7d11fd9e66407c49cb6c8546a2ae45ea993a240c', @@ -20,7 +35,7 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_build-tools_version # and whatever else without interference from each other. - 'android_sdk_build-tools_version': 'DLK621q5_Bga5EsOr7cp6bHWWxFKx6UHLu_Ix_m3AckC', + 'android_sdk_build-tools_version': '5DL7LQQjVMLClXLzLgmGysccPGsGcjJdvH9z5-uetiIC', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_emulator_version # and whatever else without interference from each other. @@ -57,15 +72,15 @@ vars = { deps = { 'v8/build': - Var('chromium_url') + '/chromium/src/build.git' + '@' + '1e5d7d692f816af8136c738b79fe9e8dde8057f6', + Var('chromium_url') + '/chromium/src/build.git' + '@' + '693faeda4ee025796c7e473d953a5a7b6ad64c93', 'v8/third_party/depot_tools': - Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'ee7b9dda90e409fb92031d511151debe5db7db9f', + Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'f38bc1796282c61087dcf15abc61b8fd18a68402', 'v8/third_party/icu': - Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'fd97d4326fac6da84452b2d5fe75ff0949368dab', + Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '53f6b233a41ec982d8445996247093f7aaf41639', 'v8/third_party/instrumented_libraries': Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + 'b1c3ca20848c117eb935b02c25d441f03e6fbc5e', 'v8/buildtools': - Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '67b293ca1316d06f7f00160ce35c92b8849a9dc9', + Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '74cfb57006f83cfe050817526db359d5c8a11628', 'v8/buildtools/clang_format/script': Var('chromium_url') + '/chromium/llvm-project/cfe/tools/clang-format.git' + '@' + '96636aa0e9f047f17447f2d45a094d0b59ed7917', 'v8/buildtools/linux64': { @@ -105,9 +120,9 @@ deps = { 'condition': 'host_os == "win"', }, 'v8/base/trace_event/common': - Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + 'cfe8887fa6ac3170e23a68949930e28d4705a16f', + Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + '5e4fce17a9d2439c44a7b57ceecef6df9287ec2f', 'v8/third_party/android_ndk': { - 'url': Var('chromium_url') + '/android_ndk.git' + '@' + '4e2cea441bfd43f0863d14f57b1e1844260b9884', + 'url': Var('chromium_url') + '/android_ndk.git' + '@' + '62582753e869484bf0cc7f7e8d184ce0077033c2', 'condition': 'checkout_android', }, 'v8/third_party/android_sdk/public': { @@ -153,7 +168,7 @@ deps = { 'dep_type': 'cipd', }, 'v8/third_party/catapult': { - 'url': Var('chromium_url') + '/catapult.git' + '@' + '53913cecb11a3ef993f6496b9110964e2e2aeec3', + 'url': Var('chromium_url') + '/catapult.git' + '@' + 'e7c719c3e85f76938bf4fef0ba37c27f89246f71', 'condition': 'checkout_android', }, 'v8/third_party/colorama/src': { @@ -161,11 +176,11 @@ deps = { 'condition': 'checkout_android', }, 'v8/third_party/fuchsia-sdk': { - 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '5fd29151cf35c0813c33cc368a7c78389e3f5caa', + 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '1785f0ac8e1fe81cb25e260acbe7de8f62fa3e44', 'condition': 'checkout_fuchsia', }, 'v8/third_party/googletest/src': - Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '6077f444da944d96d311d358d761164261f1cdd0', + Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '565f1b848215b77c3732bca345fe76a0431d8b34', 'v8/third_party/jinja2': Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'b41863e42637544c2941b574c7877d3e1f663e25', 'v8/third_party/markupsafe': @@ -177,7 +192,7 @@ deps = { 'v8/test/mozilla/data': Var('chromium_url') + '/v8/deps/third_party/mozilla-tests.git' + '@' + 'f6c578a10ea707b1a8ab0b88943fe5115ce2b9be', 'v8/test/test262/data': - Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '26a2268436f28f64c4539d9aab9ebd0f0b7c99c5', + Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '59a1a016b7cf5cf43f66b274c7d1db4ec6066935', 'v8/test/test262/harness': Var('chromium_url') + '/external/github.com/test262-utils/test262-harness-py.git' + '@' + '4555345a943d0c99a9461182705543fb171dda4b', 'v8/third_party/qemu-linux-x64': { @@ -201,7 +216,7 @@ deps = { 'dep_type': 'cipd', }, 'v8/tools/clang': - Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'f485a21a9cb05494161d97d545c3b29447610ffb', + Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '2fef805e5b05b26a8c87c47865590b5f43218611', 'v8/tools/luci-go': { 'packages': [ { @@ -230,10 +245,8 @@ deps = { 'condition': 'checkout_mac', 'dep_type': 'cipd', }, - 'v8/test/wasm-js/data': - Var('chromium_url') + '/external/github.com/WebAssembly/spec.git' + '@' + '1a411f713d9850ce7da24719aba5bb80c535f562', 'v8/third_party/perfetto': - Var('android_url') + '/platform/external/perfetto.git' + '@' + '0e8281399fd854de13461f2c1c9f2fb0b8e9c3ae', + Var('android_url') + '/platform/external/perfetto.git' + '@' + '01615892494a9a8dc84414962d0a817bf97de2c2', 'v8/third_party/protobuf': Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + 'b68a347f56137b4b1a746e8c7438495a6ac1bd91', } @@ -346,6 +359,17 @@ hooks = [ '-s', 'v8/test/wasm-spec-tests/tests.tar.gz.sha1', ], }, + { + 'name': 'wasm_js', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--no_auth', + '-u', + '--bucket', 'v8-wasm-spec-tests', + '-s', 'v8/test/wasm-js/tests.tar.gz.sha1', + ], + }, { 'name': 'sysroot_arm', 'pattern': '.', @@ -410,6 +434,13 @@ hooks = [ 'condition': 'checkout_win', 'action': ['python', 'v8/build/vs_toolchain.py', 'update'], }, + { + # Update the Mac toolchain if necessary. + 'name': 'mac_toolchain', + 'pattern': '.', + 'condition': 'checkout_mac', + 'action': ['python', 'v8/build/mac_toolchain.py'], + }, # Pull binutils for linux, enabled debug fission for faster linking / # debugging when used with clang on Ubuntu Precise. # https://code.google.com/p/chromium/issues/detail?id=352046 @@ -444,6 +475,7 @@ hooks = [ 'action': [ 'python', 'v8/build/fuchsia/update_sdk.py', + '--boot-images={checkout_fuchsia_boot_images}', ], }, { diff --git a/deps/v8/OWNERS b/deps/v8/OWNERS index be360966665b38..9ab84b1e2759de 100644 --- a/deps/v8/OWNERS +++ b/deps/v8/OWNERS @@ -1,31 +1,31 @@ # Eng reviewer. Please reach out before adding new top-level directories. # Disagreement among owners should be escalated to eng reviewers. -file://ENG_REVIEW_OWNERS +file:ENG_REVIEW_OWNERS -per-file .clang-format=file://INFRA_OWNERS -per-file .clang-tidy=file://INFRA_OWNERS -per-file .editorconfig=file://INFRA_OWNERS -per-file .flake8=file://INFRA_OWNERS -per-file .git-blame-ignore-revs=file://INFRA_OWNERS -per-file .gitattributes=file://INFRA_OWNERS -per-file .gitignore=file://INFRA_OWNERS -per-file .gn=file://INFRA_OWNERS -per-file .vpython=file://INFRA_OWNERS -per-file .ycm_extra_conf.py=file://INFRA_OWNERS -per-file BUILD.gn=file://COMMON_OWNERS -per-file DEPS=file://INFRA_OWNERS +per-file .clang-format=file:INFRA_OWNERS +per-file .clang-tidy=file:INFRA_OWNERS +per-file .editorconfig=file:INFRA_OWNERS +per-file .flake8=file:INFRA_OWNERS +per-file .git-blame-ignore-revs=file:INFRA_OWNERS +per-file .gitattributes=file:INFRA_OWNERS +per-file .gitignore=file:INFRA_OWNERS +per-file .gn=file:INFRA_OWNERS +per-file .vpython=file:INFRA_OWNERS +per-file .ycm_extra_conf.py=file:INFRA_OWNERS +per-file BUILD.gn=file:COMMON_OWNERS +per-file DEPS=file:INFRA_OWNERS # For Test262 rolls. per-file DEPS=mathias@chromium.org -per-file PRESUBMIT=file://INFRA_OWNERS -per-file codereview.settings=file://INFRA_OWNERS +per-file PRESUBMIT=file:INFRA_OWNERS +per-file codereview.settings=file:INFRA_OWNERS -per-file AUTHORS=file://COMMON_OWNERS -per-file WATCHLIST=file://COMMON_OWNERS +per-file AUTHORS=file:COMMON_OWNERS +per-file WATCHLIST=file:COMMON_OWNERS -per-file *-mips*=file://MIPS_OWNERS -per-file *-mips64*=file://MIPS_OWNERS -per-file *-ppc*=file://PPC_OWNERS -per-file *-s390*=file://S390_OWNERS +per-file *-mips*=file:MIPS_OWNERS +per-file *-mips64*=file:MIPS_OWNERS +per-file *-ppc*=file:PPC_OWNERS +per-file *-s390*=file:S390_OWNERS # TEAM: v8-dev@googlegroups.com # COMPONENT: Blink>JavaScript diff --git a/deps/v8/base/trace_event/common/trace_event_common.h b/deps/v8/base/trace_event/common/trace_event_common.h index f1878a18da91c6..57ac0254d96376 100644 --- a/deps/v8/base/trace_event/common/trace_event_common.h +++ b/deps/v8/base/trace_event/common/trace_event_common.h @@ -256,6 +256,13 @@ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val, \ arg2_name, arg2_val) +#define TRACE_EVENT_INSTANT_WITH_FLAGS0(category_group, name, scope_and_flags) \ + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ + scope_and_flags) +#define TRACE_EVENT_INSTANT_WITH_FLAGS1(category_group, name, scope_and_flags, \ + arg1_name, arg1_val) \ + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ + scope_and_flags, arg1_name, arg1_val) #define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope, \ timestamp) \ @@ -285,12 +292,12 @@ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ arg2_name, arg2_val) -#define TRACE_EVENT_COPY_BEGIN0(category_group, name) \ - INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \ - TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_BEGIN1(category_group, name, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +#define TRACE_EVENT_BEGIN_WITH_FLAGS0(category_group, name, flags) \ + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, flags) +#define TRACE_EVENT_BEGIN_WITH_FLAGS1(category_group, name, flags, arg1_name, \ + arg1_val) \ + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \ + flags, arg1_name, arg1_val) #define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \ @@ -341,12 +348,12 @@ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ arg2_name, arg2_val) -#define TRACE_EVENT_COPY_END0(category_group, name) \ - INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \ - TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_END1(category_group, name, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +#define TRACE_EVENT_END_WITH_FLAGS0(category_group, name, flags) \ + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags) +#define TRACE_EVENT_END_WITH_FLAGS1(category_group, name, flags, arg1_name, \ + arg1_val) \ + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags, \ + arg1_name, arg1_val) #define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \ @@ -580,6 +587,9 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) +#define TRACE_EVENT_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ + category_group, name, id, flags) // Similar to TRACE_EVENT_ASYNC_BEGINx but with a custom |at| timestamp // provided. @@ -606,6 +616,11 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0( \ + category_group, name, id, timestamp, flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ + TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \ + TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags) // Records a single ASYNC_STEP_INTO event for |step| immediately. If the // category is not enabled, then this does nothing. The |name| and |id| must @@ -677,6 +692,9 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) +#define TRACE_EVENT_ASYNC_END_WITH_FLAGS0(category_group, name, id, flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ + category_group, name, id, flags) // Similar to TRACE_EVENT_ASYNC_ENDx but with a custom |at| timestamp provided. #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \ @@ -702,6 +720,11 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(category_group, name, \ + id, timestamp, flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ + TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \ + TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags) // NESTABLE_ASYNC_* APIs are used to describe an async operation, which can // be nested within a NESTABLE_ASYNC event and/or have inner NESTABLE_ASYNC @@ -935,6 +958,9 @@ #define TRACE_TASK_EXECUTION(run_function, task) \ INTERNAL_TRACE_TASK_EXECUTION(run_function, task) +#define TRACE_LOG_MESSAGE(file, message, line) \ + INTERNAL_TRACE_LOG_MESSAGE(file, message, line) + // TRACE_EVENT_METADATA* events are information related to other // injected events, not events in their own right. #define TRACE_EVENT_METADATA1(category_group, name, arg1_name, arg1_val) \ @@ -1075,6 +1101,8 @@ // TODO(eseckler): Remove once we have native support for typed proto events in // TRACE_EVENT macros. #define TRACE_EVENT_FLAG_TYPED_PROTO_ARGS (static_cast(1 << 15)) +#define TRACE_EVENT_FLAG_JAVA_STRING_LITERALS \ + (static_cast(1 << 16)) #define TRACE_EVENT_FLAG_SCOPE_MASK \ (static_cast(TRACE_EVENT_FLAG_SCOPE_OFFSET | \ diff --git a/deps/v8/benchmarks/OWNERS b/deps/v8/benchmarks/OWNERS index 852d438bb0a884..3c70cea2fd5e6a 100644 --- a/deps/v8/benchmarks/OWNERS +++ b/deps/v8/benchmarks/OWNERS @@ -1 +1 @@ -file://COMMON_OWNERS +file:../COMMON_OWNERS diff --git a/deps/v8/build_overrides/OWNERS b/deps/v8/build_overrides/OWNERS index bdb1d555a4fb98..cb04fa0838fbb5 100644 --- a/deps/v8/build_overrides/OWNERS +++ b/deps/v8/build_overrides/OWNERS @@ -1 +1 @@ -file://INFRA_OWNERS +file:../INFRA_OWNERS diff --git a/deps/v8/build_overrides/build.gni b/deps/v8/build_overrides/build.gni index 12ef8b28d6b612..5b99eb94022596 100644 --- a/deps/v8/build_overrides/build.gni +++ b/deps/v8/build_overrides/build.gni @@ -35,5 +35,16 @@ tsan_suppressions_file = "//build/sanitizers/tsan_suppressions.cc" # Skip assertions about 4GiB file size limit. ignore_elf32_limitations = true -# Use the system install of Xcode for tools like ibtool, libtool, etc. -use_system_xcode = true +if (host_os == "mac") { + _result = exec_script("//build/mac/should_use_hermetic_xcode.py", + [ target_os ], + "value") + assert(_result != 2, + "Do not allow building targets with the default" + + "hermetic toolchain if the minimum OS version is not met.") + assert(_result != 3, + "iOS does not support building with a hermetic toolchain. " + + "Please install Xcode.") + + use_system_xcode = _result == 0 +} diff --git a/deps/v8/custom_deps/OWNERS b/deps/v8/custom_deps/OWNERS index bdb1d555a4fb98..cb04fa0838fbb5 100644 --- a/deps/v8/custom_deps/OWNERS +++ b/deps/v8/custom_deps/OWNERS @@ -1 +1 @@ -file://INFRA_OWNERS +file:../INFRA_OWNERS diff --git a/deps/v8/gni/OWNERS b/deps/v8/gni/OWNERS index bdb1d555a4fb98..cb04fa0838fbb5 100644 --- a/deps/v8/gni/OWNERS +++ b/deps/v8/gni/OWNERS @@ -1 +1 @@ -file://INFRA_OWNERS +file:../INFRA_OWNERS diff --git a/deps/v8/gni/snapshot_toolchain.gni b/deps/v8/gni/snapshot_toolchain.gni index f4f1f1d88e258d..b5fb1823b382e0 100644 --- a/deps/v8/gni/snapshot_toolchain.gni +++ b/deps/v8/gni/snapshot_toolchain.gni @@ -107,3 +107,12 @@ if (v8_snapshot_toolchain == "") { assert(v8_snapshot_toolchain != "", "Do not know how to build a snapshot for $current_toolchain " + "on $host_os $host_cpu") + +# We reuse the snapshot toolchain for building torque and other generators to +# avoid building v8_libbase on the host more than once. On mips with big endian, +# the snapshot toolchain is the target toolchain and, hence, can't be used. +v8_generator_toolchain = v8_snapshot_toolchain +if (host_cpu == "x64" && + (v8_current_cpu == "mips" || v8_current_cpu == "mips64")) { + v8_generator_toolchain = "//build/toolchain/linux:clang_x64" +} diff --git a/deps/v8/include/OWNERS b/deps/v8/include/OWNERS index 7ffbf74ce94d90..b64069847bc1cc 100644 --- a/deps/v8/include/OWNERS +++ b/deps/v8/include/OWNERS @@ -3,8 +3,8 @@ danno@chromium.org ulan@chromium.org yangguo@chromium.org -per-file *DEPS=file://COMMON_OWNERS -per-file v8-internal.h=file://COMMON_OWNERS +per-file *DEPS=file:../COMMON_OWNERS +per-file v8-internal.h=file:../COMMON_OWNERS per-file v8-inspector.h=dgozman@chromium.org per-file v8-inspector.h=pfeldman@chromium.org per-file v8-inspector.h=kozyatinskiy@chromium.org diff --git a/deps/v8/include/libplatform/v8-tracing.h b/deps/v8/include/libplatform/v8-tracing.h index e7cd8bfcdb66d0..df145e95bf723b 100644 --- a/deps/v8/include/libplatform/v8-tracing.h +++ b/deps/v8/include/libplatform/v8-tracing.h @@ -244,6 +244,8 @@ class V8_PLATFORM_EXPORT TracingController TracingController(); ~TracingController() override; + + // Takes ownership of |trace_buffer|. void Initialize(TraceBuffer* trace_buffer); #ifdef V8_USE_PERFETTO // Must be called before StartTracing() if V8_USE_PERFETTO is true. Provides diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h index fe2ce67e0df04e..6ecddf45d6ae92 100644 --- a/deps/v8/include/v8-internal.h +++ b/deps/v8/include/v8-internal.h @@ -63,8 +63,8 @@ struct SmiTagging<4> { V8_INLINE static int SmiToInt(const internal::Address value) { int shift_bits = kSmiTagSize + kSmiShiftSize; - // Shift down (requires >> to be sign extending). - return static_cast(static_cast(value)) >> shift_bits; + // Truncate and shift down (requires >> to be sign extending). + return static_cast(static_cast(value)) >> shift_bits; } V8_INLINE static constexpr bool IsValidSmi(intptr_t value) { // Is value in range [kSmiMinValue, kSmiMaxValue]. @@ -152,6 +152,7 @@ class Internals { static const uint32_t kNumIsolateDataSlots = 4; + // IsolateData layout guarantees. static const int kIsolateEmbedderDataOffset = 0; static const int kExternalMemoryOffset = kNumIsolateDataSlots * kApiSystemPointerSize; @@ -159,8 +160,14 @@ class Internals { kExternalMemoryOffset + kApiInt64Size; static const int kExternalMemoryAtLastMarkCompactOffset = kExternalMemoryLimitOffset + kApiInt64Size; - static const int kIsolateRootsOffset = + static const int kIsolateFastCCallCallerFpOffset = kExternalMemoryAtLastMarkCompactOffset + kApiInt64Size; + static const int kIsolateFastCCallCallerPcOffset = + kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize; + static const int kIsolateStackGuardOffset = + kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize; + static const int kIsolateRootsOffset = + kIsolateStackGuardOffset + 7 * kApiSystemPointerSize; static const int kUndefinedValueRootIndex = 4; static const int kTheHoleValueRootIndex = 5; @@ -174,12 +181,10 @@ class Internals { static const int kNodeStateMask = 0x7; static const int kNodeStateIsWeakValue = 2; static const int kNodeStateIsPendingValue = 3; - static const int kNodeIsIndependentShift = 3; - static const int kNodeIsActiveShift = 4; static const int kFirstNonstringType = 0x40; static const int kOddballType = 0x43; - static const int kForeignType = 0x47; + static const int kForeignType = 0x46; static const int kJSSpecialApiObjectType = 0x410; static const int kJSApiObjectType = 0x420; static const int kJSObjectType = 0x421; diff --git a/deps/v8/include/v8-platform.h b/deps/v8/include/v8-platform.h index 7e43b0d9db4a9d..b707fafc49229a 100644 --- a/deps/v8/include/v8-platform.h +++ b/deps/v8/include/v8-platform.h @@ -439,14 +439,6 @@ class Platform { */ virtual void DumpWithoutCrashing() {} - /** - * Lets the embedder to add crash keys. - */ - virtual void AddCrashKey(int id, const char* name, uintptr_t value) { - // "noop" is a valid implementation if the embedder doesn't care to log - // additional data for crashes. - } - protected: /** * Default implementation of current wall-clock time in milliseconds diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index 645920d9c1b357..360850b631c7f9 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -18,14 +18,18 @@ namespace v8 { class HeapGraphNode; struct HeapStatsUpdate; -typedef uint32_t SnapshotObjectId; - +using NativeObject = void*; +using SnapshotObjectId = uint32_t; struct CpuProfileDeoptFrame { int script_id; size_t position; }; +namespace internal { +class CpuProfile; +} // namespace internal + } // namespace v8 #ifdef V8_OS_WIN @@ -48,75 +52,6 @@ template class V8_EXPORT std::vector; namespace v8 { -// TickSample captures the information collected for each sample. -struct V8_EXPORT TickSample { - // Internal profiling (with --prof + tools/$OS-tick-processor) wants to - // include the runtime function we're calling. Externally exposed tick - // samples don't care. - enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame }; - - TickSample() - : state(OTHER), - pc(nullptr), - external_callback_entry(nullptr), - frames_count(0), - has_external_callback(false), - update_stats(true) {} - - /** - * Initialize a tick sample from the isolate. - * \param isolate The isolate. - * \param state Execution state. - * \param record_c_entry_frame Include or skip the runtime function. - * \param update_stats Whether update the sample to the aggregated stats. - * \param use_simulator_reg_state When set to true and V8 is running under a - * simulator, the method will use the simulator - * register state rather than the one provided - * with |state| argument. Otherwise the method - * will use provided register |state| as is. - */ - void Init(Isolate* isolate, const v8::RegisterState& state, - RecordCEntryFrame record_c_entry_frame, bool update_stats, - bool use_simulator_reg_state = true); - /** - * Get a call stack sample from the isolate. - * \param isolate The isolate. - * \param state Register state. - * \param record_c_entry_frame Include or skip the runtime function. - * \param frames Caller allocated buffer to store stack frames. - * \param frames_limit Maximum number of frames to capture. The buffer must - * be large enough to hold the number of frames. - * \param sample_info The sample info is filled up by the function - * provides number of actual captured stack frames and - * the current VM state. - * \param use_simulator_reg_state When set to true and V8 is running under a - * simulator, the method will use the simulator - * register state rather than the one provided - * with |state| argument. Otherwise the method - * will use provided register |state| as is. - * \note GetStackSample is thread and signal safe and should only be called - * when the JS thread is paused or interrupted. - * Otherwise the behavior is undefined. - */ - static bool GetStackSample(Isolate* isolate, v8::RegisterState* state, - RecordCEntryFrame record_c_entry_frame, - void** frames, size_t frames_limit, - v8::SampleInfo* sample_info, - bool use_simulator_reg_state = true); - StateTag state; // The state of the VM. - void* pc; // Instruction pointer. - union { - void* tos; // Top stack value (*sp). - void* external_callback_entry; - }; - static const unsigned kMaxFramesCountLog2 = 8; - static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1; - void* stack[kMaxFramesCount]; // Call stack. - unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames. - bool has_external_callback : 1; - bool update_stats : 1; // Whether the sample should update aggregated stats. -}; - /** * CpuProfileNode represents a node in a call graph. */ @@ -307,6 +242,15 @@ enum CpuProfilingNamingMode { kDebugNaming, }; +enum CpuProfilingLoggingMode { + // Enables logging when a profile is active, and disables logging when all + // profiles are detached. + kLazyLogging, + // Enables logging for the lifetime of the CpuProfiler. Calls to + // StartRecording are faster, at the expense of runtime overhead. + kEagerLogging, +}; + /** * Optional profiling attributes. */ @@ -328,21 +272,25 @@ class V8_EXPORT CpuProfilingOptions { * zero, the sampling interval will be equal to * the profiler's sampling interval. */ - CpuProfilingOptions(CpuProfilingMode mode = kLeafNodeLineNumbers, - unsigned max_samples = kNoSampleLimit, - int sampling_interval_us = 0) - : mode_(mode), - max_samples_(max_samples), - sampling_interval_us_(sampling_interval_us) {} + CpuProfilingOptions( + CpuProfilingMode mode = kLeafNodeLineNumbers, + unsigned max_samples = kNoSampleLimit, int sampling_interval_us = 0, + MaybeLocal filter_context = MaybeLocal()); CpuProfilingMode mode() const { return mode_; } unsigned max_samples() const { return max_samples_; } int sampling_interval_us() const { return sampling_interval_us_; } private: + friend class internal::CpuProfile; + + bool has_filter_context() const { return !filter_context_.IsEmpty(); } + void* raw_filter_context() const; + CpuProfilingMode mode_; unsigned max_samples_; int sampling_interval_us_; + CopyablePersistentTraits::CopyablePersistent filter_context_; }; /** @@ -356,9 +304,9 @@ class V8_EXPORT CpuProfiler { * initialized. The profiler object must be disposed after use by calling * |Dispose| method. */ - static CpuProfiler* New(Isolate* isolate); static CpuProfiler* New(Isolate* isolate, - CpuProfilingNamingMode mode); + CpuProfilingNamingMode = kDebugNaming, + CpuProfilingLoggingMode = kLazyLogging); /** * Synchronously collect current stack sample in all profilers attached to @@ -407,10 +355,8 @@ class V8_EXPORT CpuProfiler { * discarded. */ void StartProfiling( - Local title, CpuProfilingMode mode, bool record_samples = false); - void StartProfiling( - Local title, CpuProfilingMode mode, bool record_samples, - unsigned max_samples); + Local title, CpuProfilingMode mode, bool record_samples = false, + unsigned max_samples = CpuProfilingOptions::kNoSampleLimit); /** * The same as StartProfiling above, but the CpuProfilingMode defaults to * kLeafNodeLineNumbers mode, which was the previous default behavior of the @@ -801,6 +747,12 @@ class V8_EXPORT EmbedderGraph { */ virtual const char* NamePrefix() { return nullptr; } + /** + * Returns the NativeObject that can be used for querying the + * |HeapSnapshot|. + */ + virtual NativeObject GetNativeObject() { return nullptr; } + Node(const Node&) = delete; Node& operator=(const Node&) = delete; }; @@ -863,6 +815,12 @@ class V8_EXPORT HeapProfiler { */ SnapshotObjectId GetObjectId(Local value); + /** + * Returns SnapshotObjectId for a native object referenced by |value| if it + * has been seen by the heap profiler, kUnknownObjectId otherwise. + */ + SnapshotObjectId GetObjectId(NativeObject value); + /** * Returns heap object with given SnapshotObjectId if the object is alive, * otherwise empty handle is returned. diff --git a/deps/v8/include/v8-util.h b/deps/v8/include/v8-util.h index 24962607076f78..29d813e4274d16 100644 --- a/deps/v8/include/v8-util.h +++ b/deps/v8/include/v8-util.h @@ -194,14 +194,6 @@ class PersistentValueMapBase { return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key)); } - /** - * Call V8::RegisterExternallyReferencedObject with the map value for given - * key. - */ - V8_DEPRECATED( - "Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference", - inline void RegisterExternallyReferencedObject(K& key)); - /** * Return value for key and remove it from the map. */ @@ -352,16 +344,6 @@ class PersistentValueMapBase { const char* label_; }; -template -inline void -PersistentValueMapBase::RegisterExternallyReferencedObject( - K& key) { - assert(Contains(key)); - V8::RegisterExternallyReferencedObject( - reinterpret_cast(FromVal(Traits::Get(&impl_, key))), - reinterpret_cast(GetIsolate())); -} - template class PersistentValueMap : public PersistentValueMapBase { public: diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index a87655058a058d..38881eb38fcbbf 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -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 7 -#define V8_MINOR_VERSION 7 -#define V8_BUILD_NUMBER 299 -#define V8_PATCH_LEVEL 13 +#define V8_MINOR_VERSION 8 +#define V8_BUILD_NUMBER 279 +#define V8_PATCH_LEVEL 23 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index f3fbdc696294e4..d66f360c990d3e 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -122,13 +123,13 @@ class ExternalString; class Isolate; class LocalEmbedderHeapTracer; class MicrotaskQueue; -class NeverReadOnlySpaceObject; struct ScriptStreamingData; template class CustomArguments; class PropertyCallbackArguments; class FunctionCallbackArguments; class GlobalHandles; class ScopedExternalStringLock; +class ThreadLocalTop; namespace wasm { class NativeModule; @@ -545,38 +546,6 @@ template class PersistentBase { */ V8_INLINE void AnnotateStrongRetainer(const char* label); - /** - * Allows the embedder to tell the v8 garbage collector that a certain object - * is alive. Only allowed when the embedder is asked to trace its heap by - * EmbedderHeapTracer. - */ - V8_DEPRECATED( - "Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference", - V8_INLINE void RegisterExternalReference(Isolate* isolate) const); - - /** - * Marks the reference to this object independent. Garbage collector is free - * to ignore any object groups containing this object. Weak callback for an - * independent handle should not assume that it will be preceded by a global - * GC prologue callback or followed by a global GC epilogue callback. - */ - V8_DEPRECATED( - "Weak objects are always considered independent. " - "Use TracedGlobal when trying to use EmbedderHeapTracer. " - "Use a strong handle when trying to keep an object alive.", - V8_INLINE void MarkIndependent()); - - /** - * Marks the reference to this object as active. The scavenge garbage - * collection should not reclaim the objects marked as active, even if the - * object held by the handle is otherwise unreachable. - * - * This bit is cleared after the each garbage collection pass. - */ - V8_DEPRECATED("Use TracedGlobal.", V8_INLINE void MarkActive()); - - V8_DEPRECATED("See MarkIndependent.", V8_INLINE bool IsIndependent() const); - /** Returns true if the handle's reference is weak. */ V8_INLINE bool IsWeak() const; @@ -823,24 +792,43 @@ template using UniquePersistent = Global; /** - * A traced handle with move semantics, similar to std::unique_ptr. The handle - * is to be used together with |v8::EmbedderHeapTracer| and specifies edges from - * the embedder into V8's heap. + * Trait specifying behavior of |TracedGlobal|. + */ +template +struct TracedGlobalTrait { + /** + * Specifies whether |TracedGlobal| should clear its handle on destruction. + * + * V8 will *not* clear the embedder-side memory of the handle. The embedder is + * expected to report all |TracedGlobal| handles through + * |EmbedderHeapTracer| upon garabge collection. + * + * See |EmbedderHeapTracer::IsRootForNonTracingGC| for handling with + * non-tracing GCs in V8. + */ + static constexpr bool kRequiresExplicitDestruction = true; +}; + +/** + * A traced handle with copy and move semantics. The handle is to be used + * together with |v8::EmbedderHeapTracer| and specifies edges from the embedder + * into V8's heap. * * The exact semantics are: * - Tracing garbage collections use |v8::EmbedderHeapTracer|. * - Non-tracing garbage collections refer to * |v8::EmbedderHeapTracer::IsRootForNonTracingGC()| whether the handle should * be treated as root or not. + * + * For destruction semantics see |TracedGlobalTrait|. */ template -class V8_EXPORT TracedGlobal { +class TracedGlobal { public: /** * An empty TracedGlobal without storage cell. */ TracedGlobal() = default; - ~TracedGlobal() { Reset(); } /** * Construct a TracedGlobal from a Local. @@ -857,7 +845,41 @@ class V8_EXPORT TracedGlobal { /** * Move constructor initializing TracedGlobal from an existing one. */ - V8_INLINE TracedGlobal(TracedGlobal&& other); + V8_INLINE TracedGlobal(TracedGlobal&& other) { + // Forward to operator=. + *this = std::move(other); + } + + /** + * Move constructor initializing TracedGlobal from an existing one. + */ + template + V8_INLINE TracedGlobal(TracedGlobal&& other) { + // Forward to operator=. + *this = std::move(other); + } + + /** + * Copy constructor initializing TracedGlobal from an existing one. + */ + V8_INLINE TracedGlobal(const TracedGlobal& other) { + // Forward to operator=; + *this = other; + } + + /** + * Copy constructor initializing TracedGlobal from an existing one. + */ + template + V8_INLINE TracedGlobal(const TracedGlobal& other) { + // Forward to operator=; + *this = other; + } + + /** + * Move assignment operator initializing TracedGlobal from an existing one. + */ + V8_INLINE TracedGlobal& operator=(TracedGlobal&& rhs); /** * Move assignment operator initializing TracedGlobal from an existing one. @@ -866,10 +888,21 @@ class V8_EXPORT TracedGlobal { V8_INLINE TracedGlobal& operator=(TracedGlobal&& rhs); /** - * TracedGlobal only supports move semantics and forbids copying. + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. */ - TracedGlobal(const TracedGlobal&) = delete; - void operator=(const TracedGlobal&) = delete; + V8_INLINE TracedGlobal& operator=(const TracedGlobal& rhs); + + /** + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. + */ + template + V8_INLINE TracedGlobal& operator=(const TracedGlobal& rhs); /** * Returns true if this TracedGlobal is empty, i.e., has not been assigned an @@ -903,8 +936,8 @@ class V8_EXPORT TracedGlobal { template V8_INLINE bool operator==(const TracedGlobal& that) const { - internal::Address* a = reinterpret_cast(this->val_); - internal::Address* b = reinterpret_cast(that.val_); + internal::Address* a = reinterpret_cast(**this); + internal::Address* b = reinterpret_cast(*that); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -912,8 +945,8 @@ class V8_EXPORT TracedGlobal { template V8_INLINE bool operator==(const Local& that) const { - internal::Address* a = reinterpret_cast(this->val_); - internal::Address* b = reinterpret_cast(that.val_); + internal::Address* a = reinterpret_cast(**this); + internal::Address* b = reinterpret_cast(*that); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -954,11 +987,32 @@ class V8_EXPORT TracedGlobal { void* parameter, WeakCallbackInfo::Callback callback); private: - V8_INLINE static T* New(Isolate* isolate, T* that, T** slot); + // Wrapping type used when clearing on destruction is required. + struct WrappedForDestruction { + T* value; + + explicit WrappedForDestruction(T* val) : value(val) {} + ~WrappedForDestruction(); + operator T*() const { return value; } + T* operator*() const { return value; } + T* operator->() const { return value; } + WrappedForDestruction& operator=(const WrappedForDestruction& other) { + value = other.value; + return *this; + } + WrappedForDestruction& operator=(T* val) { + value = val; + return *this; + } + }; + + V8_INLINE static T* New(Isolate* isolate, T* that, void* slot); T* operator*() const { return this->val_; } - T* val_ = nullptr; + typename std::conditional< + TracedGlobalTrait>::kRequiresExplicitDestruction, + WrappedForDestruction, T*>::type val_{nullptr}; friend class EmbedderHeapTracer; template @@ -1732,14 +1786,8 @@ class V8_EXPORT ScriptCompiler { Local arguments[], size_t context_extension_count, Local context_extensions[], CompileOptions options = kNoCompileOptions, - NoCacheReason no_cache_reason = kNoCacheNoReason); - - static V8_WARN_UNUSED_RESULT MaybeLocal CompileFunctionInContext( - Local context, Source* source, size_t arguments_count, - Local arguments[], size_t context_extension_count, - Local context_extensions[], CompileOptions options, - NoCacheReason no_cache_reason, - Local* script_or_module_out); + NoCacheReason no_cache_reason = kNoCacheNoReason, + Local* script_or_module_out = nullptr); /** * Creates and returns code cache for the specified unbound_script. @@ -2007,6 +2055,7 @@ struct SampleInfo { StateTag vm_state; // Current VM state. void* external_callback_entry; // External callback address if VM is // executing an external callback. + void* top_context; // Incumbent native context address. }; struct MemoryRange { @@ -2564,9 +2613,6 @@ class V8_EXPORT Value : public Data { V8_WARN_UNUSED_RESULT MaybeLocal ToBigInt( Local context) const; - V8_DEPRECATED("ToBoolean can never throw. Use Local version.", - V8_WARN_UNUSED_RESULT MaybeLocal ToBoolean( - Local context) const); V8_WARN_UNUSED_RESULT MaybeLocal ToNumber( Local context) const; V8_WARN_UNUSED_RESULT MaybeLocal ToString( @@ -2582,16 +2628,6 @@ class V8_EXPORT Value : public Data { V8_WARN_UNUSED_RESULT MaybeLocal ToInt32(Local context) const; Local ToBoolean(Isolate* isolate) const; - V8_DEPRECATED("Use maybe version", - Local ToNumber(Isolate* isolate) const); - V8_DEPRECATED("Use maybe version", - Local ToString(Isolate* isolate) const); - V8_DEPRECATED("Use maybe version", - Local ToObject(Isolate* isolate) const); - V8_DEPRECATED("Use maybe version", - Local ToInteger(Isolate* isolate) const); - V8_DEPRECATED("Use maybe version", - Local ToInt32(Isolate* isolate) const); /** * Attempts to convert a string to an array index. @@ -2602,9 +2638,6 @@ class V8_EXPORT Value : public Data { bool BooleanValue(Isolate* isolate) const; - V8_DEPRECATED("BooleanValue can never throw. Use Isolate version.", - V8_WARN_UNUSED_RESULT Maybe BooleanValue( - Local context) const); V8_WARN_UNUSED_RESULT Maybe NumberValue(Local context) const; V8_WARN_UNUSED_RESULT Maybe IntegerValue( Local context) const; @@ -2924,43 +2957,23 @@ class V8_EXPORT String : public Name { V8_INLINE static String* Cast(v8::Value* obj); - // TODO(dcarney): remove with deprecation of New functions. - enum NewStringType { - kNormalString = static_cast(v8::NewStringType::kNormal), - kInternalizedString = static_cast(v8::NewStringType::kInternalized) - }; - - /** Allocates a new string from UTF-8 data.*/ - static V8_DEPRECATED( - "Use maybe version", - Local NewFromUtf8(Isolate* isolate, const char* data, - NewStringType type = kNormalString, - int length = -1)); - /** Allocates a new string from UTF-8 data. Only returns an empty value when * length > kMaxLength. **/ static V8_WARN_UNUSED_RESULT MaybeLocal NewFromUtf8( - Isolate* isolate, const char* data, v8::NewStringType type, - int length = -1); + Isolate* isolate, const char* data, + NewStringType type = NewStringType::kNormal, int length = -1); /** Allocates a new string from Latin-1 data. Only returns an empty value * when length > kMaxLength. **/ static V8_WARN_UNUSED_RESULT MaybeLocal NewFromOneByte( - Isolate* isolate, const uint8_t* data, v8::NewStringType type, - int length = -1); - - /** Allocates a new string from UTF-16 data.*/ - static V8_DEPRECATED( - "Use maybe version", - Local NewFromTwoByte(Isolate* isolate, const uint16_t* data, - NewStringType type = kNormalString, - int length = -1)); + Isolate* isolate, const uint8_t* data, + NewStringType type = NewStringType::kNormal, int length = -1); /** Allocates a new string from UTF-16 data. Only returns an empty value when * length > kMaxLength. **/ static V8_WARN_UNUSED_RESULT MaybeLocal NewFromTwoByte( - Isolate* isolate, const uint16_t* data, v8::NewStringType type, - int length = -1); + Isolate* isolate, const uint16_t* data, + NewStringType type = NewStringType::kNormal, int length = -1); /** * Creates a new string by concatenating the left and the right strings @@ -2999,10 +3012,6 @@ class V8_EXPORT String : public Name { * should the underlying buffer be deallocated or modified except through the * destructor of the external string resource. */ - static V8_DEPRECATED( - "Use maybe version", - Local NewExternal(Isolate* isolate, - ExternalOneByteStringResource* resource)); static V8_WARN_UNUSED_RESULT MaybeLocal NewExternalOneByte( Isolate* isolate, ExternalOneByteStringResource* resource); @@ -3399,8 +3408,6 @@ enum class IntegrityLevel { kFrozen, kSealed }; */ class V8_EXPORT Object : public Value { public: - V8_DEPRECATED("Use maybe version", - bool Set(Local key, Local value)); /** * Set only return Just(true) or Empty(), so if it should never fail, use * result.Check(). @@ -3408,8 +3415,6 @@ class V8_EXPORT Object : public Value { V8_WARN_UNUSED_RESULT Maybe Set(Local context, Local key, Local value); - V8_DEPRECATED("Use maybe version", - bool Set(uint32_t index, Local value)); V8_WARN_UNUSED_RESULT Maybe Set(Local context, uint32_t index, Local value); @@ -3454,11 +3459,9 @@ class V8_EXPORT Object : public Value { Local context, Local key, PropertyDescriptor& descriptor); // NOLINT(runtime/references) - V8_DEPRECATED("Use maybe version", Local Get(Local key)); V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context, Local key); - V8_DEPRECATED("Use maybe version", Local Get(uint32_t index)); V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context, uint32_t index); @@ -3782,6 +3785,15 @@ class V8_EXPORT Object : public Value { */ bool IsConstructor(); + /** + * True if this object can carry information relevant to the embedder in its + * embedder fields, false otherwise. This is generally true for objects + * constructed through function templates but also holds for other types where + * V8 automatically adds internal fields at compile time, such as e.g. + * v8::ArrayBuffer. + */ + bool IsApiWrapper(); + /** * Call an Object as a function if a callback is set by the * ObjectTemplate::SetCallAsFunctionHandler method. @@ -3942,9 +3954,6 @@ class ReturnValue { } // Local setters template - V8_INLINE V8_DEPRECATED("Use Global<> instead", - void Set(const Persistent& handle)); - template V8_INLINE void Set(const Global& handle); template V8_INLINE void Set(const TracedGlobal& handle); @@ -4850,8 +4859,8 @@ class V8_EXPORT ArrayBuffer : public Object { bool IsDetachable() const; // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATE_SOON("Use IsDetachable() instead.", - inline bool IsNeuterable() const) { + V8_DEPRECATED("Use IsDetachable() instead.", + inline bool IsNeuterable() const) { return IsDetachable(); } @@ -4864,7 +4873,7 @@ class V8_EXPORT ArrayBuffer : public Object { void Detach(); // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATE_SOON("Use Detach() instead.", inline void Neuter()) { Detach(); } + V8_DEPRECATED("Use Detach() instead.", inline void Neuter()) { Detach(); } /** * Make this ArrayBuffer external. The pointer to underlying memory block @@ -5209,8 +5218,7 @@ class V8_EXPORT SharedArrayBuffer : public Object { allocation_length_(0), allocation_mode_(Allocator::AllocationMode::kNormal), deleter_(nullptr), - deleter_data_(nullptr), - is_growable_(false) {} + deleter_data_(nullptr) {} void* AllocationBase() const { return allocation_base_; } size_t AllocationLength() const { return allocation_length_; } @@ -5222,13 +5230,12 @@ class V8_EXPORT SharedArrayBuffer : public Object { size_t ByteLength() const { return byte_length_; } DeleterCallback Deleter() const { return deleter_; } void* DeleterData() const { return deleter_data_; } - bool IsGrowable() const { return is_growable_; } private: Contents(void* data, size_t byte_length, void* allocation_base, size_t allocation_length, Allocator::AllocationMode allocation_mode, DeleterCallback deleter, - void* deleter_data, bool is_growable); + void* deleter_data); void* data_; size_t byte_length_; @@ -5237,7 +5244,6 @@ class V8_EXPORT SharedArrayBuffer : public Object { Allocator::AllocationMode allocation_mode_; DeleterCallback deleter_; void* deleter_data_; - bool is_growable_; friend class SharedArrayBuffer; }; @@ -5335,38 +5341,6 @@ class V8_EXPORT Date : public Object { V8_INLINE static Date* Cast(Value* obj); - /** - * Time zone redetection indicator for - * DateTimeConfigurationChangeNotification. - * - * kSkip indicates V8 that the notification should not trigger redetecting - * host time zone. kRedetect indicates V8 that host time zone should be - * redetected, and used to set the default time zone. - * - * The host time zone detection may require file system access or similar - * operations unlikely to be available inside a sandbox. If v8 is run inside a - * sandbox, the host time zone has to be detected outside the sandbox before - * calling DateTimeConfigurationChangeNotification function. - */ - enum class TimeZoneDetection { kSkip, kRedetect }; - - /** - * Notification that the embedder has changed the time zone, - * daylight savings time, or other date / time configuration - * parameters. V8 keeps a cache of various values used for - * date / time computation. This notification will reset - * those cached values for the current context so that date / - * time configuration changes would be reflected in the Date - * object. - * - * This API should not be called more than needed as it will - * negatively impact the performance of date operations. - */ - V8_DEPRECATED("Use Isolate::DateTimeConfigurationChangeNotification", - static void DateTimeConfigurationChangeNotification( - Isolate* isolate, TimeZoneDetection time_zone_detection = - TimeZoneDetection::kSkip)); - private: static void CheckCast(Value* obj); }; @@ -5502,6 +5476,32 @@ class V8_EXPORT RegExp : public Object { static void CheckCast(Value* obj); }; +/** + * An instance of the built-in FinalizationGroup constructor. + * + * This API is experimental and may change significantly. + */ +class V8_EXPORT FinalizationGroup : public Object { + public: + /** + * Runs the cleanup callback of the given FinalizationGroup. + * + * V8 will inform the embedder that there are finalizer callbacks be + * called through HostCleanupFinalizationGroupCallback. + * + * HostCleanupFinalizationGroupCallback should schedule a task to + * call FinalizationGroup::Cleanup() at some point in the + * future. It's the embedders responsiblity to make this call at a + * time which does not interrupt synchronous ECMAScript code + * execution. + * + * If the result is Nothing then an exception has + * occurred. Otherwise the result is |true| if the cleanup callback + * was called successfully. The result is never |false|. + */ + static V8_WARN_UNUSED_RESULT Maybe Cleanup( + Local finalization_group); +}; /** * A JavaScript value that wraps a C++ void*. This type of value is mainly used @@ -6054,21 +6054,6 @@ class V8_EXPORT FunctionTemplate : public Template { */ void SetAcceptAnyReceiver(bool value); - /** - * Determines whether the __proto__ accessor ignores instances of - * the function template. If instances of the function template are - * ignored, __proto__ skips all instances and instead returns the - * next object in the prototype chain. - * - * Call with a value of true to make the __proto__ accessor ignore - * instances of the function template. Call with a value of false - * to make the __proto__ accessor not ignore instances of the - * function template. By default, instances of a function template - * are not ignored. - */ - V8_DEPRECATED("This feature is incompatible with ES6+.", - void SetHiddenPrototype(bool value)); - /** * Sets the ReadOnly flag in the attributes of the 'prototype' property * of functions created from this FunctionTemplate to true. @@ -6572,7 +6557,26 @@ V8_INLINE Local False(Isolate* isolate); */ class V8_EXPORT ResourceConstraints { public: - ResourceConstraints(); + /** + * Configures the constraints with reasonable default values based on the + * provided heap size limit. The heap size includes both the young and + * the old generation. + * + * \param initial_heap_size_in_bytes The initial heap size or zero. + * By default V8 starts with a small heap and dynamically grows it to + * match the set of live objects. This may lead to ineffective + * garbage collections at startup if the live set is large. + * Setting the initial heap size avoids such garbage collections. + * Note that this does not affect young generation garbage collections. + * + * \param maximum_heap_size_in_bytes The hard limit for the heap size. + * When the heap size approaches this limit, V8 will perform series of + * garbage collections and invoke the NearHeapLimitCallback. If the garbage + * collections do not help and the callback does not increase the limit, + * then V8 will crash with V8::FatalProcessOutOfMemory. + */ + void ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes, + size_t maximum_heap_size_in_bytes); /** * Configures the constraints with reasonable default values based on the @@ -6596,12 +6600,8 @@ class V8_EXPORT ResourceConstraints { * The amount of virtual memory reserved for generated code. This is relevant * for 64-bit architectures that rely on code range for calls in code. */ - size_t code_range_size_in_bytes() const { - return code_range_size_ * kMB; - } - void set_code_range_size_in_bytes(size_t limit) { - code_range_size_ = limit / kMB; - } + size_t code_range_size_in_bytes() const { return code_range_size_; } + void set_code_range_size_in_bytes(size_t limit) { code_range_size_ = limit; } /** * The maximum size of the old generation. @@ -6611,10 +6611,10 @@ class V8_EXPORT ResourceConstraints { * increase the limit, then V8 will crash with V8::FatalProcessOutOfMemory. */ size_t max_old_generation_size_in_bytes() const { - return max_old_space_size_ * kMB; + return max_old_generation_size_; } void set_max_old_generation_size_in_bytes(size_t limit) { - max_old_space_size_ = limit / kMB; + max_old_generation_size_ = limit; } /** @@ -6622,21 +6622,25 @@ class V8_EXPORT ResourceConstraints { * and a large object space. This affects frequency of Scavenge garbage * collections and should be typically much smaller that the old generation. */ - size_t max_young_generation_size_in_bytes() const; - void set_max_young_generation_size_in_bytes(size_t limit); + size_t max_young_generation_size_in_bytes() const { + return max_young_generation_size_; + } + void set_max_young_generation_size_in_bytes(size_t limit) { + max_young_generation_size_ = limit; + } size_t initial_old_generation_size_in_bytes() const { - return 0; + return initial_old_generation_size_; } void set_initial_old_generation_size_in_bytes(size_t initial_size) { - // Not available on Node 12. + initial_old_generation_size_ = initial_size; } size_t initial_young_generation_size_in_bytes() const { - return 0; + return initial_young_generation_size_; } void set_initial_young_generation_size_in_bytes(size_t initial_size) { - // Not available on Node 12. + initial_young_generation_size_ = initial_size; } /** @@ -6644,27 +6648,23 @@ class V8_EXPORT ResourceConstraints { */ V8_DEPRECATE_SOON("Use code_range_size_in_bytes.", size_t code_range_size() const) { - return code_range_size_; + return code_range_size_ / kMB; } V8_DEPRECATE_SOON("Use set_code_range_size_in_bytes.", void set_code_range_size(size_t limit_in_mb)) { - code_range_size_ = limit_in_mb; + code_range_size_ = limit_in_mb * kMB; } V8_DEPRECATE_SOON("Use max_young_generation_size_in_bytes.", - size_t max_semi_space_size_in_kb() const) { - return max_semi_space_size_in_kb_; - } + size_t max_semi_space_size_in_kb() const); V8_DEPRECATE_SOON("Use set_max_young_generation_size_in_bytes.", - void set_max_semi_space_size_in_kb(size_t limit_in_kb)) { - max_semi_space_size_in_kb_ = limit_in_kb; - } + void set_max_semi_space_size_in_kb(size_t limit_in_kb)); V8_DEPRECATE_SOON("Use max_old_generation_size_in_bytes.", size_t max_old_space_size() const) { - return max_old_space_size_; + return max_old_generation_size_ / kMB; } V8_DEPRECATE_SOON("Use set_max_old_generation_size_in_bytes.", void set_max_old_space_size(size_t limit_in_mb)) { - max_old_space_size_ = limit_in_mb; + max_old_generation_size_ = limit_in_mb * kMB; } V8_DEPRECATE_SOON("Zone does not pool memory any more.", size_t max_zone_pool_size() const) { @@ -6677,15 +6677,13 @@ class V8_EXPORT ResourceConstraints { private: static constexpr size_t kMB = 1048576u; - - // max_semi_space_size_ is in KB - size_t max_semi_space_size_in_kb_ = 0; - - // The remaining limits are in MB - size_t max_old_space_size_ = 0; - uint32_t* stack_limit_ = nullptr; size_t code_range_size_ = 0; + size_t max_old_generation_size_ = 0; + size_t max_young_generation_size_ = 0; size_t max_zone_pool_size_ = 0; + size_t initial_old_generation_size_ = 0; + size_t initial_young_generation_size_ = 0; + uint32_t* stack_limit_ = nullptr; }; @@ -6743,10 +6741,34 @@ typedef void* (*CreateHistogramCallback)(const char* name, typedef void (*AddHistogramSampleCallback)(void* histogram, int sample); +// --- Crashkeys Callback --- +enum class CrashKeyId { + kIsolateAddress, + kReadonlySpaceFirstPageAddress, + kMapSpaceFirstPageAddress, + kCodeSpaceFirstPageAddress, +}; + +typedef void (*AddCrashKeyCallback)(CrashKeyId id, const std::string& value); + // --- Enter/Leave Script Callback --- typedef void (*BeforeCallEnteredCallback)(Isolate*); typedef void (*CallCompletedCallback)(Isolate*); +/** + * HostCleanupFinalizationGroupCallback is called when we require the + * embedder to enqueue a task that would call + * FinalizationGroup::Cleanup(). + * + * The FinalizationGroup is the one for which the embedder needs to + * call FinalizationGroup::Cleanup() on. + * + * The context provided is the one in which the FinalizationGroup was + * created in. + */ +typedef void (*HostCleanupFinalizationGroupCallback)( + Local context, Local fg); + /** * HostImportModuleDynamicallyCallback is called when we require the * embedder to load a module. This is used as part of the dynamic @@ -6844,7 +6866,8 @@ class PromiseRejectMessage { typedef void (*PromiseRejectCallback)(PromiseRejectMessage message); // --- Microtasks Callbacks --- -typedef void (*MicrotasksCompletedCallback)(Isolate*); +V8_DEPRECATE_SOON("Use *WithData version.", + typedef void (*MicrotasksCompletedCallback)(Isolate*)); typedef void (*MicrotasksCompletedCallbackWithData)(Isolate*, void*); typedef void (*MicrotaskCallback)(void* data); @@ -6878,7 +6901,8 @@ class V8_EXPORT MicrotaskQueue { /** * Creates an empty MicrotaskQueue instance. */ - static std::unique_ptr New(Isolate* isolate); + static std::unique_ptr New( + Isolate* isolate, MicrotasksPolicy policy = MicrotasksPolicy::kAuto); virtual ~MicrotaskQueue() = default; @@ -6926,6 +6950,15 @@ class V8_EXPORT MicrotaskQueue { */ virtual bool IsRunningMicrotasks() const = 0; + /** + * Returns the current depth of nested MicrotasksScope that has + * kRunMicrotasks. + */ + virtual int GetMicrotasksScopeDepth() const = 0; + + MicrotaskQueue(const MicrotaskQueue&) = delete; + MicrotaskQueue& operator=(const MicrotaskQueue&) = delete; + private: friend class internal::MicrotaskQueue; MicrotaskQueue() = default; @@ -7006,6 +7039,10 @@ typedef void (*WasmStreamingCallback)(const FunctionCallbackInfo&); // --- Callback for checking if WebAssembly threads are enabled --- typedef bool (*WasmThreadsEnabledCallback)(Local context); +// --- Callback for loading source map file for WASM profiling support +typedef Local (*WasmLoadSourceMapCallback)(Isolate* isolate, + const char* name); + // --- Garbage Collection Callbacks --- /** @@ -7382,7 +7419,7 @@ class V8_EXPORT EmbedderHeapTracer { /** * Called at the beginning of a GC cycle. */ - V8_DEPRECATE_SOON("Use version with flags.", virtual void TracePrologue()) {} + V8_DEPRECATED("Use version with flags.", virtual void TracePrologue()) {} virtual void TracePrologue(TraceFlags flags); /** @@ -7410,8 +7447,9 @@ class V8_EXPORT EmbedderHeapTracer { * overriden to fill a |TraceSummary| that is used by V8 to schedule future * garbage collections. */ - virtual void TraceEpilogue() {} - virtual void TraceEpilogue(TraceSummary* trace_summary) { TraceEpilogue(); } + V8_DEPRECATE_SOON("Use version with parameter.", + virtual void TraceEpilogue()) {} + virtual void TraceEpilogue(TraceSummary* trace_summary); /** * Called upon entering the final marking pause. No more incremental marking @@ -7433,14 +7471,37 @@ class V8_EXPORT EmbedderHeapTracer { /** * Returns true if the TracedGlobal handle should be considered as root for * the currently running non-tracing garbage collection and false otherwise. + * The default implementation will keep all TracedGlobal references as roots. * - * Default implementation will keep all TracedGlobal references as roots. + * If this returns false, then V8 may decide that the object referred to by + * such a handle is reclaimed. In that case: + * - No action is required if handles are used with destructors. + * - When run without destructors (by specializing + * |TracedGlobalTrait::kRequiresExplicitDestruction|) V8 calls + * |ResetHandleInNonTracingGC|. + * + * Note that the |handle| is different from the |TracedGlobal| handle that + * the embedder holds for retaining the object. The embedder may use + * |TracedGlobal::WrapperClassId()| to distinguish cases where it wants + * handles to be treated as roots from not being treated as roots. */ virtual bool IsRootForNonTracingGC( const v8::TracedGlobal& handle) { return true; } + /** + * Used in combination with |IsRootForNonTracingGC|. Called by V8 when an + * object that is backed by a handle is reclaimed by a non-tracing garbage + * collection. It is up to the embedder to reset the original handle. + * + * Note that the |handle| is different from the |TracedGlobal| handle that + * the embedder holds for retaining the object. It is up to the embedder to + * find the orignal |TracedGlobal| handle via the object or class id. + */ + virtual void ResetHandleInNonTracingGC( + const v8::TracedGlobal& handle) {} + /* * Called by the embedder to immediately perform a full garbage collection. * @@ -7672,6 +7733,9 @@ class V8_EXPORT Isolate { private: internal::Isolate* const isolate_; internal::MicrotaskQueue* const microtask_queue_; + internal::Address previous_stack_height_; + + friend class internal::ThreadLocalTop; }; /** @@ -7785,9 +7849,10 @@ class V8_EXPORT Isolate { kStringNormalize = 75, kCallSiteAPIGetFunctionSloppyCall = 76, kCallSiteAPIGetThisSloppyCall = 77, + kRegExpMatchAllWithNonGlobalRegExp = 78, // If you add new values here, you'll also need to update Chromium's: - // web_feature.mojom, UseCounterCallback.cpp, and enums.xml. V8 changes to + // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to // this list need to be landed first, then changes on the Chromium side. kUseCounterFeatureCount // This enum value must be last. }; @@ -7845,6 +7910,18 @@ class V8_EXPORT Isolate { */ static Isolate* GetCurrent(); + /** + * Clears the set of objects held strongly by the heap. This set of + * objects are originally built when a WeakRef is created or + * successfully dereferenced. + * + * The embedder is expected to call this when a synchronous sequence + * of ECMAScript execution completes. It's the embedders + * responsiblity to make this call at a time which does not + * interrupt synchronous ECMAScript code execution. + */ + void ClearKeptObjects(); + /** * Custom callback used by embedders to help V8 determine if it should abort * when it throws and no internal handler is predicted to catch the @@ -7858,6 +7935,14 @@ class V8_EXPORT Isolate { void SetAbortOnUncaughtExceptionCallback( AbortOnUncaughtExceptionCallback callback); + /** + * This specifies the callback to be called when finalization groups + * are ready to be cleaned up and require FinalizationGroup::Cleanup() + * to be called in a future task. + */ + void SetHostCleanupFinalizationGroupCallback( + HostCleanupFinalizationGroupCallback callback); + /** * This specifies the callback called by the upcoming dynamic * import() language feature to load modules. @@ -8411,6 +8496,13 @@ class V8_EXPORT Isolate { void SetCreateHistogramFunction(CreateHistogramCallback); void SetAddHistogramSampleFunction(AddHistogramSampleCallback); + /** + * Enables the host application to provide a mechanism for recording a + * predefined set of data as crash keys to be used in postmortem debugging in + * case of a crash. + */ + void SetAddCrashKeyCallback(AddCrashKeyCallback); + /** * Optional notification that the embedder is idle. * V8 uses the notification to perform garbage collection. @@ -8610,6 +8702,8 @@ class V8_EXPORT Isolate { void SetWasmThreadsEnabledCallback(WasmThreadsEnabledCallback callback); + void SetWasmLoadSourceMapCallback(WasmLoadSourceMapCallback callback); + /** * Check if V8 is dead and therefore unusable. This is the case after * fatal errors such as out-of-memory situations. @@ -8819,7 +8913,9 @@ class V8_EXPORT V8 { * Sets V8 flags from a string. */ static void SetFlagsFromString(const char* str); - static void SetFlagsFromString(const char* str, int length); + static void SetFlagsFromString(const char* str, size_t length); + V8_DEPRECATED("use size_t version", + static void SetFlagsFromString(const char* str, int length)); /** * Sets V8 flags from the command line. @@ -8970,11 +9066,14 @@ class V8_EXPORT V8 { internal::Address* handle); static internal::Address* GlobalizeTracedReference(internal::Isolate* isolate, internal::Address* handle, - internal::Address* slot); + internal::Address* slot, + bool has_destructor); static void MoveGlobalReference(internal::Address** from, internal::Address** to); static void MoveTracedGlobalReference(internal::Address** from, internal::Address** to); + static void CopyTracedGlobalReference(const internal::Address* const* from, + internal::Address** to); static internal::Address* CopyGlobalReference(internal::Address* from); static void DisposeGlobal(internal::Address* global_handle); static void DisposeTracedGlobal(internal::Address* global_handle); @@ -8990,9 +9089,6 @@ class V8_EXPORT V8 { const char* label); static Value* Eternalize(Isolate* isolate, Value* handle); - static void RegisterExternallyReferencedObject(internal::Address* location, - internal::Isolate* isolate); - template friend class PersistentValueMapBase; @@ -9948,14 +10044,6 @@ void Persistent::Copy(const Persistent& that) { M::Copy(that, this); } -template -bool PersistentBase::IsIndependent() const { - typedef internal::Internals I; - if (this->IsEmpty()) return false; - return I::GetNodeFlag(reinterpret_cast(this->val_), - I::kNodeIsIndependentShift); -} - template bool PersistentBase::IsWeak() const { typedef internal::Internals I; @@ -10022,31 +10110,6 @@ void PersistentBase::AnnotateStrongRetainer(const char* label) { label); } -template -void PersistentBase::RegisterExternalReference(Isolate* isolate) const { - if (IsEmpty()) return; - V8::RegisterExternallyReferencedObject( - reinterpret_cast(this->val_), - reinterpret_cast(isolate)); -} - -template -void PersistentBase::MarkIndependent() { - typedef internal::Internals I; - if (this->IsEmpty()) return; - I::UpdateNodeFlag(reinterpret_cast(this->val_), true, - I::kNodeIsIndependentShift); -} - -template -void PersistentBase::MarkActive() { - typedef internal::Internals I; - if (this->IsEmpty()) return; - I::UpdateNodeFlag(reinterpret_cast(this->val_), true, - I::kNodeIsActiveShift); -} - - template void PersistentBase::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; @@ -10093,18 +10156,26 @@ Global& Global::operator=(Global&& rhs) { } template -T* TracedGlobal::New(Isolate* isolate, T* that, T** slot) { +TracedGlobal::WrappedForDestruction::~WrappedForDestruction() { + if (value == nullptr) return; + V8::DisposeTracedGlobal(reinterpret_cast(value)); + value = nullptr; +} + +template +T* TracedGlobal::New(Isolate* isolate, T* that, void* slot) { if (that == nullptr) return nullptr; internal::Address* p = reinterpret_cast(that); return reinterpret_cast(V8::GlobalizeTracedReference( reinterpret_cast(isolate), p, - reinterpret_cast(slot))); + reinterpret_cast(slot), + TracedGlobalTrait>::kRequiresExplicitDestruction)); } template void TracedGlobal::Reset() { if (IsEmpty()) return; - V8::DisposeTracedGlobal(reinterpret_cast(val_)); + V8::DisposeTracedGlobal(reinterpret_cast(**this)); val_ = nullptr; } @@ -10118,19 +10189,23 @@ void TracedGlobal::Reset(Isolate* isolate, const Local& other) { } template -TracedGlobal::TracedGlobal(TracedGlobal&& other) : val_(other.val_) { - if (other.val_ != nullptr) { - V8::MoveTracedGlobalReference( - reinterpret_cast(&other.val_), - reinterpret_cast(&this->val_)); - other.val_ = nullptr; - } +template +TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) { + TYPE_CHECK(T, S); + *this = std::move(rhs.template As()); + return *this; } template template -TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) { +TracedGlobal& TracedGlobal::operator=(const TracedGlobal& rhs) { TYPE_CHECK(T, S); + *this = rhs.template As(); + return *this; +} + +template +TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) { if (this != &rhs) { this->Reset(); if (rhs.val_ != nullptr) { @@ -10144,11 +10219,24 @@ TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) { return *this; } +template +TracedGlobal& TracedGlobal::operator=(const TracedGlobal& rhs) { + if (this != &rhs) { + this->Reset(); + if (rhs.val_ != nullptr) { + V8::CopyTracedGlobalReference( + reinterpret_cast(&rhs.val_), + reinterpret_cast(&this->val_)); + } + } + return *this; +} + template void TracedGlobal::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; if (IsEmpty()) return; - internal::Address* obj = reinterpret_cast(this->val_); + internal::Address* obj = reinterpret_cast(**this); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; *reinterpret_cast(addr) = class_id; } @@ -10157,7 +10245,7 @@ template uint16_t TracedGlobal::WrapperClassId() const { typedef internal::Internals I; if (IsEmpty()) return 0; - internal::Address* obj = reinterpret_cast(this->val_); + internal::Address* obj = reinterpret_cast(**this); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; return *reinterpret_cast(addr); } @@ -10166,23 +10254,12 @@ template void TracedGlobal::SetFinalizationCallback( void* parameter, typename WeakCallbackInfo::Callback callback) { V8::SetFinalizationCallbackTraced( - reinterpret_cast(this->val_), parameter, callback); + reinterpret_cast(**this), parameter, callback); } template ReturnValue::ReturnValue(internal::Address* slot) : value_(slot) {} -template -template -void ReturnValue::Set(const Persistent& handle) { - TYPE_CHECK(T, S); - if (V8_UNLIKELY(handle.IsEmpty())) { - *value_ = GetDefaultValue(); - } else { - *value_ = *reinterpret_cast(*handle); - } -} - template template void ReturnValue::Set(const Global& handle) { @@ -11111,9 +11188,12 @@ int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( } if (change_in_bytes < 0) { - const int64_t lower_limit = *external_memory_limit + change_in_bytes; - if (lower_limit > I::kExternalAllocationSoftLimit) + const int64_t lower_limit = + static_cast(static_cast(*external_memory_limit) + + static_cast(change_in_bytes)); + if (lower_limit > I::kExternalAllocationSoftLimit) { *external_memory_limit = lower_limit; + } } else if (change_in_bytes > 0 && amount > *external_memory_limit) { ReportExternalAllocationLimitReached(); } diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h index 7bd2938225bc74..7670c0e449c7fd 100644 --- a/deps/v8/include/v8config.h +++ b/deps/v8/include/v8config.h @@ -186,6 +186,8 @@ // V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported // V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported // V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported +// V8_HAS_COMPUTED_GOTO - computed goto/labels as values +// supported // V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported // V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported @@ -214,6 +216,7 @@ # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ (__has_attribute(warn_unused_result)) +# define V8_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned)) # define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16)) # define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32)) # define V8_HAS_BUILTIN_BSWAP64 (__has_builtin(__builtin_bswap64)) @@ -226,6 +229,10 @@ # define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow)) # define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow)) +// Clang has no __has_feature for computed gotos. +// GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html +# define V8_HAS_COMPUTED_GOTO 1 + # if __cplusplus >= 201402L # define V8_CAN_HAVE_DCHECK_IN_CONSTEXPR 1 # endif @@ -256,12 +263,16 @@ # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ (!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0)) +# define V8_HAS_BUILTIN_ASSUME_ALIGNED (V8_GNUC_PREREQ(4, 7, 0)) # define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0)) # define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0)) # define V8_HAS_BUILTIN_EXPECT (V8_GNUC_PREREQ(2, 96, 0)) # define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0)) # define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0)) +// GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html +#define V8_HAS_COMPUTED_GOTO (V8_GNUC_PREREQ(2, 0, 0)) + #endif #if defined(_MSC_VER) @@ -291,6 +302,12 @@ # define V8_INLINE inline #endif +#if V8_HAS_BUILTIN_ASSUME_ALIGNED +# define V8_ASSUME_ALIGNED(ptr, alignment) \ + __builtin_assume_aligned((ptr), (alignment)) +#else +# define V8_ASSUME_ALIGNED(ptr) (ptr) +#endif // A macro used to tell the compiler to never inline a particular function. // Don't bother for debug builds. diff --git a/deps/v8/infra/OWNERS b/deps/v8/infra/OWNERS index a75a43666efa57..a33a8ba8ed96fa 100644 --- a/deps/v8/infra/OWNERS +++ b/deps/v8/infra/OWNERS @@ -1,3 +1,3 @@ -file://INFRA_OWNERS +file:../INFRA_OWNERS tandrii@chromium.org diff --git a/deps/v8/infra/testing/builders.pyl b/deps/v8/infra/testing/builders.pyl index 965300da7735f2..305007354d7509 100644 --- a/deps/v8/infra/testing/builders.pyl +++ b/deps/v8/infra/testing/builders.pyl @@ -485,13 +485,8 @@ 'swarming_dimensions' : { 'os': 'Ubuntu-16.04', }, - 'swarming_task_attrs': { - 'expiration': 14400, - 'hard_timeout': 3600, - 'priority': 35, - }, 'tests': [ - {'name': 'v8testing', 'shards': 7}, + {'name': 'v8testing', 'shards': 12}, ], }, ############################################################################## @@ -548,7 +543,7 @@ # Win64 'v8_win64_asan_rel_ng_triggered': { 'swarming_dimensions' : { - 'os': 'Windows-10', + 'os': 'Windows-10-15063', }, 'tests': [ {'name': 'v8testing', 'shards': 5}, @@ -834,7 +829,7 @@ }, 'tests': [ {'name': 'mozilla', 'variant': 'default'}, - {'name': 'test262', 'variant': 'default', 'shards': 4}, + {'name': 'test262', 'variant': 'default', 'shards': 6}, {'name': 'v8testing', 'variant': 'default', 'shards': 3}, ], }, @@ -1260,7 +1255,7 @@ }, 'V8 Win64 ASAN': { 'swarming_dimensions': { - 'os': 'Windows-10', + 'os': 'Windows-10-15063', }, 'tests': [ {'name': 'v8testing', 'shards': 5}, @@ -1412,8 +1407,8 @@ 'os': 'Ubuntu-16.04', }, 'tests': [ - {'name': 'mjsunit_sp_frame_access'}, - {'name': 'mozilla'}, + {'name': 'mjsunit_sp_frame_access', 'shards': 4}, + {'name': 'mozilla', 'shards': 4}, {'name': 'test262', 'variant': 'default'}, {'name': 'v8testing', 'shards': 8}, {'name': 'v8testing', 'variant': 'extra', 'shards': 4}, @@ -1423,14 +1418,14 @@ 'name': 'mozilla', 'suffix': 'armv8-a', 'test_args': ['--extra-flags', '--enable-armv8'], - 'shards': 2, + 'shards': 3, }, { 'name': 'test262', 'suffix': 'armv8-a', 'variant': 'default', 'test_args': ['--extra-flags', '--enable-armv8'], - 'shards': 2, + 'shards': 3, }, { 'name': 'v8testing', @@ -1822,9 +1817,9 @@ 'os': 'Ubuntu-16.04', }, 'tests': [ - {'name': 'mozilla'}, - {'name': 'test262', 'variant': 'default'}, - {'name': 'v8testing', 'shards': 8}, + {'name': 'mozilla', 'shards': 2}, + {'name': 'test262', 'variant': 'default', 'shards': 2}, + {'name': 'v8testing', 'shards': 10}, ], }, 'V8 arm - sim - stable branch': { @@ -1842,9 +1837,9 @@ 'os': 'Ubuntu-16.04', }, 'tests': [ - {'name': 'mozilla'}, - {'name': 'test262', 'variant': 'default'}, - {'name': 'v8testing', 'shards': 8}, + {'name': 'mozilla', 'shards': 2}, + {'name': 'test262', 'variant': 'default', 'shards': 2}, + {'name': 'v8testing', 'shards': 10}, ], }, 'V8 mips64el - sim - beta branch': { diff --git a/deps/v8/src/OWNERS b/deps/v8/src/OWNERS index c6881f232117b2..3e21b6ea369970 100644 --- a/deps/v8/src/OWNERS +++ b/deps/v8/src/OWNERS @@ -1,5 +1,5 @@ -per-file *DEPS=file://COMMON_OWNERS -per-file intl-*=file://INTL_OWNERS -per-file *-intl*=file://INTL_OWNERS +per-file *DEPS=file:../COMMON_OWNERS +per-file intl-*=file:../INTL_OWNERS +per-file *-intl*=file:../INTL_OWNERS # COMPONENT: Blink>JavaScript diff --git a/deps/v8/src/api/OWNERS b/deps/v8/src/api/OWNERS index ce6fb20af84d38..ef5a56dbfcecf3 100644 --- a/deps/v8/src/api/OWNERS +++ b/deps/v8/src/api/OWNERS @@ -1,4 +1,4 @@ -file://include/OWNERS +file:../../include/OWNERS clemensh@chromium.org ishell@chromium.org jkummerow@chromium.org diff --git a/deps/v8/src/api/api-inl.h b/deps/v8/src/api/api-inl.h index d152412b474f95..1a6b512e83a651 100644 --- a/deps/v8/src/api/api-inl.h +++ b/deps/v8/src/api/api-inl.h @@ -8,6 +8,7 @@ #include "src/api/api.h" #include "src/handles/handles-inl.h" #include "src/objects/foreign-inl.h" +#include "src/objects/js-weak-refs.h" #include "src/objects/objects-inl.h" #include "src/objects/stack-frame-info.h" @@ -84,6 +85,7 @@ MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView) MAKE_TO_LOCAL(ToLocal, JSDataView, DataView) MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray) MAKE_TO_LOCAL(ToLocalShared, JSArrayBuffer, SharedArrayBuffer) +MAKE_TO_LOCAL(ToLocal, JSFinalizationGroup, FinalizationGroup) TYPED_ARRAYS(MAKE_TO_LOCAL_TYPED_ARRAY) diff --git a/deps/v8/src/api/api-natives.cc b/deps/v8/src/api/api-natives.cc index cd380d3cda1aa2..b96b6fc4f62b2e 100644 --- a/deps/v8/src/api/api-natives.cc +++ b/deps/v8/src/api/api-natives.cc @@ -42,9 +42,17 @@ MaybeHandle InstantiateObject(Isolate* isolate, bool is_prototype); MaybeHandle InstantiateFunction( - Isolate* isolate, Handle data, + Isolate* isolate, Handle native_context, + Handle data, MaybeHandle maybe_name = MaybeHandle()); +MaybeHandle InstantiateFunction( + Isolate* isolate, Handle data, + MaybeHandle maybe_name = MaybeHandle()) { + return InstantiateFunction(isolate, isolate->native_context(), data, + maybe_name); +} + MaybeHandle Instantiate( Isolate* isolate, Handle data, MaybeHandle maybe_name = MaybeHandle()) { @@ -277,73 +285,73 @@ MaybeHandle ConfigureInstance(Isolate* isolate, Handle obj, // the cache for those cases. enum class CachingMode { kLimited, kUnlimited }; -MaybeHandle ProbeInstantiationsCache(Isolate* isolate, - int serial_number, - CachingMode caching_mode) { +MaybeHandle ProbeInstantiationsCache( + Isolate* isolate, Handle native_context, int serial_number, + CachingMode caching_mode) { DCHECK_LE(1, serial_number); if (serial_number <= TemplateInfo::kFastTemplateInstantiationsCacheSize) { - Handle fast_cache = - isolate->fast_template_instantiations_cache(); - Handle object{fast_cache->get(serial_number - 1), isolate}; + FixedArray fast_cache = + native_context->fast_template_instantiations_cache(); + Handle object{fast_cache.get(serial_number - 1), isolate}; if (object->IsUndefined(isolate)) return {}; return Handle::cast(object); } if (caching_mode == CachingMode::kUnlimited || (serial_number <= TemplateInfo::kSlowTemplateInstantiationsCacheSize)) { - Handle slow_cache = - isolate->slow_template_instantiations_cache(); - int entry = slow_cache->FindEntry(isolate, serial_number); + SimpleNumberDictionary slow_cache = + native_context->slow_template_instantiations_cache(); + int entry = slow_cache.FindEntry(isolate, serial_number); if (entry != SimpleNumberDictionary::kNotFound) { - return handle(JSObject::cast(slow_cache->ValueAt(entry)), isolate); + return handle(JSObject::cast(slow_cache.ValueAt(entry)), isolate); } } return {}; } -void CacheTemplateInstantiation(Isolate* isolate, int serial_number, - CachingMode caching_mode, +void CacheTemplateInstantiation(Isolate* isolate, + Handle native_context, + int serial_number, CachingMode caching_mode, Handle object) { DCHECK_LE(1, serial_number); if (serial_number <= TemplateInfo::kFastTemplateInstantiationsCacheSize) { Handle fast_cache = - isolate->fast_template_instantiations_cache(); + handle(native_context->fast_template_instantiations_cache(), isolate); Handle new_cache = FixedArray::SetAndGrow(isolate, fast_cache, serial_number - 1, object); if (*new_cache != *fast_cache) { - isolate->native_context()->set_fast_template_instantiations_cache( - *new_cache); + native_context->set_fast_template_instantiations_cache(*new_cache); } } else if (caching_mode == CachingMode::kUnlimited || (serial_number <= TemplateInfo::kSlowTemplateInstantiationsCacheSize)) { Handle cache = - isolate->slow_template_instantiations_cache(); + handle(native_context->slow_template_instantiations_cache(), isolate); auto new_cache = SimpleNumberDictionary::Set(isolate, cache, serial_number, object); if (*new_cache != *cache) { - isolate->native_context()->set_slow_template_instantiations_cache( - *new_cache); + native_context->set_slow_template_instantiations_cache(*new_cache); } } } -void UncacheTemplateInstantiation(Isolate* isolate, int serial_number, - CachingMode caching_mode) { +void UncacheTemplateInstantiation(Isolate* isolate, + Handle native_context, + int serial_number, CachingMode caching_mode) { DCHECK_LE(1, serial_number); if (serial_number <= TemplateInfo::kFastTemplateInstantiationsCacheSize) { - Handle fast_cache = - isolate->fast_template_instantiations_cache(); - DCHECK(!fast_cache->get(serial_number - 1).IsUndefined(isolate)); - fast_cache->set_undefined(serial_number - 1); + FixedArray fast_cache = + native_context->fast_template_instantiations_cache(); + DCHECK(!fast_cache.get(serial_number - 1).IsUndefined(isolate)); + fast_cache.set_undefined(serial_number - 1); } else if (caching_mode == CachingMode::kUnlimited || (serial_number <= TemplateInfo::kSlowTemplateInstantiationsCacheSize)) { Handle cache = - isolate->slow_template_instantiations_cache(); + handle(native_context->slow_template_instantiations_cache(), isolate); int entry = cache->FindEntry(isolate, serial_number); DCHECK_NE(SimpleNumberDictionary::kNotFound, entry); cache = SimpleNumberDictionary::DeleteEntry(isolate, cache, entry); - isolate->native_context()->set_slow_template_instantiations_cache(*cache); + native_context->set_slow_template_instantiations_cache(*cache); } } @@ -375,7 +383,8 @@ MaybeHandle InstantiateObject(Isolate* isolate, // Fast path. Handle result; if (serial_number) { - if (ProbeInstantiationsCache(isolate, serial_number, CachingMode::kLimited) + if (ProbeInstantiationsCache(isolate, isolate->native_context(), + serial_number, CachingMode::kLimited) .ToHandle(&result)) { return isolate->factory()->CopyJSObject(result); } @@ -419,8 +428,8 @@ MaybeHandle InstantiateObject(Isolate* isolate, JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); // Don't cache prototypes. if (serial_number) { - CacheTemplateInstantiation(isolate, serial_number, CachingMode::kLimited, - result); + CacheTemplateInstantiation(isolate, isolate->native_context(), + serial_number, CachingMode::kLimited, result); result = isolate->factory()->CopyJSObject(result); } } @@ -451,13 +460,13 @@ MaybeHandle GetInstancePrototype(Isolate* isolate, } } // namespace -MaybeHandle InstantiateFunction(Isolate* isolate, - Handle data, - MaybeHandle maybe_name) { +MaybeHandle InstantiateFunction( + Isolate* isolate, Handle native_context, + Handle data, MaybeHandle maybe_name) { int serial_number = Smi::ToInt(data->serial_number()); if (serial_number) { Handle result; - if (ProbeInstantiationsCache(isolate, serial_number, + if (ProbeInstantiationsCache(isolate, native_context, serial_number, CachingMode::kUnlimited) .ToHandle(&result)) { return Handle::cast(result); @@ -503,17 +512,17 @@ MaybeHandle InstantiateFunction(Isolate* isolate, : JS_SPECIAL_API_OBJECT_TYPE; Handle function = ApiNatives::CreateApiFunction( - isolate, data, prototype, function_type, maybe_name); + isolate, native_context, data, prototype, function_type, maybe_name); if (serial_number) { // Cache the function. - CacheTemplateInstantiation(isolate, serial_number, CachingMode::kUnlimited, - function); + CacheTemplateInstantiation(isolate, native_context, serial_number, + CachingMode::kUnlimited, function); } MaybeHandle result = ConfigureInstance(isolate, function, data); if (result.is_null()) { // Uncache on error. if (serial_number) { - UncacheTemplateInstantiation(isolate, serial_number, + UncacheTemplateInstantiation(isolate, native_context, serial_number, CachingMode::kUnlimited); } return MaybeHandle(); @@ -543,6 +552,14 @@ void AddPropertyToPropertyList(Isolate* isolate, Handle templ, } // namespace +MaybeHandle ApiNatives::InstantiateFunction( + Isolate* isolate, Handle native_context, + Handle data, MaybeHandle maybe_name) { + InvokeScope invoke_scope(isolate); + return ::v8::internal::InstantiateFunction(isolate, native_context, data, + maybe_name); +} + MaybeHandle ApiNatives::InstantiateFunction( Handle data, MaybeHandle maybe_name) { Isolate* isolate = data->GetIsolate(); @@ -626,8 +643,9 @@ void ApiNatives::AddNativeDataProperty(Isolate* isolate, } Handle ApiNatives::CreateApiFunction( - Isolate* isolate, Handle obj, - Handle prototype, InstanceType type, MaybeHandle maybe_name) { + Isolate* isolate, Handle native_context, + Handle obj, Handle prototype, + InstanceType type, MaybeHandle maybe_name) { Handle shared = FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj, maybe_name); @@ -635,8 +653,8 @@ Handle ApiNatives::CreateApiFunction( DCHECK(shared->HasSharedName()); Handle result = - isolate->factory()->NewFunctionFromSharedFunctionInfo( - shared, isolate->native_context()); + isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, + native_context); if (obj->remove_prototype()) { DCHECK(prototype.is_null()); diff --git a/deps/v8/src/api/api-natives.h b/deps/v8/src/api/api-natives.h index 153212cc6c43d7..fb59eb6cfcdb3f 100644 --- a/deps/v8/src/api/api-natives.h +++ b/deps/v8/src/api/api-natives.h @@ -24,6 +24,11 @@ class ApiNatives { public: static const int kInitialFunctionCacheSize = 256; + V8_WARN_UNUSED_RESULT static MaybeHandle InstantiateFunction( + Isolate* isolate, Handle native_context, + Handle data, + MaybeHandle maybe_name = MaybeHandle()); + V8_WARN_UNUSED_RESULT static MaybeHandle InstantiateFunction( Handle data, MaybeHandle maybe_name = MaybeHandle()); @@ -36,9 +41,9 @@ class ApiNatives { Handle data); static Handle CreateApiFunction( - Isolate* isolate, Handle obj, - Handle prototype, InstanceType type, - MaybeHandle name = MaybeHandle()); + Isolate* isolate, Handle native_context, + Handle obj, Handle prototype, + InstanceType type, MaybeHandle name = MaybeHandle()); static void AddDataProperty(Isolate* isolate, Handle info, Handle name, Handle value, diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc index ca5d9ce5d26cd7..30eceb6223377f 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -68,6 +68,7 @@ #include "src/objects/js-generator-inl.h" #include "src/objects/js-promise-inl.h" #include "src/objects/js-regexp-inl.h" +#include "src/objects/js-weak-refs-inl.h" #include "src/objects/module-inl.h" #include "src/objects/objects-inl.h" #include "src/objects/oddball.h" @@ -121,9 +122,9 @@ #include #include "include/v8-wasm-trap-handler-win.h" #include "src/trap-handler/handler-inside-win.h" -#if V8_TARGET_ARCH_X64 +#if defined(V8_OS_WIN64) #include "src/diagnostics/unwinding-info-win64.h" -#endif // V8_TARGET_ARCH_X64 +#endif // V8_OS_WIN64 #endif // V8_OS_WIN namespace v8 { @@ -237,18 +238,10 @@ namespace v8 { #define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \ EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, Nothing()) -#define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \ - return maybe_local.FromMaybe(Local()); - #define RETURN_ESCAPED(value) return handle_scope.Escape(value); namespace { -Local ContextFromNeverReadOnlySpaceObject( - i::Handle obj) { - return reinterpret_cast(obj->GetIsolate())->GetCurrentContext(); -} - class InternalEscapableScope : public v8::EscapableHandleScope { public: explicit inline InternalEscapableScope(i::Isolate* isolate) @@ -269,7 +262,7 @@ void CheckMicrotasksScopesConsistency(i::MicrotaskQueue* microtask_queue) { template class CallDepthScope { public: - explicit CallDepthScope(i::Isolate* isolate, Local context) + CallDepthScope(i::Isolate* isolate, Local context) : isolate_(isolate), context_(context), escaped_(false), @@ -280,7 +273,7 @@ class CallDepthScope { ? i::InterruptsScope::kRunInterrupts : i::InterruptsScope::kPostponeInterrupts) : i::InterruptsScope::kNoop) { - isolate_->handle_scope_implementer()->IncrementCallDepth(); + isolate_->thread_local_top()->IncrementCallDepth(this); isolate_->set_next_v8_call_is_safe_for_termination(false); if (!context.IsEmpty()) { i::Handle env = Utils::OpenHandle(*context); @@ -304,7 +297,7 @@ class CallDepthScope { i::Handle env = Utils::OpenHandle(*context_); microtask_queue = env->native_context().microtask_queue(); } - if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth(); + if (!escaped_) isolate_->thread_local_top()->DecrementCallDepth(this); if (do_callback) isolate_->FireCallCompletedCallback(microtask_queue); // TODO(jochen): This should be #ifdef DEBUG #ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY @@ -316,11 +309,10 @@ class CallDepthScope { void Escape() { DCHECK(!escaped_); escaped_ = true; - auto handle_scope_implementer = isolate_->handle_scope_implementer(); - handle_scope_implementer->DecrementCallDepth(); - bool clear_exception = - handle_scope_implementer->CallDepthIsZero() && - isolate_->thread_local_top()->try_catch_handler_ == nullptr; + auto thread_local_top = isolate_->thread_local_top(); + thread_local_top->DecrementCallDepth(this); + bool clear_exception = thread_local_top->CallDepthIsZero() && + thread_local_top->try_catch_handler_ == nullptr; isolate_->OptionalRescheduleException(clear_exception); } @@ -331,6 +323,12 @@ class CallDepthScope { bool do_callback_; bool safe_for_termination_; i::InterruptsScope interrupts_scope_; + i::Address previous_stack_height_; + + friend class i::ThreadLocalTop; + + DISALLOW_NEW_AND_DELETE() + DISALLOW_COPY_AND_ASSIGN(CallDepthScope); }; } // namespace @@ -819,10 +817,15 @@ StartupData SnapshotCreator::CreateBlob( // Complete in-object slack tracking for all functions. fun.CompleteInobjectSlackTrackingIfActive(); - fun.ResetIfBytecodeFlushed(); - // Also, clear out feedback vectors, or any optimized code. - if (fun.IsOptimized() || fun.IsInterpreted()) { + // Note that checking for fun.IsOptimized() || fun.IsInterpreted() is not + // sufficient because the function can have a feedback vector even if it + // is not compiled (e.g. when the bytecode was flushed). On the other + // hand, only checking for the feedback vector is not sufficient because + // there can be multiple functions sharing the same feedback vector. So we + // need all these checks. + if (fun.IsOptimized() || fun.IsInterpreted() || + !fun.raw_feedback_cell().value().IsUndefined()) { fun.raw_feedback_cell().set_value( i::ReadOnlyRoots(isolate).undefined_value()); fun.set_code(isolate->builtins()->builtin(i::Builtins::kCompileLazy)); @@ -891,13 +894,17 @@ void V8::SetDcheckErrorHandler(DcheckErrorCallback that) { } void V8::SetFlagsFromString(const char* str) { - SetFlagsFromString(str, static_cast(strlen(str))); + SetFlagsFromString(str, strlen(str)); +} + +void V8::SetFlagsFromString(const char* str, size_t length) { + i::FlagList::SetFlagsFromString(str, length); + i::FlagList::EnforceFlagImplications(); } void V8::SetFlagsFromString(const char* str, int length) { CHECK_LE(0, length); - i::FlagList::SetFlagsFromString(str, static_cast(length)); - i::FlagList::EnforceFlagImplications(); + SetFlagsFromString(str, static_cast(length)); } void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { @@ -961,7 +968,31 @@ Extension::Extension(const char* name, const char* source, int dep_count, CHECK(source != nullptr || source_length_ == 0); } -ResourceConstraints::ResourceConstraints() {} +void ResourceConstraints::ConfigureDefaultsFromHeapSize( + size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes) { + CHECK_LE(initial_heap_size_in_bytes, maximum_heap_size_in_bytes); + if (maximum_heap_size_in_bytes == 0) { + return; + } + size_t young_generation, old_generation; + i::Heap::GenerationSizesFromHeapSize(maximum_heap_size_in_bytes, + &young_generation, &old_generation); + set_max_young_generation_size_in_bytes( + i::Max(young_generation, i::Heap::MinYoungGenerationSize())); + set_max_old_generation_size_in_bytes( + i::Max(old_generation, i::Heap::MinOldGenerationSize())); + if (initial_heap_size_in_bytes > 0) { + i::Heap::GenerationSizesFromHeapSize(initial_heap_size_in_bytes, + &young_generation, &old_generation); + // We do not set lower bounds for the initial sizes. + set_initial_young_generation_size_in_bytes(young_generation); + set_initial_old_generation_size_in_bytes(old_generation); + } + if (i::kRequiresCodeRange) { + set_code_range_size_in_bytes( + i::Min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes)); + } +} void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, uint64_t virtual_memory_limit) { @@ -979,14 +1010,15 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, } } -size_t ResourceConstraints::max_young_generation_size_in_bytes() const { - return i::Heap::YoungGenerationSizeFromSemiSpaceSize( - max_semi_space_size_in_kb_ * i::KB); +size_t ResourceConstraints::max_semi_space_size_in_kb() const { + return i::Heap::SemiSpaceSizeFromYoungGenerationSize( + max_young_generation_size_) / + i::KB; } -void ResourceConstraints::set_max_young_generation_size_in_bytes(size_t limit) { - max_semi_space_size_in_kb_ = - i::Heap::SemiSpaceSizeFromYoungGenerationSize(limit) / i::KB; +void ResourceConstraints::set_max_semi_space_size_in_kb(size_t limit_in_kb) { + set_max_young_generation_size_in_bytes( + i::Heap::YoungGenerationSizeFromSemiSpaceSize(limit_in_kb * i::KB)); } i::Address* V8::GlobalizeReference(i::Isolate* isolate, i::Address* obj) { @@ -1001,10 +1033,11 @@ i::Address* V8::GlobalizeReference(i::Isolate* isolate, i::Address* obj) { } i::Address* V8::GlobalizeTracedReference(i::Isolate* isolate, i::Address* obj, - internal::Address* slot) { + internal::Address* slot, + bool has_destructor) { LOG_API(isolate, TracedGlobal, New); i::Handle result = - isolate->global_handles()->CreateTraced(*obj, slot); + isolate->global_handles()->CreateTraced(*obj, slot, has_destructor); #ifdef VERIFY_HEAP if (i::FLAG_verify_heap) { i::Object(*obj).ObjectVerify(isolate); @@ -1027,9 +1060,9 @@ void V8::MoveTracedGlobalReference(internal::Address** from, i::GlobalHandles::MoveTracedGlobal(from, to); } -void V8::RegisterExternallyReferencedObject(i::Address* location, - i::Isolate* isolate) { - isolate->heap()->RegisterExternallyReferencedObject(location); +void V8::CopyTracedGlobalReference(const internal::Address* const* from, + internal::Address** to) { + i::GlobalHandles::CopyTracedGlobal(from, to); } void V8::MakeWeak(i::Address* location, void* parameter, @@ -1281,7 +1314,6 @@ void Context::SetEmbedderData(int index, v8::Local value) { void* Context::SlowGetAlignedPointerFromEmbedderData(int index) { const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()"; - HandleScope handle_scope(GetIsolate()); i::Handle data = EmbedderDataFor(this, index, false, location); if (data.is_null()) return nullptr; @@ -1604,10 +1636,6 @@ void FunctionTemplate::SetAcceptAnyReceiver(bool value) { info->set_accept_any_receiver(value); } -void FunctionTemplate::SetHiddenPrototype(bool value) { - /* No-op for ABI compatibility. */ -} - void FunctionTemplate::ReadOnlyPrototype() { auto info = Utils::OpenHandle(this); EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype"); @@ -2325,7 +2353,8 @@ Local Module::CreateSyntheticModule( i::Handle i_export_names = i_isolate->factory()->NewFixedArray( static_cast(export_names.size())); for (int i = 0; i < i_export_names->length(); ++i) { - i::Handle str = Utils::OpenHandle(*export_names[i]); + i::Handle str = i_isolate->factory()->InternalizeString( + Utils::OpenHandle(*export_names[i])); i_export_names->set(i, *str); } return v8::Utils::ToLocal( @@ -2483,16 +2512,6 @@ bool IsIdentifier(i::Isolate* isolate, i::Handle string) { } } // anonymous namespace -MaybeLocal ScriptCompiler::CompileFunctionInContext( - Local v8_context, Source* source, size_t arguments_count, - Local arguments[], size_t context_extension_count, - Local context_extensions[], CompileOptions options, - NoCacheReason no_cache_reason) { - return ScriptCompiler::CompileFunctionInContext( - v8_context, source, arguments_count, arguments, context_extension_count, - context_extensions, options, no_cache_reason, nullptr); -} - MaybeLocal ScriptCompiler::CompileFunctionInContext( Local v8_context, Source* source, size_t arguments_count, Local arguments[], size_t context_extension_count, @@ -3487,12 +3506,6 @@ MaybeLocal Value::ToString(Local context) const { RETURN_ESCAPED(result); } - -Local Value::ToString(Isolate* isolate) const { - RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String); -} - - MaybeLocal Value::ToDetailString(Local context) const { i::Handle obj = Utils::OpenHandle(this); if (obj->IsString()) return ToApiHandle(obj); @@ -3514,11 +3527,6 @@ MaybeLocal Value::ToObject(Local context) const { RETURN_ESCAPED(result); } - -Local Value::ToObject(Isolate* isolate) const { - RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object); -} - MaybeLocal Value::ToBigInt(Local context) const { i::Handle obj = Utils::OpenHandle(this); if (obj->IsBigInt()) return ToApiHandle(obj); @@ -3535,11 +3543,6 @@ bool Value::BooleanValue(Isolate* v8_isolate) const { reinterpret_cast(v8_isolate)); } -MaybeLocal Value::ToBoolean(Local context) const { - return ToBoolean(context->GetIsolate()); -} - - Local Value::ToBoolean(Isolate* v8_isolate) const { auto isolate = reinterpret_cast(v8_isolate); return ToApiHandle( @@ -3557,12 +3560,6 @@ MaybeLocal Value::ToNumber(Local context) const { RETURN_ESCAPED(result); } - -Local Value::ToNumber(Isolate* isolate) const { - RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number); -} - - MaybeLocal Value::ToInteger(Local context) const { auto obj = Utils::OpenHandle(this); if (obj->IsSmi()) return ToApiHandle(obj); @@ -3574,12 +3571,6 @@ MaybeLocal Value::ToInteger(Local context) const { RETURN_ESCAPED(result); } - -Local Value::ToInteger(Isolate* isolate) const { - RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer); -} - - MaybeLocal Value::ToInt32(Local context) const { auto obj = Utils::OpenHandle(this); if (obj->IsSmi()) return ToApiHandle(obj); @@ -3591,12 +3582,6 @@ MaybeLocal Value::ToInt32(Local context) const { RETURN_ESCAPED(result); } - -Local Value::ToInt32(Isolate* isolate) const { - RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32); -} - - MaybeLocal Value::ToUint32(Local context) const { auto obj = Utils::OpenHandle(this); if (obj->IsSmi()) return ToApiHandle(obj); @@ -3823,13 +3808,6 @@ void v8::RegExp::CheckCast(v8::Value* that) { "Could not convert to regular expression"); } - -Maybe Value::BooleanValue(Local context) const { - i::Isolate* isolate = reinterpret_cast(context->GetIsolate()); - return Just(Utils::OpenHandle(this)->BooleanValue(isolate)); -} - - Maybe Value::NumberValue(Local context) const { auto obj = Utils::OpenHandle(this); if (obj->IsNumber()) return Just(obj->Number()); @@ -3963,11 +3941,6 @@ Maybe v8::Object::Set(v8::Local context, return Just(true); } -bool v8::Object::Set(v8::Local key, v8::Local value) { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - return Set(context, key, value).FromMaybe(false); -} - Maybe v8::Object::Set(v8::Local context, uint32_t index, v8::Local value) { auto isolate = reinterpret_cast(context->GetIsolate()); @@ -3981,11 +3954,6 @@ Maybe v8::Object::Set(v8::Local context, uint32_t index, return Just(true); } -bool v8::Object::Set(uint32_t index, v8::Local value) { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - return Set(context, index, value).FromMaybe(false); -} - Maybe v8::Object::CreateDataProperty(v8::Local context, v8::Local key, v8::Local value) { @@ -4203,11 +4171,6 @@ MaybeLocal v8::Object::Get(Local context, RETURN_ESCAPED(Utils::ToLocal(result)); } -Local v8::Object::Get(v8::Local key) { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value); -} - MaybeLocal v8::Object::Get(Local context, uint32_t index) { PREPARE_FOR_EXECUTION(context, Object, Get, Value); auto self = Utils::OpenHandle(this); @@ -4218,11 +4181,6 @@ MaybeLocal v8::Object::Get(Local context, uint32_t index) { RETURN_ESCAPED(Utils::ToLocal(result)); } -Local v8::Object::Get(uint32_t index) { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value); -} - MaybeLocal v8::Object::GetPrivate(Local context, Local key) { return Get(context, Local(reinterpret_cast(*key))); @@ -4750,6 +4708,11 @@ bool v8::Object::IsConstructor() { return self->IsConstructor(); } +bool v8::Object::IsApiWrapper() { + auto self = i::Handle::cast(Utils::OpenHandle(this)); + return self->IsApiWrapper(); +} + MaybeLocal Object::CallAsFunction(Local context, Local recv, int argc, Local argv[]) { @@ -4930,7 +4893,7 @@ Local Function::GetDisplayName() const { } auto func = i::Handle::cast(self); i::Handle property_name = - isolate->factory()->NewStringFromStaticChars("displayName"); + isolate->factory()->display_name_string(); i::Handle value = i::JSReceiver::GetDataProperty(func, property_name); if (value->IsString()) { @@ -5642,14 +5605,14 @@ bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) { #if defined(V8_OS_WIN) void V8::SetUnhandledExceptionCallback( UnhandledExceptionCallback unhandled_exception_callback) { -#if defined(V8_TARGET_ARCH_X64) +#if defined(V8_OS_WIN64) v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback( unhandled_exception_callback); #else - // Not implemented on ARM64. -#endif + // Not implemented, port needed. +#endif // V8_OS_WIN64 } -#endif +#endif // V8_OS_WIN void v8::V8::SetEntropySource(EntropySource entropy_source) { base::RandomNumberGenerator::SetEntropySource(entropy_source); @@ -6175,9 +6138,9 @@ inline int StringLength(const uint16_t* string) { V8_WARN_UNUSED_RESULT inline i::MaybeHandle NewString(i::Factory* factory, - v8::NewStringType type, + NewStringType type, i::Vector string) { - if (type == v8::NewStringType::kInternalized) { + if (type == NewStringType::kInternalized) { return factory->InternalizeUtf8String(string); } return factory->NewStringFromUtf8(string); @@ -6185,9 +6148,9 @@ inline i::MaybeHandle NewString(i::Factory* factory, V8_WARN_UNUSED_RESULT inline i::MaybeHandle NewString(i::Factory* factory, - v8::NewStringType type, + NewStringType type, i::Vector string) { - if (type == v8::NewStringType::kInternalized) { + if (type == NewStringType::kInternalized) { return factory->InternalizeString(string); } return factory->NewStringFromOneByte(string); @@ -6195,15 +6158,14 @@ inline i::MaybeHandle NewString(i::Factory* factory, V8_WARN_UNUSED_RESULT inline i::MaybeHandle NewString(i::Factory* factory, - v8::NewStringType type, + NewStringType type, i::Vector string) { - if (type == v8::NewStringType::kInternalized) { + if (type == NewStringType::kInternalized) { return factory->InternalizeString(string); } return factory->NewStringFromTwoByte(string); } - STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength); } // anonymous namespace @@ -6228,43 +6190,21 @@ STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength); result = Utils::ToLocal(handle_result); \ } -Local String::NewFromUtf8(Isolate* isolate, - const char* data, - NewStringType type, - int length) { - NEW_STRING(isolate, String, NewFromUtf8, char, data, - static_cast(type), length); - RETURN_TO_LOCAL_UNCHECKED(result, String); -} - - MaybeLocal String::NewFromUtf8(Isolate* isolate, const char* data, - v8::NewStringType type, int length) { + NewStringType type, int length) { NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length); return result; } - MaybeLocal String::NewFromOneByte(Isolate* isolate, const uint8_t* data, - v8::NewStringType type, int length) { + NewStringType type, int length) { NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length); return result; } - -Local String::NewFromTwoByte(Isolate* isolate, - const uint16_t* data, - NewStringType type, - int length) { - NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, - static_cast(type), length); - RETURN_TO_LOCAL_UNCHECKED(result, String); -} - - MaybeLocal String::NewFromTwoByte(Isolate* isolate, const uint16_t* data, - v8::NewStringType type, int length) { + NewStringType type, int length) { NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length); return result; } @@ -6311,7 +6251,7 @@ MaybeLocal v8::String::NewExternalTwoByte( MaybeLocal v8::String::NewExternalOneByte( Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { - CHECK(resource && resource->data()); + CHECK_NOT_NULL(resource); // TODO(dcarney): throw a context free exception. if (resource->length() > static_cast(i::String::kMaxLength)) { return MaybeLocal(); @@ -6319,25 +6259,18 @@ MaybeLocal v8::String::NewExternalOneByte( i::Isolate* i_isolate = reinterpret_cast(isolate); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); LOG_API(i_isolate, String, NewExternalOneByte); - if (resource->length() > 0) { - i::Handle string = i_isolate->factory() - ->NewExternalStringFromOneByte(resource) - .ToHandleChecked(); - return Utils::ToLocal(string); - } else { + if (resource->length() == 0) { // The resource isn't going to be used, free it immediately. resource->Dispose(); return Utils::ToLocal(i_isolate->factory()->empty_string()); } + CHECK_NOT_NULL(resource->data()); + i::Handle string = i_isolate->factory() + ->NewExternalStringFromOneByte(resource) + .ToHandleChecked(); + return Utils::ToLocal(string); } - -Local v8::String::NewExternal( - Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { - RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String); -} - - bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { i::DisallowHeapAllocation no_allocation; @@ -6611,23 +6544,14 @@ double v8::Date::ValueOf() const { // Assert that the static TimeZoneDetection cast in // DateTimeConfigurationChangeNotification is valid. -#define TIME_ZONE_DETECTION_ASSERT_EQ(value) \ - STATIC_ASSERT( \ - static_cast(v8::Isolate::TimeZoneDetection::value) == \ - static_cast(base::TimezoneCache::TimeZoneDetection::value)); \ - STATIC_ASSERT(static_cast(v8::Isolate::TimeZoneDetection::value) == \ - static_cast(v8::Date::TimeZoneDetection::value)); +#define TIME_ZONE_DETECTION_ASSERT_EQ(value) \ + STATIC_ASSERT( \ + static_cast(v8::Isolate::TimeZoneDetection::value) == \ + static_cast(base::TimezoneCache::TimeZoneDetection::value)); TIME_ZONE_DETECTION_ASSERT_EQ(kSkip) TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect) #undef TIME_ZONE_DETECTION_ASSERT_EQ -// static -void v8::Date::DateTimeConfigurationChangeNotification( - Isolate* isolate, TimeZoneDetection time_zone_detection) { - isolate->DateTimeConfigurationChangeNotification( - static_cast(time_zone_detection)); -} - MaybeLocal v8::RegExp::New(Local context, Local pattern, Flags flags) { PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp); @@ -7546,15 +7470,14 @@ v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() { v8::SharedArrayBuffer::Contents::Contents( void* data, size_t byte_length, void* allocation_base, size_t allocation_length, Allocator::AllocationMode allocation_mode, - DeleterCallback deleter, void* deleter_data, bool is_growable) + DeleterCallback deleter, void* deleter_data) : data_(data), byte_length_(byte_length), allocation_base_(allocation_base), allocation_length_(allocation_length), allocation_mode_(allocation_mode), deleter_(deleter), - deleter_data_(deleter_data), - is_growable_(is_growable) { + deleter_data_(deleter_data) { DCHECK_LE(allocation_base_, data_); DCHECK_LE(byte_length_, allocation_length_); } @@ -7572,8 +7495,7 @@ v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() { : reinterpret_cast(ArrayBufferDeleter), self->is_wasm_memory() ? static_cast(self->GetIsolate()->wasm_engine()) - : static_cast(self->GetIsolate()->array_buffer_allocator()), - false); + : static_cast(self->GetIsolate()->array_buffer_allocator())); return contents; } @@ -7794,6 +7716,11 @@ bool Isolate::InContext() { return !isolate->context().is_null(); } +void Isolate::ClearKeptObjects() { + i::Isolate* isolate = reinterpret_cast(this); + isolate->ClearKeptObjects(); +} + v8::Local Isolate::GetCurrentContext() { i::Isolate* isolate = reinterpret_cast(this); i::Context context = isolate->context(); @@ -8057,6 +7984,28 @@ void Isolate::SetAbortOnUncaughtExceptionCallback( isolate->SetAbortOnUncaughtExceptionCallback(callback); } +void Isolate::SetHostCleanupFinalizationGroupCallback( + HostCleanupFinalizationGroupCallback callback) { + i::Isolate* isolate = reinterpret_cast(this); + isolate->SetHostCleanupFinalizationGroupCallback(callback); +} + +Maybe FinalizationGroup::Cleanup( + Local finalization_group) { + i::Handle fg = Utils::OpenHandle(*finalization_group); + i::Isolate* isolate = fg->native_context().GetIsolate(); + i::Handle i_context(fg->native_context(), isolate); + Local context = Utils::ToLocal(i_context); + ENTER_V8(isolate, context, FinalizationGroup, Cleanup, Nothing(), + i::HandleScope); + i::Handle callback(fg->cleanup(), isolate); + fg->set_scheduled_for_cleanup(false); + has_pending_exception = + i::JSFinalizationGroup::Cleanup(isolate, fg, callback).IsNothing(); + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); + return Just(true); +} + void Isolate::SetHostImportModuleDynamicallyCallback( HostImportModuleDynamicallyCallback callback) { i::Isolate* isolate = reinterpret_cast(this); @@ -8135,13 +8084,13 @@ Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope( Isolate* isolate) : isolate_(reinterpret_cast(isolate)), microtask_queue_(isolate_->default_microtask_queue()) { - isolate_->handle_scope_implementer()->IncrementCallDepth(); + isolate_->thread_local_top()->IncrementCallDepth(this); microtask_queue_->IncrementMicrotasksSuppressions(); } Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() { microtask_queue_->DecrementMicrotasksSuppressions(); - isolate_->handle_scope_implementer()->DecrementCallDepth(); + isolate_->thread_local_top()->DecrementCallDepth(this); } Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate) @@ -8266,8 +8215,10 @@ bool Isolate::GetHeapCodeAndMetadataStatistics( void Isolate::GetStackSample(const RegisterState& state, void** frames, size_t frames_limit, SampleInfo* sample_info) { RegisterState regs = state; - if (TickSample::GetStackSample(this, ®s, TickSample::kSkipCEntryFrame, - frames, frames_limit, sample_info)) { + i::Isolate* isolate = reinterpret_cast(this); + if (i::TickSample::GetStackSample(isolate, ®s, + i::TickSample::kSkipCEntryFrame, frames, + frames_limit, sample_info)) { return; } sample_info->frames_count = 0; @@ -8427,6 +8378,11 @@ void Isolate::SetAddHistogramSampleFunction( ->SetAddHistogramSampleFunction(callback); } +void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) { + i::Isolate* isolate = reinterpret_cast(this); + isolate->SetAddCrashKeyCallback(callback); +} + bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) { // Returning true tells the caller that it need not // continue to call IdleNotification. @@ -8582,6 +8538,9 @@ CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback, CALLBACK_SETTER(WasmThreadsEnabledCallback, WasmThreadsEnabledCallback, wasm_threads_enabled_callback) +CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback, + wasm_load_source_map_callback) + void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback, void* data) { i::Isolate* isolate = reinterpret_cast(this); @@ -8713,8 +8672,13 @@ void v8::Isolate::LocaleConfigurationChangeNotification() { } // static -std::unique_ptr MicrotaskQueue::New(Isolate* isolate) { - return i::MicrotaskQueue::New(reinterpret_cast(isolate)); +std::unique_ptr MicrotaskQueue::New(Isolate* isolate, + MicrotasksPolicy policy) { + auto microtask_queue = + i::MicrotaskQueue::New(reinterpret_cast(isolate)); + microtask_queue->set_microtasks_policy(policy); + std::unique_ptr ret(std::move(microtask_queue)); + return ret; } MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type) @@ -8737,7 +8701,11 @@ MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::~MicrotasksScope() { if (run_) { microtask_queue_->DecrementMicrotasksScopeDepth(); - if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy()) { + if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() && + !isolate_->has_scheduled_exception()) { + DCHECK_IMPLIES(isolate_->has_scheduled_exception(), + isolate_->scheduled_exception() == + i::ReadOnlyRoots(isolate_).termination_exception()); microtask_queue_->PerformCheckpoint(reinterpret_cast(isolate_)); } } @@ -9896,13 +9864,32 @@ int CpuProfile::GetSamplesCount() const { return reinterpret_cast(this)->samples_count(); } -CpuProfiler* CpuProfiler::New(Isolate* isolate) { - return New(isolate, kDebugNaming); +CpuProfiler* CpuProfiler::New(Isolate* isolate, + CpuProfilingNamingMode naming_mode, + CpuProfilingLoggingMode logging_mode) { + return reinterpret_cast(new i::CpuProfiler( + reinterpret_cast(isolate), naming_mode, logging_mode)); +} + +CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode, + unsigned max_samples, + int sampling_interval_us, + MaybeLocal filter_context) + : mode_(mode), + max_samples_(max_samples), + sampling_interval_us_(sampling_interval_us) { + if (!filter_context.IsEmpty()) { + Local local_filter_context = filter_context.ToLocalChecked(); + filter_context_.Reset(local_filter_context->GetIsolate(), + local_filter_context); + } } -CpuProfiler* CpuProfiler::New(Isolate* isolate, CpuProfilingNamingMode mode) { - return reinterpret_cast( - new i::CpuProfiler(reinterpret_cast(isolate), mode)); +void* CpuProfilingOptions::raw_filter_context() const { + return reinterpret_cast( + i::Context::cast(*Utils::OpenPersistent(filter_context_)) + .native_context() + .address()); } void CpuProfiler::Dispose() { delete reinterpret_cast(this); } @@ -9941,12 +9928,6 @@ void CpuProfiler::StartProfiling(Local title, bool record_samples) { *Utils::OpenHandle(*title), options); } -void CpuProfiler::StartProfiling(Local title, CpuProfilingMode mode, - bool record_samples) { - StartProfiling(title, mode, record_samples, - CpuProfilingOptions::kNoSampleLimit); -} - void CpuProfiler::StartProfiling(Local title, CpuProfilingMode mode, bool record_samples, unsigned max_samples) { CpuProfilingOptions options(mode, record_samples ? max_samples : 0); @@ -10174,6 +10155,10 @@ SnapshotObjectId HeapProfiler::GetObjectId(Local value) { return reinterpret_cast(this)->GetSnapshotObjectId(obj); } +SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) { + return reinterpret_cast(this)->GetSnapshotObjectId(value); +} + Local HeapProfiler::FindObjectById(SnapshotObjectId id) { i::Handle obj = reinterpret_cast(this)->FindHeapObjectById(id); @@ -10306,6 +10291,17 @@ void EmbedderHeapTracer::TracePrologue(TraceFlags flags) { #endif } +void EmbedderHeapTracer::TraceEpilogue(TraceSummary* trace_summary) { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" +#endif + TraceEpilogue(); +#if __clang__ +#pragma clang diagnostic pop +#endif +} + void EmbedderHeapTracer::FinalizeTracing() { if (isolate_) { i::Isolate* isolate = reinterpret_cast(isolate_); @@ -10354,8 +10350,7 @@ void EmbedderHeapTracer::RegisterEmbedderReference( if (ref.IsEmpty()) return; i::Heap* const heap = reinterpret_cast(isolate_)->heap(); - heap->RegisterExternallyReferencedObject( - reinterpret_cast(ref.val_)); + heap->RegisterExternallyReferencedObject(reinterpret_cast(*ref)); } void EmbedderHeapTracer::IterateTracedGlobalHandles( @@ -10559,7 +10554,6 @@ void InvokeFunctionCallback(const v8::FunctionCallbackInfo& info, #undef EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE #undef RETURN_ON_FAILED_EXECUTION #undef RETURN_ON_FAILED_EXECUTION_PRIMITIVE -#undef RETURN_TO_LOCAL_UNCHECKED #undef RETURN_ESCAPED #undef SET_FIELD_WRAPPED #undef NEW_STRING diff --git a/deps/v8/src/api/api.h b/deps/v8/src/api/api.h index 6135a7dfc62024..21bbb3a101549d 100644 --- a/deps/v8/src/api/api.h +++ b/deps/v8/src/api/api.h @@ -90,6 +90,7 @@ class RegisteredExtension { V(Data, Object) \ V(RegExp, JSRegExp) \ V(Object, JSReceiver) \ + V(FinalizationGroup, JSFinalizationGroup) \ V(Array, JSArray) \ V(Map, JSMap) \ V(Set, JSSet) \ @@ -198,6 +199,8 @@ class Utils { v8::internal::Handle obj); static inline Local ToLocalBigUint64Array( v8::internal::Handle obj); + static inline Local ToLocal( + v8::internal::Handle obj); static inline Local ToLocalShared( v8::internal::Handle obj); @@ -248,9 +251,9 @@ class Utils { template static inline Local Convert(v8::internal::Handle obj); - template + template static inline v8::internal::Handle OpenPersistent( - const v8::Persistent& persistent) { + const v8::Persistent& persistent) { return v8::internal::Handle( reinterpret_cast(persistent.val_)); } @@ -354,7 +357,6 @@ class HandleScopeImplementer { explicit HandleScopeImplementer(Isolate* isolate) : isolate_(isolate), spare_(nullptr), - call_depth_(0), last_handle_before_deferred_block_(nullptr) {} ~HandleScopeImplementer() { DeleteArray(spare_); } @@ -373,11 +375,6 @@ class HandleScopeImplementer { inline internal::Address* GetSpareOrNewBlock(); inline void DeleteExtensions(internal::Address* prev_limit); - // Call depth represents nested v8 api calls. - inline void IncrementCallDepth() { call_depth_++; } - inline void DecrementCallDepth() { call_depth_--; } - inline bool CallDepthIsZero() { return call_depth_ == 0; } - inline void EnterContext(Context context); inline void LeaveContext(); inline bool LastEnteredContextWas(Context context); @@ -414,7 +411,6 @@ class HandleScopeImplementer { saved_contexts_.detach(); spare_ = nullptr; last_handle_before_deferred_block_ = nullptr; - call_depth_ = 0; } void Free() { @@ -431,7 +427,7 @@ class HandleScopeImplementer { DeleteArray(spare_); spare_ = nullptr; } - DCHECK_EQ(call_depth_, 0); + DCHECK(isolate_->thread_local_top()->CallDepthIsZero()); } void BeginDeferredScope(); @@ -451,8 +447,6 @@ class HandleScopeImplementer { // Used as a stack to keep track of saved contexts. DetachableVector saved_contexts_; Address* spare_; - int call_depth_; - Address* last_handle_before_deferred_block_; // This is only used for threading support. HandleScopeData handle_scope_data_; diff --git a/deps/v8/src/ast/ast-traversal-visitor.h b/deps/v8/src/ast/ast-traversal-visitor.h index b4836ff7847488..2796e59a8dbb90 100644 --- a/deps/v8/src/ast/ast-traversal-visitor.h +++ b/deps/v8/src/ast/ast-traversal-visitor.h @@ -382,6 +382,12 @@ void AstTraversalVisitor::VisitThrow(Throw* expr) { RECURSE_EXPRESSION(Visit(expr->exception())); } +template +void AstTraversalVisitor::VisitOptionalChain(OptionalChain* expr) { + PROCESS_EXPRESSION(expr); + RECURSE_EXPRESSION(Visit(expr->expression())); +} + template void AstTraversalVisitor::VisitProperty(Property* expr) { PROCESS_EXPRESSION(expr); diff --git a/deps/v8/src/ast/ast.cc b/deps/v8/src/ast/ast.cc index 9987eb28449a21..4b6c4805dedc16 100644 --- a/deps/v8/src/ast/ast.cc +++ b/deps/v8/src/ast/ast.cc @@ -122,6 +122,10 @@ bool Expression::IsUndefinedLiteral() const { var_proxy->raw_name()->IsOneByteEqualTo("undefined"); } +bool Expression::IsLiteralButNotNullOrUndefined() const { + return IsLiteral() && !IsNullOrUndefinedLiteral(); +} + bool Expression::ToBooleanIsTrue() const { return IsLiteral() && AsLiteral()->ToBooleanIsTrue(); } @@ -217,13 +221,7 @@ bool FunctionLiteral::AllowsLazyCompilation() { } bool FunctionLiteral::SafeToSkipArgumentsAdaptor() const { - // TODO(bmeurer,verwaest): The --fast_calls_with_arguments_mismatches - // is mostly here for checking the real-world impact of the calling - // convention. There's not really a point in turning off this flag - // otherwise, so we should remove it at some point, when we're done - // with the experiments (https://crbug.com/v8/8895). - return FLAG_fast_calls_with_arguments_mismatches && - language_mode() == LanguageMode::kStrict && + return language_mode() == LanguageMode::kStrict && scope()->arguments() == nullptr && scope()->rest_parameter() == nullptr; } diff --git a/deps/v8/src/ast/ast.h b/deps/v8/src/ast/ast.h index bd52d1b2c04065..ced9f775dd57bc 100644 --- a/deps/v8/src/ast/ast.h +++ b/deps/v8/src/ast/ast.h @@ -16,6 +16,7 @@ #include "src/common/globals.h" #include "src/execution/isolate.h" #include "src/heap/factory.h" +#include "src/objects/function-syntax-kind.h" #include "src/objects/literal-objects.h" #include "src/objects/smi.h" #include "src/parsing/token.h" @@ -94,6 +95,7 @@ namespace internal { V(ImportCallExpression) \ V(Literal) \ V(NativeFunctionLiteral) \ + V(OptionalChain) \ V(Property) \ V(ResolvedProperty) \ V(Spread) \ @@ -168,11 +170,13 @@ class AstNode: public ZoneObject { void* operator new(size_t size); int position_; - class NodeTypeField : public BitField {}; + using NodeTypeField = BitField; protected: uint32_t bit_field_; - static const uint8_t kNextBitFieldIndex = NodeTypeField::kNext; + + template + using NextBitField = NodeTypeField::Next; AstNode(int position, NodeType type) : position_(position), bit_field_(NodeTypeField::encode(type)) {} @@ -182,8 +186,6 @@ class AstNode: public ZoneObject { class Statement : public AstNode { protected: Statement(int position, NodeType type) : AstNode(position, type) {} - - static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex; }; @@ -245,6 +247,14 @@ class Expression : public AstNode { // that this also checks for loads of the global "undefined" variable. bool IsUndefinedLiteral() const; + // True if either null literal or undefined literal. + inline bool IsNullOrUndefinedLiteral() const { + return IsNullLiteral() || IsUndefinedLiteral(); + } + + // True if a literal and not null or undefined. + bool IsLiteralButNotNullOrUndefined() const; + bool IsCompileTimeValue(); bool IsPattern() { @@ -265,15 +275,15 @@ class Expression : public AstNode { } private: - class IsParenthesizedField - : public BitField {}; + using IsParenthesizedField = AstNode::NextBitField; protected: Expression(int pos, NodeType type) : AstNode(pos, type) { DCHECK(!is_parenthesized()); } - static const uint8_t kNextBitFieldIndex = IsParenthesizedField::kNext; + template + using NextBitField = IsParenthesizedField::Next; }; class FailureExpression : public Expression { @@ -321,8 +331,7 @@ class BreakableStatement : public Statement { } private: - class BreakableTypeField - : public BitField {}; + using BreakableTypeField = Statement::NextBitField; protected: BreakableStatement(BreakableType breakable_type, int position, NodeType type) @@ -330,7 +339,8 @@ class BreakableStatement : public Statement { bit_field_ |= BreakableTypeField::encode(breakable_type); } - static const uint8_t kNextBitFieldIndex = BreakableTypeField::kNext; + template + using NextBitField = BreakableTypeField::Next; }; class Block : public BreakableStatement { @@ -357,10 +367,8 @@ class Block : public BreakableStatement { ZonePtrList statements_; Scope* scope_; - class IgnoreCompletionField - : public BitField {}; - class IsLabeledField - : public BitField {}; + using IgnoreCompletionField = BreakableStatement::NextBitField; + using IsLabeledField = IgnoreCompletionField::Next; protected: Block(Zone* zone, ZonePtrList* labels, int capacity, @@ -448,8 +456,7 @@ class VariableDeclaration : public Declaration { private: friend class AstNodeFactory; - class IsNestedField - : public BitField {}; + using IsNestedField = Declaration::NextBitField; protected: explicit VariableDeclaration(int pos, bool is_nested = false) @@ -457,7 +464,8 @@ class VariableDeclaration : public Declaration { bit_field_ = IsNestedField::update(bit_field_, is_nested); } - static const uint8_t kNextBitFieldIndex = IsNestedField::kNext; + template + using NextBitField = IsNestedField::Next; }; // For var declarations that appear in a block scope. @@ -524,9 +532,6 @@ class IterationStatement : public BreakableStatement { body_(nullptr) {} void Initialize(Statement* body) { body_ = body; } - static const uint8_t kNextBitFieldIndex = - BreakableStatement::kNextBitFieldIndex; - private: ZonePtrList* labels_; ZonePtrList* own_labels_; @@ -740,8 +745,7 @@ class ReturnStatement final : public JumpStatement { Expression* expression_; int end_position_; - class TypeField - : public BitField {}; + using TypeField = JumpStatement::NextBitField; }; @@ -977,8 +981,7 @@ class SloppyBlockFunctionStatement final : public Statement { private: friend class AstNodeFactory; - class TokenField - : public BitField {}; + using TokenField = Statement::NextBitField; SloppyBlockFunctionStatement(int pos, Variable* var, Token::Value init, Statement* statement) @@ -1079,7 +1082,7 @@ class Literal final : public Expression { private: friend class AstNodeFactory; - class TypeField : public BitField {}; + using TypeField = Expression::NextBitField; Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) { bit_field_ = TypeField::update(bit_field_, kSmi); @@ -1210,10 +1213,9 @@ class AggregateLiteral : public MaterializedLiteral { private: int depth_ : 31; - class NeedsInitialAllocationSiteField - : public BitField {}; - class IsSimpleField - : public BitField {}; + using NeedsInitialAllocationSiteField = + MaterializedLiteral::NextBitField; + using IsSimpleField = NeedsInitialAllocationSiteField::Next; protected: friend class AstNodeFactory; @@ -1236,7 +1238,8 @@ class AggregateLiteral : public MaterializedLiteral { bit_field_ = NeedsInitialAllocationSiteField::update(bit_field_, required); } - static const uint8_t kNextBitFieldIndex = IsSimpleField::kNext; + template + using NextBitField = IsSimpleField::Next; }; // Common supertype for ObjectLiteralProperty and ClassLiteralProperty @@ -1375,12 +1378,6 @@ class ObjectLiteral final : public AggregateLiteral { static_cast(AggregateLiteral::kNeedsInitialAllocationSite) < static_cast(kFastElements)); - struct Accessors: public ZoneObject { - Accessors() : getter(nullptr), setter(nullptr) {} - ObjectLiteralProperty* getter; - ObjectLiteralProperty* setter; - }; - private: friend class AstNodeFactory; @@ -1408,19 +1405,14 @@ class ObjectLiteral final : public AggregateLiteral { void set_has_null_protoype(bool has_null_prototype) { bit_field_ = HasNullPrototypeField::update(bit_field_, has_null_prototype); } - uint32_t boilerplate_properties_; Handle boilerplate_description_; ZoneList properties_; - class HasElementsField - : public BitField {}; - class HasRestPropertyField - : public BitField {}; - class FastElementsField - : public BitField {}; - class HasNullPrototypeField - : public BitField {}; + using HasElementsField = AggregateLiteral::NextBitField; + using HasRestPropertyField = HasElementsField::Next; + using FastElementsField = HasRestPropertyField::Next; + using HasNullPrototypeField = FastElementsField::Next; }; // An array literal has a literals object that is used @@ -1512,6 +1504,9 @@ class VariableProxy final : public Expression { var()->SetMaybeAssigned(); } } + void clear_is_assigned() { + bit_field_ = IsAssignedField::update(bit_field_, false); + } bool is_resolved() const { return IsResolvedField::decode(bit_field_); } void set_is_resolved() { @@ -1586,15 +1581,11 @@ class VariableProxy final : public Expression { explicit VariableProxy(const VariableProxy* copy_from); - class IsAssignedField - : public BitField {}; - class IsResolvedField : public BitField {}; - class IsRemovedFromUnresolvedField - : public BitField {}; - class IsNewTargetField - : public BitField {}; - class HoleCheckModeField - : public BitField {}; + using IsAssignedField = Expression::NextBitField; + using IsResolvedField = IsAssignedField::Next; + using IsRemovedFromUnresolvedField = IsResolvedField::Next; + using IsNewTargetField = IsRemovedFromUnresolvedField::Next; + using HoleCheckModeField = IsNewTargetField::Next; union { const AstRawString* raw_name_; // if !is_resolved_ @@ -1607,20 +1598,41 @@ class VariableProxy final : public Expression { friend base::ThreadedListTraits; }; +// Wraps an optional chain to provide a wrapper for jump labels. +class OptionalChain final : public Expression { + public: + Expression* expression() const { return expression_; } + + private: + friend class AstNodeFactory; + + explicit OptionalChain(Expression* expression) + : Expression(0, kOptionalChain), expression_(expression) {} + + Expression* expression_; +}; + // Assignments to a property will use one of several types of property access. // Otherwise, the assignment is to a non-property (a global, a local slot, a // parameter slot, or a destructuring pattern). enum AssignType { - NON_PROPERTY, // destructuring - NAMED_PROPERTY, // obj.key - KEYED_PROPERTY, // obj[key] - NAMED_SUPER_PROPERTY, // super.key - KEYED_SUPER_PROPERTY, // super[key] - PRIVATE_METHOD // obj.#key: #key is a private method + NON_PROPERTY, // destructuring + NAMED_PROPERTY, // obj.key + KEYED_PROPERTY, // obj[key] + NAMED_SUPER_PROPERTY, // super.key + KEYED_SUPER_PROPERTY, // super[key] + PRIVATE_METHOD, // obj.#key: #key is a private method + PRIVATE_GETTER_ONLY, // obj.#key: #key only has a getter defined + PRIVATE_SETTER_ONLY, // obj.#key: #key only has a setter defined + PRIVATE_GETTER_AND_SETTER // obj.#key: #key has both accessors defined }; class Property final : public Expression { public: + bool is_optional_chain_link() const { + return IsOptionalChainLinkField::decode(bit_field_); + } + bool IsValidReferenceExpression() const { return true; } Expression* obj() const { return obj_; } @@ -1637,8 +1649,21 @@ class Property final : public Expression { VariableProxy* proxy = property->key()->AsVariableProxy(); DCHECK_NOT_NULL(proxy); Variable* var = proxy->var(); - // Use KEYED_PROPERTY for private fields. - return var->requires_brand_check() ? PRIVATE_METHOD : KEYED_PROPERTY; + + switch (var->mode()) { + case VariableMode::kPrivateMethod: + return PRIVATE_METHOD; + case VariableMode::kConst: + return KEYED_PROPERTY; // Use KEYED_PROPERTY for private fields. + case VariableMode::kPrivateGetterOnly: + return PRIVATE_GETTER_ONLY; + case VariableMode::kPrivateSetterOnly: + return PRIVATE_SETTER_ONLY; + case VariableMode::kPrivateGetterAndSetter: + return PRIVATE_GETTER_AND_SETTER; + default: + UNREACHABLE(); + } } bool super_access = property->IsSuperAccess(); return (property->key()->IsPropertyName()) @@ -1649,10 +1674,13 @@ class Property final : public Expression { private: friend class AstNodeFactory; - Property(Expression* obj, Expression* key, int pos) + Property(Expression* obj, Expression* key, int pos, bool optional_chain) : Expression(pos, kProperty), obj_(obj), key_(key) { + bit_field_ |= IsOptionalChainLinkField::encode(optional_chain); } + using IsOptionalChainLinkField = Expression::NextBitField; + Expression* obj_; Expression* key_; }; @@ -1690,6 +1718,10 @@ class Call final : public Expression { return IsTaggedTemplateField::decode(bit_field_); } + bool is_optional_chain_link() const { + return IsOptionalChainLinkField::decode(bit_field_); + } + bool only_last_arg_is_spread() { return !arguments_.is_empty() && arguments_.last()->IsSpread(); } @@ -1722,13 +1754,14 @@ class Call final : public Expression { Call(Zone* zone, Expression* expression, const ScopedPtrList& arguments, int pos, - PossiblyEval possibly_eval) + PossiblyEval possibly_eval, bool optional_chain) : Expression(pos, kCall), expression_(expression), arguments_(0, nullptr) { bit_field_ |= IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) | - IsTaggedTemplateField::encode(false); + IsTaggedTemplateField::encode(false) | + IsOptionalChainLinkField::encode(optional_chain); arguments.CopyTo(&arguments_, zone); } @@ -1739,14 +1772,14 @@ class Call final : public Expression { expression_(expression), arguments_(0, nullptr) { bit_field_ |= IsPossiblyEvalField::encode(false) | - IsTaggedTemplateField::encode(true); + IsTaggedTemplateField::encode(true) | + IsOptionalChainLinkField::encode(false); arguments.CopyTo(&arguments_, zone); } - class IsPossiblyEvalField - : public BitField {}; - class IsTaggedTemplateField - : public BitField {}; + using IsPossiblyEvalField = Expression::NextBitField; + using IsTaggedTemplateField = IsPossiblyEvalField::Next; + using IsOptionalChainLinkField = IsTaggedTemplateField::Next; Expression* expression_; ZonePtrList arguments_; @@ -1838,8 +1871,7 @@ class UnaryOperation final : public Expression { Expression* expression_; - class OperatorField - : public BitField {}; + using OperatorField = Expression::NextBitField; }; @@ -1865,8 +1897,7 @@ class BinaryOperation final : public Expression { Expression* left_; Expression* right_; - class OperatorField - : public BitField {}; + using OperatorField = Expression::NextBitField; }; class NaryOperation final : public Expression { @@ -1925,8 +1956,7 @@ class NaryOperation final : public Expression { }; ZoneVector subsequent_; - class OperatorField - : public BitField {}; + using OperatorField = Expression::NextBitField; }; class CountOperation final : public Expression { @@ -1946,9 +1976,8 @@ class CountOperation final : public Expression { bit_field_ |= IsPrefixField::encode(is_prefix) | TokenField::encode(op); } - class IsPrefixField - : public BitField {}; - class TokenField : public BitField {}; + using IsPrefixField = Expression::NextBitField; + using TokenField = IsPrefixField::Next; Expression* expression_; }; @@ -1978,8 +2007,7 @@ class CompareOperation final : public Expression { Expression* left_; Expression* right_; - class OperatorField - : public BitField {}; + using OperatorField = Expression::NextBitField; }; @@ -2071,10 +2099,8 @@ class Assignment : public Expression { private: friend class AstNodeFactory; - class TokenField - : public BitField {}; - class LookupHoistingModeField : public BitField { - }; + using TokenField = Expression::NextBitField; + using LookupHoistingModeField = TokenField::Next; Expression* target_; Expression* value_; @@ -2132,8 +2158,7 @@ class Suspend : public Expression { Expression* expression_; - class OnAbruptResumeField - : public BitField {}; + using OnAbruptResumeField = Expression::NextBitField; }; class Yield final : public Suspend { @@ -2175,14 +2200,6 @@ class Throw final : public Expression { class FunctionLiteral final : public Expression { public: - enum FunctionType { - kAnonymousExpression, - kNamedExpression, - kDeclaration, - kAccessorOrMethod, - kWrapped, - }; - enum ParameterFlag : uint8_t { kNoDuplicateParameters, kHasDuplicateParameters @@ -2204,12 +2221,8 @@ class FunctionLiteral final : public Expression { int function_token_position() const { return function_token_position_; } int start_position() const; int end_position() const; - bool is_declaration() const { return function_type() == kDeclaration; } - bool is_named_expression() const { - return function_type() == kNamedExpression; - } bool is_anonymous_expression() const { - return function_type() == kAnonymousExpression; + return syntax_kind() == FunctionSyntaxKind::kAnonymousExpression; } void mark_as_oneshot_iife() { @@ -2219,7 +2232,6 @@ class FunctionLiteral final : public Expression { bool is_toplevel() const { return function_literal_id() == kFunctionLiteralIdTopLevel; } - bool is_wrapped() const { return function_type() == kWrapped; } V8_EXPORT_PRIVATE LanguageMode language_mode() const; static bool NeedsHomeObject(Expression* expr); @@ -2289,8 +2301,8 @@ class FunctionLiteral final : public Expression { V8_EXPORT_PRIVATE bool ShouldEagerCompile() const; V8_EXPORT_PRIVATE void SetShouldEagerCompile(); - FunctionType function_type() const { - return FunctionTypeBits::decode(bit_field_); + FunctionSyntaxKind syntax_kind() const { + return FunctionSyntaxKindBits::decode(bit_field_); } FunctionKind kind() const; @@ -2342,7 +2354,7 @@ class FunctionLiteral final : public Expression { AstValueFactory* ast_value_factory, DeclarationScope* scope, const ScopedPtrList& body, int expected_property_count, int parameter_count, - int function_length, FunctionType function_type, + int function_length, FunctionSyntaxKind function_syntax_kind, ParameterFlag has_duplicate_parameters, EagerCompileHint eager_compile_hint, int position, bool has_braces, int function_literal_id, @@ -2359,28 +2371,28 @@ class FunctionLiteral final : public Expression { body_(0, nullptr), raw_inferred_name_(ast_value_factory->empty_cons_string()), produced_preparse_data_(produced_preparse_data) { - bit_field_ |= - FunctionTypeBits::encode(function_type) | Pretenure::encode(false) | - HasDuplicateParameters::encode(has_duplicate_parameters == - kHasDuplicateParameters) | - DontOptimizeReasonField::encode(BailoutReason::kNoReason) | - RequiresInstanceMembersInitializer::encode(false) | - HasBracesField::encode(has_braces) | OneshotIIFEBit::encode(false); + bit_field_ |= FunctionSyntaxKindBits::encode(function_syntax_kind) | + Pretenure::encode(false) | + HasDuplicateParameters::encode(has_duplicate_parameters == + kHasDuplicateParameters) | + DontOptimizeReasonField::encode(BailoutReason::kNoReason) | + RequiresInstanceMembersInitializer::encode(false) | + HasBracesField::encode(has_braces) | + OneshotIIFEBit::encode(false); if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile(); body.CopyTo(&body_, zone); } - class FunctionTypeBits - : public BitField {}; - class Pretenure : public BitField {}; - class HasDuplicateParameters : public BitField {}; - class DontOptimizeReasonField - : public BitField {}; - class RequiresInstanceMembersInitializer - : public BitField {}; - class HasBracesField - : public BitField {}; - class OneshotIIFEBit : public BitField {}; + using FunctionSyntaxKindBits = + Expression::NextBitField; + using Pretenure = FunctionSyntaxKindBits::Next; + using HasDuplicateParameters = Pretenure::Next; + using DontOptimizeReasonField = + HasDuplicateParameters::Next; + using RequiresInstanceMembersInitializer = + DontOptimizeReasonField::Next; + using HasBracesField = RequiresInstanceMembersInitializer::Next; + using OneshotIIFEBit = HasBracesField::Next; // expected_property_count_ is the sum of instance fields and properties. // It can vary depending on whether a function is lazily or eagerly parsed. @@ -2432,6 +2444,11 @@ class ClassLiteralProperty final : public LiteralProperty { return private_or_computed_name_var_; } + bool NeedsHomeObjectOnClassPrototype() const { + return is_private() && kind_ == METHOD && + FunctionLiteral::NeedsHomeObject(value_); + } + private: friend class AstNodeFactory; @@ -2525,12 +2542,9 @@ class ClassLiteral final : public Expression { ZonePtrList* properties_; FunctionLiteral* static_fields_initializer_; FunctionLiteral* instance_members_initializer_function_; - class HasNameStaticProperty - : public BitField {}; - class HasStaticComputedNames - : public BitField {}; - class IsAnonymousExpression - : public BitField {}; + using HasNameStaticProperty = Expression::NextBitField; + using HasStaticComputedNames = HasNameStaticProperty::Next; + using IsAnonymousExpression = HasStaticComputedNames::Next; }; @@ -3046,8 +3060,13 @@ class AstNodeFactory final { return new (zone_) Variable(variable); } - Property* NewProperty(Expression* obj, Expression* key, int pos) { - return new (zone_) Property(obj, key, pos); + OptionalChain* NewOptionalChain(Expression* expression) { + return new (zone_) OptionalChain(expression); + } + + Property* NewProperty(Expression* obj, Expression* key, int pos, + bool optional_chain = false) { + return new (zone_) Property(obj, key, pos, optional_chain); } ResolvedProperty* NewResolvedProperty(VariableProxy* obj, @@ -3058,8 +3077,10 @@ class AstNodeFactory final { Call* NewCall(Expression* expression, const ScopedPtrList& arguments, int pos, - Call::PossiblyEval possibly_eval = Call::NOT_EVAL) { - return new (zone_) Call(zone_, expression, arguments, pos, possibly_eval); + Call::PossiblyEval possibly_eval = Call::NOT_EVAL, + bool optional_chain = false) { + return new (zone_) + Call(zone_, expression, arguments, pos, possibly_eval, optional_chain); } Call* NewTaggedTemplate(Expression* expression, @@ -3189,13 +3210,13 @@ class AstNodeFactory final { const ScopedPtrList& body, int expected_property_count, int parameter_count, int function_length, FunctionLiteral::ParameterFlag has_duplicate_parameters, - FunctionLiteral::FunctionType function_type, + FunctionSyntaxKind function_syntax_kind, FunctionLiteral::EagerCompileHint eager_compile_hint, int position, bool has_braces, int function_literal_id, ProducedPreparseData* produced_preparse_data = nullptr) { return new (zone_) FunctionLiteral( zone_, name, ast_value_factory_, scope, body, expected_property_count, - parameter_count, function_length, function_type, + parameter_count, function_length, function_syntax_kind, has_duplicate_parameters, eager_compile_hint, position, has_braces, function_literal_id, produced_preparse_data); } @@ -3209,7 +3230,7 @@ class AstNodeFactory final { return new (zone_) FunctionLiteral( zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope, body, expected_property_count, parameter_count, parameter_count, - FunctionLiteral::kAnonymousExpression, + FunctionSyntaxKind::kAnonymousExpression, FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kShouldLazyCompile, 0, /* has_braces */ false, kFunctionLiteralIdTopLevel); diff --git a/deps/v8/src/ast/modules.cc b/deps/v8/src/ast/modules.cc index 261b72c352a55d..dbd20f50a80869 100644 --- a/deps/v8/src/ast/modules.cc +++ b/deps/v8/src/ast/modules.cc @@ -84,10 +84,11 @@ void SourceTextModuleDescriptor::AddStarExport( } namespace { -Handle ToStringOrUndefined(Isolate* isolate, const AstRawString* s) { +Handle ToStringOrUndefined(Isolate* isolate, + const AstRawString* s) { return (s == nullptr) - ? Handle::cast(isolate->factory()->undefined_value()) - : Handle::cast(s->string()); + ? Handle::cast(isolate->factory()->undefined_value()) + : Handle::cast(s->string()); } } // namespace diff --git a/deps/v8/src/ast/prettyprinter.cc b/deps/v8/src/ast/prettyprinter.cc index c0fe3baff398bc..581517ee4ec34a 100644 --- a/deps/v8/src/ast/prettyprinter.cc +++ b/deps/v8/src/ast/prettyprinter.cc @@ -27,6 +27,8 @@ CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js) is_call_error_ = false; is_iterator_error_ = false; is_async_iterator_error_ = false; + destructuring_prop_ = nullptr; + destructuring_assignment_ = nullptr; is_user_js_ = is_user_js; function_kind_ = kNormalFunction; InitializeAstVisitor(isolate); @@ -299,24 +301,50 @@ void CallPrinter::VisitVariableProxy(VariableProxy* node) { void CallPrinter::VisitAssignment(Assignment* node) { - Find(node->target()); - if (node->target()->IsArrayLiteral()) { - // Special case the visit for destructuring array assignment. - bool was_found = false; - if (node->value()->position() == position_) { - is_iterator_error_ = true; + bool was_found = false; + if (node->target()->IsObjectLiteral()) { + ObjectLiteral* target = node->target()->AsObjectLiteral(); + if (target->position() == position_) { was_found = !found_; - if (was_found) { - found_ = true; + found_ = true; + destructuring_assignment_ = node; + } else { + for (ObjectLiteralProperty* prop : *target->properties()) { + if (prop->value()->position() == position_) { + was_found = !found_; + found_ = true; + destructuring_prop_ = prop; + destructuring_assignment_ = node; + break; + } } } - Find(node->value(), true); - if (was_found) { - done_ = true; - found_ = false; + } + if (!was_found) { + Find(node->target()); + if (node->target()->IsArrayLiteral()) { + // Special case the visit for destructuring array assignment. + bool was_found = false; + if (node->value()->position() == position_) { + is_iterator_error_ = true; + was_found = !found_; + found_ = true; + } + Find(node->value(), true); + if (was_found) { + done_ = true; + found_ = false; + } + } else { + Find(node->value()); } } else { - Find(node->value()); + Find(node->value(), true); + } + + if (was_found) { + done_ = true; + found_ = false; } } @@ -342,6 +370,9 @@ void CallPrinter::VisitAwait(Await* node) { Find(node->expression()); } void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); } +void CallPrinter::VisitOptionalChain(OptionalChain* node) { + Find(node->expression()); +} void CallPrinter::VisitProperty(Property* node) { Expression* key = node->key(); @@ -349,12 +380,18 @@ void CallPrinter::VisitProperty(Property* node) { if (literal != nullptr && literal->BuildValue(isolate_)->IsInternalizedString()) { Find(node->obj(), true); + if (node->is_optional_chain_link()) { + Print("?"); + } Print("."); // TODO(adamk): Teach Literal how to print its values without // allocating on the heap. PrintLiteral(literal->BuildValue(isolate_), false); } else { Find(node->obj(), true); + if (node->is_optional_chain_link()) { + Print("?."); + } Print("["); Find(key, true); Print("]"); @@ -1272,6 +1309,11 @@ void AstPrinter::VisitThrow(Throw* node) { Visit(node->exception()); } +void AstPrinter::VisitOptionalChain(OptionalChain* node) { + IndentedScope indent(this, "OPTIONAL_CHAIN", node->position()); + Visit(node->expression()); +} + void AstPrinter::VisitProperty(Property* node) { EmbeddedVector buf; SNPrintF(buf, "PROPERTY"); @@ -1289,6 +1331,18 @@ void AstPrinter::VisitProperty(Property* node) { PrintIndentedVisit("PRIVATE_METHOD", node->key()); break; } + case PRIVATE_GETTER_ONLY: { + PrintIndentedVisit("PRIVATE_GETTER_ONLY", node->key()); + break; + } + case PRIVATE_SETTER_ONLY: { + PrintIndentedVisit("PRIVATE_SETTER_ONLY", node->key()); + break; + } + case PRIVATE_GETTER_AND_SETTER: { + PrintIndentedVisit("PRIVATE_GETTER_AND_SETTER", node->key()); + break; + } case KEYED_PROPERTY: case KEYED_SUPER_PROPERTY: { PrintIndentedVisit("KEY", node->key()); diff --git a/deps/v8/src/ast/prettyprinter.h b/deps/v8/src/ast/prettyprinter.h index cceb5fc269b5ef..322fd9fb1437bf 100644 --- a/deps/v8/src/ast/prettyprinter.h +++ b/deps/v8/src/ast/prettyprinter.h @@ -31,6 +31,12 @@ class CallPrinter final : public AstVisitor { kCallAndAsyncIterator }; ErrorHint GetErrorHint() const; + ObjectLiteralProperty* destructuring_prop() const { + return destructuring_prop_; + } + Assignment* destructuring_assignment() const { + return destructuring_assignment_; + } // Individual nodes #define DECLARE_VISIT(type) void Visit##type(type* node); @@ -54,6 +60,8 @@ class CallPrinter final : public AstVisitor { bool is_iterator_error_; bool is_async_iterator_error_; bool is_call_error_; + ObjectLiteralProperty* destructuring_prop_; + Assignment* destructuring_assignment_; FunctionKind function_kind_; DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc index 237d98ec6047f2..c8002dd088c9c7 100644 --- a/deps/v8/src/ast/scopes.cc +++ b/deps/v8/src/ast/scopes.cc @@ -40,7 +40,6 @@ Variable* VariableMap::Declare(Zone* zone, Scope* scope, VariableKind kind, InitializationFlag initialization_flag, MaybeAssignedFlag maybe_assigned_flag, - RequiresBrandCheckFlag requires_brand_check, bool* was_added) { // AstRawStrings are unambiguous, i.e., the same string is always represented // by the same AstRawString*. @@ -52,9 +51,8 @@ Variable* VariableMap::Declare(Zone* zone, Scope* scope, if (*was_added) { // The variable has not been declared yet -> insert it. DCHECK_EQ(name, p->key); - Variable* variable = - new (zone) Variable(scope, name, mode, kind, initialization_flag, - maybe_assigned_flag, requires_brand_check); + Variable* variable = new (zone) Variable( + scope, name, mode, kind, initialization_flag, maybe_assigned_flag); p->value = variable; } return reinterpret_cast(p->value); @@ -170,7 +168,6 @@ Scope::Scope(Zone* zone, ScopeType scope_type, Handle scope_info) #ifdef DEBUG already_resolved_ = true; #endif - if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true; set_language_mode(scope_info->language_mode()); num_heap_slots_ = scope_info->ContextLength(); DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); @@ -186,6 +183,10 @@ DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type, params_(0, zone) { DCHECK_NE(scope_type, SCRIPT_SCOPE); SetDefaults(); + if (scope_info->SloppyEvalCanExtendVars()) { + DCHECK(!is_eval_scope()); + sloppy_eval_can_extend_vars_ = true; + } } Scope::Scope(Zone* zone, const AstRawString* catch_variable_name, @@ -258,7 +259,8 @@ void Scope::SetDefaults() { set_language_mode(LanguageMode::kSloppy); - scope_calls_eval_ = false; + calls_eval_ = false; + sloppy_eval_can_extend_vars_ = false; scope_nonlinear_ = false; is_hidden_ = false; is_debug_evaluate_scope_ = false; @@ -380,11 +382,8 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, if (deserialization_mode == DeserializationMode::kIncludingVariables && script_scope->scope_info_.is_null()) { - Handle table( - isolate->native_context()->script_context_table(), isolate); - Handle first = ScriptContextTable::GetContext(isolate, table, 0); - Handle scope_info(first->scope_info(), isolate); - script_scope->SetScriptScopeInfo(scope_info); + script_scope->SetScriptScopeInfo( + ReadOnlyRoots(isolate).global_this_binding_scope_info_handle()); } if (innermost_scope == nullptr) return script_scope; @@ -626,7 +625,7 @@ Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name, : NORMAL_VARIABLE; function_ = new (zone()) Variable(this, name, VariableMode::kConst, kind, kCreatedInitialized); - if (calls_sloppy_eval()) { + if (sloppy_eval_can_extend_vars()) { cache->NonLocal(name, VariableMode::kDynamic); } else { cache->variables_.Add(zone(), function_); @@ -652,7 +651,8 @@ Scope* Scope::FinalizeBlockScope() { #endif if (variables_.occupancy() > 0 || - (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) { + (is_declaration_scope() && + AsDeclarationScope()->sloppy_eval_can_extend_vars())) { return this; } @@ -682,10 +682,10 @@ Scope* Scope::FinalizeBlockScope() { if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true; - // No need to propagate scope_calls_eval_, since if it was relevant to - // this scope we would have had to bail out at the top. - DCHECK(!scope_calls_eval_ || !is_declaration_scope() || - !is_sloppy(language_mode())); + // No need to propagate sloppy_eval_can_extend_vars_, since if it was relevant + // to this scope we would have had to bail out at the top. + DCHECK(!is_declaration_scope() || + !AsDeclarationScope()->sloppy_eval_can_extend_vars()); // This block does not need a context. num_heap_slots_ = 0; @@ -750,8 +750,8 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) { outer_closure->locals_.Rewind(top_local_); // Move eval calls since Snapshot's creation into new_parent. - if (outer_scope_and_calls_eval_->scope_calls_eval_) { - new_parent->scope_calls_eval_ = true; + if (outer_scope_and_calls_eval_->calls_eval_) { + new_parent->RecordDeclarationScopeEvalCall(); new_parent->inner_scope_calls_eval_ = true; } @@ -787,13 +787,11 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) { VariableMode mode; InitializationFlag init_flag; MaybeAssignedFlag maybe_assigned_flag; - RequiresBrandCheckFlag requires_brand_check = kNoBrandCheck; { location = VariableLocation::CONTEXT; index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode, - &init_flag, &maybe_assigned_flag, - &requires_brand_check); + &init_flag, &maybe_assigned_flag); found = index >= 0; } @@ -818,9 +816,9 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) { } bool was_added; - Variable* var = cache->variables_.Declare( - zone(), this, name, mode, NORMAL_VARIABLE, init_flag, maybe_assigned_flag, - requires_brand_check, &was_added); + Variable* var = + cache->variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE, + init_flag, maybe_assigned_flag, &was_added); DCHECK(was_added); var->AllocateTo(location, index); return var; @@ -873,6 +871,8 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, VariableKind kind, bool* was_added, InitializationFlag init_flag) { 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 @@ -905,6 +905,8 @@ Variable* Scope::DeclareVariable( VariableMode mode, VariableKind kind, InitializationFlag init, bool* was_added, bool* sloppy_mode_block_scope_function_redefinition, bool* ok) { + // Private methods should be declared with ClassScope::DeclarePrivateName() + DCHECK(!IsPrivateMethodOrAccessorVariableMode(mode)); DCHECK(IsDeclaredVariableMode(mode)); DCHECK(!already_resolved_); DCHECK(!GetDeclarationScope()->is_being_lazily_parsed()); @@ -990,7 +992,8 @@ Variable* Scope::DeclareVariableName(const AstRawString* name, DCHECK(IsDeclaredVariableMode(mode)); DCHECK(!already_resolved_); DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); - + // Private methods should be declared with ClassScope::DeclarePrivateName() + DCHECK(!IsPrivateMethodOrAccessorVariableMode(mode)); if (mode == VariableMode::kVar && !is_declaration_scope()) { return GetDeclarationScope()->DeclareVariableName(name, mode, was_added, kind); @@ -1044,7 +1047,7 @@ Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, bool was_added; return cache->variables_.Declare( zone(), this, name, VariableMode::kDynamicGlobal, kind, - kCreatedInitialized, kNotAssigned, kNoBrandCheck, &was_added); + kCreatedInitialized, kNotAssigned, &was_added); // TODO(neis): Mark variable as maybe-assigned? } @@ -1243,7 +1246,7 @@ int Scope::ContextChainLengthUntilOutermostSloppyEval() const { if (!s->NeedsContext()) continue; length++; if (s->is_declaration_scope() && - s->AsDeclarationScope()->calls_sloppy_eval()) { + s->AsDeclarationScope()->sloppy_eval_can_extend_vars()) { result = length; } } @@ -1384,14 +1387,16 @@ void Scope::CollectNonLocals(DeclarationScope* max_outer_scope, void Scope::AnalyzePartially(DeclarationScope* max_outer_scope, AstNodeFactory* ast_node_factory, - UnresolvedList* new_unresolved_list) { - this->ForEach([max_outer_scope, ast_node_factory, - new_unresolved_list](Scope* scope) { + UnresolvedList* new_unresolved_list, + bool maybe_in_arrowhead) { + this->ForEach([max_outer_scope, ast_node_factory, new_unresolved_list, + maybe_in_arrowhead](Scope* scope) { DCHECK_IMPLIES(scope->is_declaration_scope(), !scope->AsDeclarationScope()->was_lazily_parsed()); for (VariableProxy* proxy = scope->unresolved_list_.first(); proxy != nullptr; proxy = proxy->next_unresolved()) { + if (proxy->is_removed_from_unresolved()) continue; DCHECK(!proxy->is_resolved()); Variable* var = Lookup(proxy, scope, max_outer_scope->outer_scope()); @@ -1399,7 +1404,8 @@ void Scope::AnalyzePartially(DeclarationScope* max_outer_scope, // Don't copy unresolved references to the script scope, unless it's a // reference to a private name or method. In that case keep it so we // can fail later. - if (!max_outer_scope->outer_scope()->is_script_scope()) { + if (!max_outer_scope->outer_scope()->is_script_scope() || + maybe_in_arrowhead) { VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); new_unresolved_list->Add(copy); } @@ -1434,6 +1440,7 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, sloppy_block_functions_.Clear(); rare_data_ = nullptr; has_rest_ = false; + function_ = nullptr; DCHECK_NE(zone_, ast_value_factory->zone()); zone_->ReleaseMemory(); @@ -1487,17 +1494,19 @@ void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) { } void DeclarationScope::AnalyzePartially(Parser* parser, - AstNodeFactory* ast_node_factory) { + AstNodeFactory* ast_node_factory, + bool maybe_in_arrowhead) { DCHECK(!force_eager_compilation_); UnresolvedList new_unresolved_list; if (!IsArrowFunction(function_kind_) && - (!outer_scope_->is_script_scope() || + (!outer_scope_->is_script_scope() || maybe_in_arrowhead || (preparse_data_builder_ != nullptr && preparse_data_builder_->HasInnerFunctions()))) { // Try to resolve unresolved variables for this Scope and migrate those // which cannot be resolved inside. It doesn't make sense to try to resolve // them in the outer Scopes here, because they are incomplete. - Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list); + Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list, + maybe_in_arrowhead); // Migrate function_ to the right Zone. if (function_ != nullptr) { @@ -1596,10 +1605,6 @@ void PrintVar(int indent, Variable* var) { if (comma) PrintF(", "); PrintF("hole initialization elided"); } - if (var->requires_brand_check()) { - if (comma) PrintF(", "); - PrintF("requires brand check"); - } PrintF("\n"); } @@ -1676,7 +1681,8 @@ void Scope::Print(int n) { Indent(n1, "// strict mode scope\n"); } if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); - if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) { + if (is_declaration_scope() && + AsDeclarationScope()->sloppy_eval_can_extend_vars()) { Indent(n1, "// scope calls sloppy 'eval'\n"); } if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) { @@ -1774,9 +1780,9 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { // Declare a new non-local. DCHECK(IsDynamicVariableMode(mode)); bool was_added; - Variable* var = variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE, - kCreatedInitialized, kNotAssigned, - kNoBrandCheck, &was_added); + Variable* var = + variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE, + kCreatedInitialized, kNotAssigned, &was_added); // Allocate it by giving it a dynamic lookup. var->AllocateTo(VariableLocation::LOOKUP, -1); return var; @@ -1814,7 +1820,18 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope, // We found a variable and we are done. (Even if there is an 'eval' in this // scope which introduces the same variable again, the resulting variable // remains the same.) - if (var != nullptr) { + // + // For sloppy eval though, we skip dynamic variable to avoid resolving to a + // variable when the variable and proxy are in the same eval execution. The + // variable is not available on subsequent lazy executions of functions in + // the eval, so this avoids inner functions from looking up different + // variables during eager and lazy compilation. + // + // TODO(leszeks): Maybe we want to restrict this to e.g. lookups of a proxy + // living in a different scope to the current one, or some other + // optimisation. + if (var != nullptr && + !(scope->is_eval_scope() && var->mode() == VariableMode::kDynamic)) { if (mode == kParsedScope && force_context_allocation && !var->is_dynamic()) { var->ForceContextAllocation(); @@ -1829,8 +1846,9 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope, return LookupWith(proxy, scope, outer_scope_end, entry_point, force_context_allocation); } - if (V8_UNLIKELY(scope->is_declaration_scope() && - scope->AsDeclarationScope()->calls_sloppy_eval())) { + if (V8_UNLIKELY( + scope->is_declaration_scope() && + scope->AsDeclarationScope()->sloppy_eval_can_extend_vars())) { return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point, force_context_allocation); } @@ -1901,7 +1919,7 @@ Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope, Scope* outer_scope_end, Scope* entry_point, bool force_context_allocation) { DCHECK(scope->is_declaration_scope() && - scope->AsDeclarationScope()->calls_sloppy_eval()); + scope->AsDeclarationScope()->sloppy_eval_can_extend_vars()); // If we're compiling eval, it's possible that the outer scope is the first // ScopeInfo-backed scope. @@ -2065,7 +2083,7 @@ bool Scope::MustAllocate(Variable* var) { if (!var->raw_name()->IsEmpty() && (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) { var->set_is_used(); - if (inner_scope_calls_eval_) var->SetMaybeAssigned(); + if (inner_scope_calls_eval_ && !var->is_this()) var->SetMaybeAssigned(); } DCHECK(!var->has_forced_context_allocation() || var->is_used()); // Global variables do not need to be allocated. @@ -2081,11 +2099,14 @@ bool Scope::MustAllocateInContext(Variable* var) { // // Temporary variables are always stack-allocated. Catch-bound variables are // always context-allocated. - if (var->mode() == VariableMode::kTemporary) return false; + VariableMode mode = var->mode(); + if (mode == VariableMode::kTemporary) return false; if (is_catch_scope()) return true; - if ((is_script_scope() || is_eval_scope()) && - IsLexicalVariableMode(var->mode())) { - return true; + if (is_script_scope() || is_eval_scope()) { + if (IsLexicalVariableMode(mode) || + IsPrivateMethodOrAccessorVariableMode(mode)) { + return true; + } } return var->has_forced_context_allocation() || inner_scope_calls_eval_; } @@ -2248,9 +2269,9 @@ void Scope::AllocateVariablesRecursively() { scope->is_with_scope() || scope->is_module_scope() || scope->IsAsmModule() || scope->ForceContextForLanguageMode() || (scope->is_function_scope() && - scope->AsDeclarationScope()->calls_sloppy_eval()) || + scope->AsDeclarationScope()->sloppy_eval_can_extend_vars()) || (scope->is_block_scope() && scope->is_declaration_scope() && - scope->AsDeclarationScope()->calls_sloppy_eval()); + scope->AsDeclarationScope()->sloppy_eval_can_extend_vars()); // If we didn't allocate any locals in the local context, then we only // need the minimal number of slots if we must have a context. @@ -2326,15 +2347,28 @@ int Scope::ContextLocalCount() const { (is_function_var_in_context ? 1 : 0); } -Variable* ClassScope::DeclarePrivateName( - const AstRawString* name, RequiresBrandCheckFlag requires_brand_check, - bool* was_added) { +bool IsComplementaryAccessorPair(VariableMode a, VariableMode b) { + switch (a) { + case VariableMode::kPrivateGetterOnly: + return b == VariableMode::kPrivateSetterOnly; + case VariableMode::kPrivateSetterOnly: + return b == VariableMode::kPrivateGetterOnly; + default: + return false; + } +} + +Variable* ClassScope::DeclarePrivateName(const AstRawString* name, + VariableMode mode, bool* was_added) { Variable* result = EnsureRareData()->private_name_map.Declare( - zone(), this, name, VariableMode::kConst, NORMAL_VARIABLE, + zone(), this, name, mode, NORMAL_VARIABLE, InitializationFlag::kNeedsInitialization, - MaybeAssignedFlag::kMaybeAssigned, requires_brand_check, was_added); + MaybeAssignedFlag::kMaybeAssigned, was_added); if (*was_added) { locals_.Add(result); + } else if (IsComplementaryAccessorPair(result->mode(), mode)) { + *was_added = true; + result->set_mode(VariableMode::kPrivateGetterAndSetter); } result->ForceContextAllocation(); return result; @@ -2416,22 +2450,20 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) { VariableMode mode; InitializationFlag init_flag; MaybeAssignedFlag maybe_assigned_flag; - RequiresBrandCheckFlag requires_brand_check; - int index = - ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode, &init_flag, - &maybe_assigned_flag, &requires_brand_check); + int index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode, + &init_flag, &maybe_assigned_flag); if (index < 0) { return nullptr; } - DCHECK_EQ(mode, VariableMode::kConst); + DCHECK(IsConstVariableMode(mode)); DCHECK_EQ(init_flag, InitializationFlag::kNeedsInitialization); DCHECK_EQ(maybe_assigned_flag, MaybeAssignedFlag::kMaybeAssigned); // Add the found private name to the map to speed up subsequent // lookups for the same name. bool was_added; - Variable* var = DeclarePrivateName(name, requires_brand_check, &was_added); + Variable* var = DeclarePrivateName(name, mode, &was_added); DCHECK(was_added); var->AllocateTo(VariableLocation::CONTEXT, index); return var; @@ -2450,7 +2482,9 @@ Variable* ClassScope::LookupPrivateName(VariableProxy* proxy) { if (var == nullptr && !class_scope->scope_info_.is_null()) { var = class_scope->LookupPrivateNameInScopeInfo(proxy->raw_name()); } - return var; + if (var != nullptr) { + return var; + } } return nullptr; } diff --git a/deps/v8/src/ast/scopes.h b/deps/v8/src/ast/scopes.h index 932d5c70b937b8..73e6e8fd89755f 100644 --- a/deps/v8/src/ast/scopes.h +++ b/deps/v8/src/ast/scopes.h @@ -5,6 +5,7 @@ #ifndef V8_AST_SCOPES_H_ #define V8_AST_SCOPES_H_ +#include #include "src/ast/ast.h" #include "src/base/compiler-specific.h" #include "src/base/hashmap.h" @@ -13,6 +14,7 @@ #include "src/objects/function-kind.h" #include "src/objects/objects.h" #include "src/utils/pointer-with-payload.h" +#include "src/utils/utils.h" #include "src/zone/zone.h" namespace v8 { @@ -42,7 +44,6 @@ class VariableMap : public ZoneHashMap { VariableMode mode, VariableKind kind, InitializationFlag initialization_flag, MaybeAssignedFlag maybe_assigned_flag, - RequiresBrandCheckFlag requires_brand_check, bool* was_added); V8_EXPORT_PRIVATE Variable* Lookup(const AstRawString* name); @@ -111,8 +112,10 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { } void RestoreEvalFlag() { - outer_scope_and_calls_eval_->scope_calls_eval_ = - outer_scope_and_calls_eval_.GetPayload(); + if (outer_scope_and_calls_eval_.GetPayload()) { + // This recreates both calls_eval and sloppy_eval_can_extend_vars. + outer_scope_and_calls_eval_.GetPointer()->RecordEvalCall(); + } } void Reparent(DeclarationScope* new_parent); @@ -265,9 +268,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // Inform the scope and outer scopes that the corresponding code contains an // eval call. - void RecordEvalCall() { - scope_calls_eval_ = true; - } + inline void RecordEvalCall(); void RecordInnerScopeEvalCall() { inner_scope_calls_eval_ = true; @@ -460,7 +461,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { int ContextChainLength(Scope* scope) const; // The number of contexts between this and the outermost context that has a - // sloppy eval call. One if this->calls_sloppy_eval(). + // sloppy eval call. One if this->sloppy_eval_can_extend_vars(). int ContextChainLengthUntilOutermostSloppyEval() const; // Find the closest class scope in the current scope and outer scopes. If no @@ -558,7 +559,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { MaybeAssignedFlag maybe_assigned_flag, bool* was_added) { Variable* result = variables_.Declare(zone, this, name, mode, kind, initialization_flag, - maybe_assigned_flag, kNoBrandCheck, was_added); + maybe_assigned_flag, was_added); if (*was_added) locals_.Add(result); return result; } @@ -610,7 +611,8 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // list along the way, so full resolution cannot be done afterwards. void AnalyzePartially(DeclarationScope* max_outer_scope, AstNodeFactory* ast_node_factory, - UnresolvedList* new_unresolved_list); + UnresolvedList* new_unresolved_list, + bool maybe_in_arrowhead); void CollectNonLocals(DeclarationScope* max_outer_scope, Isolate* isolate, ParseInfo* info, Handle* non_locals); @@ -703,9 +705,11 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // The language mode of this scope. STATIC_ASSERT(LanguageModeSize == 2); bool is_strict_ : 1; - // This scope or a nested catch scope or with scope contain an 'eval' call. At - // the 'eval' call site this scope is the declaration scope. - bool scope_calls_eval_ : 1; + // This scope contains an 'eval' call. + bool calls_eval_ : 1; + // The context associated with this scope can be extended by a sloppy eval + // called inside of it. + bool sloppy_eval_can_extend_vars_ : 1; // This scope's declarations might not be executed in order (e.g., switch). bool scope_nonlinear_ : 1; bool is_hidden_ : 1; @@ -753,11 +757,50 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { IsClassConstructor(function_kind()))); } - bool calls_sloppy_eval() const { - // TODO(delphick): Calculate this when setting and change the name of - // scope_calls_eval_. - return !is_script_scope() && scope_calls_eval_ && - is_sloppy(language_mode()); + // Inform the scope and outer scopes that the corresponding code contains an + // eval call. + void RecordDeclarationScopeEvalCall() { + calls_eval_ = true; + + // If this isn't a sloppy eval, we don't care about it. + if (language_mode() != LanguageMode::kSloppy) return; + + // Sloppy eval in script scopes can only introduce global variables anyway, + // so we don't care that it calls sloppy eval. + if (is_script_scope()) return; + + // Sloppy eval in a eval scope can only introduce variables into the outer + // (non-eval) declaration scope, not into this eval scope. + if (is_eval_scope()) { +#ifdef DEBUG + // One of three things must be true: + // 1. The outer non-eval declaration scope should already be marked as + // being extendable by sloppy eval, by the current sloppy eval rather + // than the inner one, + // 2. The outer non-eval declaration scope is a script scope and thus + // isn't extendable anyway, or + // 3. This is a debug evaluate and all bets are off. + DeclarationScope* outer_decl_scope = outer_scope()->GetDeclarationScope(); + while (outer_decl_scope->is_eval_scope()) { + outer_decl_scope = outer_decl_scope->GetDeclarationScope(); + } + if (outer_decl_scope->is_debug_evaluate_scope()) { + // Don't check anything. + // TODO(9662): Figure out where variables declared by an eval inside a + // debug-evaluate actually go. + } else if (!outer_decl_scope->is_script_scope()) { + DCHECK(outer_decl_scope->sloppy_eval_can_extend_vars_); + } +#endif + + return; + } + + sloppy_eval_can_extend_vars_ = true; + } + + bool sloppy_eval_can_extend_vars() const { + return sloppy_eval_can_extend_vars_; } bool was_lazily_parsed() const { return was_lazily_parsed_; } @@ -972,7 +1015,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { // this records variables which cannot be resolved inside the Scope (we don't // yet know what they will resolve to since the outer Scopes are incomplete) // and recreates them with the correct Zone with ast_node_factory. - void AnalyzePartially(Parser* parser, AstNodeFactory* ast_node_factory); + void AnalyzePartially(Parser* parser, AstNodeFactory* ast_node_factory, + bool maybe_in_arrowhead); // Allocate ScopeInfos for top scope and any inner scopes that need them. // Does nothing if ScopeInfo is already allocated. @@ -1138,13 +1182,21 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { RareData* rare_data_ = nullptr; }; +void Scope::RecordEvalCall() { + calls_eval_ = true; + GetDeclarationScope()->RecordDeclarationScopeEvalCall(); + RecordInnerScopeEvalCall(); +} + Scope::Snapshot::Snapshot(Scope* scope) - : outer_scope_and_calls_eval_(scope, scope->scope_calls_eval_), + : outer_scope_and_calls_eval_(scope, scope->calls_eval_), top_inner_scope_(scope->inner_scope_), top_unresolved_(scope->unresolved_list_.end()), top_local_(scope->GetClosureScope()->locals_.end()) { // Reset in order to record eval calls during this Snapshot's lifetime. - outer_scope_and_calls_eval_.GetPointer()->scope_calls_eval_ = false; + outer_scope_and_calls_eval_.GetPointer()->calls_eval_ = false; + outer_scope_and_calls_eval_.GetPointer()->sloppy_eval_can_extend_vars_ = + false; } class ModuleScope final : public DeclarationScope { @@ -1175,8 +1227,7 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope { // Declare a private name in the private name map and add it to the // local variables of this scope. - Variable* DeclarePrivateName(const AstRawString* name, - RequiresBrandCheckFlag requires_brand_check, + Variable* DeclarePrivateName(const AstRawString* name, VariableMode mode, bool* was_added); void AddUnresolvedPrivateName(VariableProxy* proxy); diff --git a/deps/v8/src/ast/source-range-ast-visitor.cc b/deps/v8/src/ast/source-range-ast-visitor.cc index 2fcf151999ace0..d171e30587584f 100644 --- a/deps/v8/src/ast/source-range-ast-visitor.cc +++ b/deps/v8/src/ast/source-range-ast-visitor.cc @@ -25,14 +25,6 @@ void SourceRangeAstVisitor::VisitBlock(Block* stmt) { } } -void SourceRangeAstVisitor::VisitSwitchStatement(SwitchStatement* stmt) { - AstTraversalVisitor::VisitSwitchStatement(stmt); - ZonePtrList* clauses = stmt->cases(); - for (CaseClause* clause : *clauses) { - MaybeRemoveLastContinuationRange(clause->statements()); - } -} - void SourceRangeAstVisitor::VisitFunctionLiteral(FunctionLiteral* expr) { AstTraversalVisitor::VisitFunctionLiteral(expr); ZonePtrList* stmts = expr->body(); diff --git a/deps/v8/src/ast/source-range-ast-visitor.h b/deps/v8/src/ast/source-range-ast-visitor.h index 4ba5feb2d299f9..4ea36a947f58e6 100644 --- a/deps/v8/src/ast/source-range-ast-visitor.h +++ b/deps/v8/src/ast/source-range-ast-visitor.h @@ -34,7 +34,6 @@ class SourceRangeAstVisitor final friend class AstTraversalVisitor; void VisitBlock(Block* stmt); - void VisitSwitchStatement(SwitchStatement* stmt); void VisitFunctionLiteral(FunctionLiteral* expr); bool VisitNode(AstNode* node); diff --git a/deps/v8/src/ast/variables.h b/deps/v8/src/ast/variables.h index 7805fa20c8c8f6..1ff6f9f4228375 100644 --- a/deps/v8/src/ast/variables.h +++ b/deps/v8/src/ast/variables.h @@ -21,8 +21,7 @@ class Variable final : public ZoneObject { public: Variable(Scope* scope, const AstRawString* name, VariableMode mode, VariableKind kind, InitializationFlag initialization_flag, - MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, - RequiresBrandCheckFlag requires_brand_check = kNoBrandCheck) + MaybeAssignedFlag maybe_assigned_flag = kNotAssigned) : scope_(scope), name_(name), local_if_not_shadowed_(nullptr), @@ -32,7 +31,6 @@ class Variable final : public ZoneObject { bit_field_(MaybeAssignedFlagField::encode(maybe_assigned_flag) | InitializationFlagField::encode(initialization_flag) | VariableModeField::encode(mode) | - RequiresBrandCheckField::encode(requires_brand_check) | IsUsedField::encode(false) | ForceContextAllocationField::encode(false) | ForceHoleInitializationField::encode(false) | @@ -58,6 +56,9 @@ class Variable final : public ZoneObject { Handle name() const { return name_->string(); } const AstRawString* raw_name() const { return name_; } VariableMode mode() const { return VariableModeField::decode(bit_field_); } + void set_mode(VariableMode mode) { + bit_field_ = VariableModeField::update(bit_field_, mode); + } bool has_forced_context_allocation() const { return ForceContextAllocationField::decode(bit_field_); } @@ -72,6 +73,8 @@ class Variable final : public ZoneObject { return MaybeAssignedFlagField::decode(bit_field_); } void SetMaybeAssigned() { + if (mode() == VariableMode::kConst) return; + // If this variable is dynamically shadowing another variable, then that // variable could also be assigned (in the non-shadowing case). if (has_local_if_not_shadowed()) { @@ -80,22 +83,14 @@ class Variable final : public ZoneObject { if (!maybe_assigned()) { local_if_not_shadowed()->SetMaybeAssigned(); } - DCHECK(local_if_not_shadowed()->maybe_assigned()); + DCHECK_IMPLIES(local_if_not_shadowed()->mode() != VariableMode::kConst, + local_if_not_shadowed()->maybe_assigned()); } set_maybe_assigned(); } - RequiresBrandCheckFlag get_requires_brand_check_flag() const { - return RequiresBrandCheckField::decode(bit_field_); - } - bool requires_brand_check() const { - return get_requires_brand_check_flag() == kRequiresBrandCheck; - } - - void set_requires_brand_check() { - bit_field_ = - RequiresBrandCheckField::update(bit_field_, kRequiresBrandCheck); + return IsPrivateMethodOrAccessorVariableMode(mode()); } int initializer_position() { return initializer_position_; } @@ -125,7 +120,8 @@ class Variable final : public ZoneObject { // declaration time. Only returns valid results after scope analysis. bool binding_needs_init() const { DCHECK_IMPLIES(initialization_flag() == kNeedsInitialization, - IsLexicalVariableMode(mode())); + IsLexicalVariableMode(mode()) || + IsPrivateMethodOrAccessorVariableMode(mode())); DCHECK_IMPLIES(ForceHoleInitializationField::decode(bit_field_), initialization_flag() == kNeedsInitialization); @@ -149,7 +145,8 @@ class Variable final : public ZoneObject { // be required at runtime. void ForceHoleInitialization() { DCHECK_EQ(kNeedsInitialization, initialization_flag()); - DCHECK(IsLexicalVariableMode(mode())); + DCHECK(IsLexicalVariableMode(mode()) || + IsPrivateMethodOrAccessorVariableMode(mode())); bit_field_ = ForceHoleInitializationField::update(bit_field_, true); } @@ -243,25 +240,16 @@ class Variable final : public ZoneObject { bit_field_ = MaybeAssignedFlagField::update(bit_field_, kMaybeAssigned); } - class VariableModeField : public BitField16 {}; - class VariableKindField - : public BitField16 {}; - class LocationField - : public BitField16 {}; - class ForceContextAllocationField - : public BitField16 {}; - class IsUsedField - : public BitField16 {}; - class InitializationFlagField - : public BitField16 {}; - class ForceHoleInitializationField - : public BitField16 {}; - class MaybeAssignedFlagField - : public BitField16 {}; - class RequiresBrandCheckField - : public BitField16 {}; + using VariableModeField = BitField16; + using VariableKindField = VariableModeField::Next; + using LocationField = VariableKindField::Next; + using ForceContextAllocationField = LocationField::Next; + using IsUsedField = ForceContextAllocationField::Next; + using InitializationFlagField = IsUsedField::Next; + using ForceHoleInitializationField = InitializationFlagField::Next; + using MaybeAssignedFlagField = + ForceHoleInitializationField::Next; + Variable** next() { return &next_; } friend List; friend base::ThreadedListTraits; diff --git a/deps/v8/src/base/address-region.h b/deps/v8/src/base/address-region.h index 1fdc479f6f3e93..0f4809f9e81574 100644 --- a/deps/v8/src/base/address-region.h +++ b/deps/v8/src/base/address-region.h @@ -45,6 +45,13 @@ class AddressRegion { return contains(region.address_, region.size_); } + base::AddressRegion GetOverlap(AddressRegion region) const { + Address overlap_start = std::max(begin(), region.begin()); + Address overlap_end = + std::max(overlap_start, std::min(end(), region.end())); + return {overlap_start, overlap_end - overlap_start}; + } + bool operator==(AddressRegion other) const { return address_ == other.address_ && size_ == other.size_; } diff --git a/deps/v8/src/base/flags.h b/deps/v8/src/base/flags.h index 055f0ff498484f..c2b7952260a5b5 100644 --- a/deps/v8/src/base/flags.h +++ b/deps/v8/src/base/flags.h @@ -53,13 +53,13 @@ class Flags final { } constexpr Flags operator&(const Flags& flags) const { - return Flags(*this) &= flags; + return Flags(mask_ & flags.mask_); } constexpr Flags operator|(const Flags& flags) const { - return Flags(*this) |= flags; + return Flags(mask_ | flags.mask_); } constexpr Flags operator^(const Flags& flags) const { - return Flags(*this) ^= flags; + return Flags(mask_ ^ flags.mask_); } Flags& operator&=(flag_type flag) { return operator&=(Flags(flag)); } diff --git a/deps/v8/src/base/page-allocator.cc b/deps/v8/src/base/page-allocator.cc index b339f528d2b9d3..76a0aff39953a4 100644 --- a/deps/v8/src/base/page-allocator.cc +++ b/deps/v8/src/base/page-allocator.cc @@ -36,9 +36,9 @@ void* PageAllocator::GetRandomMmapAddr() { return base::OS::GetRandomMmapAddr(); } -void* PageAllocator::AllocatePages(void* address, size_t size, size_t alignment, +void* PageAllocator::AllocatePages(void* hint, size_t size, size_t alignment, PageAllocator::Permission access) { - return base::OS::Allocate(address, size, alignment, + return base::OS::Allocate(hint, size, alignment, static_cast(access)); } diff --git a/deps/v8/src/base/page-allocator.h b/deps/v8/src/base/page-allocator.h index ced1156ccaee38..2b8ee1a5e5e740 100644 --- a/deps/v8/src/base/page-allocator.h +++ b/deps/v8/src/base/page-allocator.h @@ -26,7 +26,7 @@ class V8_BASE_EXPORT PageAllocator void* GetRandomMmapAddr() override; - void* AllocatePages(void* address, size_t size, size_t alignment, + void* AllocatePages(void* hint, size_t size, size_t alignment, PageAllocator::Permission access) override; bool FreePages(void* address, size_t size) override; diff --git a/deps/v8/src/base/platform/mutex.h b/deps/v8/src/base/platform/mutex.h index 2b8b55eeb5f247..c48cf8d3393c12 100644 --- a/deps/v8/src/base/platform/mutex.h +++ b/deps/v8/src/base/platform/mutex.h @@ -67,6 +67,8 @@ class V8_BASE_EXPORT Mutex final { return native_handle_; } + V8_INLINE void AssertHeld() { DCHECK_EQ(1, level_); } + private: NativeHandle native_handle_; #ifdef DEBUG diff --git a/deps/v8/src/base/platform/platform-cygwin.cc b/deps/v8/src/base/platform/platform-cygwin.cc index 17f9aa3f17e5cb..92a5fbe490f4c3 100644 --- a/deps/v8/src/base/platform/platform-cygwin.cc +++ b/deps/v8/src/base/platform/platform-cygwin.cc @@ -95,13 +95,13 @@ double LocalTimeOffset(double time_ms, bool is_utc) { } // static -void* OS::Allocate(void* address, size_t size, size_t alignment, +void* OS::Allocate(void* hint, size_t size, size_t alignment, MemoryPermission access) { size_t page_size = AllocatePageSize(); DCHECK_EQ(0, size % page_size); DCHECK_EQ(0, alignment % page_size); DCHECK_LE(page_size, alignment); - address = AlignedAddress(address, alignment); + hint = AlignedAddress(hint, alignment); DWORD flags = (access == OS::MemoryPermission::kNoAccess) ? MEM_RESERVE @@ -109,7 +109,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, DWORD protect = GetProtectionFromMemoryPermission(access); // First, try an exact size aligned allocation. - uint8_t* base = RandomizedVirtualAlloc(size, flags, protect, address); + uint8_t* base = RandomizedVirtualAlloc(size, flags, protect, hint); if (base == nullptr) return nullptr; // Can't allocate, we're OOM. // If address is suitably aligned, we're done. @@ -120,7 +120,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, CHECK(Free(base, size)); // Clear the hint. It's unlikely we can allocate at this address. - address = nullptr; + hint = nullptr; // Add the maximum misalignment so we are guaranteed an aligned base address // in the allocated region. @@ -128,7 +128,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, const int kMaxAttempts = 3; aligned_base = nullptr; for (int i = 0; i < kMaxAttempts; ++i) { - base = RandomizedVirtualAlloc(padded_size, flags, protect, address); + base = RandomizedVirtualAlloc(padded_size, flags, protect, hint); if (base == nullptr) return nullptr; // Can't allocate, we're OOM. // Try to trim the allocation by freeing the padded allocation and then diff --git a/deps/v8/src/base/platform/platform-posix.cc b/deps/v8/src/base/platform/platform-posix.cc index 6da83d7e0208a3..c50cdd7a98eefd 100644 --- a/deps/v8/src/base/platform/platform-posix.cc +++ b/deps/v8/src/base/platform/platform-posix.cc @@ -137,10 +137,10 @@ int GetFlagsForMemoryPermission(OS::MemoryPermission access) { return flags; } -void* Allocate(void* address, size_t size, OS::MemoryPermission access) { +void* Allocate(void* hint, size_t size, OS::MemoryPermission access) { int prot = GetProtectionFromMemoryPermission(access); int flags = GetFlagsForMemoryPermission(access); - void* result = mmap(address, size, prot, flags, kMmapFd, kMmapFdOffset); + void* result = mmap(hint, size, prot, flags, kMmapFd, kMmapFdOffset); if (result == MAP_FAILED) return nullptr; return result; } @@ -278,16 +278,16 @@ void* OS::GetRandomMmapAddr() { // TODO(bbudge) Move Cygwin and Fuchsia stuff into platform-specific files. #if !V8_OS_CYGWIN && !V8_OS_FUCHSIA // static -void* OS::Allocate(void* address, size_t size, size_t alignment, +void* OS::Allocate(void* hint, size_t size, size_t alignment, MemoryPermission access) { size_t page_size = AllocatePageSize(); DCHECK_EQ(0, size % page_size); DCHECK_EQ(0, alignment % page_size); - address = AlignedAddress(address, alignment); + hint = AlignedAddress(hint, alignment); // Add the maximum misalignment so we are guaranteed an aligned base address. size_t request_size = size + (alignment - page_size); request_size = RoundUp(request_size, OS::AllocatePageSize()); - void* result = base::Allocate(address, request_size, access); + void* result = base::Allocate(hint, request_size, access); if (result == nullptr) return nullptr; // Unmap memory allocated before the aligned base address. @@ -761,13 +761,12 @@ void Thread::set_name(const char* name) { name_[sizeof(name_) - 1] = '\0'; } - -void Thread::Start() { +bool Thread::Start() { int result; pthread_attr_t attr; memset(&attr, 0, sizeof(attr)); result = pthread_attr_init(&attr); - DCHECK_EQ(0, result); + if (result != 0) return false; size_t stack_size = stack_size_; if (stack_size == 0) { #if V8_OS_MACOSX @@ -780,17 +779,17 @@ void Thread::Start() { } if (stack_size > 0) { result = pthread_attr_setstacksize(&attr, stack_size); - DCHECK_EQ(0, result); + if (result != 0) return pthread_attr_destroy(&attr), false; } { MutexGuard lock_guard(&data_->thread_creation_mutex_); result = pthread_create(&data_->thread_, &attr, ThreadEntry, this); + if (result != 0 || data_->thread_ == kNoThread) { + return pthread_attr_destroy(&attr), false; + } } - DCHECK_EQ(0, result); result = pthread_attr_destroy(&attr); - DCHECK_EQ(0, result); - DCHECK_NE(data_->thread_, kNoThread); - USE(result); + return result == 0; } void Thread::Join() { pthread_join(data_->thread_, nullptr); } diff --git a/deps/v8/src/base/platform/platform-win32.cc b/deps/v8/src/base/platform/platform-win32.cc index d01b1c07fe1926..04ef8a30f229bd 100644 --- a/deps/v8/src/base/platform/platform-win32.cc +++ b/deps/v8/src/base/platform/platform-win32.cc @@ -798,13 +798,13 @@ uint8_t* RandomizedVirtualAlloc(size_t size, DWORD flags, DWORD protect, } // namespace // static -void* OS::Allocate(void* address, size_t size, size_t alignment, +void* OS::Allocate(void* hint, size_t size, size_t alignment, MemoryPermission access) { size_t page_size = AllocatePageSize(); DCHECK_EQ(0, size % page_size); DCHECK_EQ(0, alignment % page_size); DCHECK_LE(page_size, alignment); - address = AlignedAddress(address, alignment); + hint = AlignedAddress(hint, alignment); DWORD flags = (access == OS::MemoryPermission::kNoAccess) ? MEM_RESERVE @@ -812,7 +812,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, DWORD protect = GetProtectionFromMemoryPermission(access); // First, try an exact size aligned allocation. - uint8_t* base = RandomizedVirtualAlloc(size, flags, protect, address); + uint8_t* base = RandomizedVirtualAlloc(size, flags, protect, hint); if (base == nullptr) return nullptr; // Can't allocate, we're OOM. // If address is suitably aligned, we're done. @@ -824,7 +824,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, CHECK(Free(base, size)); // Clear the hint. It's unlikely we can allocate at this address. - address = nullptr; + hint = nullptr; // Add the maximum misalignment so we are guaranteed an aligned base address // in the allocated region. @@ -832,7 +832,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, const int kMaxAttempts = 3; aligned_base = nullptr; for (int i = 0; i < kMaxAttempts; ++i) { - base = RandomizedVirtualAlloc(padded_size, flags, protect, address); + base = RandomizedVirtualAlloc(padded_size, flags, protect, hint); if (base == nullptr) return nullptr; // Can't allocate, we're OOM. // Try to trim the allocation by freeing the padded allocation and then @@ -1352,13 +1352,13 @@ Thread::~Thread() { // Create a new thread. It is important to use _beginthreadex() instead of // the Win32 function CreateThread(), because the CreateThread() does not // initialize thread specific structures in the C runtime library. -void Thread::Start() { - data_->thread_ = reinterpret_cast( - _beginthreadex(nullptr, static_cast(stack_size_), ThreadEntry, - this, 0, &data_->thread_id_)); +bool Thread::Start() { + uintptr_t result = _beginthreadex(nullptr, static_cast(stack_size_), + ThreadEntry, this, 0, &data_->thread_id_); + data_->thread_ = reinterpret_cast(result); + return result != 0; } - // Wait for thread to terminate. void Thread::Join() { if (data_->thread_id_ != GetCurrentThreadId()) { diff --git a/deps/v8/src/base/platform/platform.h b/deps/v8/src/base/platform/platform.h index e073704b2c1ace..e1f84043eb8a73 100644 --- a/deps/v8/src/base/platform/platform.h +++ b/deps/v8/src/base/platform/platform.h @@ -333,15 +333,16 @@ class V8_BASE_EXPORT Thread { virtual ~Thread(); // Start new thread by calling the Run() method on the new thread. - void Start(); + V8_WARN_UNUSED_RESULT bool Start(); // Start new thread and wait until Run() method is called on the new thread. - void StartSynchronously() { + bool StartSynchronously() { start_semaphore_ = new Semaphore(0); - Start(); + if (!Start()) return false; start_semaphore_->Wait(); delete start_semaphore_; start_semaphore_ = nullptr; + return true; } // Wait until thread terminates. diff --git a/deps/v8/src/base/utils/random-number-generator.cc b/deps/v8/src/base/utils/random-number-generator.cc index 3b38858192970e..17c2cced8a452b 100644 --- a/deps/v8/src/base/utils/random-number-generator.cc +++ b/deps/v8/src/base/utils/random-number-generator.cc @@ -51,6 +51,13 @@ RandomNumberGenerator::RandomNumberGenerator() { result = rand_s(&second_half); DCHECK_EQ(0, result); SetSeed((static_cast(first_half) << 32) + second_half); +#elif V8_OS_MACOSX + // Despite its prefix suggests it is not RC4 algorithm anymore. + // It always succeeds while having decent performance and + // no file descriptor involved. + int64_t seed; + arc4random_buf(&seed, sizeof(seed)); + SetSeed(seed); #else // Gather entropy from /dev/urandom if available. FILE* fp = fopen("/dev/urandom", "rb"); diff --git a/deps/v8/src/builtins/OWNERS b/deps/v8/src/builtins/OWNERS index 450423f87850ba..f52e1c9ca8effc 100644 --- a/deps/v8/src/builtins/OWNERS +++ b/deps/v8/src/builtins/OWNERS @@ -1,3 +1,3 @@ -file://COMMON_OWNERS +file:../../COMMON_OWNERS # COMPONENT: Blink>JavaScript>Runtime diff --git a/deps/v8/src/builtins/arguments.tq b/deps/v8/src/builtins/arguments.tq index 6df5f801a3945a..18d6c23b3d9a38 100644 --- a/deps/v8/src/builtins/arguments.tq +++ b/deps/v8/src/builtins/arguments.tq @@ -8,7 +8,7 @@ struct Arguments { const length: intptr; } -extern operator '[]' macro GetArgumentValue(Arguments, intptr): Object; +extern operator '[]' macro GetArgumentValue(Arguments, intptr): JSAny; extern macro GetFrameArguments(FrameWithArguments, intptr): Arguments; diff --git a/deps/v8/src/builtins/arm/builtins-arm.cc b/deps/v8/src/builtins/arm/builtins-arm.cc index 9b9956b0fbba0a..e9b562620fcee5 100644 --- a/deps/v8/src/builtins/arm/builtins-arm.cc +++ b/deps/v8/src/builtins/arm/builtins-arm.cc @@ -90,12 +90,24 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm, namespace { +void LoadRealStackLimit(MacroAssembler* masm, Register destination) { + DCHECK(masm->root_array_available()); + Isolate* isolate = masm->isolate(); + ExternalReference limit = ExternalReference::address_of_real_jslimit(isolate); + DCHECK(TurboAssembler::IsAddressableThroughRootRegister(isolate, limit)); + + intptr_t offset = + TurboAssembler::RootRegisterOffsetForExternalReference(isolate, limit); + CHECK(is_int32(offset)); + __ ldr(destination, MemOperand(kRootRegister, offset)); +} + void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, Register scratch, Label* stack_overflow) { // Check the stack for overflow. We are not trying to catch // interruptions (e.g. debug break and preemption) here, so the "real stack // limit" is checked. - __ LoadRoot(scratch, RootIndex::kRealStackLimit); + LoadRealStackLimit(masm, scratch); // Make scratch the space we have left. The stack might already be overflowed // here which will cause scratch to become negative. __ sub(scratch, sp, scratch); @@ -428,7 +440,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { // Check the stack for overflow. We are not trying to catch interruptions // (i.e. debug break and preemption) here, so check the "real stack limit". Label stack_overflow; - __ CompareRoot(sp, RootIndex::kRealStackLimit); + LoadRealStackLimit(masm, scratch); + __ cmp(sp, scratch); __ b(lo, &stack_overflow); // Push receiver. @@ -1116,7 +1129,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Do a stack check to ensure we don't go over the limit. Label ok; __ sub(r9, sp, Operand(r4)); - __ LoadRoot(r2, RootIndex::kRealStackLimit); + LoadRealStackLimit(masm, r2); __ cmp(r9, Operand(r2)); __ b(hs, &ok); __ CallRuntime(Runtime::kThrowStackOverflow); @@ -2089,7 +2102,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { // Compute the space we have left. The stack might already be overflowed // here which will cause remaining_stack_size to become negative. - __ LoadRoot(remaining_stack_size, RootIndex::kRealStackLimit); + LoadRealStackLimit(masm, remaining_stack_size); __ sub(remaining_stack_size, sp, remaining_stack_size); // Check if the arguments will overflow the stack. @@ -2517,7 +2530,10 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) { __ push(kWasmCompileLazyFuncIndexRegister); // Load the correct CEntry builtin from the instance object. __ ldr(r2, FieldMemOperand(kWasmInstanceRegister, - WasmInstanceObject::kCEntryStubOffset)); + WasmInstanceObject::kIsolateRootOffset)); + auto centry_id = + Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit; + __ ldr(r2, MemOperand(r2, IsolateData::builtin_slot_offset(centry_id))); // Initialize the JavaScript context with 0. CEntry will use it to // set the current context on the isolate. __ Move(cp, Smi::zero()); diff --git a/deps/v8/src/builtins/arm64/builtins-arm64.cc b/deps/v8/src/builtins/arm64/builtins-arm64.cc index bcee8f0b5dcbbe..4e159a69b7ede8 100644 --- a/deps/v8/src/builtins/arm64/builtins-arm64.cc +++ b/deps/v8/src/builtins/arm64/builtins-arm64.cc @@ -24,6 +24,10 @@ #include "src/runtime/runtime.h" #include "src/wasm/wasm-objects.h" +#if defined(V8_OS_WIN) +#include "src/diagnostics/unwinding-info-win64.h" +#endif // V8_OS_WIN + namespace v8 { namespace internal { @@ -85,6 +89,17 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm, namespace { +void LoadRealStackLimit(MacroAssembler* masm, Register destination) { + DCHECK(masm->root_array_available()); + Isolate* isolate = masm->isolate(); + ExternalReference limit = ExternalReference::address_of_real_jslimit(isolate); + DCHECK(TurboAssembler::IsAddressableThroughRootRegister(isolate, limit)); + + intptr_t offset = + TurboAssembler::RootRegisterOffsetForExternalReference(isolate, limit); + __ Ldr(destination, MemOperand(kRootRegister, offset)); +} + void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, Label* stack_overflow) { UseScratchRegisterScope temps(masm); @@ -94,7 +109,7 @@ void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, // We are not trying to catch interruptions (e.g. debug break and // preemption) here, so the "real stack limit" is checked. - __ LoadRoot(scratch, RootIndex::kRealStackLimit); + LoadRealStackLimit(masm, scratch); // Make scratch the space we have left. The stack might already be overflowed // here which will cause scratch to become negative. __ Sub(scratch, sp, scratch); @@ -476,7 +491,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { // Check the stack for overflow. We are not trying to catch interruptions // (i.e. debug break and preemption) here, so check the "real stack limit". Label stack_overflow; - __ CompareRoot(sp, RootIndex::kRealStackLimit); + LoadRealStackLimit(masm, x10); + __ Cmp(sp, x10); __ B(lo, &stack_overflow); // Get number of arguments for generator function. @@ -623,6 +639,23 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, // will have no effect on the model or real hardware. __ EnableInstrumentation(); +#if defined(V8_OS_WIN) + // Windows ARM64 relies on a frame pointer (fp/x29 which are aliases to each + // other) chain to do stack unwinding, but JSEntry breaks that by setting fp + // to point to bad_frame_pointer below. To fix unwind information for this + // case, JSEntry registers the offset (from current fp to the caller's fp + // saved by PushCalleeSavedRegisters on stack) to xdata_encoder which then + // emits the offset value as part of result unwind data accordingly. The + // current offset is kFramePointerOffset which includes bad_frame_pointer + // saved below plus kFramePointerOffsetInPushCalleeSavedRegisters. + const int kFramePointerOffset = + kFramePointerOffsetInPushCalleeSavedRegisters + kSystemPointerSize; + win64_unwindinfo::XdataEncoder* xdata_encoder = masm->GetXdataEncoder(); + if (xdata_encoder) { + xdata_encoder->onFramePointerAdjustment(kFramePointerOffset); + } +#endif + __ PushCalleeSavedRegisters(); // Set up the reserved register for 0.0. @@ -1223,7 +1256,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Do a stack check to ensure we don't go over the limit. Label ok; __ Sub(x10, sp, Operand(x11)); - __ CompareRoot(x10, RootIndex::kRealStackLimit); + { + UseScratchRegisterScope temps(masm); + Register scratch = temps.AcquireX(); + LoadRealStackLimit(masm, scratch); + __ Cmp(x10, scratch); + } __ B(hs, &ok); __ CallRuntime(Runtime::kThrowStackOverflow); __ Bind(&ok); @@ -2469,7 +2507,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { // (i.e. debug break and preemption) here, so check the "real stack // limit". Label done; - __ LoadRoot(x10, RootIndex::kRealStackLimit); + LoadRealStackLimit(masm, x10); // Make x10 the space we have left. The stack might already be overflowed // here which will cause x10 to become negative. __ Sub(x10, sp, x10); @@ -3031,9 +3069,12 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) { // function. __ Push(kWasmInstanceRegister, kWasmCompileLazyFuncIndexRegister); // Load the correct CEntry builtin from the instance object. + __ Ldr(x2, FieldMemOperand(kWasmInstanceRegister, + WasmInstanceObject::kIsolateRootOffset)); + auto centry_id = + Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit; __ LoadTaggedPointerField( - x2, FieldMemOperand(kWasmInstanceRegister, - WasmInstanceObject::kCEntryStubOffset)); + x2, MemOperand(x2, IsolateData::builtin_slot_offset(centry_id))); // Initialize the JavaScript context with 0. CEntry will use it to // set the current context on the isolate. __ Mov(cp, Smi::zero()); diff --git a/deps/v8/src/builtins/array-copywithin.tq b/deps/v8/src/builtins/array-copywithin.tq index 94d871e8f74c13..574eaf9b9de4cc 100644 --- a/deps/v8/src/builtins/array-copywithin.tq +++ b/deps/v8/src/builtins/array-copywithin.tq @@ -9,7 +9,7 @@ namespace array_copywithin { // https://tc39.github.io/ecma262/#sec-array.prototype.copyWithin transitioning javascript builtin ArrayPrototypeCopyWithin( - js-implicit context: Context, receiver: Object)(...arguments): Object { + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); @@ -68,7 +68,7 @@ namespace array_copywithin { // d. If fromPresent is true, then. if (fromPresent == True) { // i. Let fromVal be ? Get(O, fromKey). - const fromVal: Object = GetProperty(object, from); + const fromVal: JSAny = GetProperty(object, from); // ii. Perform ? Set(O, toKey, fromVal, true). SetProperty(object, to, fromVal); diff --git a/deps/v8/src/builtins/array-every.tq b/deps/v8/src/builtins/array-every.tq index 3451cd769b92e7..8f4c0e1f231dca 100644 --- a/deps/v8/src/builtins/array-every.tq +++ b/deps/v8/src/builtins/array-every.tq @@ -5,15 +5,14 @@ namespace array { transitioning javascript builtin ArrayEveryLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, - length: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -27,9 +26,9 @@ namespace array { transitioning javascript builtin ArrayEveryLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, length: Object, - result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny, + result: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -53,9 +52,9 @@ namespace array { } transitioning builtin ArrayEveryLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, - _array: Object, o: JSReceiver, initialK: Number, length: Number, - _initialTo: Object): Object { + _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, + _array: JSAny, o: JSReceiver, initialK: Number, length: Number, + _initialTo: JSAny): JSAny { // 5. Let k be 0. // 6. Repeat, while k < len for (let k: Number = initialK; k < length; k++) { @@ -69,10 +68,10 @@ namespace array { // 6c. If kPresent is true, then if (kPresent == True) { // 6c. i. Let kValue be ? Get(O, Pk). - const kValue: Object = GetProperty(o, k); + const kValue: JSAny = GetProperty(o, k); // 6c. ii. Perform ? Call(callbackfn, T, ). - const result: Object = Call(context, callbackfn, thisArg, kValue, k, o); + const result: JSAny = Call(context, callbackfn, thisArg, kValue, k, o); // iii. If selected is true, then... if (!ToBoolean(result)) { @@ -86,7 +85,7 @@ namespace array { } transitioning macro FastArrayEvery(implicit context: Context)( - o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object + o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): JSAny labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast(len) otherwise goto Bailout(k); @@ -99,8 +98,8 @@ namespace array { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k); - const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; - const result: Object = + const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue; + const result: JSAny = Call(context, callbackfn, thisArg, value, k, fastOW.Get()); if (!ToBoolean(result)) { return False; @@ -111,8 +110,8 @@ namespace array { // https://tc39.github.io/ecma262/#sec-array.prototype.every transitioning javascript builtin - ArrayEvery(js-implicit context: Context, receiver: Object)(...arguments): - Object { + ArrayEvery(js-implicit context: Context, receiver: JSAny)(...arguments): + JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.every'); @@ -129,7 +128,7 @@ namespace array { const callbackfn = Cast(arguments[0]) otherwise TypeError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. - const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + const thisArg: JSAny = arguments.length > 1 ? arguments[1] : Undefined; // Special cases. try { diff --git a/deps/v8/src/builtins/array-filter.tq b/deps/v8/src/builtins/array-filter.tq index 9acd0d04ee3cd7..4d23144329ab47 100644 --- a/deps/v8/src/builtins/array-filter.tq +++ b/deps/v8/src/builtins/array-filter.tq @@ -5,15 +5,15 @@ namespace array_filter { transitioning javascript builtin ArrayFilterLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, array: Object, initialK: Object, - length: Object, initialTo: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, array: JSAny, initialK: JSAny, + length: JSAny, initialTo: JSAny): JSAny { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -29,10 +29,9 @@ namespace array_filter { transitioning javascript builtin ArrayFilterLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, array: Object, initialK: Object, - length: Object, valueK: Object, initialTo: Object, - result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, array: JSAny, initialK: JSAny, + length: JSAny, valueK: JSAny, initialTo: JSAny, result: JSAny): JSAny { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -60,9 +59,9 @@ namespace array_filter { } transitioning builtin ArrayFilterLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, array: JSReceiver, o: JSReceiver, initialK: Number, length: Number, - initialTo: Number): Object { + initialTo: Number): JSAny { let to: Number = initialTo; // 5. Let k be 0. // 6. Repeat, while k < len @@ -77,10 +76,10 @@ namespace array_filter { // 6c. If kPresent is true, then if (kPresent == True) { // 6c. i. Let kValue be ? Get(O, Pk). - const kValue: Object = GetProperty(o, k); + const kValue: JSAny = GetProperty(o, k); // 6c. ii. Perform ? Call(callbackfn, T, ). - const result: Object = Call(context, callbackfn, thisArg, kValue, k, o); + const result: JSAny = Call(context, callbackfn, thisArg, kValue, k, o); // iii. If selected is true, then... if (ToBoolean(result)) { @@ -97,7 +96,7 @@ namespace array_filter { } transitioning macro FastArrayFilter(implicit context: Context)( - fastO: FastJSArray, len: Smi, callbackfn: Callable, thisArg: Object, + fastO: FastJSArray, len: Smi, callbackfn: Callable, thisArg: JSAny, output: FastJSArray) labels Bailout(Number, Number) { let k: Smi = 0; let to: Smi = 0; @@ -112,8 +111,8 @@ namespace array_filter { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k, to); - const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; - const result: Object = + const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue; + const result: JSAny = Call(context, callbackfn, thisArg, value, k, fastOW.Get()); if (ToBoolean(result)) { try { @@ -147,8 +146,8 @@ namespace array_filter { // https://tc39.github.io/ecma262/#sec-array.prototype.filter transitioning javascript builtin - ArrayFilter(js-implicit context: Context, receiver: Object)(...arguments): - Object { + ArrayFilter(js-implicit context: Context, receiver: JSAny)(...arguments): + JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.filter'); @@ -165,7 +164,7 @@ namespace array_filter { const callbackfn = Cast(arguments[0]) otherwise TypeError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. - const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + const thisArg: JSAny = arguments.length > 1 ? arguments[1] : Undefined; let output: JSReceiver; // Special cases. diff --git a/deps/v8/src/builtins/array-find.tq b/deps/v8/src/builtins/array-find.tq index ef54dd4666ef72..ec840a4c98b09b 100644 --- a/deps/v8/src/builtins/array-find.tq +++ b/deps/v8/src/builtins/array-find.tq @@ -5,15 +5,14 @@ namespace array_find { transitioning javascript builtin ArrayFindLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, - length: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny { // All continuation points in the optimized find implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -26,9 +25,9 @@ namespace array_find { transitioning javascript builtin ArrayFindLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - _callback: Object, _thisArg: Object, _initialK: Object, _length: Object, - _result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + _callback: JSAny, _thisArg: JSAny, _initialK: JSAny, _length: JSAny, + _result: JSAny): JSAny { // This deopt continuation point is never actually called, it just // exists to make stack traces correct from a ThrowTypeError if the // callback was found to be non-callable. @@ -40,9 +39,9 @@ namespace array_find { // before iteration continues. transitioning javascript builtin ArrayFindLoopAfterCallbackLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, length: Object, - foundValue: Object, isFound: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny, + foundValue: JSAny, isFound: JSAny): JSAny { // All continuation points in the optimized find implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -65,8 +64,8 @@ namespace array_find { } transitioning builtin ArrayFindLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, - o: JSReceiver, initialK: Number, length: Number): Object { + _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, + o: JSReceiver, initialK: Number, length: Number): JSAny { // 5. Let k be 0. // 6. Repeat, while k < len for (let k: Number = initialK; k < length; k++) { @@ -75,12 +74,11 @@ namespace array_find { // side-effect free and HasProperty/GetProperty do the conversion inline. // 6b. i. Let kValue be ? Get(O, Pk). - const value: Object = GetProperty(o, k); + const value: JSAny = GetProperty(o, k); // 6c. Let testResult be ToBoolean(? Call(predicate, T, <>)). - const testResult: Object = - Call(context, callbackfn, thisArg, value, k, o); + const testResult: JSAny = Call(context, callbackfn, thisArg, value, k, o); // 6d. If testResult is true, return kValue. if (ToBoolean(testResult)) { @@ -93,7 +91,7 @@ namespace array_find { } transitioning macro FastArrayFind(implicit context: Context)( - o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object + o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): JSAny labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast(len) otherwise goto Bailout(k); @@ -107,8 +105,8 @@ namespace array_find { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k); - const value: Object = fastOW.LoadElementOrUndefined(k); - const testResult: Object = + const value: JSAny = fastOW.LoadElementOrUndefined(k); + const testResult: JSAny = Call(context, callbackfn, thisArg, value, k, fastOW.Get()); if (ToBoolean(testResult)) { return value; @@ -119,8 +117,8 @@ namespace array_find { // https://tc39.github.io/ecma262/#sec-array.prototype.find transitioning javascript builtin - ArrayPrototypeFind(js-implicit context: Context, receiver: Object)( - ...arguments): Object { + ArrayPrototypeFind(js-implicit context: Context, receiver: JSAny)( + ...arguments): JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.find'); @@ -138,7 +136,7 @@ namespace array_find { Cast(arguments[0]) otherwise NotCallableError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. - const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + const thisArg: JSAny = arguments.length > 1 ? arguments[1] : Undefined; // Special cases. try { diff --git a/deps/v8/src/builtins/array-findindex.tq b/deps/v8/src/builtins/array-findindex.tq index 5a8bb85fbadd4c..6145c8146455b5 100644 --- a/deps/v8/src/builtins/array-findindex.tq +++ b/deps/v8/src/builtins/array-findindex.tq @@ -5,15 +5,14 @@ namespace array_findindex { transitioning javascript builtin ArrayFindIndexLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, - length: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny { // All continuation points in the optimized findIndex implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -26,9 +25,9 @@ namespace array_findindex { transitioning javascript builtin ArrayFindIndexLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - _callback: Object, _thisArg: Object, _initialK: Object, _length: Object, - _result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + _callback: JSAny, _thisArg: JSAny, _initialK: JSAny, _length: JSAny, + _result: JSAny): JSAny { // This deopt continuation point is never actually called, it just // exists to make stack traces correct from a ThrowTypeError if the // callback was found to be non-callable. @@ -40,9 +39,9 @@ namespace array_findindex { // before iteration continues. transitioning javascript builtin ArrayFindIndexLoopAfterCallbackLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, length: Object, - foundValue: Object, isFound: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny, + foundValue: JSAny, isFound: JSAny): JSAny { // All continuation points in the optimized findIndex implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -66,7 +65,7 @@ namespace array_findindex { transitioning builtin ArrayFindIndexLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, o: JSReceiver, initialK: Number, length: Number): Number { // 5. Let k be 0. // 6. Repeat, while k < len @@ -76,12 +75,11 @@ namespace array_findindex { // side-effect free and HasProperty/GetProperty do the conversion inline. // 6b. i. Let kValue be ? Get(O, Pk). - const value: Object = GetProperty(o, k); + const value: JSAny = GetProperty(o, k); // 6c. Let testResult be ToBoolean(? Call(predicate, T, <>)). - const testResult: Object = - Call(context, callbackfn, thisArg, value, k, o); + const testResult: JSAny = Call(context, callbackfn, thisArg, value, k, o); // 6d. If testResult is true, return k. if (ToBoolean(testResult)) { @@ -94,7 +92,7 @@ namespace array_findindex { } transitioning macro FastArrayFindIndex(implicit context: Context)( - o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Number + o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): Number labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast(len) otherwise goto Bailout(k); @@ -108,8 +106,8 @@ namespace array_findindex { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k); - const value: Object = fastOW.LoadElementOrUndefined(k); - const testResult: Object = + const value: JSAny = fastOW.LoadElementOrUndefined(k); + const testResult: JSAny = Call(context, callbackfn, thisArg, value, k, fastOW.Get()); if (ToBoolean(testResult)) { return k; @@ -120,8 +118,8 @@ namespace array_findindex { // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex transitioning javascript builtin - ArrayPrototypeFindIndex(js-implicit context: Context, receiver: Object)( - ...arguments): Object { + ArrayPrototypeFindIndex(js-implicit context: Context, receiver: JSAny)( + ...arguments): JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.findIndex'); @@ -139,7 +137,7 @@ namespace array_findindex { Cast(arguments[0]) otherwise NotCallableError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. - const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + const thisArg: JSAny = arguments.length > 1 ? arguments[1] : Undefined; // Special cases. try { diff --git a/deps/v8/src/builtins/array-foreach.tq b/deps/v8/src/builtins/array-foreach.tq index f52d944291ec7f..5b6e3926016c2c 100644 --- a/deps/v8/src/builtins/array-foreach.tq +++ b/deps/v8/src/builtins/array-foreach.tq @@ -5,9 +5,8 @@ namespace array_foreach { transitioning javascript builtin ArrayForEachLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, - length: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny { // All continuation points in the optimized forEach implemntation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -23,9 +22,9 @@ namespace array_foreach { transitioning javascript builtin ArrayForEachLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, length: Object, - _result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny, + _result: JSAny): JSAny { // All continuation points in the optimized forEach implemntation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -40,9 +39,9 @@ namespace array_foreach { } transitioning builtin ArrayForEachLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, - _array: Object, o: JSReceiver, initialK: Number, len: Number, - _to: Object): Object { + _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, + _array: JSAny, o: JSReceiver, initialK: Number, len: Number, + _to: JSAny): JSAny { // variables {array} and {to} are ignored. // 5. Let k be 0. @@ -58,7 +57,7 @@ namespace array_foreach { // 6c. If kPresent is true, then if (kPresent == True) { // 6c. i. Let kValue be ? Get(O, Pk). - const kValue: Object = GetProperty(o, k); + const kValue: JSAny = GetProperty(o, k); // 6c. ii. Perform ? Call(callbackfn, T, ). Call(context, callbackfn, thisArg, kValue, k, o); @@ -70,7 +69,7 @@ namespace array_foreach { } transitioning macro FastArrayForEach(implicit context: Context)( - o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object + o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): JSAny labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast(len) otherwise goto Bailout(k); @@ -83,7 +82,7 @@ namespace array_foreach { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k); - const value: Object = fastOW.LoadElementNoHole(k) + const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue; Call(context, callbackfn, thisArg, value, k, fastOW.Get()); } @@ -92,8 +91,8 @@ namespace array_foreach { // https://tc39.github.io/ecma262/#sec-array.prototype.foreach transitioning javascript builtin - ArrayForEach(js-implicit context: Context, receiver: Object)(...arguments): - Object { + ArrayForEach(js-implicit context: Context, receiver: JSAny)(...arguments): + JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.forEach'); @@ -110,7 +109,7 @@ namespace array_foreach { const callbackfn = Cast(arguments[0]) otherwise TypeError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. - const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + const thisArg: JSAny = arguments.length > 1 ? arguments[1] : Undefined; // Special cases. let k: Number = 0; diff --git a/deps/v8/src/builtins/array-join.tq b/deps/v8/src/builtins/array-join.tq index c04233b22244ec..08b5221e099c6b 100644 --- a/deps/v8/src/builtins/array-join.tq +++ b/deps/v8/src/builtins/array-join.tq @@ -3,7 +3,7 @@ // found in the LICENSE file. namespace array_join { - type LoadJoinElementFn = builtin(Context, JSReceiver, Number) => Object; + type LoadJoinElementFn = builtin(Context, JSReceiver, Number) => JSAny; // Fast C call to write a fixed array (see Buffer.fixedArray) to a single // string. @@ -12,12 +12,12 @@ namespace array_join { FixedArray, intptr, String, String): String; transitioning builtin LoadJoinElement( - context: Context, receiver: JSReceiver, k: Number): Object { + context: Context, receiver: JSReceiver, k: Number): JSAny { return GetProperty(receiver, k); } - LoadJoinElement( - context: Context, receiver: JSReceiver, k: Number): Object { + transitioning LoadJoinElement( + context: Context, receiver: JSReceiver, k: Number): JSAny { const array: JSArray = UnsafeCast(receiver); const dict: NumberDictionary = UnsafeCast(array.elements); try { @@ -33,15 +33,15 @@ namespace array_join { } LoadJoinElement( - context: Context, receiver: JSReceiver, k: Number): Object { + context: Context, receiver: JSReceiver, k: Number): JSAny { const array: JSArray = UnsafeCast(receiver); const fixedArray: FixedArray = UnsafeCast(array.elements); const element: Object = fixedArray.objects[UnsafeCast(k)]; - return element == TheHole ? kEmptyString : element; + return element == TheHole ? kEmptyString : UnsafeCast(element); } LoadJoinElement( - context: Context, receiver: JSReceiver, k: Number): Object { + context: Context, receiver: JSReceiver, k: Number): JSAny { const array: JSArray = UnsafeCast(receiver); const fixedDoubleArray: FixedDoubleArray = UnsafeCast(array.elements); @@ -51,7 +51,7 @@ namespace array_join { } builtin LoadJoinTypedElement( - context: Context, receiver: JSReceiver, k: Number): Object { + context: Context, receiver: JSReceiver, k: Number): JSAny { const typedArray: JSTypedArray = UnsafeCast(receiver); assert(!IsDetachedBuffer(typedArray.buffer)); return typed_array::LoadFixedTypedArrayElementAsTagged( @@ -60,14 +60,14 @@ namespace array_join { } transitioning builtin ConvertToLocaleString( - context: Context, element: Object, locales: Object, - options: Object): String { + context: Context, element: JSAny, locales: JSAny, + options: JSAny): String { if (IsNullOrUndefined(element)) return kEmptyString; - const prop: Object = GetProperty(element, 'toLocaleString'); + const prop: JSAny = GetProperty(element, 'toLocaleString'); try { const callable: Callable = Cast(prop) otherwise TypeError; - let result: Object; + let result: JSAny; if (IsNullOrUndefined(locales)) { result = Call(context, callable, element); } else if (IsNullOrUndefined(options)) { @@ -86,29 +86,25 @@ namespace array_join { // (see LoadJoinElement). macro CannotUseSameArrayAccessor(implicit context: Context)( loadFn: LoadJoinElementFn, receiver: JSReceiver, originalMap: Map, - originalLen: Number): never - labels Cannot, Can; + originalLen: Number): bool; CannotUseSameArrayAccessor(implicit context: Context)( loadFn: LoadJoinElementFn, receiver: JSReceiver, originalMap: Map, - originalLen: Number): never - labels Cannot, Can { - if (loadFn == LoadJoinElement) goto Can; + originalLen: Number): bool { + if (loadFn == LoadJoinElement) return false; const array: JSArray = UnsafeCast(receiver); - if (originalMap != array.map) goto Cannot; - if (originalLen != array.length) goto Cannot; - if (IsNoElementsProtectorCellInvalid()) goto Cannot; - goto Can; + if (originalMap != array.map) return true; + if (originalLen != array.length) return true; + if (IsNoElementsProtectorCellInvalid()) return true; + return false; } CannotUseSameArrayAccessor(implicit context: Context)( _loadFn: LoadJoinElementFn, receiver: JSReceiver, _initialMap: Map, - _initialLen: Number): never - labels Cannot, Can { + _initialLen: Number): bool { const typedArray: JSTypedArray = UnsafeCast(receiver); - if (IsDetachedBuffer(typedArray.buffer)) goto Cannot; - goto Can; + return IsDetachedBuffer(typedArray.buffer); } // Calculates the running total length of the resulting string. If the @@ -261,7 +257,7 @@ namespace array_join { transitioning macro ArrayJoinImpl(implicit context: Context)( receiver: JSReceiver, sep: String, lengthNumber: Number, - useToLocaleString: constexpr bool, locales: Object, options: Object, + useToLocaleString: constexpr bool, locales: JSAny, options: JSAny, initialLoadFn: LoadJoinElementFn): String { const initialMap: Map = receiver.map; const len: uintptr = Convert(lengthNumber); @@ -287,7 +283,7 @@ namespace array_join { } // b. Let element be ? Get(O, ! ToString(k)). - const element: Object = loadFn(context, receiver, Convert(k++)); + const element: JSAny = loadFn(context, receiver, Convert(k++)); // c. If element is undefined or null, let next be the empty String; // otherwise, let next be ? ToString(element). @@ -304,7 +300,7 @@ namespace array_join { case (num: Number): { next = NumberToString(num); } - case (obj: HeapObject): { + case (obj: JSAny): { if (IsNullOrUndefined(obj)) continue; next = ToString(context, obj); } @@ -325,11 +321,11 @@ namespace array_join { transitioning macro ArrayJoin(implicit context: Context)( useToLocaleString: constexpr bool, receiver: JSReceiver, sep: String, - lenNumber: Number, locales: Object, options: Object): Object; + lenNumber: Number, locales: JSAny, options: JSAny): JSAny; - ArrayJoin(implicit context: Context)( + transitioning ArrayJoin(implicit context: Context)( useToLocaleString: constexpr bool, receiver: JSReceiver, sep: String, - lenNumber: Number, locales: Object, options: Object): Object { + lenNumber: Number, locales: JSAny, options: JSAny): JSAny { const map: Map = receiver.map; const kind: ElementsKind = map.elements_kind; let loadFn: LoadJoinElementFn; @@ -374,9 +370,9 @@ namespace array_join { receiver, sep, lenNumber, useToLocaleString, locales, options, loadFn); } - ArrayJoin(implicit context: Context)( + transitioning ArrayJoin(implicit context: Context)( useToLocaleString: constexpr bool, receiver: JSReceiver, sep: String, - lenNumber: Number, locales: Object, options: Object): Object { + lenNumber: Number, locales: JSAny, options: JSAny): JSAny { const map: Map = receiver.map; const kind: ElementsKind = map.elements_kind; let loadFn: LoadJoinElementFn; @@ -465,11 +461,9 @@ namespace array_join { } // Fast path the common non-nested calls. If the receiver is not already on - // the stack, add it to the stack and go to ReceiverAdded. Otherwise go to - // ReceiverNotAdded. + // the stack, add it to the stack and return true. Otherwise return false. macro JoinStackPushInline(implicit context: Context)(receiver: JSReceiver): - never - labels ReceiverAdded, ReceiverNotAdded { + bool { try { const stack: FixedArray = LoadJoinStack() otherwise IfUninitialized; @@ -477,7 +471,7 @@ namespace array_join { stack.objects[0] = receiver; } else if (JoinStackPush(stack, receiver) == False) deferred { - goto ReceiverNotAdded; + return false; } } label IfUninitialized { @@ -486,13 +480,13 @@ namespace array_join { stack.objects[0] = receiver; SetJoinStack(stack); } - goto ReceiverAdded; + return true; } // Removes a receiver from the stack. The FixedArray will automatically shrink // to Heap::kMinJoinStackSize once the stack becomes empty. builtin JoinStackPop(implicit context: Context)( - stack: FixedArray, receiver: JSReceiver): Object { + stack: FixedArray, receiver: JSReceiver): JSAny { const len: intptr = stack.length_intptr; for (let i: intptr = 0; i < len; i++) { if (stack.objects[i] == receiver) { @@ -532,7 +526,7 @@ namespace array_join { transitioning macro CycleProtectedArrayJoin(implicit context: Context)( useToLocaleString: constexpr bool, o: JSReceiver, len: Number, - sepObj: Object, locales: Object, options: Object): Object { + sepObj: JSAny, locales: JSAny, options: JSAny): JSAny { // 3. If separator is undefined, let sep be the single-element String ",". // 4. Else, let sep be ? ToString(separator). const sep: String = @@ -542,7 +536,7 @@ namespace array_join { // the normal join algorithm. if (len > 0 && JoinStackPushInline(o)) { try { - const result: Object = + const result: JSAny = ArrayJoin(useToLocaleString, o, sep, len, locales, options); JoinStackPopInline(o); return result; @@ -557,9 +551,9 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-array.prototype.join transitioning javascript builtin - ArrayPrototypeJoin(js-implicit context: Context, receiver: Object)( - ...arguments): Object { - const separator: Object = arguments[0]; + ArrayPrototypeJoin(js-implicit context: Context, receiver: JSAny)( + ...arguments): JSAny { + const separator: JSAny = arguments[0]; // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -577,9 +571,9 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-array.prototype.tolocalestring transitioning javascript builtin ArrayPrototypeToLocaleString( - js-implicit context: Context, receiver: Object)(...arguments): Object { - const locales: Object = arguments[0]; - const options: Object = arguments[1]; + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { + const locales: JSAny = arguments[0]; + const options: JSAny = arguments[1]; // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -597,12 +591,12 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-array.prototype.tostring transitioning javascript builtin ArrayPrototypeToString( - js-implicit context: Context, receiver: Object)(...arguments): Object { + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { // 1. Let array be ? ToObject(this value). const array: JSReceiver = ToObject_Inline(context, receiver); // 2. Let func be ? Get(array, "join"). - const prop: Object = GetProperty(array, 'join'); + const prop: JSAny = GetProperty(array, 'join'); try { // 3. If IsCallable(func) is false, let func be the intrinsic function // %ObjProto_toString%. @@ -618,8 +612,8 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.join transitioning javascript builtin TypedArrayPrototypeJoin( - js-implicit context: Context, receiver: Object)(...arguments): Object { - const separator: Object = arguments[0]; + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { + const separator: JSAny = arguments[0]; // Spec: ValidateTypedArray is applied to the this value prior to evaluating // the algorithm. @@ -633,9 +627,9 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tolocalestring transitioning javascript builtin TypedArrayPrototypeToLocaleString( - js-implicit context: Context, receiver: Object)(...arguments): Object { - const locales: Object = arguments[0]; - const options: Object = arguments[1]; + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { + const locales: JSAny = arguments[0]; + const options: JSAny = arguments[1]; // Spec: ValidateTypedArray is applied to the this value prior to evaluating // the algorithm. diff --git a/deps/v8/src/builtins/array-lastindexof.tq b/deps/v8/src/builtins/array-lastindexof.tq index 5ebc451e435117..7765eff6822f34 100644 --- a/deps/v8/src/builtins/array-lastindexof.tq +++ b/deps/v8/src/builtins/array-lastindexof.tq @@ -4,20 +4,20 @@ namespace array_lastindexof { macro LoadWithHoleCheck( - elements: FixedArrayBase, index: Smi): Object + elements: FixedArrayBase, index: Smi): JSAny labels IfHole; LoadWithHoleCheck(implicit context: Context)( - elements: FixedArrayBase, index: Smi): Object + elements: FixedArrayBase, index: Smi): JSAny labels IfHole { const elements: FixedArray = UnsafeCast(elements); const element: Object = elements.objects[index]; if (element == TheHole) goto IfHole; - return element; + return UnsafeCast(element); } LoadWithHoleCheck(implicit context: Context)( - elements: FixedArrayBase, index: Smi): Object + elements: FixedArrayBase, index: Smi): JSAny labels IfHole { const elements: FixedDoubleArray = UnsafeCast(elements); const element: float64 = LoadDoubleWithHoleCheck(elements, index) @@ -26,7 +26,7 @@ namespace array_lastindexof { } macro FastArrayLastIndexOf( - context: Context, array: JSArray, from: Smi, searchElement: Object): Smi { + context: Context, array: JSArray, from: Smi, searchElement: JSAny): Smi { const elements: FixedArrayBase = array.elements; let k: Smi = from; @@ -40,7 +40,7 @@ namespace array_lastindexof { while (k >= 0) { try { - const element: Object = LoadWithHoleCheck(elements, k) + const element: JSAny = LoadWithHoleCheck(elements, k) otherwise Hole; const same: Boolean = StrictEqual(searchElement, element); @@ -80,8 +80,8 @@ namespace array_lastindexof { } macro TryFastArrayLastIndexOf( - context: Context, receiver: JSReceiver, searchElement: Object, - from: Number): Object + context: Context, receiver: JSReceiver, searchElement: JSAny, + from: Number): JSAny labels Slow { const array: FastJSArray = Cast(receiver) otherwise Slow; const length: Smi = array.length; @@ -99,8 +99,8 @@ namespace array_lastindexof { } transitioning macro GenericArrayLastIndexOf( - context: Context, object: JSReceiver, searchElement: Object, - from: Number): Object { + context: Context, object: JSReceiver, searchElement: JSAny, + from: Number): JSAny { let k: Number = from; // 7. Repeat, while k >= 0. @@ -111,7 +111,7 @@ namespace array_lastindexof { // b. If kPresent is true, then. if (kPresent == True) { // i. Let elementK be ? Get(O, ! ToString(k)). - const element: Object = GetProperty(object, k); + const element: JSAny = GetProperty(object, k); // ii. Let same be the result of performing Strict Equality Comparison // searchElement === elementK. @@ -131,7 +131,7 @@ namespace array_lastindexof { // https://tc39.github.io/ecma262/#sec-array.prototype.lastIndexOf transitioning javascript builtin ArrayPrototypeLastIndexOf( - js-implicit context: Context, receiver: Object)(...arguments): Object { + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); @@ -144,7 +144,7 @@ namespace array_lastindexof { // Step 4 - 6. const from: Number = GetFromIndex(context, length, arguments); - const searchElement: Object = arguments[0]; + const searchElement: JSAny = arguments[0]; try { return TryFastArrayLastIndexOf(context, object, searchElement, from) diff --git a/deps/v8/src/builtins/array-map.tq b/deps/v8/src/builtins/array-map.tq index dda569c68236b3..c4b0e8a358a20d 100644 --- a/deps/v8/src/builtins/array-map.tq +++ b/deps/v8/src/builtins/array-map.tq @@ -5,15 +5,15 @@ namespace array_map { transitioning javascript builtin ArrayMapLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, array: Object, initialK: Object, - length: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, array: JSAny, initialK: JSAny, + length: JSAny): JSAny { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -28,9 +28,9 @@ namespace array_map { transitioning javascript builtin ArrayMapLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, array: Object, initialK: Object, - length: Object, result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, array: JSAny, initialK: JSAny, + length: JSAny, result: JSAny): JSAny { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -57,9 +57,9 @@ namespace array_map { } transitioning builtin ArrayMapLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, array: JSReceiver, o: JSReceiver, initialK: Number, - length: Number): Object { + length: Number): JSAny { // 6. Let k be 0. // 7. Repeat, while k < len for (let k: Number = initialK; k < length; k++) { @@ -73,10 +73,10 @@ namespace array_map { // 7c. If kPresent is true, then: if (kPresent == True) { // i. Let kValue be ? Get(O, Pk). - const kValue: Object = GetProperty(o, k); + const kValue: JSAny = GetProperty(o, k); // ii. Let mapped_value be ? Call(callbackfn, T, kValue, k, O). - const mappedValue: Object = + const mappedValue: JSAny = Call(context, callbackfn, thisArg, kValue, k, o); // iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mapped_value). @@ -127,12 +127,12 @@ namespace array_map { SmiUntag(length), kAllowLargeObjectAllocation); a = NewJSArray(map, this.fixedArray); for (let i: Smi = 0; i < validLength; i++) { - typeswitch (this.fixedArray.objects[i]) { + typeswitch ( + UnsafeCast<(Number | TheHole)>(this.fixedArray.objects[i])) { case (n: Number): { elements.floats[i] = Convert(n); } - case (h: HeapObject): { - assert(h == TheHole); + case (TheHole): { } } } @@ -147,7 +147,7 @@ namespace array_map { return a; } - StoreResult(implicit context: Context)(index: Smi, result: Object) { + StoreResult(implicit context: Context)(index: Smi, result: JSAny) { typeswitch (result) { case (s: Smi): { this.fixedArray.objects[index] = s; @@ -156,7 +156,7 @@ namespace array_map { this.onlySmis = false; this.fixedArray.objects[index] = s; } - case (s: HeapObject): { + case (s: JSAnyNotNumber): { this.onlySmis = false; this.onlyNumbers = false; this.fixedArray.objects[index] = s; @@ -185,7 +185,7 @@ namespace array_map { transitioning macro FastArrayMap(implicit context: Context)( fastO: FastJSArrayForRead, len: Smi, callbackfn: Callable, - thisArg: Object): JSArray + thisArg: JSAny): JSArray labels Bailout(JSArray, Smi) { let k: Smi = 0; let fastOW = NewFastJSArrayForReadWitness(fastO); @@ -201,9 +201,9 @@ namespace array_map { if (k >= fastOW.Get().length) goto PrepareBailout(k); try { - const value: Object = fastOW.LoadElementNoHole(k) + const value: JSAny = fastOW.LoadElementNoHole(k) otherwise FoundHole; - const result: Object = + const result: JSAny = Call(context, callbackfn, thisArg, value, k, fastOW.Get()); vector.StoreResult(k, result); } @@ -224,8 +224,7 @@ namespace array_map { // https://tc39.github.io/ecma262/#sec-array.prototype.map transitioning javascript builtin - ArrayMap(js-implicit context: Context, receiver: Object)(...arguments): - Object { + ArrayMap(js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.map'); @@ -241,7 +240,7 @@ namespace array_map { const callbackfn = Cast(arguments[0]) otherwise TypeError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. - const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + const thisArg: JSAny = arguments.length > 1 ? arguments[1] : Undefined; let array: JSReceiver; let k: Number = 0; diff --git a/deps/v8/src/builtins/array-of.tq b/deps/v8/src/builtins/array-of.tq index 72933186257231..ceb9edff63c5b8 100644 --- a/deps/v8/src/builtins/array-of.tq +++ b/deps/v8/src/builtins/array-of.tq @@ -5,8 +5,7 @@ namespace array_of { // https://tc39.github.io/ecma262/#sec-array.of transitioning javascript builtin - ArrayOf(js-implicit context: Context, receiver: Object)(...arguments): - Object { + ArrayOf(js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { // 1. Let len be the actual number of arguments passed to this function. const len: Smi = Convert(arguments.length); @@ -14,7 +13,7 @@ namespace array_of { const items: Arguments = arguments; // 3. Let C be the this value. - const c: Object = receiver; + const c: JSAny = receiver; let a: JSReceiver; @@ -24,7 +23,7 @@ namespace array_of { // a. Let A be ? Construct(C, « len »). a = Construct(c, len); } - case (Object): { + case (JSAny): { // a. Let A be ? ArrayCreate(len). a = ArrayCreate(len); } @@ -36,7 +35,7 @@ namespace array_of { // 7. Repeat, while k < len while (k < len) { // a. Let kValue be items[k]. - const kValue: Object = items[Convert(k)]; + const kValue: JSAny = items[Convert(k)]; // b. Let Pk be ! ToString(k). // c. Perform ? CreateDataPropertyOrThrow(A, Pk, kValue). diff --git a/deps/v8/src/builtins/array-reduce-right.tq b/deps/v8/src/builtins/array-reduce-right.tq index b1aa71b85b4623..ae5ca99d3d5e14 100644 --- a/deps/v8/src/builtins/array-reduce-right.tq +++ b/deps/v8/src/builtins/array-reduce-right.tq @@ -6,13 +6,13 @@ namespace array { transitioning javascript builtin ArrayReduceRightPreLoopEagerDeoptContinuation( js-implicit context: Context, - receiver: Object)(callback: Object, length: Object): Object { + receiver: JSAny)(callback: JSAny, length: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -27,15 +27,15 @@ namespace array { transitioning javascript builtin ArrayReduceRightLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, initialK: Object, length: Object, - accumulator: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, initialK: JSAny, length: JSAny, + accumulator: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -48,9 +48,8 @@ namespace array { transitioning javascript builtin ArrayReduceRightLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, initialK: Object, length: Object, - result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, initialK: JSAny, length: JSAny, result: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -67,8 +66,9 @@ namespace array { transitioning builtin ArrayReduceRightLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object, - o: JSReceiver, initialK: Number, _length: Number): Object { + _receiver: JSReceiver, callbackfn: Callable, + initialAccumulator: JSAny | TheHole, o: JSReceiver, initialK: Number, + _length: Number): JSAny { let accumulator = initialAccumulator; // 8b and 9. Repeat, while k >= 0 @@ -83,16 +83,20 @@ namespace array { // 8b iii and 9c. If kPresent is true, then if (present == True) { // 8b iii and 9c i. Let kValue be ? Get(O, Pk). - const value: Object = GetProperty(o, k); - - if (accumulator == TheHole) { - // 8b iii 1. - accumulator = value; - } else { - // 9c. ii. Set accumulator to ? Call(callbackfn, undefined, - // ). - accumulator = - Call(context, callbackfn, Undefined, accumulator, value, k, o); + const value: JSAny = GetProperty(o, k); + + typeswitch (accumulator) { + case (TheHole): { + // 8b iii 1. + accumulator = value; + } + case (accumulatorNotHole: JSAny): { + // 9c. ii. Set accumulator to ? Call(callbackfn, undefined, + // ). + accumulator = Call( + context, callbackfn, Undefined, accumulatorNotHole, value, k, + o); + } } } @@ -102,16 +106,20 @@ namespace array { // 8c. if kPresent is false, throw a TypeError exception. // If the accumulator is discovered with the sentinel hole value, // this means kPresent is false. - if (accumulator == TheHole) { - ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduceRight'); + typeswitch (accumulator) { + case (TheHole): { + ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduceRight'); + } + case (accumulator: JSAny): { + return accumulator; + } } - return accumulator; } transitioning macro FastArrayReduceRight(implicit context: Context)( o: JSReceiver, len: Number, callbackfn: Callable, - initialAccumulator: Object): Object - labels Bailout(Number, Object) { + initialAccumulator: JSAny | TheHole): JSAny + labels Bailout(Number, JSAny | TheHole) { let accumulator = initialAccumulator; const smiLen = Cast(len) otherwise goto Bailout(len - 1, accumulator); const fastO = Cast(o) @@ -125,25 +133,32 @@ namespace array { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k, accumulator); - const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; - if (accumulator == TheHole) { - accumulator = value; - } else { - accumulator = Call( - context, callbackfn, Undefined, accumulator, value, k, - fastOW.Get()); + const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue; + typeswitch (accumulator) { + case (TheHole): { + accumulator = value; + } + case (accumulatorNotHole: JSAny): { + accumulator = Call( + context, callbackfn, Undefined, accumulatorNotHole, value, k, + fastOW.Get()); + } } } - if (accumulator == TheHole) { - ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduceRight'); + typeswitch (accumulator) { + case (TheHole): { + ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduceRight'); + } + case (accumulator: JSAny): { + return accumulator; + } } - return accumulator; } // https://tc39.github.io/ecma262/#sec-array.prototype.reduceRight transitioning javascript builtin - ArrayReduceRight(js-implicit context: Context, receiver: Object)( - ...arguments): Object { + ArrayReduceRight(js-implicit context: Context, receiver: JSAny)(...arguments): + JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.reduceRight'); @@ -163,14 +178,14 @@ namespace array { // exception. (This case is handled at the end of // ArrayReduceRightLoopContinuation). - const initialValue: Object = + const initialValue: JSAny | TheHole = arguments.length > 1 ? arguments[1] : TheHole; try { return FastArrayReduceRight(o, len, callbackfn, initialValue) otherwise Bailout; } - label Bailout(value: Number, accumulator: Object) { + label Bailout(value: Number, accumulator: JSAny | TheHole) { return ArrayReduceRightLoopContinuation( o, callbackfn, accumulator, o, value, len); } diff --git a/deps/v8/src/builtins/array-reduce.tq b/deps/v8/src/builtins/array-reduce.tq index a5f6feb9ccedf3..1021c4864281fe 100644 --- a/deps/v8/src/builtins/array-reduce.tq +++ b/deps/v8/src/builtins/array-reduce.tq @@ -6,13 +6,13 @@ namespace array { transitioning javascript builtin ArrayReducePreLoopEagerDeoptContinuation( js-implicit context: Context, - receiver: Object)(callback: Object, length: Object): Object { + receiver: JSAny)(callback: JSAny, length: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -27,15 +27,15 @@ namespace array { transitioning javascript builtin ArrayReduceLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, initialK: Object, length: Object, - accumulator: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, initialK: JSAny, length: JSAny, + accumulator: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -48,9 +48,8 @@ namespace array { transitioning javascript builtin ArrayReduceLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, initialK: Object, length: Object, - result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, initialK: JSAny, length: JSAny, result: JSAny): JSAny { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -66,8 +65,9 @@ namespace array { } transitioning builtin ArrayReduceLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object, - o: JSReceiver, initialK: Number, length: Number): Object { + _receiver: JSReceiver, callbackfn: Callable, + initialAccumulator: JSAny | TheHole, o: JSReceiver, initialK: Number, + length: Number): JSAny { let accumulator = initialAccumulator; // 8b and 9. Repeat, while k < len @@ -82,16 +82,20 @@ namespace array { // 6c. If kPresent is true, then if (present == True) { // 6c. i. Let kValue be ? Get(O, Pk). - const value: Object = GetProperty(o, k); - - if (accumulator == TheHole) { - // 8b. - accumulator = value; - } else { - // 9c. ii. Set accumulator to ? Call(callbackfn, undefined, - // ). - accumulator = - Call(context, callbackfn, Undefined, accumulator, value, k, o); + const value: JSAny = GetProperty(o, k); + + typeswitch (accumulator) { + case (TheHole): { + // 8b. + accumulator = value; + } + case (accumulatorNotHole: JSAny): { + // 9c. ii. Set accumulator to ? Call(callbackfn, undefined, + // ). + accumulator = Call( + context, callbackfn, Undefined, accumulatorNotHole, value, k, + o); + } } } @@ -101,16 +105,20 @@ namespace array { // 8c. if kPresent is false, throw a TypeError exception. // If the accumulator is discovered with the sentinel hole value, // this means kPresent is false. - if (accumulator == TheHole) { - ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduce'); + typeswitch (accumulator) { + case (TheHole): { + ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduce'); + } + case (accumulator: JSAny): { + return accumulator; + } } - return accumulator; } transitioning macro FastArrayReduce(implicit context: Context)( o: JSReceiver, len: Number, callbackfn: Callable, - initialAccumulator: Object): Object - labels Bailout(Number, Object) { + initialAccumulator: JSAny | TheHole): JSAny + labels Bailout(Number, JSAny | TheHole) { const k = 0; let accumulator = initialAccumulator; Cast(len) otherwise goto Bailout(k, accumulator); @@ -125,25 +133,32 @@ namespace array { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k, accumulator); - const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; - if (accumulator == TheHole) { - accumulator = value; - } else { - accumulator = Call( - context, callbackfn, Undefined, accumulator, value, k, - fastOW.Get()); + const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue; + typeswitch (accumulator) { + case (TheHole): { + accumulator = value; + } + case (accumulatorNotHole: JSAny): { + accumulator = Call( + context, callbackfn, Undefined, accumulatorNotHole, value, k, + fastOW.Get()); + } } } - if (accumulator == TheHole) { - ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduce'); + typeswitch (accumulator) { + case (TheHole): { + ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduce'); + } + case (accumulator: JSAny): { + return accumulator; + } } - return accumulator; } // https://tc39.github.io/ecma262/#sec-array.prototype.reduce transitioning javascript builtin - ArrayReduce(js-implicit context: Context, receiver: Object)(...arguments): - Object { + ArrayReduce(js-implicit context: Context, receiver: JSAny)(...arguments): + JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.reduce'); @@ -163,14 +178,14 @@ namespace array { // exception. (This case is handled at the end of // ArrayReduceLoopContinuation). - const initialValue: Object = + const initialValue: JSAny | TheHole = arguments.length > 1 ? arguments[1] : TheHole; try { return FastArrayReduce(o, len, callbackfn, initialValue) otherwise Bailout; } - label Bailout(value: Number, accumulator: Object) { + label Bailout(value: Number, accumulator: JSAny | TheHole) { return ArrayReduceLoopContinuation( o, callbackfn, accumulator, o, value, len); } diff --git a/deps/v8/src/builtins/array-reverse.tq b/deps/v8/src/builtins/array-reverse.tq index 82d2e6b6058661..5e9d3a00f39d95 100644 --- a/deps/v8/src/builtins/array-reverse.tq +++ b/deps/v8/src/builtins/array-reverse.tq @@ -12,10 +12,10 @@ namespace array_reverse { return UnsafeCast(elements.objects[index]); } - LoadElement( - implicit context: Context)(elements: FixedArrayBase, index: Smi): Object { + LoadElement( + implicit context: Context)(elements: FixedArrayBase, index: Smi): JSAny { const elements: FixedArray = UnsafeCast(elements); - return elements.objects[index]; + return UnsafeCast(elements.objects[index]); } LoadElement( @@ -38,9 +38,9 @@ namespace array_reverse { StoreFixedArrayElement(elems, index, value, SKIP_WRITE_BARRIER); } - StoreElement( + StoreElement( implicit context: - Context)(elements: FixedArrayBase, index: Smi, value: Object) { + Context)(elements: FixedArrayBase, index: Smi, value: JSAny) { const elements: FixedArray = UnsafeCast(elements); elements.objects[index] = value; } @@ -70,8 +70,8 @@ namespace array_reverse { } } - transitioning macro GenericArrayReverse(context: Context, receiver: Object): - Object { + transitioning macro GenericArrayReverse(context: Context, receiver: JSAny): + JSAny { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); @@ -89,8 +89,8 @@ namespace array_reverse { let upper: Number = length - 1; while (lower < upper) { - let lowerValue: Object = Undefined; - let upperValue: Object = Undefined; + let lowerValue: JSAny = Undefined; + let upperValue: JSAny = Undefined; // b. Let upperP be ! ToString(upper). // c. Let lowerP be ! ToString(lower). @@ -142,7 +142,7 @@ namespace array_reverse { return object; } - macro TryFastPackedArrayReverse(implicit context: Context)(receiver: Object) + macro TryFastPackedArrayReverse(implicit context: Context)(receiver: JSAny) labels Slow { const array: FastJSArray = Cast(receiver) otherwise Slow; @@ -153,7 +153,7 @@ namespace array_reverse { array.elements, array.length); } else if (kind == PACKED_ELEMENTS) { array::EnsureWriteableFastElements(array); - FastPackedArrayReverse( + FastPackedArrayReverse( array.elements, array.length); } else if (kind == PACKED_DOUBLE_ELEMENTS) { FastPackedArrayReverse( @@ -165,7 +165,7 @@ namespace array_reverse { // https://tc39.github.io/ecma262/#sec-array.prototype.reverse transitioning javascript builtin ArrayPrototypeReverse( - js-implicit context: Context, receiver: Object)(...arguments): Object { + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { try { TryFastPackedArrayReverse(receiver) otherwise Baseline; return receiver; diff --git a/deps/v8/src/builtins/array-shift.tq b/deps/v8/src/builtins/array-shift.tq index 4dd82d7b886d0a..48ffe3b4875805 100644 --- a/deps/v8/src/builtins/array-shift.tq +++ b/deps/v8/src/builtins/array-shift.tq @@ -3,11 +3,10 @@ // found in the LICENSE file. namespace array_shift { - extern builtin ArrayShift(Context, JSFunction, Object, int32); + extern builtin ArrayShift(Context, JSFunction, JSAny, int32): JSAny; - macro TryFastArrayShift(implicit context: Context)( - receiver: Object, arguments: Arguments): Object - labels Slow { + macro TryFastArrayShift(implicit context: Context)(receiver: JSAny): JSAny + labels Slow, Runtime { const array: FastJSArray = Cast(receiver) otherwise Slow; let witness = NewFastJSArrayWitness(array); @@ -17,35 +16,28 @@ namespace array_shift { return Undefined; } - try { - const newLength = array.length - 1; + const newLength = array.length - 1; - // Check that we're not supposed to right-trim the backing store, as - // implemented in elements.cc:ElementsAccessorBase::SetLengthImpl. - if ((newLength + newLength + kMinAddedElementsCapacity) < - array.elements.length) { - goto Runtime; - } + // Check that we're not supposed to right-trim the backing store, as + // implemented in elements.cc:ElementsAccessorBase::SetLengthImpl. + if ((newLength + newLength + kMinAddedElementsCapacity) < + array.elements.length) { + goto Runtime; + } - // Check that we're not supposed to left-trim the backing store, as - // implemented in elements.cc:FastElementsAccessor::MoveElements. - if (newLength > kMaxCopyElements) goto Runtime; + // Check that we're not supposed to left-trim the backing store, as + // implemented in elements.cc:FastElementsAccessor::MoveElements. + if (newLength > kMaxCopyElements) goto Runtime; - const result = witness.LoadElementOrUndefined(0); - witness.ChangeLength(newLength); - witness.MoveElements(0, 1, Convert(newLength)); - witness.StoreHole(newLength); - return result; - } - label Runtime { - tail ArrayShift( - context, LoadTargetFromFrame(), Undefined, - Convert(arguments.length)); - } + const result = witness.LoadElementOrUndefined(0); + witness.ChangeLength(newLength); + witness.MoveElements(0, 1, Convert(newLength)); + witness.StoreHole(newLength); + return result; } transitioning macro GenericArrayShift(implicit context: - Context)(receiver: Object): Object { + Context)(receiver: JSAny): JSAny { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); @@ -78,7 +70,7 @@ namespace array_shift { // d. If fromPresent is true, then if (fromPresent == True) { // i. Let fromVal be ? Get(O, from). - const fromValue: Object = GetProperty(object, from); + const fromValue: JSAny = GetProperty(object, from); // ii. Perform ? Set(O, to, fromValue, true). SetProperty(object, to, fromValue); @@ -103,12 +95,17 @@ namespace array_shift { // https://tc39.github.io/ecma262/#sec-array.prototype.shift transitioning javascript builtin ArrayPrototypeShift( - js-implicit context: Context, receiver: Object)(...arguments): Object { + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { try { - return TryFastArrayShift(receiver, arguments) otherwise Slow; + return TryFastArrayShift(receiver) otherwise Slow, Runtime; } label Slow { return GenericArrayShift(receiver); } + label Runtime { + tail ArrayShift( + context, LoadTargetFromFrame(), Undefined, + Convert(arguments.length)); + } } } diff --git a/deps/v8/src/builtins/array-slice.tq b/deps/v8/src/builtins/array-slice.tq index c3a6ac75cb0ec7..57ddc8dea1c852 100644 --- a/deps/v8/src/builtins/array-slice.tq +++ b/deps/v8/src/builtins/array-slice.tq @@ -4,7 +4,7 @@ namespace array_slice { macro HandleSimpleArgumentsSlice( - context: Context, args: JSArgumentsObjectWithLength, start: Smi, + context: NativeContext, args: JSArgumentsObjectWithLength, start: Smi, count: Smi): JSArray labels Bailout { // If the resulting array doesn't fit in new space, use the slow path. @@ -27,7 +27,7 @@ namespace array_slice { } macro HandleFastAliasedSloppyArgumentsSlice( - context: Context, args: JSArgumentsObjectWithLength, start: Smi, + context: NativeContext, args: JSArgumentsObjectWithLength, start: Smi, count: Smi): JSArray labels Bailout { // If the resulting array doesn't fit in new space, use the slow path. @@ -63,9 +63,9 @@ namespace array_slice { for (let current: Smi = start; current < to; ++current) { const e: Object = sloppyElements.objects[current + kSloppyArgumentsParameterMapStart]; - const newElement: Object = e != TheHole ? - argumentsContext[UnsafeCast(e)] : - unmappedElements.objects[current]; + const newElement: JSAny = UnsafeCast( + e != TheHole ? argumentsContext[UnsafeCast(e)] : + unmappedElements.objects[current]); // It is safe to skip the write barrier here because resultElements was // allocated together with result in a folded allocation. // TODO(tebbi): The verification of this fails at the moment due to @@ -86,7 +86,7 @@ namespace array_slice { } macro HandleFastSlice( - context: Context, o: Object, startNumber: Number, + context: NativeContext, o: JSAny, startNumber: Number, countNumber: Number): JSArray labels Bailout { const start: Smi = Cast(startNumber) otherwise Bailout; @@ -114,7 +114,7 @@ namespace array_slice { otherwise Bailout; } } - case (Object): { + case (JSAny): { } } goto Bailout; @@ -122,15 +122,15 @@ namespace array_slice { // https://tc39.github.io/ecma262/#sec-array.prototype.slice transitioning javascript builtin - ArrayPrototypeSlice(js-implicit context: Context, receiver: Object)( - ...arguments): Object { + ArrayPrototypeSlice(js-implicit context: Context, receiver: JSAny)( + ...arguments): JSAny { // Handle array cloning case if the receiver is a fast array. if (arguments.length == 0) { typeswitch (receiver) { case (a: FastJSArrayForCopy): { return CloneFastJSArray(context, a); } - case (Object): { + case (JSAny): { } } } @@ -142,7 +142,7 @@ namespace array_slice { const len: Number = GetLengthProperty(o); // 3. Let relativeStart be ? ToInteger(start). - const start: Object = arguments[0]; + const start: JSAny = arguments[0]; const relativeStart: Number = ToInteger_Inline(context, start); // 4. If relativeStart < 0, let k be max((len + relativeStart), 0); @@ -152,7 +152,7 @@ namespace array_slice { // 5. If end is undefined, let relativeEnd be len; // else let relativeEnd be ? ToInteger(end). - const end: Object = arguments[1]; + const end: JSAny = arguments[1]; const relativeEnd: Number = end == Undefined ? len : ToInteger_Inline(context, end); @@ -172,7 +172,8 @@ namespace array_slice { assert(count <= len); try { - return HandleFastSlice(context, o, k, count) otherwise Slow; + return HandleFastSlice(UnsafeCast(context), o, k, count) + otherwise Slow; } label Slow {} @@ -193,7 +194,7 @@ namespace array_slice { // c. If kPresent is true, then if (fromPresent == True) { // i. Let kValue be ? Get(O, Pk). - const kValue: Object = GetProperty(o, pK); + const kValue: JSAny = GetProperty(o, pK); // ii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), kValue). FastCreateDataProperty(a, n, kValue); diff --git a/deps/v8/src/builtins/array-some.tq b/deps/v8/src/builtins/array-some.tq index a30af4e47a42c4..5d93dd0b726017 100644 --- a/deps/v8/src/builtins/array-some.tq +++ b/deps/v8/src/builtins/array-some.tq @@ -5,15 +5,14 @@ namespace array { transitioning javascript builtin ArraySomeLoopEagerDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, - length: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny { // All continuation points in the optimized some implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. // // Also, this great mass of casts is necessary because the signature - // of Torque javascript builtins requires Object type for all parameters + // of Torque javascript builtins requires JSAny type for all parameters // other than {context}. const jsreceiver = Cast(receiver) otherwise unreachable; const callbackfn = Cast(callback) otherwise unreachable; @@ -27,9 +26,9 @@ namespace array { transitioning javascript builtin ArraySomeLoopLazyDeoptContinuation( - js-implicit context: Context, receiver: Object)( - callback: Object, thisArg: Object, initialK: Object, length: Object, - result: Object): Object { + js-implicit context: Context, receiver: JSAny)( + callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny, + result: JSAny): JSAny { // All continuation points in the optimized some implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -53,9 +52,9 @@ namespace array { } transitioning builtin ArraySomeLoopContinuation(implicit context: Context)( - _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, - _array: Object, o: JSReceiver, initialK: Number, length: Number, - _initialTo: Object): Object { + _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, + _array: JSAny, o: JSReceiver, initialK: Number, length: Number, + _initialTo: JSAny): JSAny { // 5. Let k be 0. // 6. Repeat, while k < len for (let k: Number = initialK; k < length; k++) { @@ -69,10 +68,10 @@ namespace array { // 6c. If kPresent is true, then if (kPresent == True) { // 6c. i. Let kValue be ? Get(O, Pk). - const kValue: Object = GetProperty(o, k); + const kValue: JSAny = GetProperty(o, k); // 6c. ii. Perform ? Call(callbackfn, T, ). - const result: Object = Call(context, callbackfn, thisArg, kValue, k, o); + const result: JSAny = Call(context, callbackfn, thisArg, kValue, k, o); // iii. If selected is true, then... if (ToBoolean(result)) { @@ -86,7 +85,7 @@ namespace array { } transitioning macro FastArraySome(implicit context: Context)( - o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object + o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): JSAny labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast(len) otherwise goto Bailout(k); @@ -99,8 +98,8 @@ namespace array { // Ensure that we haven't walked beyond a possibly updated length. if (k >= fastOW.Get().length) goto Bailout(k); - const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; - const result: Object = + const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue; + const result: JSAny = Call(context, callbackfn, thisArg, value, k, fastOW.Get()); if (ToBoolean(result)) { return True; @@ -111,8 +110,8 @@ namespace array { // https://tc39.github.io/ecma262/#sec-array.prototype.some transitioning javascript builtin - ArraySome(js-implicit context: Context, receiver: Object)(...arguments): - Object { + ArraySome(js-implicit context: Context, receiver: JSAny)(...arguments): + JSAny { try { RequireObjectCoercible(receiver, 'Array.prototype.some'); @@ -129,7 +128,7 @@ namespace array { const callbackfn = Cast(arguments[0]) otherwise TypeError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. - const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + const thisArg: JSAny = arguments.length > 1 ? arguments[1] : Undefined; // Special cases. try { diff --git a/deps/v8/src/builtins/array-splice.tq b/deps/v8/src/builtins/array-splice.tq index 3b65bb03d48bac..04885dbb9c481a 100644 --- a/deps/v8/src/builtins/array-splice.tq +++ b/deps/v8/src/builtins/array-splice.tq @@ -95,7 +95,7 @@ namespace array_splice { const typedNewElements: FixedArrayType = UnsafeCast(a.elements); for (let i: intptr = 2; i < args.length; ++i) { - const e: Object = args[i]; + const e: JSAny = args[i]; // The argument elements were already validated to be an appropriate // {ElementType} to store in {FixedArrayType}. typedNewElements[k++] = UnsafeCast(e); @@ -109,7 +109,7 @@ namespace array_splice { transitioning macro FastArraySplice( context: Context, args: Arguments, o: JSReceiver, originalLengthNumber: Number, actualStartNumber: Number, insertCount: Smi, - actualDeleteCountNumber: Number): Object + actualDeleteCountNumber: Number): JSAny labels Bailout { const originalLength: Smi = Cast(originalLengthNumber) otherwise Bailout; @@ -132,7 +132,7 @@ namespace array_splice { const oldElementsKind: ElementsKind = elementsKind; for (let i: intptr = 2; i < args.length; ++i) { - const e: Object = args[i]; + const e: JSAny = args[i]; if (IsFastSmiElementsKind(elementsKind)) { if (TaggedIsNotSmi(e)) { const heapObject: HeapObject = UnsafeCast(e); @@ -166,7 +166,7 @@ namespace array_splice { } if (IsFastSmiOrTaggedElementsKind(elementsKind)) { - FastSplice( + FastSplice( args, a, length, newLength, actualStart, insertCount, actualDeleteCount); } else { @@ -180,7 +180,7 @@ namespace array_splice { transitioning macro FillDeletedElementsArray( context: Context, o: JSReceiver, actualStart: Number, - actualDeleteCount: Number, a: JSReceiver): Object { + actualDeleteCount: Number, a: JSReceiver): JSAny { // 10. Let k be 0. let k: Number = 0; @@ -195,7 +195,7 @@ namespace array_splice { // c. If fromPresent is true, then if (fromPresent == True) { // i. Let fromValue be ? Get(O, from). - const fromValue: Object = GetProperty(o, from); + const fromValue: JSAny = GetProperty(o, from); // ii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(k), fromValue). FastCreateDataProperty(a, k, fromValue); @@ -231,7 +231,7 @@ namespace array_splice { // iv. If fromPresent is true, then if (fromPresent == True) { // 1. Let fromValue be ? Get(O, from). - const fromValue: Object = GetProperty(o, from); + const fromValue: JSAny = GetProperty(o, from); // 2. Perform ? Set(O, to, fromValue, true). SetProperty(o, to, fromValue); @@ -280,7 +280,7 @@ namespace array_splice { // iv. If fromPresent is true, then if (fromPresent == True) { // 1. Let fromValue be ? Get(O, from). - const fromValue: Object = GetProperty(o, from); + const fromValue: JSAny = GetProperty(o, from); // 2. Perform ? Set(O, to, fromValue, true). SetProperty(o, to, fromValue); @@ -298,8 +298,7 @@ namespace array_splice { transitioning macro SlowSplice( context: Context, arguments: Arguments, o: JSReceiver, len: Number, - actualStart: Number, insertCount: Smi, - actualDeleteCount: Number): Object { + actualStart: Number, insertCount: Smi, actualDeleteCount: Number): JSAny { // 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). const a: JSReceiver = ArraySpeciesCreate(context, o, actualDeleteCount); const itemCount: Number = insertCount; @@ -332,7 +331,7 @@ namespace array_splice { // element. if (arguments.length > 2) { for (let i: intptr = 2; i < arguments.length; ++i) { - const e: Object = arguments[i]; + const e: JSAny = arguments[i]; // b. Perform ? Set(O, ! ToString(k), E, true). SetProperty(o, k, e); @@ -350,8 +349,8 @@ namespace array_splice { // https://tc39.github.io/ecma262/#sec-array.prototype.splice transitioning javascript builtin - ArrayPrototypeSplice(js-implicit context: Context, receiver: Object)( - ...arguments): Object { + ArrayPrototypeSplice(js-implicit context: Context, receiver: JSAny)( + ...arguments): JSAny { // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject(context, receiver); @@ -359,7 +358,7 @@ namespace array_splice { const len: Number = GetLengthProperty(o); // 3. Let relativeStart be ? ToInteger(start). - const start: Object = arguments[0]; + const start: JSAny = arguments[0]; const relativeStart: Number = ToInteger_Inline(context, start); // 4. If relativeStart < 0, let actualStart be max((len + relativeStart), @@ -388,7 +387,7 @@ namespace array_splice { // a. Let insertCount be the Number of actual arguments minus 2. insertCount = Convert(arguments.length) - 2; // b. Let dc be ? ToInteger(deleteCount). - const deleteCount: Object = arguments[1]; + const deleteCount: JSAny = arguments[1]; const dc: Number = ToInteger_Inline(context, deleteCount); // c. Let actualDeleteCount be min(max(dc, 0), len - actualStart). actualDeleteCount = Min(Max(dc, 0), len - actualStart); diff --git a/deps/v8/src/builtins/array-unshift.tq b/deps/v8/src/builtins/array-unshift.tq index e685d520cd963a..422eee158de535 100644 --- a/deps/v8/src/builtins/array-unshift.tq +++ b/deps/v8/src/builtins/array-unshift.tq @@ -3,25 +3,10 @@ // found in the LICENSE file. namespace array_unshift { - extern builtin ArrayUnshift(Context, JSFunction, Object, int32); - - macro TryFastArrayUnshift( - context: Context, receiver: Object, arguments: Arguments): never - labels Slow { - const array: FastJSArray = Cast(receiver) otherwise Slow; - array::EnsureWriteableFastElements(array); - - const map: Map = array.map; - if (!IsExtensibleMap(map)) goto Slow; - EnsureArrayLengthWritable(map) otherwise Slow; - - tail ArrayUnshift( - context, LoadTargetFromFrame(), Undefined, - Convert(arguments.length)); - } + extern builtin ArrayUnshift(Context, JSFunction, JSAny, int32): JSAny; transitioning macro GenericArrayUnshift( - context: Context, receiver: Object, arguments: Arguments): Number { + context: Context, receiver: JSAny, arguments: Arguments): Number { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); @@ -55,7 +40,7 @@ namespace array_unshift { // iv. If fromPresent is true, then if (fromPresent == True) { // 1. Let fromValue be ? Get(O, from). - const fromValue: Object = GetProperty(object, from); + const fromValue: JSAny = GetProperty(object, from); // 2. Perform ? Set(O, to, fromValue, true). SetProperty(object, to, fromValue); @@ -93,11 +78,20 @@ namespace array_unshift { // https://tc39.github.io/ecma262/#sec-array.prototype.unshift transitioning javascript builtin ArrayPrototypeUnshift( - js-implicit context: Context, receiver: Object)(...arguments): Object { + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { try { - TryFastArrayUnshift(context, receiver, arguments) otherwise Baseline; + const array: FastJSArray = Cast(receiver) otherwise Slow; + array::EnsureWriteableFastElements(array); + + const map: Map = array.map; + if (!IsExtensibleMap(map)) goto Slow; + EnsureArrayLengthWritable(map) otherwise Slow; + + tail ArrayUnshift( + context, LoadTargetFromFrame(), Undefined, + Convert(arguments.length)); } - label Baseline { + label Slow { return GenericArrayUnshift(context, receiver, arguments); } } diff --git a/deps/v8/src/builtins/array.tq b/deps/v8/src/builtins/array.tq index 7e044e086b89b3..b9ae314c08a297 100644 --- a/deps/v8/src/builtins/array.tq +++ b/deps/v8/src/builtins/array.tq @@ -32,30 +32,15 @@ namespace array { assert(array.elements.map != kCOWMap); } - macro IsJSArray(implicit context: Context)(o: Object): bool { - typeswitch (o) { - case (JSArray): { - return true; - } - case (Object): { - return false; - } - } - } - - macro LoadElementOrUndefined(a: FixedArray, i: Smi): Object { - const e: Object = a.objects[i]; - return e == TheHole ? Undefined : e; + macro LoadElementOrUndefined(implicit context: + Context)(a: FixedArray, i: Smi): JSAny { + const e = UnsafeCast<(JSAny | TheHole)>(a.objects[i]); + return ReplaceTheHoleWithUndefined(e); } macro LoadElementOrUndefined(a: FixedDoubleArray, i: Smi): NumberOrUndefined { - try { - const f: float64 = LoadDoubleWithHoleCheck(a, i) otherwise IfHole; - return AllocateHeapNumberWithValue(f); - } - label IfHole { - return Undefined; - } + const f: float64 = LoadDoubleWithHoleCheck(a, i) otherwise return Undefined; + return AllocateHeapNumberWithValue(f); } macro StoreArrayHole(elements: FixedDoubleArray, k: Smi): void { @@ -66,5 +51,5 @@ namespace array { elements.objects[k] = TheHole; } - extern macro SetPropertyLength(implicit context: Context)(Object, Number); + extern macro SetPropertyLength(implicit context: Context)(JSAny, Number); } diff --git a/deps/v8/src/builtins/base.tq b/deps/v8/src/builtins/base.tq index 07af1f441f8060..aa5d4cc50a731c 100644 --- a/deps/v8/src/builtins/base.tq +++ b/deps/v8/src/builtins/base.tq @@ -43,6 +43,29 @@ extern class HeapObject extends Tagged { type Object = Smi | HeapObject; +// Defined to coincide with https://tc39.es/ecma262/#sec-ispropertykey +// Doesn't include PrivateSymbol. +type PropertyKey = String | PublicSymbol; + +// TODO(tebbi): PrivateSymbol is only exposed to JavaScript through the debugger +// API. We should reconsider this and try not to expose it at all. Then JSAny +// would not need to contain it. + +// A JavaScript primitive value as defined in +// https://tc39.es/ecma262/#sec-primitive-value. +type JSPrimitive = Numeric | String | Symbol | Boolean | + Null | Undefined; + +// A user-exposed JavaScript value, as opposed to V8-internal values like +// TheHole or FixedArray. +type JSAny = JSReceiver | JSPrimitive; + +type JSAnyNotNumber = BigInt | String | Symbol | Boolean | + Null | Undefined | JSReceiver; + +// This is the intersection of JSAny and HeapObject. +type JSAnyNotSmi = JSAnyNotNumber | HeapNumber; + type int32 generates 'TNode' constexpr 'int32_t'; type uint32 generates 'TNode' constexpr 'uint32_t'; type int31 extends int32 @@ -56,6 +79,8 @@ type uint16 extends uint31 type int8 extends int16 generates 'TNode' constexpr 'int8_t'; type uint8 extends uint16 generates 'TNode' constexpr 'uint8_t'; +type char8 extends int8 constexpr 'char'; +type char16 extends uint16 constexpr 'char16_t'; type int64 generates 'TNode' constexpr 'int64_t'; type intptr generates 'TNode' constexpr 'intptr_t'; type uintptr generates 'TNode' constexpr 'uintptr_t'; @@ -77,7 +102,7 @@ extern class Context extends HeapObject { extension: Object; native_context: Object; } -type NativeContext extends Context; +type NativeContext extends Context generates 'TNode'; @generateCppClass extern class Oddball extends HeapObject { @@ -97,6 +122,9 @@ type Numeric = Number | BigInt; extern class Name extends HeapObject { hash_field: uint32; } +// This is the same as Name, but with the information that there are no other +// kinds of names. +type AnyName = PrivateSymbol | PublicSymbol | String; @generateCppClass extern class Symbol extends Name { @@ -104,6 +132,9 @@ extern class Symbol extends Name { name: Object; // The print name of a symbol, or undefined if none. } +type PublicSymbol extends Symbol; +type PrivateSymbol extends Symbol; + @abstract @generateCppClass extern class String extends Name { @@ -136,9 +167,11 @@ extern class SeqString extends String { } @generateCppClass extern class SeqOneByteString extends SeqString { + chars[length]: char8; } @generateCppClass extern class SeqTwoByteString extends SeqString { + chars[length]: char16; } @generateCppClass @@ -185,7 +218,6 @@ type DirectString extends String; type RootIndex generates 'TNode' constexpr 'RootIndex'; @abstract -@generateCppClass extern class FixedArrayBase extends HeapObject { length: Smi; } @@ -205,7 +237,7 @@ type LayoutDescriptor extends ByteArray type TransitionArray extends WeakFixedArray generates 'TNode'; -type InstanceType extends uint16 constexpr 'InstanceType'; +type InstanceType extends uint16 constexpr 'v8::internal::InstanceType'; extern class Map extends HeapObject { instance_size_in_words: uint8; @@ -388,8 +420,8 @@ extern class JSProxy extends JSReceiver { // Just a starting shape for JSObject; properties can move after initialization. @noVerifier extern class JSProxyRevocableResult extends JSObject { - proxy: Object; - revoke: Object; + proxy: JSAny; + revoke: JSAny; } macro NewJSProxyRevocableResult(implicit context: Context)( @@ -412,22 +444,24 @@ extern class JSGlobalProxy extends JSObject { @generateCppClass extern class JSPrimitiveWrapper extends JSObject { - value: Object; + value: JSAny; } -extern class JSArgumentsObject extends JSObject {} +@generateCppClass +extern class JSArgumentsObject extends JSObject { +} // Just a starting shape for JSObject; properties can move after initialization. @noVerifier @hasSameInstanceTypeAsParent extern class JSArgumentsObjectWithLength extends JSArgumentsObject { - length: Object; + length: JSAny; } // Just a starting shape for JSObject; properties can move after initialization. @hasSameInstanceTypeAsParent extern class JSSloppyArgumentsObject extends JSArgumentsObjectWithLength { - callee: Object; + callee: JSAny; } // Just a starting shape for JSObject; properties can move after initialization. @@ -492,8 +526,8 @@ type NoSharedNameSentinel extends Smi; @generateCppClass extern class CallHandlerInfo extends Struct { - callback: Foreign | Undefined; - js_callback: Foreign | Undefined; + callback: NonNullForeign | Undefined | Zero; + js_callback: NonNullForeign | Undefined | Zero; data: Object; } @@ -510,18 +544,37 @@ extern class Module extends HeapObject { type SourceTextModuleInfo extends FixedArray; +@generateCppClass extern class SourceTextModule extends Module { + // The code representing this module, or an abstraction thereof. code: SharedFunctionInfo | JSFunction | JSGeneratorObject | SourceTextModuleInfo; + + // Arrays of cells corresponding to regular exports and regular imports. + // A cell's position in the array is determined by the cell index of the + // associated module entry (which coincides with the variable index of the + // associated variable). regular_exports: FixedArray; regular_imports: FixedArray; + + // Modules imported or re-exported by this module. + // Corresponds 1-to-1 to the module specifier strings in + // SourceTextModuleInfo::module_requests. requested_modules: FixedArray; + + // Script from which the module originates. script: Script; + + // The value of import.meta inside of this module. + // Lazily initialized on first access. It's the hole before first access and + // a JSObject afterwards. import_meta: TheHole | JSObject; + dfs_index: Smi; dfs_ancestor_index: Smi; } +@generateCppClass extern class SyntheticModule extends Module { name: String; export_names: FixedArray; @@ -529,6 +582,7 @@ extern class SyntheticModule extends Module { } @abstract +@generateCppClass extern class JSModuleNamespace extends JSObject { module: Module; } @@ -539,14 +593,23 @@ extern class TemplateList extends FixedArray { } @abstract +@generateCppClass extern class JSWeakCollection extends JSObject { + // The backing hash table mapping keys to values. table: Object; } -extern class JSWeakSet extends JSWeakCollection {} -extern class JSWeakMap extends JSWeakCollection {} +@generateCppClass +extern class JSWeakSet extends JSWeakCollection { +} +@generateCppClass +extern class JSWeakMap extends JSWeakCollection { +} +@generateCppClass extern class JSCollectionIterator extends JSObject { + // The backing hash table mapping keys to values. table: Object; + // The index into the data table. index: Object; } @@ -601,7 +664,10 @@ extern class Script extends Struct { host_defined_options: Object; } -extern class EmbedderDataArray extends HeapObject { length: Smi; } +@generateCppClass +extern class EmbedderDataArray extends HeapObject { + length: Smi; +} type ScopeInfo extends HeapObject generates 'TNode'; @@ -631,9 +697,15 @@ extern class SharedFunctionInfo extends HeapObject { @if(V8_SFI_HAS_UNIQUE_ID) unique_id: int32; } +@generateCppClass extern class JSBoundFunction extends JSObject { + // The wrapped function object. bound_target_function: Callable; - bound_this: Object; + // The value that is always passed as the this value when calling the wrapped + // function. + bound_this: JSAny; + // A list of values whose elements are used as the first arguments to any call + // to the wrapped function. bound_arguments: FixedArray; } @@ -644,7 +716,7 @@ extern class JSBoundFunction extends JSObject { type NonNullForeign extends Foreign; // A function built with InstantiateFunction for the public API. -type CallableApiObject extends HeapObject; +type CallableApiObject extends JSObject; // A JSProxy with the callable bit set. type CallableJSProxy extends JSProxy; @@ -729,14 +801,26 @@ extern class JSTypedArray extends JSArrayBufferView { } @abstract +@generateCppClass extern class JSCollection extends JSObject { + // The backing hash table. table: Object; } -extern class JSSet extends JSCollection {} -extern class JSMap extends JSCollection {} +@generateCppClass +extern class JSSet extends JSCollection { +} +@generateCppClass +extern class JSMap extends JSCollection { +} +@generateCppClass extern class JSDate extends JSObject { + // If one component is NaN, all of them are, indicating a NaN time value. + + // The time value. value: NumberOrUndefined; + + // Cached values: year: Undefined | Smi | NaN; month: Undefined | Smi | NaN; day: Undefined | Smi | NaN; @@ -744,6 +828,9 @@ extern class JSDate extends JSObject { hour: Undefined | Smi | NaN; min: Undefined | Smi | NaN; sec: Undefined | Smi | NaN; + + // Sample of the date cache stamp at the moment when chached fields were + // cached. cache_stamp: Undefined | Smi | NaN; } @@ -752,8 +839,11 @@ extern class JSGlobalObject extends JSObject { global_proxy: JSGlobalProxy; } +@generateCppClass extern class JSAsyncFromSyncIterator extends JSObject { sync_iterator: JSReceiver; + // The "next" method is loaded during GetIterator, and is not reloaded for + // subsequent "next" invocations. next: Object; } @@ -763,6 +853,7 @@ extern class JSStringIterator extends JSObject { } @abstract +@generateCppClass extern class TemplateInfo extends Struct { tag: Object; serial_number: Object; @@ -772,12 +863,15 @@ extern class TemplateInfo extends Struct { } @generatePrint +@generateCppClass extern class TemplateObjectDescription extends Struct { raw_strings: FixedArray; cooked_strings: FixedArray; } +@generateCppClass extern class FunctionTemplateRareData extends Struct { + // See DECL_RARE_ACCESSORS in FunctionTemplateInfo. prototype_template: Object; prototype_provider_template: Object; parent_template: Object; @@ -788,17 +882,31 @@ extern class FunctionTemplateRareData extends Struct { access_check_info: Object; } +@generateCppClass extern class FunctionTemplateInfo extends TemplateInfo { + // Handler invoked when calling an instance of this FunctionTemplateInfo. + // Either CallInfoHandler or Undefined. call_code: Object; class_name: Object; + // If the signature is a FunctionTemplateInfo it is used to check whether the + // receiver calling the associated JSFunction is a compatible receiver, i.e. + // it is an instance of the signature FunctionTemplateInfo or any of the + // receiver's prototypes are. signature: Object; - function_template_rare_data: Object; + // If any of the setters declared by DECL_RARE_ACCESSORS are used then a + // FunctionTemplateRareData will be stored here. Until then this contains + // undefined. + rare_data: HeapObject; shared_function_info: Object; flag: Smi; length: Smi; + // Either the_hole or a private symbol. Used to cache the result on + // the receiver under the the cached_property_name when this + // FunctionTemplateInfo is used as a getter. cached_property_name: Object; } +@generateCppClass extern class ObjectTemplateInfo extends TemplateInfo { constructor: Object; data: Object; @@ -809,7 +917,7 @@ extern class PropertyArray extends HeapObject { length_and_hash: Smi; } type DependentCode extends WeakFixedArray; extern class PropertyCell extends HeapObject { - name: Name; + name: AnyName; property_details_raw: Smi; value: Object; dependent_code: DependentCode; @@ -840,6 +948,7 @@ const UTF32: extern class Foreign extends HeapObject { foreign_address: RawPtr; } +@generateCppClass extern class InterceptorInfo extends Struct { getter: NonNullForeign | Zero | Undefined; setter: NonNullForeign | Zero | Undefined; @@ -852,6 +961,7 @@ extern class InterceptorInfo extends Struct { flags: Smi; } +@generateCppClass extern class AccessCheckInfo extends Struct { callback: Foreign | Zero | Undefined; named_interceptor: InterceptorInfo | Zero | Undefined; @@ -859,14 +969,21 @@ extern class AccessCheckInfo extends Struct { data: Object; } +@generateCppClass extern class ArrayBoilerplateDescription extends Struct { flags: Smi; constant_elements: FixedArrayBase; } -extern class AliasedArgumentsEntry extends Struct { aliased_context_slot: Smi; } +@generateCppClass +extern class AliasedArgumentsEntry extends Struct { + aliased_context_slot: Smi; +} -extern class Cell extends HeapObject { value: Object; } +@generateCppClass +extern class Cell extends HeapObject { + value: Object; +} extern class DataHandler extends Struct { smi_handler: Smi | Code; @@ -881,39 +998,58 @@ extern class DataHandler extends Struct { @abstract @dirtyInstantiatedAbstractClass +@generateCppClass extern class JSGeneratorObject extends JSObject { function: JSFunction; context: Context; - receiver: Object; + receiver: JSAny; + + // For executing generators: the most recent input value. + // For suspended generators: debug information (bytecode offset). + // There is currently no need to remember the most recent input value for a + // suspended generator. input_or_debug_pos: Object; + resume_mode: Smi; continuation: Smi; + + // Saved interpreter register file. parameters_and_registers: FixedArray; } +@generateCppClass extern class JSAsyncFunctionObject extends JSGeneratorObject { promise: JSPromise; } +@generateCppClass extern class JSAsyncGeneratorObject extends JSGeneratorObject { + // Pointer to the head of a singly linked list of AsyncGeneratorRequest, or + // undefined. queue: HeapObject; is_awaiting: Smi; } +@generateCppClass extern class JSPromise extends JSObject { + // Smi 0 terminated list of PromiseReaction objects in case the JSPromise was + // not settled yet, otherwise the result. reactions_or_result: Object; flags: Smi; } @abstract +@generateCppClass extern class Microtask extends Struct { } +@generateCppClass extern class CallbackTask extends Microtask { callback: Foreign; data: Foreign; } +@generateCppClass extern class CallableTask extends Microtask { callable: JSReceiver; context: Context; @@ -931,11 +1067,13 @@ extern class StackFrameInfo extends Struct { type_name: String | Null | Undefined; eval_origin: String | Null | Undefined; wasm_module_name: String | Null | Undefined; + wasm_instance: WasmInstanceObject | Null | Undefined; flag: Smi; } type FrameArray extends FixedArray; +@generateCppClass extern class StackTraceFrame extends Struct { frame_array: FrameArray | Undefined; frame_index: Smi; @@ -943,6 +1081,7 @@ extern class StackTraceFrame extends Struct { id: Smi; } +@generateCppClass extern class ClassPositions extends Struct { start: Smi; end: Smi; @@ -958,7 +1097,7 @@ extern class WasmExportedFunctionData extends Struct { // The remaining fields are for fast calling from C++. The contract is // that they are lazily populated, and either all will be present or none. c_wrapper_code: Object; - wasm_call_target: Smi; // Pseudo-smi: one-bit shift on all platforms. + wasm_call_target: Smi | Foreign; packed_args_size: Smi; } @@ -972,7 +1111,7 @@ extern class WasmJSFunctionData extends Struct { extern class WasmCapiFunctionData extends Struct { call_target: RawPtr; - embedder_data: RawPtr; + embedder_data: Foreign; // Managed wrapper_code: Code; serialized_signature: ByteArray; // PodArray } @@ -995,7 +1134,13 @@ extern class WasmDebugInfo extends Struct { c_wasm_entry_map: Foreign | Undefined; // Managed } -extern class WasmExceptionTag extends Struct { index: Smi; } +@generateCppClass +extern class WasmExceptionTag extends Struct { + index: Smi; +} + +const kTaggedSize: constexpr int31 generates 'kTaggedSize'; +const kDoubleSize: constexpr int31 generates 'kDoubleSize'; const kSmiTagSize: constexpr int31 generates 'kSmiTagSize'; const V8_INFINITY: constexpr float64 generates 'V8_INFINITY'; @@ -1013,8 +1158,8 @@ const PACKED_DOUBLE_ELEMENTS: constexpr ElementsKind generates 'PACKED_DOUBLE_ELEMENTS'; const HOLEY_DOUBLE_ELEMENTS: constexpr ElementsKind generates 'HOLEY_DOUBLE_ELEMENTS'; -const LAST_FROZEN_ELEMENTS_KIND: - constexpr ElementsKind generates 'LAST_FROZEN_ELEMENTS_KIND'; +const LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND: constexpr ElementsKind + generates 'LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND'; const DICTIONARY_ELEMENTS: constexpr ElementsKind generates 'DICTIONARY_ELEMENTS'; @@ -1186,6 +1331,7 @@ extern macro Int32FalseConstant(): bool; extern macro EmptyStringConstant(): EmptyString; extern macro LengthStringConstant(): String; extern macro NanConstant(): NaN; +extern macro IteratorSymbolConstant(): Symbol; const TheHole: TheHole = TheHoleConstant(); const Null: Null = NullConstant(); @@ -1207,6 +1353,7 @@ const SKIP_WRITE_BARRIER: const UNSAFE_SKIP_WRITE_BARRIER: constexpr WriteBarrierMode generates 'UNSAFE_SKIP_WRITE_BARRIER'; +@generateCppClass extern class AsyncGeneratorRequest extends Struct { next: AsyncGeneratorRequest | Undefined; resume_mode: Smi; @@ -1214,6 +1361,7 @@ extern class AsyncGeneratorRequest extends Struct { promise: JSPromise; } +@generateCppClass extern class SourceTextModuleInfoEntry extends Struct { export_name: String | Undefined; local_name: String | Undefined; @@ -1224,31 +1372,43 @@ extern class SourceTextModuleInfoEntry extends Struct { end_pos: Smi; } +@generateCppClass extern class PromiseCapability extends Struct { promise: JSReceiver | Undefined; resolve: Object; reject: Object; } +@generateCppClass extern class PromiseReaction extends Struct { next: PromiseReaction | Zero; reject_handler: Callable | Undefined; fulfill_handler: Callable | Undefined; + // Either a JSPromise (in case of native promises), a PromiseCapability + // (general case), or undefined (in case of await). promise_or_capability: JSPromise | PromiseCapability | Undefined; } @abstract +@generateCppClass extern class PromiseReactionJobTask extends Microtask { argument: Object; context: Context; handler: Callable | Undefined; + // Either a JSPromise (in case of native promises), a PromiseCapability + // (general case), or undefined (in case of await). promise_or_capability: JSPromise | PromiseCapability | Undefined; } -extern class PromiseFulfillReactionJobTask extends PromiseReactionJobTask {} +@generateCppClass +extern class PromiseFulfillReactionJobTask extends PromiseReactionJobTask { +} -extern class PromiseRejectReactionJobTask extends PromiseReactionJobTask {} +@generateCppClass +extern class PromiseRejectReactionJobTask extends PromiseReactionJobTask { +} +@generateCppClass extern class PromiseResolveThenableJobTask extends Microtask { context: Context; promise_to_resolve: JSPromise; @@ -1256,6 +1416,7 @@ extern class PromiseResolveThenableJobTask extends Microtask { thenable: JSReceiver; } +@generateCppClass extern class JSRegExp extends JSObject { data: FixedArray | Undefined; source: String | Undefined; @@ -1263,7 +1424,7 @@ extern class JSRegExp extends JSObject { } extern transitioning macro AllocateJSIteratorResult(implicit context: Context)( - Object, Boolean): JSObject; + JSAny, Boolean): JSObject; // Note: Although a condition for a FastJSRegExp is having a positive smi // lastIndex (see RegExpBuiltinsAssembler::BranchIfFastRegExp), it is possible @@ -1282,13 +1443,16 @@ RegExpBuiltinsAssembler::FastStoreLastIndex(FastJSRegExp, Smi): void; @hasSameInstanceTypeAsParent extern class JSRegExpResult extends JSArray { - index: Object; - input: Object; - groups: Object; + index: JSAny; + input: JSAny; + groups: JSAny; } +@generateCppClass extern class JSRegExpStringIterator extends JSObject { - iterating_reg_exp: Object; + // The [[IteratingRegExp]] internal property. + iterating_reg_exp: JSAny; + // The [[IteratedString]] internal property. iterated_string: String; flags: Smi; } @@ -1466,32 +1630,33 @@ extern macro Comment(constexpr string); extern macro StaticAssert(bool); extern macro Print(Object); extern macro DebugBreak(); -extern transitioning macro ToInteger_Inline(Context, Object): Number; +extern transitioning macro ToInteger_Inline(Context, JSAny): Number; extern transitioning macro ToInteger_Inline( - Context, Object, constexpr ToIntegerTruncationMode): Number; -extern transitioning macro ToLength_Inline(Context, Object): Number; -extern transitioning macro ToNumber_Inline(Context, Object): Number; -extern transitioning macro ToSmiIndex(implicit context: Context)(Object): + Context, JSAny, constexpr ToIntegerTruncationMode): Number; +extern transitioning macro ToLength_Inline(Context, JSAny): Number; +extern transitioning macro ToNumber_Inline(Context, JSAny): Number; +extern transitioning macro ToSmiIndex(implicit context: Context)(JSAny): PositiveSmi labels IfRangeError; -extern transitioning macro ToSmiLength(implicit context: Context)(Object): +extern transitioning macro ToSmiLength(implicit context: Context)(JSAny): PositiveSmi labels IfRangeError; -extern transitioning macro ToString_Inline(Context, Object): String; +extern transitioning macro ToString_Inline(Context, JSAny): String; extern transitioning macro ToThisString(implicit context: Context)( - Object, String): String; + JSAny, String): String; extern transitioning macro ToThisValue(implicit context: Context)( - Object, constexpr PrimitiveType, constexpr string): Object; + JSAny, constexpr PrimitiveType, constexpr string): JSAny; extern transitioning macro GetProperty(implicit context: Context)( - Object, Object): Object; + JSAny, JSAny): JSAny; extern transitioning builtin SetProperty(implicit context: Context)( - Object, Object, Object); + JSAny, JSAny, JSAny); extern transitioning builtin SetPropertyInLiteral(implicit context: Context)( - Object, Object, Object); + JSAny, JSAny, JSAny); extern transitioning builtin DeleteProperty(implicit context: Context)( - Object, Object, LanguageMode): Object; + JSAny, JSAny | PrivateSymbol, LanguageMode): Boolean; extern transitioning builtin HasProperty(implicit context: Context)( - Object, Object): Boolean; + JSAny, JSAny): Boolean; extern transitioning macro HasProperty_Inline(implicit context: Context)( - JSReceiver, Object): Boolean; + JSReceiver, JSAny): Boolean; +extern builtin LoadIC(Context, JSAny, JSAny, Smi, FeedbackVector): JSAny; extern macro ThrowRangeError(implicit context: Context)( constexpr MessageTemplate): never; @@ -1510,43 +1675,60 @@ extern macro ThrowTypeError(implicit context: Context)( extern transitioning runtime ThrowTypeErrorIfStrict(implicit context: Context)( Smi, Object, Object): void; -extern macro ArraySpeciesCreate(Context, Object, Number): JSReceiver; +extern transitioning macro ThrowIfNotJSReceiver(implicit context: Context)( + JSAny, constexpr MessageTemplate, constexpr string): void; + +extern macro ArraySpeciesCreate(Context, JSAny, Number): JSReceiver; extern macro ArrayCreate(implicit context: Context)(Number): JSArray; extern macro BuildAppendJSArray( - constexpr ElementsKind, FastJSArray, Object): void labels Bailout; + constexpr ElementsKind, FastJSArray, JSAny): void labels Bailout; extern macro EnsureArrayPushable(Map): ElementsKind labels Bailout; extern macro EnsureArrayLengthWritable(Map) labels Bailout; // TODO: Reduce duplication once varargs are supported in macros. extern macro Construct(implicit context: Context)( - Constructor, Object): JSReceiver; + Constructor, JSAny): JSReceiver; extern macro Construct(implicit context: Context)( - Constructor, Object, Object): JSReceiver; + Constructor, JSAny, JSAny): JSReceiver; extern macro Construct(implicit context: Context)( - Constructor, Object, Object, Object): JSReceiver; + Constructor, JSAny, JSAny, JSAny): JSReceiver; extern macro ConstructWithTarget(implicit context: Context)( Constructor, JSReceiver): JSReceiver; extern macro ConstructWithTarget(implicit context: Context)( - Constructor, JSReceiver, Object): JSReceiver; + Constructor, JSReceiver, JSAny): JSReceiver; extern macro SpeciesConstructor(implicit context: Context)( - Object, JSReceiver): JSReceiver; + JSAny, JSReceiver): JSReceiver; extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool; extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32): NameDictionary; -extern builtin ToObject(Context, Object): JSReceiver; -extern macro ToObject_Inline(Context, Object): JSReceiver; +extern builtin ToObject(Context, JSAny): JSReceiver; +extern macro ToObject_Inline(Context, JSAny): JSReceiver; extern macro IsNullOrUndefined(Object): bool; extern macro IsTheHole(Object): bool; extern macro IsString(HeapObject): bool; -transitioning builtin ToString(context: Context, o: Object): String { +transitioning builtin ToString(context: Context, o: JSAny): String { return ToStringImpl(context, o); } -extern transitioning runtime ToStringRT(Context, Object): String; +extern transitioning runtime ToStringRT(Context, JSAny): String; extern transitioning builtin NonPrimitiveToPrimitive_String( - Context, Object): Object; + Context, JSAny): JSPrimitive; +extern transitioning builtin NonPrimitiveToPrimitive_Default( + Context, JSAny): JSPrimitive; + +transitioning macro ToPrimitiveDefault(implicit context: Context)(v: JSAny): + JSPrimitive { + typeswitch (v) { + case (v: JSReceiver): { + return NonPrimitiveToPrimitive_Default(context, v); + } + case (v: JSPrimitive): { + return v; + } + } +} extern transitioning runtime NormalizeElements(Context, JSObject); extern transitioning runtime TransitionElementsKindWithKind( @@ -1556,18 +1738,15 @@ extern macro LoadBufferObject(RawPtr, constexpr int32): Object; extern macro LoadBufferPointer(RawPtr, constexpr int32): RawPtr; extern macro LoadBufferSmi(RawPtr, constexpr int32): Smi; -extern macro LoadRoot(constexpr RootIndex): Object; -extern macro StoreRoot(constexpr RootIndex, Object): Object; - extern runtime StringEqual(Context, String, String): Oddball; extern builtin StringLessThan(Context, String, String): Boolean; extern macro StringCharCodeAt(String, intptr): int32; extern runtime StringCompareSequence(Context, String, String, Number): Boolean; extern macro StringFromSingleCharCode(int32): String; -extern macro StrictEqual(Object, Object): Boolean; +extern macro StrictEqual(JSAny, JSAny): Boolean; extern macro SmiLexicographicCompare(Smi, Smi): Smi; -extern runtime ReThrow(Context, Object): never; +extern runtime ReThrow(Context, JSAny): never; extern runtime ThrowInvalidStringLength(Context): never; extern operator '==' macro WordEqual(RawPtr, RawPtr): bool; @@ -1638,38 +1817,51 @@ extern operator '<' macro Float64LessThan(float64, float64): bool; extern macro BranchIfNumberEqual(Number, Number): never labels Taken, NotTaken; operator '==' macro IsNumberEqual(a: Number, b: Number): bool { - return (BranchIfNumberEqual(a, b)) ? true : false; + BranchIfNumberEqual(a, b) otherwise return true, return false; } operator '!=' macro IsNumberNotEqual(a: Number, b: Number): bool { - return (BranchIfNumberEqual(a, b)) ? false : true; + return !(a == b); } -extern operator '<' macro BranchIfNumberLessThan(Number, Number): never +extern macro BranchIfNumberLessThan(Number, Number): never labels Taken, NotTaken; -extern operator '<=' macro BranchIfNumberLessThanOrEqual(Number, Number): never +operator '<' macro NumberIsLessThan(a: Number, b: Number): bool { + BranchIfNumberLessThan(a, b) otherwise return true, return false; +} +extern macro BranchIfNumberLessThanOrEqual(Number, Number): never labels Taken, NotTaken; +operator '<=' macro NumberIsLessThanOrEqual(a: Number, b: Number): bool { + BranchIfNumberLessThanOrEqual(a, b) otherwise return true, return false; +} -extern operator '>' macro BranchIfNumberGreaterThan(Number, Number): never - labels Taken, NotTaken; -extern operator '>=' macro BranchIfNumberGreaterThanOrEqual( - Number, Number): never +operator '>' macro NumberIsGreaterThan(a: Number, b: Number): bool { + return b < a; +} +operator '>=' macro NumberIsGreaterThanOrEqual(a: Number, b: Number): bool { + return b <= a; +} + +extern macro BranchIfFloat64IsNaN(float64): never labels Taken, NotTaken; +macro Float64IsNaN(n: float64): bool { + BranchIfFloat64IsNaN(n) otherwise return true, return false; +} -// The type of all tagged values that can safely be compared with WordEqual. +// The type of all tagged values that can safely be compared with TaggedEqual. type TaggedWithIdentity = JSReceiver | FixedArrayBase | Oddball | Map | EmptyString; -extern operator '==' macro WordEqual(TaggedWithIdentity, Object): bool; -extern operator '==' macro WordEqual(Object, TaggedWithIdentity): bool; -extern operator '==' macro WordEqual( +extern operator '==' macro TaggedEqual(TaggedWithIdentity, Object): bool; +extern operator '==' macro TaggedEqual(Object, TaggedWithIdentity): bool; +extern operator '==' macro TaggedEqual( TaggedWithIdentity, TaggedWithIdentity): bool; -extern operator '!=' macro WordNotEqual(TaggedWithIdentity, Object): bool; -extern operator '!=' macro WordNotEqual(Object, TaggedWithIdentity): bool; -extern operator '!=' macro WordNotEqual( +extern operator '!=' macro TaggedNotEqual(TaggedWithIdentity, Object): bool; +extern operator '!=' macro TaggedNotEqual(Object, TaggedWithIdentity): bool; +extern operator '!=' macro TaggedNotEqual( TaggedWithIdentity, TaggedWithIdentity): bool; // Do not overload == and != if it is unclear if object identity is the right // equality. -extern macro WordEqual(Object, Object): bool; -extern macro WordNotEqual(Object, Object): bool; +extern macro TaggedEqual(Object, Object): bool; +extern macro TaggedNotEqual(Object, Object): bool; extern operator '+' macro SmiAdd(Smi, Smi): Smi; extern operator '-' macro SmiSub(Smi, Smi): Smi; @@ -1707,11 +1899,14 @@ extern operator '*' macro ConstexprInt31Mul( constexpr int31, constexpr int31): constexpr int31; extern operator '-' macro Int32Sub(int32, int32): int32; extern operator '*' macro Int32Mul(int32, int32): int32; +extern operator '/' macro Int32Div(int32, int32): int32; extern operator '%' macro Int32Mod(int32, int32): int32; extern operator '&' macro Word32And(int32, int32): int32; extern operator '&' macro Word32And(uint32, uint32): uint32; extern operator '==' macro ConstexprInt31Equal(constexpr int31, constexpr int31): constexpr bool; +extern operator '!=' macro +ConstexprInt31NotEqual(constexpr int31, constexpr int31): constexpr bool; extern operator '>=' macro ConstexprInt31GreaterThanEqual( constexpr int31, constexpr int31): constexpr bool; @@ -1732,6 +1927,8 @@ extern operator '!=' macro Word32NotEqual(bool, bool): bool; extern operator '+' macro Float64Add(float64, float64): float64; extern operator '-' macro Float64Sub(float64, float64): float64; +extern operator '*' macro Float64Mul(float64, float64): float64; +extern operator '/' macro Float64Div(float64, float64): float64; extern operator '+' macro NumberAdd(Number, Number): Number; extern operator '-' macro NumberSub(Number, Number): Number; @@ -1845,6 +2042,146 @@ Cast(o: Object): Number return TaggedToNumber(o) otherwise CastError; } +Cast(o: Object): Undefined + labels CastError { + if (o != Undefined) goto CastError; + return %RawDownCast(o); +} + +Cast(o: Object): Numeric labels CastError { + typeswitch (o) { + case (o: Number): { + return o; + } + case (o: BigInt): { + return o; + } + case (HeapObject): { + goto CastError; + } + } +} + +Cast(o: Object): TheHole labels CastError { + if (o == TheHole) return %RawDownCast(o); + goto CastError; +} + +Cast(o: HeapObject): TheHole labels CastError { + const o: Object = o; + return Cast(o) otherwise CastError; +} + +Cast(o: Object): True labels CastError { + if (o == True) return %RawDownCast(o); + goto CastError; +} + +Cast(o: HeapObject): True labels CastError { + const o: Object = o; + return Cast(o) otherwise CastError; +} + +Cast(o: Object): False labels CastError { + if (o == False) return %RawDownCast(o); + goto CastError; +} + +Cast(o: HeapObject): False labels CastError { + const o: Object = o; + return Cast(o) otherwise CastError; +} + +Cast(o: Object): Boolean labels CastError { + typeswitch (o) { + case (o: True): { + return o; + } + case (o: False): { + return o; + } + case (Object): { + goto CastError; + } + } +} + +Cast(o: HeapObject): Boolean labels CastError { + const o: Object = o; + return Cast(o) otherwise CastError; +} + +// TODO(tebbi): These trivial casts for union types should be generated +// automatically. + +Cast(o: Object): JSPrimitive labels CastError { + typeswitch (o) { + case (o: Numeric): { + return o; + } + case (o: String): { + return o; + } + case (o: Symbol): { + return o; + } + case (o: Boolean): { + return o; + } + case (o: Undefined): { + return o; + } + case (o: Null): { + return o; + } + case (Object): { + goto CastError; + } + } +} + +Cast(o: Object): JSAny labels CastError { + typeswitch (o) { + case (o: JSPrimitive): { + return o; + } + case (o: JSReceiver): { + return o; + } + case (Object): { + goto CastError; + } + } +} + +Cast(o: Object): JSAny | TheHole labels CastError { + typeswitch (o) { + case (o: JSAny): { + return o; + } + case (o: TheHole): { + return o; + } + case (Object): { + goto CastError; + } + } +} + +Cast(o: Object): Number | TheHole labels CastError { + typeswitch (o) { + case (o: Number): { + return o; + } + case (o: TheHole): { + return o; + } + case (Object): { + goto CastError; + } + } +} + macro Cast(o: HeapObject): A labels CastError; @@ -1859,6 +2196,12 @@ Cast(o: HeapObject): Null return %RawDownCast(o); } +Cast(o: HeapObject): Undefined + labels CastError { + const o: Object = o; + return Cast(o) otherwise CastError; +} + Cast(o: HeapObject): FixedArray labels CastError { return HeapObjectToFixedArray(o) otherwise CastError; @@ -1928,6 +2271,12 @@ Cast(o: HeapObject): Context goto CastError; } +Cast(o: HeapObject): NativeContext + labels CastError { + if (IsNativeContext(o)) return %RawDownCast(o); + goto CastError; +} + Cast(o: HeapObject): JSObject labels CastError { if (IsJSObject(o)) return %RawDownCast(o); @@ -1957,6 +2306,27 @@ Cast(o: HeapObject): Symbol goto CastError; } +macro Cast(o: Symbol): T labels CastError; +Cast(o: Symbol): PublicSymbol labels CastError { + if (IsPrivateSymbol(o)) goto CastError; + return %RawDownCast(o); +} +Cast(o: Symbol): PrivateSymbol labels CastError { + if (IsPrivateSymbol(o)) { + return %RawDownCast(o); + } + goto CastError; +} + +Cast(o: HeapObject): PublicSymbol labels CastError { + const o = Cast(o) otherwise CastError; + return Cast(o) otherwise CastError; +} +Cast(o: HeapObject): PrivateSymbol labels CastError { + const o = Cast(o) otherwise CastError; + return Cast(o) otherwise CastError; +} + Cast(o: HeapObject): DirectString labels CastError { return TaggedToDirectString(o) otherwise CastError; @@ -2014,7 +2384,13 @@ Cast(implicit context: Context)(o: HeapObject): Cast(implicit context: Context)(o: HeapObject): FastJSRegExp labels CastError { - if (regexp::BranchIfFastRegExp(o)) return %RawDownCast(o); + // TODO(jgruber): Remove or redesign this. There is no single 'fast' regexp, + // the conditions to make a regexp object fast differ based on the callsite. + // For now, run the strict variant since replace (the only current callsite) + // accesses flag getters. + if (regexp::IsFastRegExpStrict(o)) { + return %RawDownCast(o); + } goto CastError; } @@ -2042,7 +2418,8 @@ Cast(implicit context: Context)(o: HeapObject): // Bailout if receiver has slow elements. const elementsKind: ElementsKind = LoadMapElementsKind(map); - if (!IsElementsKindLessThanOrEqual(elementsKind, LAST_FROZEN_ELEMENTS_KIND)) + if (!IsElementsKindLessThanOrEqual( + elementsKind, LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND)) goto CastError; // Verify that our prototype is the initial array prototype. @@ -2076,7 +2453,7 @@ Cast(implicit context: Context)( return %RawDownCast(a); } -Cast(implicit context: Context)(o: HeapObject): JSReceiver +Cast(o: HeapObject): JSReceiver labels CastError { if (IsJSReceiver(o)) return %RawDownCast(o); goto CastError; @@ -2103,6 +2480,21 @@ Cast(implicit context: Context)(o: HeapObject): CoverageInfo goto CastError; } +Cast(o: HeapObject): JSReceiver | Null + labels CastError { + typeswitch (o) { + case (o: Null): { + return o; + } + case (o: JSReceiver): { + return o; + } + case (HeapObject): { + goto CastError; + } + } +} + extern macro AllocateHeapNumberWithValue(float64): HeapNumber; extern macro ChangeInt32ToTagged(int32): Number; extern macro ChangeUint32ToTagged(uint32): Number; @@ -2132,8 +2524,8 @@ extern macro ChangeUint32ToWord(uint32): uintptr; // Doesn't sign-extend. extern macro LoadNativeContext(Context): NativeContext; extern macro TruncateFloat64ToFloat32(float64): float32; extern macro TruncateHeapNumberValueToWord32(HeapNumber): int32; -extern macro LoadJSArrayElementsMap(constexpr ElementsKind, Context): Map; -extern macro LoadJSArrayElementsMap(ElementsKind, Context): Map; +extern macro LoadJSArrayElementsMap(constexpr ElementsKind, NativeContext): Map; +extern macro LoadJSArrayElementsMap(ElementsKind, NativeContext): Map; extern macro ChangeNonnegativeNumberToUintPtr(Number): uintptr; extern macro TryNumberToUintPtr(Number): uintptr labels IfNegative; extern macro NumberConstant(constexpr float64): Number; @@ -2157,6 +2549,7 @@ extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot; extern macro IntPtrConstant(constexpr intptr): intptr; extern macro PointerConstant(constexpr RawPtr): RawPtr; extern macro SingleCharacterStringConstant(constexpr string): String; +extern macro Float64SilenceNaN(float64): float64; extern macro BitcastWordToTaggedSigned(intptr): Smi; extern macro BitcastWordToTaggedSigned(uintptr): Smi; @@ -2241,6 +2634,9 @@ FromConstexpr(e: constexpr ElementsKind): FromConstexpr(s: constexpr string): Object { return StringConstant(s); } +FromConstexpr(s: constexpr string): JSAny { + return StringConstant(s); +} FromConstexpr( c: constexpr NativeContextSlot): NativeContextSlot { return IntPtrConstant(c); @@ -2384,20 +2780,9 @@ Convert(v: Smi): bint { return SmiToBInt(v); } -macro BranchIf(implicit context: Context)(o: B): never - labels True, False { - Cast(o) otherwise False; - goto True; -} - -macro BranchIfNot(implicit context: Context)(o: B): never - labels True, False { - Cast(o) otherwise True; - goto False; -} - macro Is(implicit context: Context)(o: B): bool { - return (BranchIf(o)) ? true : false; + Cast(o) otherwise return false; + return true; } macro UnsafeCast(implicit context: Context)(o: Object): A { @@ -2405,17 +2790,15 @@ macro UnsafeCast(implicit context: Context)(o: Object): A { return %RawDownCast(o); } -UnsafeCast(o: Object): Object { - return o; -} +extern macro FixedArrayMapConstant(): Map; +extern macro FixedCOWArrayMapConstant(): Map; +extern macro EmptyByteArrayConstant(): ByteArray; +extern macro EmptyFixedArrayConstant(): FixedArray; -const kFixedArrayMap: Map = - %RawDownCast(LoadRoot(kFixedArrayMapRootIndex)); -const kCOWMap: Map = %RawDownCast(LoadRoot(kFixedCOWArrayMapRootIndex)); -const kEmptyByteArray: ByteArray = - %RawDownCast(LoadRoot(kEmptyByteArrayRootIndex)); -const kEmptyFixedArray: FixedArray = - %RawDownCast(LoadRoot(kEmptyFixedArrayRootIndex)); +const kFixedArrayMap: Map = FixedArrayMapConstant(); +const kCOWMap: Map = FixedCOWArrayMapConstant(); +const kEmptyByteArray: ByteArray = EmptyByteArrayConstant(); +const kEmptyFixedArray: FixedArray = EmptyFixedArrayConstant(); extern macro IsPrototypeInitialArrayPrototype(implicit context: Context)(Map): bool; @@ -2478,6 +2861,8 @@ extern operator '.floats[]=' macro StoreFixedDoubleArrayElement( FixedDoubleArray, intptr, float64): void; extern operator '.floats[]=' macro StoreFixedDoubleArrayElementSmi( FixedDoubleArray, Smi, float64): void; +extern operator '.floats[]' macro LoadFixedDoubleArrayElement( + FixedDoubleArray, intptr): float64; operator '[]=' macro StoreFixedDoubleArrayDirect( a: FixedDoubleArray, i: Smi, v: Number) { a.floats[i] = Convert(v); @@ -2487,14 +2872,14 @@ operator '[]=' macro StoreFixedArrayDirect(a: FixedArray, i: Smi, v: Object) { } extern macro GetNumberDictionaryNumberOfElements(NumberDictionary): Smi; -extern macro GetIteratorMethod(implicit context: Context)(HeapObject): Object +extern macro GetIteratorMethod(implicit context: Context)(HeapObject): JSAny labels IfIteratorUndefined; extern macro LoadConstructorOrBackPointer(Map): Object; -extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr): Object +extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr): JSAny labels NotData, IfHole; -extern macro BasicStoreNumberDictionaryElement(NumberDictionary, intptr, Object) +extern macro BasicStoreNumberDictionaryElement(NumberDictionary, intptr, JSAny) labels NotData, IfHole, ReadOnly; extern macro IsFastElementsKind(ElementsKind): bool; @@ -2607,16 +2992,15 @@ macro GetRegExpLastMatchInfo(implicit context: Context)(): RegExpMatchInfo { LoadNativeContext(context)[REGEXP_LAST_MATCH_INFO_INDEX]); } -extern transitioning macro Call(Context, Callable, Object): Object; -extern transitioning macro Call(Context, Callable, Object, Object): Object; -extern transitioning macro Call( - Context, Callable, Object, Object, Object): Object; +extern transitioning macro Call(Context, Callable, JSAny): JSAny; +extern transitioning macro Call(Context, Callable, JSAny, JSAny): JSAny; +extern transitioning macro Call(Context, Callable, JSAny, JSAny, JSAny): JSAny; extern transitioning macro Call( - Context, Callable, Object, Object, Object, Object): Object; + Context, Callable, JSAny, JSAny, JSAny, JSAny): JSAny; extern transitioning macro Call( - Context, Callable, Object, Object, Object, Object, Object): Object; + Context, Callable, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; extern transitioning macro Call( - Context, Callable, Object, Object, Object, Object, Object, Object): Object; + Context, Callable, JSAny, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; extern builtin CloneFastJSArray(Context, FastJSArrayForCopy): JSArray; extern macro ExtractFixedArray(FixedArrayBase, Smi, Smi, Smi): FixedArrayBase; @@ -2665,20 +3049,24 @@ macro TorqueCopyElements( count); } -macro LoadElementNoHole(a: JSArray, index: Smi): Object +macro LoadElementNoHole(a: JSArray, index: Smi): JSAny labels IfHole; LoadElementNoHole(implicit context: Context)( - a: JSArray, index: Smi): Object + a: JSArray, index: Smi): JSAny labels IfHole { try { const elements: FixedArray = Cast(a.elements) otherwise Unexpected; - const e: Object = elements.objects[index]; - if (e == TheHole) { - goto IfHole; + const e = UnsafeCast<(JSAny | TheHole)>(elements.objects[index]); + typeswitch (e) { + case (TheHole): { + goto IfHole; + } + case (e: JSAny): { + return e; + } } - return e; } label Unexpected { unreachable; @@ -2686,7 +3074,7 @@ LoadElementNoHole(implicit context: Context)( } LoadElementNoHole(implicit context: Context)( - a: JSArray, index: Smi): Object + a: JSArray, index: Smi): JSAny labels IfHole { try { const elements: FixedDoubleArray = @@ -2717,7 +3105,7 @@ struct FastJSArrayWitness { this.unstable = %RawDownCast(this.stable); } - LoadElementNoHole(implicit context: Context)(k: Smi): Object + LoadElementNoHole(implicit context: Context)(k: Smi): JSAny labels FoundHole { if (this.hasDoubles) { return LoadElementNoHole(this.unstable, k) @@ -2740,7 +3128,7 @@ struct FastJSArrayWitness { } } - LoadElementOrUndefined(implicit context: Context)(k: Smi): Object { + LoadElementOrUndefined(implicit context: Context)(k: Smi): JSAny { try { return this.LoadElementNoHole(k) otherwise FoundHole; } @@ -2760,7 +3148,7 @@ struct FastJSArrayWitness { this.unstable.length = newLength; } - Push(value: Object) labels Failed { + Push(value: JSAny) labels Failed { assert(this.arrayIsPushable); if (this.hasDoubles) { BuildAppendJSArray(HOLEY_DOUBLE_ELEMENTS, this.unstable, value) @@ -2832,7 +3220,7 @@ struct FastJSArrayForReadWitness { this.unstable = %RawDownCast(this.stable); } - LoadElementNoHole(implicit context: Context)(k: Smi): Object + LoadElementNoHole(implicit context: Context)(k: Smi): JSAny labels FoundHole { if (this.hasDoubles) { return LoadElementNoHole(this.unstable, k) @@ -2876,6 +3264,7 @@ extern macro IsJSObject(HeapObject): bool; extern macro IsJSTypedArray(HeapObject): bool; extern macro IsNumberDictionary(HeapObject): bool; extern macro IsContext(HeapObject): bool; +extern macro IsNativeContext(HeapObject): bool; extern macro IsJSReceiver(HeapObject): bool; extern macro TaggedIsCallable(Object): bool; extern macro IsDetachedBuffer(JSArrayBuffer): bool; @@ -2892,7 +3281,7 @@ extern macro IsJSArrayMap(Map): bool; extern macro IsExtensibleMap(Map): bool; extern macro IsJSPrimitiveWrapper(HeapObject): bool; extern macro IsCustomElementsReceiverInstanceType(int32): bool; -extern macro Typeof(Object): Object; +extern macro Typeof(JSAny): String; // Return true iff number is NaN. macro NumberIsNaN(number: Number): bool { @@ -2908,31 +3297,35 @@ macro NumberIsNaN(number: Number): bool { } extern macro GotoIfForceSlowPath() labels Taken; -extern macro BranchIfToBooleanIsTrue(Object): never +macro IsForceSlowPath(): bool { + GotoIfForceSlowPath() otherwise return true; + return false; +} + +extern macro BranchIfToBooleanIsTrue(JSAny): never labels Taken, NotTaken; -extern macro BranchIfToBooleanIsFalse(Object): never +extern macro BranchIfToBooleanIsFalse(JSAny): never labels Taken, NotTaken; -macro ToBoolean(obj: Object): bool { - if (BranchIfToBooleanIsTrue(obj)) { - return true; - } else { - return false; - } +macro ToBoolean(obj: JSAny): bool { + BranchIfToBooleanIsTrue(obj) otherwise return true, return false; } @export macro RequireObjectCoercible(implicit context: Context)( - value: Object, name: constexpr string): Object { + value: JSAny, name: constexpr string): JSAny { if (IsNullOrUndefined(value)) { ThrowTypeError(kCalledOnNullOrUndefined, name); } return value; } -extern macro BranchIfSameValue(Object, Object): never labels Taken, NotTaken; +extern macro BranchIfSameValue(JSAny, JSAny): never labels Taken, NotTaken; +macro SameValue(a: JSAny, b: JSAny): bool { + BranchIfSameValue(a, b) otherwise return true, return false; +} -transitioning macro ToIndex(input: Object, context: Context): Number +transitioning macro ToIndex(input: JSAny, context: Context): Number labels RangeError { if (input == Undefined) { return 0; @@ -2946,7 +3339,7 @@ transitioning macro ToIndex(input: Object, context: Context): Number return value; } -transitioning macro GetLengthProperty(implicit context: Context)(o: Object): +transitioning macro GetLengthProperty(implicit context: Context)(o: JSAny): Number { try { typeswitch (o) { @@ -2956,18 +3349,18 @@ transitioning macro GetLengthProperty(implicit context: Context)(o: Object): case (a: JSArgumentsObjectWithLength): { goto ToLength(a.length); } - case (Object): deferred { + case (JSAny): deferred { goto ToLength(GetProperty(o, kLengthString)); } } } - label ToLength(length: Object) deferred { + label ToLength(length: JSAny) deferred { return ToLength_Inline(context, length); } } transitioning macro GetMethod(implicit context: Context)( - o: Object, name: constexpr string): Callable labels IfNullOrUndefined { + o: JSAny, name: constexpr string): Callable labels IfNullOrUndefined { const value = GetProperty(o, name); if (value == Undefined || value == Null) goto IfNullOrUndefined; return Cast(value) @@ -2976,44 +3369,37 @@ transitioning macro GetMethod(implicit context: Context)( extern macro NumberToString(Number): String; extern macro IsOneByteStringInstanceType(InstanceType): bool; -extern macro AllocateSeqOneByteString(implicit context: Context)(uint32): - String; -extern macro AllocateSeqTwoByteString(implicit context: Context)(uint32): - String; +extern macro AllocateSeqOneByteString(uint32): String; +extern macro AllocateSeqTwoByteString(uint32): String; extern macro ConvertToRelativeIndex(implicit context: Context)( - Object, intptr): intptr; + JSAny, intptr): intptr; -extern builtin ObjectToString(Context, Object): Object; +extern builtin ObjectToString(Context, JSAny): JSAny; extern builtin StringRepeat(Context, String, Number): String; struct KeyValuePair { - key: Object; - value: Object; + key: JSAny; + value: JSAny; } // Macro definitions for compatibility that expose functionality to the CSA // using "legacy" APIs. In Torque code, these should not be used. @export macro IsFastJSArray(o: Object, context: Context): bool { - try { - // Long-term, it's likely not a good idea to have this slow-path test here, - // since it fundamentally breaks the type system. - GotoIfForceSlowPath() otherwise ForceSlow; - } - label ForceSlow { - return false; - } - + // Long-term, it's likely not a good idea to have this slow-path test here, + // since it fundamentally breaks the type system. + if (IsForceSlowPath()) return false; return Is(o); } @export macro BranchIfFastJSArray(o: Object, context: Context): never labels True, False { - // Long-term, it's likely not a good idea to have this slow-path test here, - // since it fundamentally breaks the type system. - GotoIfForceSlowPath() otherwise False; - BranchIf(o) otherwise True, False; + if (IsFastJSArray(o, context)) { + goto True; + } else { + goto False; + } } @export @@ -3021,8 +3407,12 @@ macro BranchIfFastJSArrayForRead(o: Object, context: Context): never labels True, False { // Long-term, it's likely not a good idea to have this slow-path test here, // since it fundamentally breaks the type system. - GotoIfForceSlowPath() otherwise False; - BranchIf(o) otherwise True, False; + if (IsForceSlowPath()) goto False; + if (Is(o)) { + goto True; + } else { + goto False; + } } @export @@ -3037,7 +3427,7 @@ macro IsFastJSArrayForReadWithNoCustomIteration(context: Context, o: Object): } extern transitioning runtime -CreateDataProperty(implicit context: Context)(JSReceiver, Object, Object); +CreateDataProperty(implicit context: Context)(JSReceiver, JSAny, JSAny); namespace runtime { extern runtime @@ -3045,7 +3435,7 @@ namespace runtime { } transitioning builtin FastCreateDataProperty(implicit context: Context)( - receiver: JSReceiver, key: Object, value: Object): Object { + receiver: JSReceiver, key: JSAny, value: JSAny): Object { try { const array = Cast(receiver) otherwise Slow; const index: Smi = Cast(key) otherwise goto Slow; @@ -3090,8 +3480,8 @@ transitioning builtin FastCreateDataProperty(implicit context: Context)( } @export -transitioning macro ToStringImpl(context: Context, o: Object): String { - let result: Object = o; +transitioning macro ToStringImpl(context: Context, o: JSAny): String { + let result: JSAny = o; while (true) { typeswitch (result) { case (num: Number): { @@ -3110,7 +3500,7 @@ transitioning macro ToStringImpl(context: Context, o: Object): String { case (Symbol): { ThrowTypeError(kSymbolToString); } - case (Object): { + case (JSAny): { return ToStringRT(context, o); } } @@ -3160,3 +3550,14 @@ builtin CheckNumberInRange(implicit context: Context)( unreachable; } } + +macro ReplaceTheHoleWithUndefined(o: JSAny | TheHole): JSAny { + typeswitch (o) { + case (TheHole): { + return Undefined; + } + case (a: JSAny): { + return a; + } + } +} diff --git a/deps/v8/src/builtins/boolean.tq b/deps/v8/src/builtins/boolean.tq index 25f9ebd3961add..e8feaf1cf1f762 100644 --- a/deps/v8/src/builtins/boolean.tq +++ b/deps/v8/src/builtins/boolean.tq @@ -5,8 +5,8 @@ namespace boolean { javascript builtin BooleanConstructor( - js-implicit context: Context, receiver: Object, newTarget: Object, - target: JSFunction)(...arguments): Object { + js-implicit context: Context, receiver: JSAny, newTarget: JSAny, + target: JSFunction)(...arguments): JSAny { const value = SelectBooleanConstant(ToBoolean(arguments[0])); if (newTarget == Undefined) { diff --git a/deps/v8/src/builtins/builtins-arguments-gen.cc b/deps/v8/src/builtins/builtins-arguments-gen.cc index d65d57cc79b079..c4399175e9846d 100644 --- a/deps/v8/src/builtins/builtins-arguments-gen.cc +++ b/deps/v8/src/builtins/builtins-arguments-gen.cc @@ -40,20 +40,20 @@ ArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map, empty ? IntPtrConstant(base_size) : ElementOffsetFromIndex(element_count, PACKED_ELEMENTS, mode, base_size + FixedArray::kHeaderSize); - TNode result = Allocate(size); + TNode result = Allocate(size); Comment("Initialize arguments object"); StoreMapNoWriteBarrier(result, map); - Node* empty_fixed_array = LoadRoot(RootIndex::kEmptyFixedArray); + TNode empty_fixed_array = EmptyFixedArrayConstant(); StoreObjectField(result, JSArray::kPropertiesOrHashOffset, empty_fixed_array); - Node* smi_arguments_count = ParameterToTagged(arguments_count, mode); + TNode smi_arguments_count = ParameterToTagged(arguments_count, mode); StoreObjectFieldNoWriteBarrier(result, JSArray::kLengthOffset, smi_arguments_count); Node* arguments = nullptr; if (!empty) { - arguments = InnerAllocate(CAST(result), elements_offset); + arguments = InnerAllocate(result, elements_offset); StoreObjectFieldNoWriteBarrier(arguments, FixedArray::kLengthOffset, smi_arguments_count); - Node* fixed_array_map = LoadRoot(RootIndex::kFixedArrayMap); + TNode fixed_array_map = FixedArrayMapConstant(); StoreMapNoWriteBarrier(arguments, fixed_array_map); } Node* parameter_map = nullptr; @@ -63,8 +63,7 @@ ArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map, parameter_map = InnerAllocate(CAST(arguments), parameter_map_offset); StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset, parameter_map); - Node* sloppy_elements_map = - LoadRoot(RootIndex::kSloppyArgumentsElementsMap); + TNode sloppy_elements_map = SloppyArgumentsElementsMapConstant(); StoreMapNoWriteBarrier(parameter_map, sloppy_elements_map); parameter_map_count = ParameterToTagged(parameter_map_count, mode); StoreObjectFieldNoWriteBarrier(parameter_map, FixedArray::kLengthOffset, @@ -97,13 +96,14 @@ Node* ArgumentsBuiltinsAssembler::ConstructParametersObjectFromArgs( VARIABLE(offset, MachineType::PointerRepresentation()); offset.Bind(IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag)); VariableList list({&offset}, zone()); - arguments.ForEach(list, - [this, elements, &offset](Node* arg) { - StoreNoWriteBarrier(MachineRepresentation::kTagged, - elements, offset.value(), arg); - Increment(&offset, kTaggedSize); - }, - first_arg, nullptr, param_mode); + arguments.ForEach( + list, + [this, elements, &offset](Node* arg) { + StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, + offset.value(), arg); + Increment(&offset, kTaggedSize); + }, + first_arg, nullptr, param_mode); return result; } @@ -121,8 +121,8 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewRestParameter(Node* context, Node* rest_count = IntPtrOrSmiSub(info.argument_count, info.formal_parameter_count, mode); - Node* const native_context = LoadNativeContext(context); - Node* const array_map = + TNode const native_context = LoadNativeContext(context); + TNode const array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); GotoIf(IntPtrOrSmiLessThanOrEqual(rest_count, zero, mode), &no_rest_parameters); @@ -164,7 +164,7 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments(Node* context, Label done(this, &result), empty(this), runtime(this, Label::kDeferred); ParameterMode mode = OptimalParameterMode(); - Node* zero = IntPtrOrSmiConstant(0, mode); + TNode zero = BIntConstant(0); TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount( CAST(context), UncheckedCast(function)); @@ -173,10 +173,10 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments(Node* context, info.argument_count, &runtime, JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize, mode); - Node* const native_context = LoadNativeContext(context); - Node* const map = + TNode const native_context = LoadNativeContext(context); + TNode const map = LoadContextElement(native_context, Context::STRICT_ARGUMENTS_MAP_INDEX); - GotoIf(WordEqual(info.argument_count, zero), &empty); + GotoIf(BIntEqual(info.argument_count, zero), &empty); result.Bind(ConstructParametersObjectFromArgs( map, info.frame, info.argument_count, zero, info.argument_count, mode, @@ -209,7 +209,7 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, VARIABLE(result, MachineRepresentation::kTagged); ParameterMode mode = OptimalParameterMode(); - Node* zero = IntPtrOrSmiConstant(0, mode); + TNode zero = BIntConstant(0); Label done(this, &result), empty(this), no_parameters(this), runtime(this, Label::kDeferred); @@ -217,9 +217,9 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount( CAST(context), UncheckedCast(function)); - GotoIf(WordEqual(info.argument_count, zero), &empty); + GotoIf(BIntEqual(info.argument_count, zero), &empty); - GotoIf(WordEqual(info.formal_parameter_count, zero), &no_parameters); + GotoIf(BIntEqual(info.formal_parameter_count, zero), &no_parameters); { Comment("Mapped parameter JSSloppyArgumentsObject"); @@ -237,8 +237,8 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, elements_allocated, &runtime, JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize * 2, mode); - Node* const native_context = LoadNativeContext(context); - Node* const map = LoadContextElement( + TNode const native_context = LoadNativeContext(context); + TNode const map = LoadContextElement( native_context, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); Node* argument_object; Node* elements; @@ -252,26 +252,26 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, StoreFixedArrayElement(CAST(map_array), 1, elements, SKIP_WRITE_BARRIER); Comment("Fill in non-mapped parameters"); - Node* argument_offset = + TNode argument_offset = ElementOffsetFromIndex(info.argument_count, PACKED_ELEMENTS, mode, FixedArray::kHeaderSize - kHeapObjectTag); - Node* mapped_offset = + TNode mapped_offset = ElementOffsetFromIndex(mapped_count, PACKED_ELEMENTS, mode, FixedArray::kHeaderSize - kHeapObjectTag); CodeStubArguments arguments(this, info.argument_count, info.frame, mode); VARIABLE(current_argument, MachineType::PointerRepresentation()); current_argument.Bind(arguments.AtIndexPtr(info.argument_count, mode)); VariableList var_list1({¤t_argument}, zone()); - mapped_offset = BuildFastLoop( + mapped_offset = UncheckedCast(BuildFastLoop( var_list1, argument_offset, mapped_offset, [this, elements, ¤t_argument](Node* offset) { Increment(¤t_argument, kSystemPointerSize); - Node* arg = LoadBufferObject( + TNode arg = LoadBufferObject( UncheckedCast(current_argument.value()), 0); StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset, arg); }, - -kTaggedSize, INTPTR_PARAMETERS); + -kTaggedSize, INTPTR_PARAMETERS)); // Copy the parameter slots and the holes in the arguments. // We need to fill in mapped_count slots. They index the context, @@ -287,13 +287,13 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, IntPtrOrSmiAdd(IntPtrOrSmiConstant(Context::MIN_CONTEXT_SLOTS, mode), info.formal_parameter_count, mode), mapped_count, mode)); - Node* the_hole = TheHoleConstant(); + TNode the_hole = TheHoleConstant(); VariableList var_list2({&context_index}, zone()); const int kParameterMapHeaderSize = FixedArray::OffsetOfElementAt(2); - Node* adjusted_map_array = IntPtrAdd( + TNode adjusted_map_array = IntPtrAdd( BitcastTaggedToWord(map_array), IntPtrConstant(kParameterMapHeaderSize - FixedArray::kHeaderSize)); - Node* zero_offset = ElementOffsetFromIndex( + TNode zero_offset = ElementOffsetFromIndex( zero, PACKED_ELEMENTS, mode, FixedArray::kHeaderSize - kHeapObjectTag); BuildFastLoop( var_list2, mapped_offset, zero_offset, @@ -317,8 +317,8 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, GotoIfFixedArraySizeDoesntFitInNewSpace( info.argument_count, &runtime, JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize, mode); - Node* const native_context = LoadNativeContext(context); - Node* const map = + TNode const native_context = LoadNativeContext(context); + TNode const map = LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX); result.Bind(ConstructParametersObjectFromArgs( map, info.frame, info.argument_count, zero, info.argument_count, mode, @@ -331,8 +331,8 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, BIND(&empty); { Comment("Empty JSSloppyArgumentsObject"); - Node* const native_context = LoadNativeContext(context); - Node* const map = + TNode const native_context = LoadNativeContext(context); + TNode const map = LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX); Node* arguments; Node* elements; diff --git a/deps/v8/src/builtins/builtins-array-gen.cc b/deps/v8/src/builtins/builtins-array-gen.cc index 07f74cb4298db9..c7d8eb009125da 100644 --- a/deps/v8/src/builtins/builtins-array-gen.cc +++ b/deps/v8/src/builtins/builtins-array-gen.cc @@ -30,272 +30,267 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler( to_(this, MachineRepresentation::kTagged, SmiConstant(0)), fully_spec_compliant_(this, {&k_, &a_, &to_}) {} - void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() { - // 6. Let A be ? TypedArraySpeciesCreate(O, len). - TNode original_array = CAST(o()); - TNode length = CAST(len_); - const char* method_name = "%TypedArray%.prototype.map"; - - TNode a = TypedArraySpeciesCreateByLength( - context(), method_name, original_array, length); - // In the Spec and our current implementation, the length check is already - // performed in TypedArraySpeciesCreate. - CSA_ASSERT(this, UintPtrLessThanOrEqual(SmiUntag(CAST(len_)), - LoadJSTypedArrayLength(a))); - fast_typed_array_target_ = - Word32Equal(LoadElementsKind(original_array), LoadElementsKind(a)); - a_.Bind(a); - } - - // See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map. - Node* ArrayBuiltinsAssembler::TypedArrayMapProcessor(Node* k_value, Node* k) { - // 8. c. Let mapped_value be ? Call(callbackfn, T, « kValue, k, O »). - Node* mapped_value = CallJS(CodeFactory::Call(isolate()), context(), - callbackfn(), this_arg(), k_value, k, o()); - Label fast(this), slow(this), done(this), detached(this, Label::kDeferred); - - // 8. d. Perform ? Set(A, Pk, mapped_value, true). - // Since we know that A is a TypedArray, this always ends up in - // #sec-integer-indexed-exotic-objects-set-p-v-receiver and then - // tc39.github.io/ecma262/#sec-integerindexedelementset . - Branch(fast_typed_array_target_, &fast, &slow); - - BIND(&fast); - // #sec-integerindexedelementset - // 5. If arrayTypeName is "BigUint64Array" or "BigInt64Array", let - // numValue be ? ToBigInt(v). - // 6. Otherwise, let numValue be ? ToNumber(value). - Node* num_value; - if (source_elements_kind_ == BIGINT64_ELEMENTS || - source_elements_kind_ == BIGUINT64_ELEMENTS) { - num_value = ToBigInt(context(), mapped_value); - } else { - num_value = ToNumber_Inline(context(), mapped_value); - } - // The only way how this can bailout is because of a detached buffer. - EmitElementStore(a(), k, num_value, source_elements_kind_, - KeyedAccessStoreMode::STANDARD_STORE, &detached, - context()); - Goto(&done); +void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() { + // 6. Let A be ? TypedArraySpeciesCreate(O, len). + TNode original_array = CAST(o()); + TNode length = CAST(len_); + const char* method_name = "%TypedArray%.prototype.map"; + + TNode a = TypedArraySpeciesCreateByLength( + context(), method_name, original_array, length); + // In the Spec and our current implementation, the length check is already + // performed in TypedArraySpeciesCreate. + CSA_ASSERT(this, UintPtrLessThanOrEqual(SmiUntag(CAST(len_)), + LoadJSTypedArrayLength(a))); + fast_typed_array_target_ = + Word32Equal(LoadElementsKind(original_array), LoadElementsKind(a)); + a_.Bind(a); +} - BIND(&slow); - SetPropertyStrict(context(), CAST(a()), CAST(k), CAST(mapped_value)); - Goto(&done); +// See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map. +Node* ArrayBuiltinsAssembler::TypedArrayMapProcessor(Node* k_value, Node* k) { + // 8. c. Let mapped_value be ? Call(callbackfn, T, « kValue, k, O »). + Node* mapped_value = CallJS(CodeFactory::Call(isolate()), context(), + callbackfn(), this_arg(), k_value, k, o()); + Label fast(this), slow(this), done(this), detached(this, Label::kDeferred); - BIND(&detached); - // tc39.github.io/ecma262/#sec-integerindexedelementset - // 8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. - ThrowTypeError(context_, MessageTemplate::kDetachedOperation, name_); + // 8. d. Perform ? Set(A, Pk, mapped_value, true). + // Since we know that A is a TypedArray, this always ends up in + // #sec-integer-indexed-exotic-objects-set-p-v-receiver and then + // tc39.github.io/ecma262/#sec-integerindexedelementset . + Branch(fast_typed_array_target_, &fast, &slow); - BIND(&done); - return a(); + BIND(&fast); + // #sec-integerindexedelementset + // 5. If arrayTypeName is "BigUint64Array" or "BigInt64Array", let + // numValue be ? ToBigInt(v). + // 6. Otherwise, let numValue be ? ToNumber(value). + Node* num_value; + if (source_elements_kind_ == BIGINT64_ELEMENTS || + source_elements_kind_ == BIGUINT64_ELEMENTS) { + num_value = ToBigInt(context(), mapped_value); + } else { + num_value = ToNumber_Inline(context(), mapped_value); } + // The only way how this can bailout is because of a detached buffer. + EmitElementStore(a(), k, num_value, source_elements_kind_, + KeyedAccessStoreMode::STANDARD_STORE, &detached, context()); + Goto(&done); - void ArrayBuiltinsAssembler::NullPostLoopAction() {} - - void ArrayBuiltinsAssembler::FillFixedArrayWithSmiZero( - TNode array, TNode smi_length) { - CSA_ASSERT(this, Word32BinaryNot(IsFixedDoubleArray(array))); + BIND(&slow); + SetPropertyStrict(context(), CAST(a()), CAST(k), CAST(mapped_value)); + Goto(&done); - TNode length = SmiToIntPtr(smi_length); - TNode byte_length = TimesTaggedSize(length); - CSA_ASSERT(this, UintPtrLessThan(length, byte_length)); + BIND(&detached); + // tc39.github.io/ecma262/#sec-integerindexedelementset + // 8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. + ThrowTypeError(context_, MessageTemplate::kDetachedOperation, name_); - static const int32_t fa_base_data_offset = - FixedArray::kHeaderSize - kHeapObjectTag; - TNode backing_store = IntPtrAdd( - BitcastTaggedToWord(array), IntPtrConstant(fa_base_data_offset)); + BIND(&done); + return a(); +} - // Call out to memset to perform initialization. - TNode memset = - ExternalConstant(ExternalReference::libc_memset_function()); - STATIC_ASSERT(kSizetSize == kIntptrSize); - CallCFunction(memset, MachineType::Pointer(), - std::make_pair(MachineType::Pointer(), backing_store), - std::make_pair(MachineType::IntPtr(), IntPtrConstant(0)), - std::make_pair(MachineType::UintPtr(), byte_length)); - } +void ArrayBuiltinsAssembler::NullPostLoopAction() {} + +void ArrayBuiltinsAssembler::FillFixedArrayWithSmiZero(TNode array, + TNode smi_length) { + CSA_ASSERT(this, Word32BinaryNot(IsFixedDoubleArray(array))); + + TNode length = SmiToIntPtr(smi_length); + TNode byte_length = TimesTaggedSize(length); + CSA_ASSERT(this, UintPtrLessThan(length, byte_length)); + + static const int32_t fa_base_data_offset = + FixedArray::kHeaderSize - kHeapObjectTag; + TNode backing_store = IntPtrAdd(BitcastTaggedToWord(array), + IntPtrConstant(fa_base_data_offset)); + + // Call out to memset to perform initialization. + TNode memset = + ExternalConstant(ExternalReference::libc_memset_function()); + STATIC_ASSERT(kSizetSize == kIntptrSize); + CallCFunction(memset, MachineType::Pointer(), + std::make_pair(MachineType::Pointer(), backing_store), + std::make_pair(MachineType::IntPtr(), IntPtrConstant(0)), + std::make_pair(MachineType::UintPtr(), byte_length)); +} - void ArrayBuiltinsAssembler::ReturnFromBuiltin(Node* value) { - if (argc_ == nullptr) { - Return(value); - } else { - // argc_ doesn't include the receiver, so it has to be added back in - // manually. - PopAndReturn(IntPtrAdd(argc_, IntPtrConstant(1)), value); - } +void ArrayBuiltinsAssembler::ReturnFromBuiltin(Node* value) { + if (argc_ == nullptr) { + Return(value); + } else { + // argc_ doesn't include the receiver, so it has to be added back in + // manually. + PopAndReturn(IntPtrAdd(argc_, IntPtrConstant(1)), value); } +} - void ArrayBuiltinsAssembler::InitIteratingArrayBuiltinBody( - TNode context, TNode receiver, Node* callbackfn, - Node* this_arg, TNode argc) { - context_ = context; - receiver_ = receiver; - callbackfn_ = callbackfn; - this_arg_ = this_arg; - argc_ = argc; - } +void ArrayBuiltinsAssembler::InitIteratingArrayBuiltinBody( + TNode context, TNode receiver, Node* callbackfn, + Node* this_arg, TNode argc) { + context_ = context; + receiver_ = receiver; + callbackfn_ = callbackfn; + this_arg_ = this_arg; + argc_ = argc; +} - void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody( - const char* name, const BuiltinResultGenerator& generator, - const CallResultProcessor& processor, const PostLoopAction& action, - ForEachDirection direction) { - name_ = name; +void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody( + const char* name, const BuiltinResultGenerator& generator, + const CallResultProcessor& processor, const PostLoopAction& action, + ForEachDirection direction) { + name_ = name; - // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray + // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray - Label throw_not_typed_array(this, Label::kDeferred); + Label throw_not_typed_array(this, Label::kDeferred); - GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array); - TNode typed_array_map = LoadMap(CAST(receiver_)); - GotoIfNot(IsJSTypedArrayMap(typed_array_map), &throw_not_typed_array); + GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array); + TNode typed_array_map = LoadMap(CAST(receiver_)); + GotoIfNot(IsJSTypedArrayMap(typed_array_map), &throw_not_typed_array); - TNode typed_array = CAST(receiver_); - o_ = typed_array; + TNode typed_array = CAST(receiver_); + o_ = typed_array; - TNode array_buffer = - LoadJSArrayBufferViewBuffer(typed_array); - ThrowIfArrayBufferIsDetached(context_, array_buffer, name_); + TNode array_buffer = LoadJSArrayBufferViewBuffer(typed_array); + ThrowIfArrayBufferIsDetached(context_, array_buffer, name_); - len_ = ChangeUintPtrToTagged(LoadJSTypedArrayLength(typed_array)); + len_ = ChangeUintPtrToTagged(LoadJSTypedArrayLength(typed_array)); - Label throw_not_callable(this, Label::kDeferred); - Label distinguish_types(this); - GotoIf(TaggedIsSmi(callbackfn_), &throw_not_callable); - Branch(IsCallableMap(LoadMap(callbackfn_)), &distinguish_types, - &throw_not_callable); + Label throw_not_callable(this, Label::kDeferred); + Label distinguish_types(this); + GotoIf(TaggedIsSmi(callbackfn_), &throw_not_callable); + Branch(IsCallableMap(LoadMap(callbackfn_)), &distinguish_types, + &throw_not_callable); - BIND(&throw_not_typed_array); - ThrowTypeError(context_, MessageTemplate::kNotTypedArray); + BIND(&throw_not_typed_array); + ThrowTypeError(context_, MessageTemplate::kNotTypedArray); - BIND(&throw_not_callable); - ThrowTypeError(context_, MessageTemplate::kCalledNonCallable, callbackfn_); + BIND(&throw_not_callable); + ThrowTypeError(context_, MessageTemplate::kCalledNonCallable, callbackfn_); - Label unexpected_instance_type(this); - BIND(&unexpected_instance_type); - Unreachable(); + Label unexpected_instance_type(this); + BIND(&unexpected_instance_type); + Unreachable(); - std::vector elements_kinds = { + std::vector elements_kinds = { #define ELEMENTS_KIND(Type, type, TYPE, ctype) TYPE##_ELEMENTS, - TYPED_ARRAYS(ELEMENTS_KIND) + TYPED_ARRAYS(ELEMENTS_KIND) #undef ELEMENTS_KIND - }; - std::list