diff --git a/common.gypi b/common.gypi index 0d96ca77b3cc70..b5e1bc0628d22c 100644 --- a/common.gypi +++ b/common.gypi @@ -27,7 +27,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.16', + 'v8_embedder_string': '-node.17', # Enable disassembler for `--print-code` v8 options 'v8_enable_disassembler': 1, diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 7f819872fa90c2..c938db9b579429 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -10011,6 +10011,25 @@ void debug::QueryObjects(v8::Local v8_context, predicate, objects); } +void debug::GlobalLexicalScopeNames( + v8::Local v8_context, + v8::PersistentValueVector* names) { + i::Handle context = Utils::OpenHandle(*v8_context); + i::Handle table( + context->global_object()->native_context()->script_context_table()); + for (int i = 0; i < table->used(); i++) { + i::Handle context = i::ScriptContextTable::GetContext(table, i); + DCHECK(context->IsScriptContext()); + i::Handle scope_info(context->scope_info()); + int local_count = scope_info->ContextLocalCount(); + for (int j = 0; j < local_count; ++j) { + i::String* name = scope_info->ContextLocalName(j); + if (i::ScopeInfo::VariableIsSynthetic(name)) continue; + names->Append(Utils::ToLocal(handle(name))); + } + } +} + Local CpuProfileNode::GetFunctionName() const { const i::ProfileNode* node = reinterpret_cast(this); i::Isolate* isolate = node->isolate(); diff --git a/deps/v8/src/debug/debug-interface.h b/deps/v8/src/debug/debug-interface.h index 78001524b2c160..887208ad727d99 100644 --- a/deps/v8/src/debug/debug-interface.h +++ b/deps/v8/src/debug/debug-interface.h @@ -401,6 +401,9 @@ void QueryObjects(v8::Local context, QueryObjectPredicate* predicate, v8::PersistentValueVector* objects); +void GlobalLexicalScopeNames(v8::Local context, + v8::PersistentValueVector* names); + } // namespace debug } // namespace v8 diff --git a/deps/v8/src/inspector/js_protocol.json b/deps/v8/src/inspector/js_protocol.json index 439de72c103b66..0be9bd2bccc434 100644 --- a/deps/v8/src/inspector/js_protocol.json +++ b/deps/v8/src/inspector/js_protocol.json @@ -353,6 +353,17 @@ { "name": "objects", "$ref": "RemoteObject", "description": "Array with objects." } ], "experimental": true + }, + { + "name": "globalLexicalScopeNames", + "parameters": [ + { "name": "executionContextId", "$ref": "ExecutionContextId", "optional": true, "description": "Specifies in which execution context to lookup global scope variables." } + ], + "returns": [ + { "name": "names", "type": "array", "items": { "type": "string" } } + ], + "description": "Returns all let, const and class variables from global scope.", + "experimental": true } ], "events": [ diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.cc b/deps/v8/src/inspector/v8-runtime-agent-impl.cc index bdae0ef7a1a810..e9159451f7aba5 100644 --- a/deps/v8/src/inspector/v8-runtime-agent-impl.cc +++ b/deps/v8/src/inspector/v8-runtime-agent-impl.cc @@ -537,6 +537,27 @@ Response V8RuntimeAgentImpl::queryObjects( resultArray, scope.objectGroupName(), false, false, objects); } +Response V8RuntimeAgentImpl::globalLexicalScopeNames( + Maybe executionContextId, + std::unique_ptr>* outNames) { + int contextId = 0; + Response response = ensureContext(m_inspector, m_session->contextGroupId(), + std::move(executionContextId), &contextId); + if (!response.isSuccess()) return response; + + InjectedScript::ContextScope scope(m_session, contextId); + response = scope.initialize(); + if (!response.isSuccess()) return response; + + v8::PersistentValueVector names(m_inspector->isolate()); + v8::debug::GlobalLexicalScopeNames(scope.context(), &names); + *outNames = protocol::Array::create(); + for (size_t i = 0; i < names.Size(); ++i) { + (*outNames)->addItem(toProtocolString(names.Get(i))); + } + return Response::OK(); +} + void V8RuntimeAgentImpl::restore() { if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled, false)) return; diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.h b/deps/v8/src/inspector/v8-runtime-agent-impl.h index 6f3b98cf44e48f..5f2be2b8aba0dd 100644 --- a/deps/v8/src/inspector/v8-runtime-agent-impl.h +++ b/deps/v8/src/inspector/v8-runtime-agent-impl.h @@ -100,6 +100,9 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { Response queryObjects( const String16& prototypeObjectId, std::unique_ptr* objects) override; + Response globalLexicalScopeNames( + Maybe executionContextId, + std::unique_ptr>* outNames) override; void reset(); void reportExecutionContextCreated(InspectedContext*); diff --git a/deps/v8/test/inspector/runtime/runtime-global-lexical-scope-names-expected.txt b/deps/v8/test/inspector/runtime/runtime-global-lexical-scope-names-expected.txt new file mode 100644 index 00000000000000..9ae422296ab516 --- /dev/null +++ b/deps/v8/test/inspector/runtime/runtime-global-lexical-scope-names-expected.txt @@ -0,0 +1,63 @@ +Test for Runtime.globalLexicalScopeVariablesNames +Running 'let a = 1' +Values: +a = 1 + +Running 'let b = 2' +Values: +a = 1 +b = 2 + +Running 'let b = 3' +Values: +a = 1 +b = 2 + +Running 'const c = 4' +Values: +a = 1 +b = 2 +c = 4 + +Running 'var d = 5' +(should not be in list of scoped variables) +Values: +a = 1 +b = 2 +c = 4 + +Running 'class Foo{}' +Values: +a = 1 +b = 2 +c = 4 +Foo = +{ + className : Function + description : class Foo{} + objectId : + type : function +} + +Adding script with scope variables +Values: +a = 1 +b = 2 +c = 4 +Foo = +{ + className : Function + description : class Foo{} + objectId : + type : function +} +e = 1 +f = 2 +g = 3 +Boo = +{ + className : Function + description : class Boo {} + objectId : + type : function +} diff --git a/deps/v8/test/inspector/runtime/runtime-global-lexical-scope-names.js b/deps/v8/test/inspector/runtime/runtime-global-lexical-scope-names.js new file mode 100644 index 00000000000000..7e41f6a99f1a16 --- /dev/null +++ b/deps/v8/test/inspector/runtime/runtime-global-lexical-scope-names.js @@ -0,0 +1,59 @@ +// Copyright 2017 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. + +let {session, contextGroup, Protocol} = + InspectorTest.start('Test for Runtime.globalLexicalScopeVariablesNames'); + +(async function test() { + InspectorTest.log('Running \'let a = 1\''); + Protocol.Runtime.evaluate({expression: 'let a = 1'}); + await dumpGlobalScopeVariables(); + + InspectorTest.log('Running \'let b = 2\''); + Protocol.Runtime.evaluate({expression: 'let b = 2'}); + await dumpGlobalScopeVariables(); + + InspectorTest.log('Running \'let b = 3\''); + Protocol.Runtime.evaluate({expression: 'let b = 3'}); + await dumpGlobalScopeVariables(); + + InspectorTest.log('Running \'const c = 4\''); + Protocol.Runtime.evaluate({expression: 'const c = 4'}); + await dumpGlobalScopeVariables(); + + InspectorTest.log('Running \'var d = 5\''); + InspectorTest.log('(should not be in list of scoped variables)'); + Protocol.Runtime.evaluate({expression: 'var d = 5'}); + await dumpGlobalScopeVariables(); + + InspectorTest.log('Running \'class Foo{}\''); + Protocol.Runtime.evaluate({expression: 'class Foo{}'}); + await dumpGlobalScopeVariables(); + + InspectorTest.log('Adding script with scope variables'); + contextGroup.addScript(` + let e = 1; + const f = 2; + const g = 3; + class Boo {}; + `); + await dumpGlobalScopeVariables(); + InspectorTest.completeTest(); +})(); + +async function dumpGlobalScopeVariables() { + let {result:{names}} = + await Protocol.Runtime.globalLexicalScopeNames(); + InspectorTest.log('Values:'); + for (let name of names) { + let {result:{result}} = await Protocol.Runtime.evaluate({expression: name}); + if (result.value) { + InspectorTest.log(`${name} = ${result.value}`); + } else { + InspectorTest.log(`${name} =`); + InspectorTest.logMessage(result); + } + } + InspectorTest.log(''); +} diff --git a/deps/v8/test/inspector/runtime/runtime-restore.js b/deps/v8/test/inspector/runtime/runtime-restore.js index 09e44677e5c13a..77fa823e7e8665 100644 --- a/deps/v8/test/inspector/runtime/runtime-restore.js +++ b/deps/v8/test/inspector/runtime/runtime-restore.js @@ -1,6 +1,6 @@ // Copyright 2017 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.v8 +// found in the LICENSE file. let {session, contextGroup, Protocol} = InspectorTest.start('Checks that Runtime agent correctly restore its state.');