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/cur-isolate.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciHRESULT GetIsolateKey(WRL::ComPtr<IDebugHostContext>& sp_ctx,
81cb0ef41Sopenharmony_ci                      int* isolate_key) {
91cb0ef41Sopenharmony_ci  auto sp_v8_module = Extension::Current()->GetV8Module(sp_ctx);
101cb0ef41Sopenharmony_ci  if (sp_v8_module == nullptr) return E_FAIL;
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci  WRL::ComPtr<IDebugHostSymbol> sp_isolate_sym;
131cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_v8_module->FindSymbolByName(kIsolateKey, &sp_isolate_sym));
141cb0ef41Sopenharmony_ci  SymbolKind kind;
151cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_isolate_sym->GetSymbolKind(&kind));
161cb0ef41Sopenharmony_ci  if (kind != SymbolData) return E_FAIL;
171cb0ef41Sopenharmony_ci  WRL::ComPtr<IDebugHostData> sp_isolate_key_data;
181cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_isolate_sym.As(&sp_isolate_key_data));
191cb0ef41Sopenharmony_ci  Location loc;
201cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_isolate_key_data->GetLocation(&loc));
211cb0ef41Sopenharmony_ci  ULONG64 bytes_read;
221cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_debug_host_memory->ReadBytes(
231cb0ef41Sopenharmony_ci      sp_ctx.Get(), loc, isolate_key, sizeof(isolate_key), &bytes_read));
241cb0ef41Sopenharmony_ci  return S_OK;
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciHRESULT GetCurrentIsolate(WRL::ComPtr<IModelObject>& sp_result) {
281cb0ef41Sopenharmony_ci  sp_result = nullptr;
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  // Get the current context
311cb0ef41Sopenharmony_ci  WRL::ComPtr<IDebugHostContext> sp_host_context;
321cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_debug_host->GetCurrentContext(&sp_host_context));
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  WRL::ComPtr<IModelObject> sp_curr_thread;
351cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(GetCurrentThread(sp_host_context, &sp_curr_thread));
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  WRL::ComPtr<IModelObject> sp_environment, sp_environment_block;
381cb0ef41Sopenharmony_ci  WRL::ComPtr<IModelObject> sp_tls_slots, sp_slot_index, sp_isolate_ptr;
391cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(
401cb0ef41Sopenharmony_ci      sp_curr_thread->GetKeyValue(L"Environment", &sp_environment, nullptr));
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_environment->GetKeyValue(L"EnvironmentBlock",
431cb0ef41Sopenharmony_ci                                             &sp_environment_block, nullptr));
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  // EnvironmentBlock and TlsSlots are native types (TypeUDT) and thus
461cb0ef41Sopenharmony_ci  // GetRawValue rather than GetKeyValue should be used to get field (member)
471cb0ef41Sopenharmony_ci  // values.
481cb0ef41Sopenharmony_ci  ModelObjectKind kind;
491cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_environment_block->GetKind(&kind));
501cb0ef41Sopenharmony_ci  if (kind != ModelObjectKind::ObjectTargetObject) return E_FAIL;
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_environment_block->GetRawValue(SymbolField, L"TlsSlots", 0,
531cb0ef41Sopenharmony_ci                                                   &sp_tls_slots));
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  int isolate_key = -1;
561cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(GetIsolateKey(sp_host_context, &isolate_key));
571cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(CreateInt32(isolate_key, &sp_slot_index));
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(GetModelAtIndex(sp_tls_slots, sp_slot_index, &sp_isolate_ptr));
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  // Need to dereference the slot and then get the address held in it
621cb0ef41Sopenharmony_ci  WRL::ComPtr<IModelObject> sp_dereferenced_slot;
631cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_isolate_ptr->Dereference(&sp_dereferenced_slot));
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  uint64_t isolate_ptr;
661cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(UnboxULong64(sp_dereferenced_slot.Get(), &isolate_ptr));
671cb0ef41Sopenharmony_ci  Location isolate_addr{isolate_ptr};
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  // If we got the isolate_key OK, then must have the V8 module loaded
701cb0ef41Sopenharmony_ci  // Get the internal Isolate type from it
711cb0ef41Sopenharmony_ci  WRL::ComPtr<IDebugHostType> sp_isolate_type, sp_isolate_ptr_type;
721cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(Extension::Current()
731cb0ef41Sopenharmony_ci                     ->GetV8Module(sp_host_context)
741cb0ef41Sopenharmony_ci                     ->FindTypeByName(kIsolate, &sp_isolate_type));
751cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(
761cb0ef41Sopenharmony_ci      sp_isolate_type->CreatePointerTo(PointerStandard, &sp_isolate_ptr_type));
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_data_model_manager->CreateTypedObject(
791cb0ef41Sopenharmony_ci      sp_host_context.Get(), isolate_addr, sp_isolate_type.Get(), &sp_result));
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  return S_OK;
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciIFACEMETHODIMP CurrIsolateAlias::Call(IModelObject* p_context_object,
851cb0ef41Sopenharmony_ci                                      ULONG64 arg_count,
861cb0ef41Sopenharmony_ci                                      IModelObject** pp_arguments,
871cb0ef41Sopenharmony_ci                                      IModelObject** pp_result,
881cb0ef41Sopenharmony_ci                                      IKeyStore** pp_metadata) noexcept {
891cb0ef41Sopenharmony_ci  *pp_result = nullptr;
901cb0ef41Sopenharmony_ci  WRL::ComPtr<IModelObject> sp_result;
911cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(GetCurrentIsolate(sp_result));
921cb0ef41Sopenharmony_ci  *pp_result = sp_result.Detach();
931cb0ef41Sopenharmony_ci  return S_OK;
941cb0ef41Sopenharmony_ci}
95