11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "tools/v8windbg/src/v8windbg-extension.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include <iostream> 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci#include "tools/v8windbg/base/utilities.h" 101cb0ef41Sopenharmony_ci#include "tools/v8windbg/src/cur-isolate.h" 111cb0ef41Sopenharmony_ci#include "tools/v8windbg/src/js-stack.h" 121cb0ef41Sopenharmony_ci#include "tools/v8windbg/src/local-variables.h" 131cb0ef41Sopenharmony_ci#include "tools/v8windbg/src/object-inspection.h" 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cistd::unique_ptr<Extension> Extension::current_extension_ = nullptr; 161cb0ef41Sopenharmony_ciconst wchar_t* pcur_isolate = L"curisolate"; 171cb0ef41Sopenharmony_ciconst wchar_t* pjs_stack = L"jsstack"; 181cb0ef41Sopenharmony_ciconst wchar_t* pv8_object = L"v8object"; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ciHRESULT CreateExtension() { 211cb0ef41Sopenharmony_ci if (Extension::Current() != nullptr || sp_data_model_manager == nullptr || 221cb0ef41Sopenharmony_ci sp_debug_host == nullptr) { 231cb0ef41Sopenharmony_ci return E_FAIL; 241cb0ef41Sopenharmony_ci } else { 251cb0ef41Sopenharmony_ci std::unique_ptr<Extension> new_extension(new (std::nothrow) Extension()); 261cb0ef41Sopenharmony_ci if (new_extension == nullptr) return E_FAIL; 271cb0ef41Sopenharmony_ci RETURN_IF_FAIL(new_extension->Initialize()); 281cb0ef41Sopenharmony_ci Extension::SetExtension(std::move(new_extension)); 291cb0ef41Sopenharmony_ci return S_OK; 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci} 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_civoid DestroyExtension() { Extension::SetExtension(nullptr); } 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_cibool Extension::DoesTypeDeriveFromObject( 361cb0ef41Sopenharmony_ci const WRL::ComPtr<IDebugHostType>& sp_type) { 371cb0ef41Sopenharmony_ci _bstr_t name; 381cb0ef41Sopenharmony_ci HRESULT hr = sp_type->GetName(name.GetAddress()); 391cb0ef41Sopenharmony_ci if (!SUCCEEDED(hr)) return false; 401cb0ef41Sopenharmony_ci if (std::string(static_cast<const char*>(name)) == kObject) return true; 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostSymbolEnumerator> sp_super_class_enumerator; 431cb0ef41Sopenharmony_ci hr = sp_type->EnumerateChildren(SymbolKind::SymbolBaseClass, nullptr, 441cb0ef41Sopenharmony_ci &sp_super_class_enumerator); 451cb0ef41Sopenharmony_ci if (!SUCCEEDED(hr)) return false; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci while (true) { 481cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostSymbol> sp_type_symbol; 491cb0ef41Sopenharmony_ci if (sp_super_class_enumerator->GetNext(&sp_type_symbol) != S_OK) break; 501cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostBaseClass> sp_base_class; 511cb0ef41Sopenharmony_ci if (FAILED(sp_type_symbol.As(&sp_base_class))) continue; 521cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostType> sp_base_type; 531cb0ef41Sopenharmony_ci hr = sp_base_class->GetType(&sp_base_type); 541cb0ef41Sopenharmony_ci if (!SUCCEEDED(hr)) continue; 551cb0ef41Sopenharmony_ci if (DoesTypeDeriveFromObject(sp_base_type)) { 561cb0ef41Sopenharmony_ci return true; 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci return false; 611cb0ef41Sopenharmony_ci} 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugHostType> Extension::GetV8ObjectType( 641cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostContext>& sp_ctx) { 651cb0ef41Sopenharmony_ci return GetTypeFromV8Module(sp_ctx, kObjectU); 661cb0ef41Sopenharmony_ci} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugHostType> Extension::GetTypeFromV8Module( 691cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostContext>& sp_ctx, const char16_t* type_name) { 701cb0ef41Sopenharmony_ci bool is_equal; 711cb0ef41Sopenharmony_ci if (sp_v8_module_ctx_ == nullptr || 721cb0ef41Sopenharmony_ci !SUCCEEDED(sp_v8_module_ctx_->IsEqualTo(sp_ctx.Get(), &is_equal)) || 731cb0ef41Sopenharmony_ci !is_equal) { 741cb0ef41Sopenharmony_ci // Context changed; clear the dictionary. 751cb0ef41Sopenharmony_ci cached_v8_module_types_.clear(); 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci GetV8Module(sp_ctx); // Will force the correct module to load 791cb0ef41Sopenharmony_ci if (sp_v8_module_ == nullptr) return nullptr; 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci auto& dictionary_entry = cached_v8_module_types_[type_name]; 821cb0ef41Sopenharmony_ci if (dictionary_entry == nullptr) { 831cb0ef41Sopenharmony_ci const std::wstring type_name_w(reinterpret_cast<const wchar_t*>(type_name)); 841cb0ef41Sopenharmony_ci // The contract from debug_helper functions is to provide type names that 851cb0ef41Sopenharmony_ci // would be valid if used in C++ code within the v8::internal namespace. 861cb0ef41Sopenharmony_ci // They might be fully qualified but aren't required to be. Thus, we must 871cb0ef41Sopenharmony_ci // simluate an "unqualified name lookup" here, by searching for the type 881cb0ef41Sopenharmony_ci // starting in the innermost namespace and working outward. 891cb0ef41Sopenharmony_ci if (SUCCEEDED(sp_v8_module_->FindTypeByName( 901cb0ef41Sopenharmony_ci (L"v8::internal::" + type_name_w).c_str(), &dictionary_entry))) { 911cb0ef41Sopenharmony_ci return dictionary_entry; 921cb0ef41Sopenharmony_ci } 931cb0ef41Sopenharmony_ci if (SUCCEEDED(sp_v8_module_->FindTypeByName((L"v8::" + type_name_w).c_str(), 941cb0ef41Sopenharmony_ci &dictionary_entry))) { 951cb0ef41Sopenharmony_ci return dictionary_entry; 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci sp_v8_module_->FindTypeByName(reinterpret_cast<PCWSTR>(type_name), 981cb0ef41Sopenharmony_ci &dictionary_entry); 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci return dictionary_entry; 1011cb0ef41Sopenharmony_ci} 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_cinamespace { 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci// Returns whether the given module appears to have symbols for V8 code. 1061cb0ef41Sopenharmony_cibool IsV8Module(IDebugHostModule* module) { 1071cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostSymbol> sp_isolate_sym; 1081cb0ef41Sopenharmony_ci // The below symbol is specific to the main V8 module and is specified with 1091cb0ef41Sopenharmony_ci // V8_NOINLINE, so it should always be present. 1101cb0ef41Sopenharmony_ci if (FAILED(module->FindSymbolByName( 1111cb0ef41Sopenharmony_ci L"v8::internal::Isolate::PushStackTraceAndDie", &sp_isolate_sym))) { 1121cb0ef41Sopenharmony_ci return false; 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci return true; 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci} // namespace 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugHostModule> Extension::GetV8Module( 1201cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostContext>& sp_ctx) { 1211cb0ef41Sopenharmony_ci // Return the cached version if it exists and the context is the same 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci // Note: Context will often have the CUSTOM flag set, which never compares 1241cb0ef41Sopenharmony_ci // equal. So for now DON'T compare by context, but by proc_id. (An API is in 1251cb0ef41Sopenharmony_ci // progress to compare by address space, which should be usable when shipped). 1261cb0ef41Sopenharmony_ci /* 1271cb0ef41Sopenharmony_ci if (sp_v8_module_ != nullptr) { 1281cb0ef41Sopenharmony_ci bool is_equal; 1291cb0ef41Sopenharmony_ci if (SUCCEEDED(sp_v8_module_ctx_->IsEqualTo(sp_ctx.Get(), &is_equal)) && 1301cb0ef41Sopenharmony_ci is_equal) { return sp_v8_module_; } else { sp_v8_module_ = nullptr; 1311cb0ef41Sopenharmony_ci sp_v8_module_ctx_ = nullptr; 1321cb0ef41Sopenharmony_ci } 1331cb0ef41Sopenharmony_ci } 1341cb0ef41Sopenharmony_ci */ 1351cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugSystemObjects> sp_sys_objects; 1361cb0ef41Sopenharmony_ci ULONG proc_id = 0; 1371cb0ef41Sopenharmony_ci if (SUCCEEDED(sp_debug_control.As(&sp_sys_objects))) { 1381cb0ef41Sopenharmony_ci if (SUCCEEDED(sp_sys_objects->GetCurrentProcessSystemId(&proc_id))) { 1391cb0ef41Sopenharmony_ci if (proc_id == v8_module_proc_id_ && sp_v8_module_ != nullptr) 1401cb0ef41Sopenharmony_ci return sp_v8_module_; 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci } 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci // Search first for a few known module names, to avoid loading symbols for 1451cb0ef41Sopenharmony_ci // unrelated modules if we can easily avoid it. Generally, failing to find a 1461cb0ef41Sopenharmony_ci // module is fast but failing to find a symbol within a module is slow. Note 1471cb0ef41Sopenharmony_ci // that "v8" is listed first because it's highly likely to be the correct 1481cb0ef41Sopenharmony_ci // module if it exists. The others might include V8 symbols depending on the 1491cb0ef41Sopenharmony_ci // build configuration. 1501cb0ef41Sopenharmony_ci std::vector<const wchar_t*> known_names = { 1511cb0ef41Sopenharmony_ci L"v8", L"v8_for_testing", L"cctest_exe", L"chrome", 1521cb0ef41Sopenharmony_ci L"d8", L"msedge", L"node", L"unittests_exe"}; 1531cb0ef41Sopenharmony_ci for (const wchar_t* name : known_names) { 1541cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostModule> sp_module; 1551cb0ef41Sopenharmony_ci if (SUCCEEDED(sp_debug_host_symbols->FindModuleByName(sp_ctx.Get(), name, 1561cb0ef41Sopenharmony_ci &sp_module))) { 1571cb0ef41Sopenharmony_ci if (IsV8Module(sp_module.Get())) { 1581cb0ef41Sopenharmony_ci sp_v8_module_ = sp_module; 1591cb0ef41Sopenharmony_ci sp_v8_module_ctx_ = sp_ctx; 1601cb0ef41Sopenharmony_ci v8_module_proc_id_ = proc_id; 1611cb0ef41Sopenharmony_ci return sp_v8_module_; 1621cb0ef41Sopenharmony_ci } 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci } 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci // Loop through all modules looking for the one that holds a known symbol. 1671cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostSymbolEnumerator> sp_enum; 1681cb0ef41Sopenharmony_ci if (SUCCEEDED( 1691cb0ef41Sopenharmony_ci sp_debug_host_symbols->EnumerateModules(sp_ctx.Get(), &sp_enum))) { 1701cb0ef41Sopenharmony_ci HRESULT hr = S_OK; 1711cb0ef41Sopenharmony_ci while (true) { 1721cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostSymbol> sp_mod_sym; 1731cb0ef41Sopenharmony_ci hr = sp_enum->GetNext(&sp_mod_sym); 1741cb0ef41Sopenharmony_ci // hr == E_BOUNDS : hit the end of the enumerator 1751cb0ef41Sopenharmony_ci // hr == E_ABORT : a user interrupt was requested 1761cb0ef41Sopenharmony_ci if (FAILED(hr)) break; 1771cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostModule> sp_module; 1781cb0ef41Sopenharmony_ci if (SUCCEEDED(sp_mod_sym.As(&sp_module))) /* should always succeed */ 1791cb0ef41Sopenharmony_ci { 1801cb0ef41Sopenharmony_ci if (IsV8Module(sp_module.Get())) { 1811cb0ef41Sopenharmony_ci sp_v8_module_ = sp_module; 1821cb0ef41Sopenharmony_ci sp_v8_module_ctx_ = sp_ctx; 1831cb0ef41Sopenharmony_ci v8_module_proc_id_ = proc_id; 1841cb0ef41Sopenharmony_ci break; 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci } 1871cb0ef41Sopenharmony_ci } 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci // This will be the located module, or still nullptr if above fails 1901cb0ef41Sopenharmony_ci return sp_v8_module_; 1911cb0ef41Sopenharmony_ci} 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ciExtension::Extension() = default; 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ciHRESULT Extension::Initialize() { 1961cb0ef41Sopenharmony_ci // Create an instance of the DataModel parent for v8::internal::Object types. 1971cb0ef41Sopenharmony_ci auto object_data_model{WRL::Make<V8ObjectDataModel>()}; 1981cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->CreateDataModelObject( 1991cb0ef41Sopenharmony_ci object_data_model.Get(), &sp_object_data_model_)); 2001cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_object_data_model_->SetConcept( 2011cb0ef41Sopenharmony_ci __uuidof(IStringDisplayableConcept), 2021cb0ef41Sopenharmony_ci static_cast<IStringDisplayableConcept*>(object_data_model.Get()), 2031cb0ef41Sopenharmony_ci nullptr)); 2041cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_object_data_model_->SetConcept( 2051cb0ef41Sopenharmony_ci __uuidof(IDynamicKeyProviderConcept), 2061cb0ef41Sopenharmony_ci static_cast<IDynamicKeyProviderConcept*>(object_data_model.Get()), 2071cb0ef41Sopenharmony_ci nullptr)); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci // Register that parent model for all known types of V8 object. 2101cb0ef41Sopenharmony_ci std::vector<std::u16string> object_class_names = ListObjectClasses(); 2111cb0ef41Sopenharmony_ci object_class_names.push_back(kObjectU); 2121cb0ef41Sopenharmony_ci object_class_names.push_back(kTaggedValueU); 2131cb0ef41Sopenharmony_ci for (const std::u16string& name : object_class_names) { 2141cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostTypeSignature> sp_object_type_signature; 2151cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_debug_host_symbols->CreateTypeSignature( 2161cb0ef41Sopenharmony_ci reinterpret_cast<const wchar_t*>(name.c_str()), nullptr, 2171cb0ef41Sopenharmony_ci &sp_object_type_signature)); 2181cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->RegisterModelForTypeSignature( 2191cb0ef41Sopenharmony_ci sp_object_type_signature.Get(), sp_object_data_model_.Get())); 2201cb0ef41Sopenharmony_ci registered_types_.push_back( 2211cb0ef41Sopenharmony_ci {sp_object_type_signature.Get(), sp_object_data_model_.Get()}); 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci // Create an instance of the DataModel parent for custom iterable fields. 2251cb0ef41Sopenharmony_ci auto indexed_field_model{WRL::Make<IndexedFieldParent>()}; 2261cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->CreateDataModelObject( 2271cb0ef41Sopenharmony_ci indexed_field_model.Get(), &sp_indexed_field_model_)); 2281cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_indexed_field_model_->SetConcept( 2291cb0ef41Sopenharmony_ci __uuidof(IIndexableConcept), 2301cb0ef41Sopenharmony_ci static_cast<IIndexableConcept*>(indexed_field_model.Get()), nullptr)); 2311cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_indexed_field_model_->SetConcept( 2321cb0ef41Sopenharmony_ci __uuidof(IIterableConcept), 2331cb0ef41Sopenharmony_ci static_cast<IIterableConcept*>(indexed_field_model.Get()), nullptr)); 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci // Create an instance of the DataModel parent class for v8::Local<*> types. 2361cb0ef41Sopenharmony_ci auto local_data_model{WRL::Make<V8LocalDataModel>()}; 2371cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->CreateDataModelObject( 2381cb0ef41Sopenharmony_ci local_data_model.Get(), &sp_local_data_model_)); 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci // Register that parent model for all known types that act like v8::Local. 2411cb0ef41Sopenharmony_ci std::vector<const wchar_t*> handle_class_names = { 2421cb0ef41Sopenharmony_ci L"v8::Local<*>", L"v8::MaybeLocal<*>", L"v8::internal::Handle<*>", 2431cb0ef41Sopenharmony_ci L"v8::internal::MaybeHandle<*>"}; 2441cb0ef41Sopenharmony_ci for (const wchar_t* name : handle_class_names) { 2451cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostTypeSignature> signature; 2461cb0ef41Sopenharmony_ci RETURN_IF_FAIL( 2471cb0ef41Sopenharmony_ci sp_debug_host_symbols->CreateTypeSignature(name, nullptr, &signature)); 2481cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->RegisterModelForTypeSignature( 2491cb0ef41Sopenharmony_ci signature.Get(), sp_local_data_model_.Get())); 2501cb0ef41Sopenharmony_ci registered_types_.push_back({signature.Get(), sp_local_data_model_.Get()}); 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci // Add the 'Value' property to the parent model. 2541cb0ef41Sopenharmony_ci auto local_value_property{WRL::Make<V8LocalValueProperty>()}; 2551cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> sp_local_value_property_model; 2561cb0ef41Sopenharmony_ci RETURN_IF_FAIL(CreateProperty(sp_data_model_manager.Get(), 2571cb0ef41Sopenharmony_ci local_value_property.Get(), 2581cb0ef41Sopenharmony_ci &sp_local_value_property_model)); 2591cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_local_data_model_->SetKey( 2601cb0ef41Sopenharmony_ci L"Value", sp_local_value_property_model.Get(), nullptr)); 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci // Register all function aliases. 2631cb0ef41Sopenharmony_ci std::vector<std::pair<const wchar_t*, WRL::ComPtr<IModelMethod>>> functions = 2641cb0ef41Sopenharmony_ci {{pcur_isolate, WRL::Make<CurrIsolateAlias>()}, 2651cb0ef41Sopenharmony_ci {pjs_stack, WRL::Make<JSStackAlias>()}, 2661cb0ef41Sopenharmony_ci {pv8_object, WRL::Make<InspectV8ObjectMethod>()}}; 2671cb0ef41Sopenharmony_ci for (const auto& function : functions) { 2681cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> method; 2691cb0ef41Sopenharmony_ci RETURN_IF_FAIL(CreateMethod(sp_data_model_manager.Get(), 2701cb0ef41Sopenharmony_ci function.second.Get(), &method)); 2711cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_debug_host_extensibility->CreateFunctionAlias( 2721cb0ef41Sopenharmony_ci function.first, method.Get())); 2731cb0ef41Sopenharmony_ci } 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ci // Register a handler for supplying stack frame locals. It has to override the 2761cb0ef41Sopenharmony_ci // getter functions for "LocalVariables" and "Parameters". 2771cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> stack_frame; 2781cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->AcquireNamedModel( 2791cb0ef41Sopenharmony_ci L"Debugger.Models.StackFrame", &stack_frame)); 2801cb0ef41Sopenharmony_ci RETURN_IF_FAIL(OverrideLocalsGetter(stack_frame.Get(), L"LocalVariables", 2811cb0ef41Sopenharmony_ci /*is_parameters=*/false)); 2821cb0ef41Sopenharmony_ci RETURN_IF_FAIL(OverrideLocalsGetter(stack_frame.Get(), L"Parameters", 2831cb0ef41Sopenharmony_ci /*is_parameters=*/true)); 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ci // Add node_id property for v8::internal::compiler::Node. 2861cb0ef41Sopenharmony_ci RETURN_IF_FAIL( 2871cb0ef41Sopenharmony_ci RegisterAndAddPropertyForClass<V8InternalCompilerNodeIdProperty>( 2881cb0ef41Sopenharmony_ci L"v8::internal::compiler::Node", L"node_id", 2891cb0ef41Sopenharmony_ci sp_compiler_node_data_model_)); 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ci // Add bitset_name property for v8::internal::compiler::Type. 2921cb0ef41Sopenharmony_ci RETURN_IF_FAIL( 2931cb0ef41Sopenharmony_ci RegisterAndAddPropertyForClass<V8InternalCompilerBitsetNameProperty>( 2941cb0ef41Sopenharmony_ci L"v8::internal::compiler::Type", L"bitset_name", 2951cb0ef41Sopenharmony_ci sp_compiler_type_data_model_)); 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci return S_OK; 2981cb0ef41Sopenharmony_ci} 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_citemplate <class PropertyClass> 3011cb0ef41Sopenharmony_ciHRESULT Extension::RegisterAndAddPropertyForClass( 3021cb0ef41Sopenharmony_ci const wchar_t* class_name, const wchar_t* property_name, 3031cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> sp_data_model) { 3041cb0ef41Sopenharmony_ci // Create an instance of the DataModel parent class. 3051cb0ef41Sopenharmony_ci auto instance_data_model{WRL::Make<V8LocalDataModel>()}; 3061cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->CreateDataModelObject( 3071cb0ef41Sopenharmony_ci instance_data_model.Get(), &sp_data_model)); 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci // Register that parent model. 3101cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostTypeSignature> class_signature; 3111cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_debug_host_symbols->CreateTypeSignature(class_name, nullptr, 3121cb0ef41Sopenharmony_ci &class_signature)); 3131cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_data_model_manager->RegisterModelForTypeSignature( 3141cb0ef41Sopenharmony_ci class_signature.Get(), sp_data_model.Get())); 3151cb0ef41Sopenharmony_ci registered_types_.push_back({class_signature.Get(), sp_data_model.Get()}); 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci // Add the property to the parent model. 3181cb0ef41Sopenharmony_ci auto property{WRL::Make<PropertyClass>()}; 3191cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> sp_property_model; 3201cb0ef41Sopenharmony_ci RETURN_IF_FAIL(CreateProperty(sp_data_model_manager.Get(), property.Get(), 3211cb0ef41Sopenharmony_ci &sp_property_model)); 3221cb0ef41Sopenharmony_ci RETURN_IF_FAIL( 3231cb0ef41Sopenharmony_ci sp_data_model->SetKey(property_name, sp_property_model.Get(), nullptr)); 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ci return S_OK; 3261cb0ef41Sopenharmony_ci} 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ciHRESULT Extension::OverrideLocalsGetter(IModelObject* stack_frame, 3291cb0ef41Sopenharmony_ci const wchar_t* key_name, 3301cb0ef41Sopenharmony_ci bool is_parameters) { 3311cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> original_boxed_getter; 3321cb0ef41Sopenharmony_ci WRL::ComPtr<IKeyStore> original_getter_metadata; 3331cb0ef41Sopenharmony_ci RETURN_IF_FAIL(stack_frame->GetKey(key_name, &original_boxed_getter, 3341cb0ef41Sopenharmony_ci &original_getter_metadata)); 3351cb0ef41Sopenharmony_ci WRL::ComPtr<IModelPropertyAccessor> original_getter; 3361cb0ef41Sopenharmony_ci RETURN_IF_FAIL(UnboxProperty(original_boxed_getter.Get(), &original_getter)); 3371cb0ef41Sopenharmony_ci auto new_getter{WRL::Make<V8LocalVariables>(original_getter, is_parameters)}; 3381cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> new_boxed_getter; 3391cb0ef41Sopenharmony_ci RETURN_IF_FAIL(CreateProperty(sp_data_model_manager.Get(), new_getter.Get(), 3401cb0ef41Sopenharmony_ci &new_boxed_getter)); 3411cb0ef41Sopenharmony_ci RETURN_IF_FAIL(stack_frame->SetKey(key_name, new_boxed_getter.Get(), 3421cb0ef41Sopenharmony_ci original_getter_metadata.Get())); 3431cb0ef41Sopenharmony_ci overridden_properties_.push_back( 3441cb0ef41Sopenharmony_ci {stack_frame, reinterpret_cast<const char16_t*>(key_name), 3451cb0ef41Sopenharmony_ci original_boxed_getter.Get(), original_getter_metadata.Get()}); 3461cb0ef41Sopenharmony_ci return S_OK; 3471cb0ef41Sopenharmony_ci} 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ciExtension::PropertyOverride::PropertyOverride() = default; 3501cb0ef41Sopenharmony_ciExtension::PropertyOverride::PropertyOverride(IModelObject* parent, 3511cb0ef41Sopenharmony_ci std::u16string key_name, 3521cb0ef41Sopenharmony_ci IModelObject* original_value, 3531cb0ef41Sopenharmony_ci IKeyStore* original_metadata) 3541cb0ef41Sopenharmony_ci : parent(parent), 3551cb0ef41Sopenharmony_ci key_name(std::move(key_name)), 3561cb0ef41Sopenharmony_ci original_value(original_value), 3571cb0ef41Sopenharmony_ci original_metadata(original_metadata) {} 3581cb0ef41Sopenharmony_ciExtension::PropertyOverride::~PropertyOverride() = default; 3591cb0ef41Sopenharmony_ciExtension::PropertyOverride::PropertyOverride(const PropertyOverride&) = 3601cb0ef41Sopenharmony_ci default; 3611cb0ef41Sopenharmony_ciExtension::PropertyOverride& Extension::PropertyOverride::operator=( 3621cb0ef41Sopenharmony_ci const PropertyOverride&) = default; 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ciExtension::RegistrationType::RegistrationType() = default; 3651cb0ef41Sopenharmony_ciExtension::RegistrationType::RegistrationType( 3661cb0ef41Sopenharmony_ci IDebugHostTypeSignature* sp_signature, IModelObject* sp_data_model) 3671cb0ef41Sopenharmony_ci : sp_signature(sp_signature), sp_data_model(sp_data_model) {} 3681cb0ef41Sopenharmony_ciExtension::RegistrationType::~RegistrationType() = default; 3691cb0ef41Sopenharmony_ciExtension::RegistrationType::RegistrationType(const RegistrationType&) = 3701cb0ef41Sopenharmony_ci default; 3711cb0ef41Sopenharmony_ciExtension::RegistrationType& Extension::RegistrationType::operator=( 3721cb0ef41Sopenharmony_ci const RegistrationType&) = default; 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ciExtension::~Extension() { 3751cb0ef41Sopenharmony_ci sp_debug_host_extensibility->DestroyFunctionAlias(pcur_isolate); 3761cb0ef41Sopenharmony_ci sp_debug_host_extensibility->DestroyFunctionAlias(pjs_stack); 3771cb0ef41Sopenharmony_ci sp_debug_host_extensibility->DestroyFunctionAlias(pv8_object); 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_ci for (const auto& registered : registered_types_) { 3801cb0ef41Sopenharmony_ci sp_data_model_manager->UnregisterModelForTypeSignature( 3811cb0ef41Sopenharmony_ci registered.sp_data_model.Get(), registered.sp_signature.Get()); 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci for (const auto& override : overridden_properties_) { 3851cb0ef41Sopenharmony_ci override.parent->SetKey( 3861cb0ef41Sopenharmony_ci reinterpret_cast<const wchar_t*>(override.key_name.c_str()), 3871cb0ef41Sopenharmony_ci override.original_value.Get(), override.original_metadata.Get()); 3881cb0ef41Sopenharmony_ci } 3891cb0ef41Sopenharmony_ci} 390