• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "tools/v8windbg/base/utilities.h"
6 
7 #include <comutil.h>
8 #include <oleauto.h>
9 
10 #include <vector>
11 
12 namespace {
13 
BoxObject(IDataModelManager * p_manager,IUnknown * p_object,ModelObjectKind kind,IModelObject ** pp_model_object)14 HRESULT BoxObject(IDataModelManager* p_manager, IUnknown* p_object,
15                   ModelObjectKind kind, IModelObject** pp_model_object) {
16   *pp_model_object = nullptr;
17 
18   VARIANT vt_val;
19   vt_val.vt = VT_UNKNOWN;
20   vt_val.punkVal = p_object;
21 
22   HRESULT hr = p_manager->CreateIntrinsicObject(kind, &vt_val, pp_model_object);
23   return hr;
24 }
25 
26 }  // namespace
27 
CreateProperty(IDataModelManager * p_manager,IModelPropertyAccessor * p_property,IModelObject ** pp_property_object)28 HRESULT CreateProperty(IDataModelManager* p_manager,
29                        IModelPropertyAccessor* p_property,
30                        IModelObject** pp_property_object) {
31   return BoxObject(p_manager, p_property, ObjectPropertyAccessor,
32                    pp_property_object);
33 }
34 
CreateMethod(IDataModelManager * p_manager,IModelMethod * p_method,IModelObject ** pp_method_object)35 HRESULT CreateMethod(IDataModelManager* p_manager, IModelMethod* p_method,
36                      IModelObject** pp_method_object) {
37   return BoxObject(p_manager, p_method, ObjectMethod, pp_method_object);
38 }
39 
UnboxProperty(IModelObject * object,IModelPropertyAccessor ** result)40 HRESULT UnboxProperty(IModelObject* object, IModelPropertyAccessor** result) {
41   ModelObjectKind kind = (ModelObjectKind)-1;
42   RETURN_IF_FAIL(object->GetKind(&kind));
43   if (kind != ObjectPropertyAccessor) return E_FAIL;
44   _variant_t variant;
45   RETURN_IF_FAIL(object->GetIntrinsicValue(&variant));
46   if (variant.vt != VT_UNKNOWN) return E_FAIL;
47   WRL::ComPtr<IModelPropertyAccessor> accessor;
48   RETURN_IF_FAIL(WRL::ComPtr<IUnknown>(variant.punkVal).As(&accessor));
49   *result = accessor.Detach();
50   return S_OK;
51 }
52 
CreateTypedIntrinsic(uint64_t value,IDebugHostType * type,IModelObject ** result)53 HRESULT CreateTypedIntrinsic(uint64_t value, IDebugHostType* type,
54                              IModelObject** result) {
55   // Figure out what kind of VARIANT we need to make.
56   IntrinsicKind kind;
57   VARTYPE carrier;
58   RETURN_IF_FAIL(type->GetIntrinsicType(&kind, &carrier));
59 
60   VARIANT vt_val;
61   switch (carrier) {
62     case VT_BOOL:
63       vt_val.boolVal = value ? VARIANT_TRUE : VARIANT_FALSE;
64       break;
65     case VT_I1:
66       vt_val.cVal = static_cast<int8_t>(value);
67       break;
68     case VT_UI1:
69       vt_val.bVal = static_cast<uint8_t>(value);
70       break;
71     case VT_I2:
72       vt_val.iVal = static_cast<int16_t>(value);
73       break;
74     case VT_UI2:
75       vt_val.uiVal = static_cast<uint16_t>(value);
76       break;
77     case VT_INT:
78       vt_val.intVal = static_cast<int>(value);
79       break;
80     case VT_UINT:
81       vt_val.uintVal = static_cast<unsigned int>(value);
82       break;
83     case VT_I4:
84       vt_val.lVal = static_cast<int32_t>(value);
85       break;
86     case VT_UI4:
87       vt_val.ulVal = static_cast<uint32_t>(value);
88       break;
89     case VT_INT_PTR:
90       vt_val.llVal = static_cast<intptr_t>(value);
91       break;
92     case VT_UINT_PTR:
93       vt_val.ullVal = static_cast<uintptr_t>(value);
94       break;
95     case VT_I8:
96       vt_val.llVal = static_cast<int64_t>(value);
97       break;
98     case VT_UI8:
99       vt_val.ullVal = static_cast<uint64_t>(value);
100       break;
101     default:
102       return E_FAIL;
103   }
104   vt_val.vt = carrier;
105   return sp_data_model_manager->CreateTypedIntrinsicObject(&vt_val, type,
106                                                            result);
107 }
108 
CreateULong64(ULONG64 value,IModelObject ** pp_int)109 HRESULT CreateULong64(ULONG64 value, IModelObject** pp_int) {
110   HRESULT hr = S_OK;
111   *pp_int = nullptr;
112 
113   VARIANT vt_val;
114   vt_val.vt = VT_UI8;
115   vt_val.ullVal = value;
116 
117   hr = sp_data_model_manager->CreateIntrinsicObject(ObjectIntrinsic, &vt_val,
118                                                     pp_int);
119   return hr;
120 }
121 
UnboxULong64(IModelObject * object,ULONG64 * value,bool convert)122 HRESULT UnboxULong64(IModelObject* object, ULONG64* value, bool convert) {
123   ModelObjectKind kind = (ModelObjectKind)-1;
124   RETURN_IF_FAIL(object->GetKind(&kind));
125   if (kind != ObjectIntrinsic) return E_FAIL;
126   _variant_t variant;
127   RETURN_IF_FAIL(object->GetIntrinsicValue(&variant));
128   if (convert) {
129     RETURN_IF_FAIL(VariantChangeType(&variant, &variant, 0, VT_UI8));
130   }
131   if (variant.vt != VT_UI8) return E_FAIL;
132   *value = variant.ullVal;
133   return S_OK;
134 }
135 
GetInt32(IDebugHostConstant * object,int * value)136 HRESULT GetInt32(IDebugHostConstant* object, int* value) {
137   variant_t variant;
138   RETURN_IF_FAIL(object->GetValue(&variant));
139 
140   if (variant.vt != VT_I4) return E_FAIL;
141   *value = variant.lVal;
142   return S_OK;
143 }
144 
CreateInt32(int value,IModelObject ** pp_int)145 HRESULT CreateInt32(int value, IModelObject** pp_int) {
146   HRESULT hr = S_OK;
147   *pp_int = nullptr;
148 
149   VARIANT vt_val;
150   vt_val.vt = VT_I4;
151   vt_val.intVal = value;
152 
153   hr = sp_data_model_manager->CreateIntrinsicObject(ObjectIntrinsic, &vt_val,
154                                                     pp_int);
155   return hr;
156 }
157 
CreateUInt32(uint32_t value,IModelObject ** pp_int)158 HRESULT CreateUInt32(uint32_t value, IModelObject** pp_int) {
159   HRESULT hr = S_OK;
160   *pp_int = nullptr;
161 
162   VARIANT vt_val;
163   vt_val.vt = VT_UI4;
164   vt_val.uintVal = value;
165 
166   hr = sp_data_model_manager->CreateIntrinsicObject(ObjectIntrinsic, &vt_val,
167                                                     pp_int);
168   return hr;
169 }
170 
CreateBool(bool value,IModelObject ** pp_val)171 HRESULT CreateBool(bool value, IModelObject** pp_val) {
172   HRESULT hr = S_OK;
173   *pp_val = nullptr;
174 
175   VARIANT vt_val;
176   vt_val.vt = VT_BOOL;
177   vt_val.boolVal = value;
178 
179   hr = sp_data_model_manager->CreateIntrinsicObject(ObjectIntrinsic, &vt_val,
180                                                     pp_val);
181   return hr;
182 }
183 
CreateNumber(double value,IModelObject ** pp_val)184 HRESULT CreateNumber(double value, IModelObject** pp_val) {
185   HRESULT hr = S_OK;
186   *pp_val = nullptr;
187 
188   VARIANT vt_val;
189   vt_val.vt = VT_R8;
190   vt_val.dblVal = value;
191 
192   hr = sp_data_model_manager->CreateIntrinsicObject(ObjectIntrinsic, &vt_val,
193                                                     pp_val);
194   return hr;
195 }
196 
CreateString(std::u16string value,IModelObject ** pp_val)197 HRESULT CreateString(std::u16string value, IModelObject** pp_val) {
198   HRESULT hr = S_OK;
199   *pp_val = nullptr;
200 
201   VARIANT vt_val;
202   vt_val.vt = VT_BSTR;
203   vt_val.bstrVal =
204       ::SysAllocString(reinterpret_cast<const OLECHAR*>(value.c_str()));
205 
206   hr = sp_data_model_manager->CreateIntrinsicObject(ObjectIntrinsic, &vt_val,
207                                                     pp_val);
208   return hr;
209 }
210 
UnboxString(IModelObject * object,BSTR * value)211 HRESULT UnboxString(IModelObject* object, BSTR* value) {
212   ModelObjectKind kind = (ModelObjectKind)-1;
213   RETURN_IF_FAIL(object->GetKind(&kind));
214   if (kind != ObjectIntrinsic) return E_FAIL;
215   _variant_t variant;
216   RETURN_IF_FAIL(object->GetIntrinsicValue(&variant));
217   if (variant.vt != VT_BSTR) return E_FAIL;
218   *value = variant.Detach().bstrVal;
219   return S_OK;
220 }
221 
GetModelAtIndex(WRL::ComPtr<IModelObject> & sp_parent,WRL::ComPtr<IModelObject> & sp_index,IModelObject ** p_result)222 HRESULT GetModelAtIndex(WRL::ComPtr<IModelObject>& sp_parent,
223                         WRL::ComPtr<IModelObject>& sp_index,
224                         IModelObject** p_result) {
225   WRL::ComPtr<IIndexableConcept> sp_indexable_concept;
226   RETURN_IF_FAIL(sp_parent->GetConcept(__uuidof(IIndexableConcept),
227                                        &sp_indexable_concept, nullptr));
228 
229   std::vector<IModelObject*> p_indexers{sp_index.Get()};
230   return sp_indexable_concept->GetAt(sp_parent.Get(), 1, p_indexers.data(),
231                                      p_result, nullptr);
232 }
233 
GetCurrentThread(WRL::ComPtr<IDebugHostContext> & sp_host_context,IModelObject ** p_current_thread)234 HRESULT GetCurrentThread(WRL::ComPtr<IDebugHostContext>& sp_host_context,
235                          IModelObject** p_current_thread) {
236   WRL::ComPtr<IModelObject> sp_boxed_context, sp_root_namespace;
237   WRL::ComPtr<IModelObject> sp_debugger, sp_sessions, sp_processes, sp_threads;
238   WRL::ComPtr<IModelObject> sp_curr_session, sp_curr_process;
239 
240   RETURN_IF_FAIL(BoxObject(sp_data_model_manager.Get(), sp_host_context.Get(),
241                            ObjectContext, &sp_boxed_context));
242   RETURN_IF_FAIL(sp_data_model_manager->GetRootNamespace(&sp_root_namespace));
243   RETURN_IF_FAIL(
244       sp_root_namespace->GetKeyValue(L"Debugger", &sp_debugger, nullptr));
245   RETURN_IF_FAIL(sp_debugger->GetKeyValue(L"Sessions", &sp_sessions, nullptr));
246   RETURN_IF_FAIL(
247       GetModelAtIndex(sp_sessions, sp_boxed_context, &sp_curr_session));
248   RETURN_IF_FAIL(
249       sp_curr_session->GetKeyValue(L"Processes", &sp_processes, nullptr));
250   RETURN_IF_FAIL(
251       GetModelAtIndex(sp_processes, sp_boxed_context, &sp_curr_process));
252   RETURN_IF_FAIL(
253       sp_curr_process->GetKeyValue(L"Threads", &sp_threads, nullptr));
254   return GetModelAtIndex(sp_threads, sp_boxed_context, p_current_thread);
255 }
256