Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.28',
'v8_embedder_string': '-node.29',

##### V8 defaults for Node.js #####

Expand All @@ -54,6 +54,8 @@
# Refs: https://github.com/nodejs/node/issues/23167
# Enable compiler warnings when using V8_DEPRECATED apis from V8 code.
'v8_deprecation_warnings': 0,
# Check that JavaScript execution is disallowed in V8 API interrupts.
'v8_disallow_js_in_api_interrupts_is_checked': 1,
# Enable compiler warnings when using V8_DEPRECATE_SOON apis from V8 code.
'v8_imminent_deprecation_warnings': 0,

Expand Down Expand Up @@ -534,6 +536,9 @@
['v8_deprecation_warnings == 1', {
'defines': ['V8_DEPRECATION_WARNINGS',],
}],
['v8_disallow_js_in_api_interrupts_is_checked == 1', {
'defines': ['V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED',],
}],
['v8_imminent_deprecation_warnings == 1', {
'defines': ['V8_IMMINENT_DEPRECATION_WARNINGS',],
}],
Expand Down
6 changes: 6 additions & 0 deletions deps/v8/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ v8_flag(name = "v8_enable_trace_maps")

v8_flag(name = "v8_enable_v8_checks")

v8_flag(
name = "v8_disallow_js_in_api_interrupts_is_checked",
default = True,
)

v8_flag(name = "v8_enable_verify_csa")

v8_flag(name = "v8_enable_verify_heap")
Expand Down Expand Up @@ -496,6 +501,7 @@ v8_config(
"v8_android_log_stdout": "V8_ANDROID_LOG_STDOUT",
"v8_code_comments": "V8_CODE_COMMENTS",
"v8_deprecation_warnings": "V8_DEPRECATION_WARNINGS",
"v8_disallow_js_in_api_interrupts_is_checked": "V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED",
"v8_imminent_deprecation_warnings": "V8_IMMINENT_DEPRECATION_WARNINGS",
"v8_enable_debug_code": "V8_ENABLE_DEBUG_CODE",
"v8_enable_disassembler": "ENABLE_DISASSEMBLER",
Expand Down
11 changes: 11 additions & 0 deletions deps/v8/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ declare_args() {
# Enable compiler warnings when using V8_DEPRECATED apis.
v8_deprecation_warnings = true

# Check that executing JavaScript inside API interrupt callbacks is
# disallowed.
v8_disallow_js_in_api_interrupts_is_checked = true

# Enable compiler warnings when using V8_DEPRECATE_SOON apis.
v8_imminent_deprecation_warnings = true

Expand Down Expand Up @@ -999,6 +1003,7 @@ external_v8_defines = [
"V8_COMPRESS_ZONES",
"V8_ENABLE_SANDBOX",
"V8_DEPRECATION_WARNINGS",
"V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED",
"V8_IMMINENT_DEPRECATION_WARNINGS",
"V8_USE_PERFETTO",
"V8_USE_PERFETTO_JSON_EXPORT",
Expand Down Expand Up @@ -1047,6 +1052,10 @@ if (v8_enable_sandbox) {
if (v8_deprecation_warnings) {
enabled_external_v8_defines += [ "V8_DEPRECATION_WARNINGS" ]
}
if (v8_disallow_js_in_api_interrupts_is_checked) {
enabled_external_v8_defines +=
[ "V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED" ]
}
if (v8_imminent_deprecation_warnings) {
enabled_external_v8_defines += [ "V8_IMMINENT_DEPRECATION_WARNINGS" ]
}
Expand Down Expand Up @@ -3093,6 +3102,8 @@ generated_file("v8_generate_features_json") {
output_conversion = "json"
contents = {
v8_deprecation_warnings = v8_deprecation_warnings
v8_disallow_js_in_api_interrupts_is_checked =
v8_disallow_js_in_api_interrupts_is_checked
v8_enable_31bit_smis_on_64bit_arch = v8_enable_31bit_smis_on_64bit_arch
v8_enable_direct_handle = v8_enable_direct_handle
v8_enable_extensible_ro_snapshot = v8_enable_extensible_ro_snapshot
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/common/assert-scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class V8_NODISCARD PerThreadAssertScope
ScopeType& operator=(const ScopeType&) = delete; \
V8_EXPORT_PRIVATE ~ScopeType(); \
\
static bool IsAllowed(Isolate* isolate); \
V8_EXPORT_PRIVATE static bool IsAllowed(Isolate* isolate); \
\
V8_EXPORT_PRIVATE static void Open(Isolate* isolate, \
bool* was_execution_allowed); \
Expand Down
7 changes: 7 additions & 0 deletions deps/v8/src/execution/isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2245,6 +2245,13 @@ void Isolate::InvokeApiInterruptCallbacks() {
}
VMState<EXTERNAL> state(this);
HandleScope handle_scope(this);
// API interrupt callbacks are forbidden from executing JavaScript on the
// interrupted Isolate (see v8::Isolate::RequestInterrupt contract in
// v8-isolate.h: "Registered |callback| must not reenter interrupted
// Isolate.").
#ifdef V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED
DisallowJavascriptExecution no_js(this);
#endif // V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED
entry.first(reinterpret_cast<v8::Isolate*>(this), entry.second);
}
}
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/inspector/v8-debugger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ void V8Debugger::handleProgramBreak(
}
});
{
v8::Isolate::AllowJavascriptExecutionScope allow_script(m_isolate);
v8::Context::Scope scope(pausedContext);

m_inspector->forEachSession(
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/inspector/v8-inspector-impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ int V8InspectorImpl::resolveUniqueContextId(

v8::MaybeLocal<v8::Value> V8InspectorImpl::compileAndRunInternalScript(
v8::Local<v8::Context> context, v8::Local<v8::String> source) {
v8::Isolate::AllowJavascriptExecutionScope allow_script(m_isolate);
v8::Local<v8::UnboundScript> unboundScript;
if (!v8::debug::CompileInspectorScript(m_isolate, source)
.ToLocal(&unboundScript))
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/inspector/v8-inspector-session-impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
}

void V8InspectorSessionImpl::dispatchProtocolMessage(StringView message) {
v8::Isolate::AllowJavascriptExecutionScope allow_script(
m_inspector->isolate());
KeepSessionAliveScope keepAlive(*this);

using v8_crdtp::span;
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/inspector/v8-regex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ V8Regex::V8Regex(V8InspectorImpl* inspector, const String16& pattern,
v8::Local<v8::RegExp> regex;
// Protect against reentrant debugger calls via interrupts.
v8::debug::PostponeInterruptsScope no_interrupts(m_inspector->isolate());
v8::Isolate::AllowJavascriptExecutionScope allow_js(m_inspector->isolate());
if (v8::RegExp::New(context, toV8String(isolate, pattern),
static_cast<v8::RegExp::Flags>(flags))
.ToLocal(&regex))
Expand Down Expand Up @@ -69,6 +70,7 @@ int V8Regex::match(const String16& string, int startFrom,
v8::MicrotasksScope::kDoNotRunMicrotasks);
// Protect against reentrant debugger calls via interrupts.
v8::debug::PostponeInterruptsScope no_interrupts(m_inspector->isolate());
v8::Isolate::AllowJavascriptExecutionScope allow_js(m_inspector->isolate());
v8::TryCatch tryCatch(isolate);

v8::Local<v8::RegExp> regex = m_regex.Get(isolate);
Expand Down
20 changes: 20 additions & 0 deletions deps/v8/test/cctest/test-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22306,6 +22306,26 @@ TEST(RequestInterruptSmallScripts) {
CHECK(interrupt_was_called);
}

#ifdef V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED
static bool interrupt_check_no_js = false;
void DisallowJsInterruptCallback(v8::Isolate* isolate, void* data) {
CHECK(!i::AllowJavascriptExecution::IsAllowed(
reinterpret_cast<i::Isolate*>(isolate)));
interrupt_check_no_js = true;
}

TEST(RequestInterruptDisallowsJavascript) {
LocalContext env;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);

interrupt_check_no_js = false;
isolate->RequestInterrupt(&DisallowJsInterruptCallback, nullptr);
CompileRun("(function(x){return x;})(1);");
CHECK(interrupt_check_no_js);
}
#endif // V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED

static v8::Global<Value> function_new_expected_env_global;
static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
v8::Isolate* isolate = info.GetIsolate();
Expand Down
8 changes: 7 additions & 1 deletion deps/v8/test/cctest/test-regexp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,13 @@ class InterruptTest {
CHECK(string->ContainsOnlyOneByte());
// Internalize the subject by using it as a computed property name in an
// object.
CompileRun("o = { [subject_string]: 'foo' }");
{
// This test is technically wrong for running JS in a C++ interrupt.
// However we know that the interuptee here is the regexp engine, which
// does not care.
Isolate::AllowJavascriptExecutionScope allow_script(isolate);
CompileRun("o = { [subject_string]: 'foo' }");
}
CHECK(string->IsOneByte());
}

Expand Down
35 changes: 35 additions & 0 deletions deps/v8/test/debugger/debug/futex-reentrant-wait.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2026 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax

var Debug = debug.Debug;
var exception = null;

Debug.setListener(function (event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.Break) {
try {
var sab2 = new SharedArrayBuffer(4);
var i32a2 = new Int32Array(sab2);
Atomics.wait(i32a2, 0, 0, 10);
} catch (e) {
exception = e;
}
}
});

let sab = new SharedArrayBuffer(4);
let i32a = new Int32Array(sab);

let timeout = {
valueOf: function() {
%ScheduleBreak();
return 10;
}
};

Atomics.wait(i32a, 0, 0, timeout);

assertNotNull(exception);
assertTrue(exception.message.includes("cannot be called in this context"));
Loading
Loading