Compartilhar via


Objetos nativos do depurador em extensões JavaScript – Detalhes do objeto do depurador

Este tópico descreve detalhes adicionais sobre como usar os objetos nativos do depurador em extensões JavaScript.

Objetos nativos do depurador representam vários constructos e comportamentos do ambiente do depurador. Os objetos podem ser passados para extensões JavaScript (ou adquiridas em) para manipular o estado do depurador.

Para obter informações sobre extensões JavaScript do objeto Depurador, consulte Native Debugger Objects in JavaScript Extensions.

Para obter informações gerais sobre como trabalhar com JavaScript, consulte JavaScript Debugger Scripting.

Por exemplo, scripts e extensões JavaScript, a equipe do depurador hospeda um repositório GitHub em https://github.com/Microsoft/WinDbg-Samples.

Objetos de depurador em extensões JavaScript

Passando objetos nativos

Os objetos do depurador podem ser passados ou adquiridos em extensões JavaScript de várias maneiras.

  • Eles podem ser passados para funções ou métodos JavaScript
  • Eles podem ser o objeto de instância de um protótipo javaScript (como um visualizador, por exemplo)
  • Eles podem ser retornados de métodos de host projetados para criar objetos nativos do depurador
  • Eles podem ser retornados de métodos de host projetados para criar objetos nativos do depurador

Os objetos do depurador que são passados para uma extensão JavaScript têm um conjunto de funcionalidades descrito nesta seção.

  • Acesso à propriedade
  • Nomes projetados
  • Tipos especiais relativos a objetos nativos do depurador
  • Atributos adicionais

Acesso à propriedade

Embora haja algumas propriedades em objetos que são colocadas lá pelo próprio provedor JavaScript, a maioria das propriedades em um objeto nativo que insere JavaScript são fornecidas pelo modelo de dados. Isso significa que, para um acesso de propriedade --- object.propertyName ou object[propertyName], ocorrerá o seguinte.

  • Se propertyName for o nome de uma propriedade projetada no objeto pelo próprio provedor JavaScript, ele resolve para isso primeiro; caso contrário,
  • Se propertyName for o nome de uma chave projetada no objeto pelo modelo de dados (outro Visualizador), ele resolve a esse nome segundo; caso contrário,
  • Se propertyName for o nome de um campo do objeto nativo, ele resolve a esse nome terceiro; caso contrário,
  • Se o objeto for um ponteiro, o ponteiro será desreferenciado e o ciclo acima continuará (uma propriedade projetada do objeto desreferenciado seguido por uma chave seguida por um campo nativo)

Os meios normais de acesso à propriedade em JavaScript -- object.propertyName e object[propertyName] -- acessarão os campos nativos subjacentes de um objeto, assim como o comando 'dx' faria dentro do depurador.

Nomes projetados

As propriedades (e métodos) a seguir são projetadas em objetos nativos que inserem JavaScript.

Método Assinatura Descrição
hostContext Propriedade Retorna um objeto que representa o contexto em que o objeto está (o espaço de endereço, o destino de depuração etc.)
targetLocation Propriedade Retorna um objeto que é uma abstração de onde o objeto está dentro de um espaço de endereço (endereço virtual, registro, sub-registro etc...)
targetSize Propriedade Retorna o tamanho do objeto (efetivamente: sizeof(<TYPE OF OBJECT>)
addParentModel .addParentModel(object) Adiciona um novo modelo pai (semelhante a um protótipo de JavaScript, mas no lado do modelo de dados) ao objeto
removeParentModel .removeParentModel(object) Remove um determinado modelo pai do objeto
runtimeTypedObject Propriedade Executa a análise no objeto e tenta convertê-lo no tipo de runtime (mais derivado)
targetType Propriedade As extensões JavaScript têm acesso direto ao sistema de tipos da linguagem subjacente. Esse acesso é expresso por meio da noção de objetos de tipo. Para obter mais informações, consulte Native Debugger Objects in JavaScript Extensions – Type Objects

Se o objeto for um ponteiro, as seguintes propriedades (e métodos) serão projetadas no ponteiro que insere JavaScript:

Nome da propriedade Assinatura Descrição
add .add(value) Executa a adição matemática de ponteiro entre o ponteiro e o valor especificado
address Propriedade Retorna o endereço do ponteiro como um objeto ordinal de 64 bits (um tipo de biblioteca)
Desreferenciamento .dereference() Desreferencia o ponteiro e retorna o objeto subjacente
Isnull Propriedade Retorna se o valor do ponteiro é nullptr (0) ou não

Tipos especiais relativos a objetos nativos do depurador

Objetos location

O objeto location que é retornado da propriedade targetLocation de um objeto nativo contém as propriedades (e métodos) a seguir.

Nome da propriedade Assinatura Descrição
add .add(value) Adiciona um deslocamento de bytes absoluto ao local.
subtrair .subtract(value) Subtrai um deslocamento de bytes absoluto do local.

Atributos adicionais

Iterabilidade

Qualquer objeto que seja entendido como iterável pelo modelo de dados (é uma matriz nativa ou tem um visualizador (NatVis ou de outra forma) que o torne iterável) terá uma função iterador (indexada por meio do Symbol.iterator padrão ES6) colocada sobre ele. Isso significa que você pode iterar um objeto nativo em JavaScript da seguinte maneira.

function iterateNative(nativeObject)
{
    for (var val of nativeObject)
    {
        // 
        // val will contain each element iterated from the native object.  This would be each element of an array,
        // each element of an STL structure which is made iterable through NatVis, each element of a data structure
        // which has a JavaScript iterator accessible via [Symbol.iterator], or each element of something
        // which is made iterable via support of IIterableConcept in C/C++.
        //
    }
}

Indexabilidade

Objetos que são entendidos como indexáveis em uma dimensão por meio de ordinais (por exemplo, matrizes nativas) serão indexáveis em JavaScript por meio do operador de acesso à propriedade padrão -- object[index]. Se um objeto for indexável por nome ou for indexável em mais de uma dimensão, os métodos getValueAt e setValueAt serão projetados no objeto para que o código JavaScript possa utilizar o indexador.

function indexNative(nativeArray)
{
    var first = nativeArray[0];
}

Conversão da cadeia de caracteres

Qualquer objeto nativo que tenha uma conversão de cadeia de caracteres de exibição por meio do suporte de IStringDisplayableConcept ou um elemento NatVis DisplayString terá essa conversão de cadeia de caracteres acessível por meio do método JavaScript toString padrão.

function stringifyNative(nativeObject)
{
    var myString = nativeObject.toString();
}

Criando objetos nativos do depurador

Conforme mencionado, um script JavaScript pode obter acesso a objetos nativos fazendo com que eles sejam passados para JavaScript de várias maneiras ou pode criá-los por meio de chamadas para a biblioteca de host. Use as funções a seguir para criar objetos nativos do depurador.

Método Assinatura Descrição

host.getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

getModuleSymbol(moduleName, symbolName, [typeName], [contextInheritor])

Retorna um objeto para um símbolo global em um módulo específico. O nome do módulo e o nome do símbolo são cadeias de caracteres.

Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não é um script de teste único deve sempre fornecer um contexto explícito.

Se o argumento typeName opcional for fornecido, o símbolo será considerado do tipo passado e o tipo indicado em símbolos será ignorado. Observe que qualquer chamador que espera operar em símbolos públicos para um módulo deve sempre fornecer um nome de tipo explícito.

host.getModuleContainingSymbol

getModuleContainingSymbol(location, [contextInheritor])

Retorna o símbolo (por exemplo: função ou dados) que contém o endereço fornecido. Observe que isso só funcionará se houver símbolos privados para o módulo que contém o endereço fornecido.

Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não é um script de teste único deve sempre fornecer um contexto explícito.

host.createPointerObject

createPointerObject(address, moduleName, typeName, [contextInheritor])

Cria um objeto de ponteiro no endereço ou local especificado. O nome do módulo e o nome do tipo são cadeias de caracteres.

Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não é um script de teste único deve sempre fornecer um contexto explícito.

host.createTypedObject

createTypedObject(location, moduleName, typeName, [contextInheritor])

Cria um objeto que representa um objeto de tipo nativo dentro do espaço de endereço de um destino de depuração no local especificado. O nome do módulo e o nome do tipo são cadeias de caracteres.

Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não é um script de teste único deve sempre fornecer um contexto explícito.

APIs de host para extensões JavaScript

O provedor JavaScript insere um objeto chamado host no namespace global de cada script que ele carrega. Esse objeto fornece acesso à funcionalidade crítica para o script, bem como acesso ao namespace do depurador. Ele é configurado em duas fases.

  • Fase 1: antes de qualquer script ser executado, o objeto host contém apenas o conjunto mínimo de funcionalidade necessário para que um script se inicialize e registre seus pontos de extensibilidade (tanto como produtor quanto consumidor). O código raiz e de inicialização não se destina a manipular o estado de um destino de depuração ou executar operações complexas e, como tal, o host não será totalmente preenchido até que o método initializeScript retorne.

  • Fase 2: após o retorno de initializeScript, o objeto host é preenchido com tudo o que é necessário para manipular o estado dos destinos de depuração.

Nível do objeto host

Algumas partes principais da funcionalidade estão diretamente sob o objeto host. O restante é subconsulta. Os namespaces incluem o seguinte.

Namespace Descrição
diagnóstico Funcionalidade para auxiliar no diagnóstico e na depuração do código de script
memória Funcionalidade para habilitar a leitura e gravação de memória em um destino de depuração

Nível raiz

Diretamente no objeto host, as propriedades, os métodos e os construtores a seguir podem ser encontrados.

Name Assinatura Fase Presente Descrição
createPointerObject

createPointerObject(address, moduleName, typeName, [contextInheritor])

2 Cria um objeto de ponteiro no endereço ou local especificado. O nome do módulo e o nome do tipo são cadeias de caracteres. O argumento contextInheritor opcional funciona como com getModuleSymbol.
createTypedObject

createTypedObject(location, moduleName, typeName, [contextInheritor])

2 Cria um objeto que representa um objeto de tipo nativo dentro do espaço de endereço de um destino de depuração no local especificado. O nome do módulo e o nome do tipo são cadeias de caracteres. O argumento contextInheritor opcional funciona como com getModuleSymbol.
currentProcess

Propriedade

2 Retorna o objeto que representa o processo atual do depurador
currentSession

Propriedade

2 Retorna o objeto que representa a sessão atual do depurador (qual destino, despejo etc...) está sendo depurado
Currentthread

Propriedade

2 Retorna o objeto que representa o thread atual do depurador
Evaluateexpression

evaluateExpression(expression, [contextInheritor])

2 Isso chama o host de depuração para avaliar uma expressão usando apenas o idioma do destino de depuração. Se o argumento contextInheritor opcional for fornecido, a expressão será avaliada no contexto (por exemplo: espaço de endereço e destino de depuração) do argumento; caso contrário, ele será avaliado no contexto atual do depurador
evaluateExpressionInContext

evaluateExpressionInContext(context, expression)

2 Isso chama o host de depuração para avaliar uma expressão usando apenas o idioma do destino de depuração. O argumento de contexto indica o ponteiro implícito a ser usado para a avaliação. A expressão será avaliada no contexto (por exemplo, espaço de endereço e destino de depuração) indicado pelo argumento de contexto .
getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

2 Retorna um objeto para um símbolo global em um módulo específico. O nome do módulo e o nome do símbolo são cadeias de caracteres. Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não é um script único deve sempre fornecer um contexto explícito
getNamedModel

getNamedModel(modelName)

2 Retorna o modelo de dados que foi registrado em relação a um determinado nome. Observe que é perfeitamente legal chamar isso em relação a um nome que ainda não está registrado. Isso criará um stub para esse nome e as manipulações do stub serão feitas no objeto real após o registro
Indexedvalue

new indexedValue(value, indicies)

2 Um construtor para um objeto que pode ser retornado de um iterador JavaScript para atribuir um conjunto padrão de índices ao valor iterado. O conjunto de índices deve ser expresso como uma matriz JavaScript.
Int64

new Int64(value, [highValue])

1 Isso constrói um tipo int64 de biblioteca. A versão de argumento único pegará qualquer valor que possa ser empacotado em um Int64 (sem conversão) e o colocará em tal. Se um segundo argumento opcional for fornecido, uma conversão do primeiro argumento será empacotada em 32 bits inferiores e uma conversão do segundo argumento será empacotada nos 32 bits superiores.
namedModelParent

new namedModelParent(object, name)

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript, isso representa o uso de um protótipo javaScript ou classe ES6 como uma extensão pai do modelo de dados de um modelo de dados com o nome fornecido
namedModelRegistration

new namedModelRegistration(object, name)

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript, isso representa o registro de um protótipo JavaScript ou classe ES6 como um modelo de dados por meio de um nome conhecido para que outras extensões possam localizar e estender
namespace

Propriedade

2 Fornece acesso direto ao namespace raiz do depurador. É possível, por exemplo, acessar a lista de processos do primeiro destino de depuração por meio de host.namespace.Debugger.Sessions.First(). Processos que usam essa propriedade
registerNamedModel

registerNamedModel(object, modelName)

2 Isso registra um protótipo javaScript ou classe ES6 como um modelo de dados sob o nome fornecido. Esse registro permite que o protótipo ou a classe sejam localizados e estendidos por outros scripts ou outras extensões do depurador. Observe que um script deve preferir retornar um objeto namedModelRegistration de seu método initializeScript em vez de fazer isso de forma imperativa. Qualquer script que faça alterações imperativamente é necessário para ter um método initializeScript para limpo.
registerExtensionForTypeSignature

registerExtensionForTypeSignature(object, typeSignature)

2 Isso registra um protótipo javaScript ou classe ES6 como um modelo de dados de extensão para um tipo nativo, conforme fornecido pela assinatura de tipo fornecida. Observe que um script deve preferir retornar um objeto typeSignatureExtension de seu método initializeScript em vez de fazer isso de forma imperativa. Qualquer script que faça alterações imperativamente é necessário para ter um método initializeScript para limpo.
registerPrototypeForTypeSignature

registerPrototypeForTypeSignature(object, typeSignature)

2 Isso registra um protótipo javaScript ou classe ES6 como o modelo de dados canônico (por exemplo, visualizador) para um tipo nativo, conforme fornecido pela assinatura de tipo fornecida. Observe que um script deve preferir retornar um objeto typeSignatureRegistration de seu método initializeScript em vez de fazer isso de forma imperativa. Qualquer script que faça alterações imperativamente é necessário para ter um método uninitializeScriptpara limpo.
parseInt64

parseInt64(string, [radix])

1 Esse método atua de forma semelhante ao método padrão JavaScript parseInt, exceto pelo fato de retornar um tipo Int64 de biblioteca. Se um radix for fornecido, a análise ocorrerá na base 2, 8, 10 ou 16, conforme indicado.
typeSignatureExtension

new typeSignatureExtension(object, typeSignature, [moduleName], [minVersion], [maxVersion])

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript, isso representa uma extensão de um tipo nativo descrito por meio de uma assinatura de tipo por um protótipo JavaScript ou classe ES6. Esse registro "adiciona campos" à visualização do depurador de qualquer tipo que corresponda à assinatura em vez de tomá-la completamente. Um nome de módulo e uma versão opcionais podem restringir o registro. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
typeSignatureRegistration

new typeSignatureRegistration(object, typeSignature, [moduleName], [minVersion], [maxVersion])

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript, isso representa um registro canônico de um protótipo JavaScript ou classe ES6 em uma assinatura de tipo nativo. Esse registro "assume" a visualização do depurador de qualquer tipo que corresponda à assinatura em vez de apenas estendê-la. Um nome de módulo e uma versão opcionais podem restringir o registro. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
unregisterNamedModel

unregisterNamedModel(modelName)

2 Isso cancela o registro de um modelo de dados da pesquisa pelo nome fornecido, desfazendo qualquer operação executada pelo registerNamedModel
unregisterExtensionForTypeSignature

unregisterExtensionForTypeSignature(object, typeSignature, [moduleName], [minVersion], [maxVersion])

2 Isso cancela o registro de um protótipo javaScript ou classe ES6 de ser um modelo de dados de extensão para um tipo nativo, conforme fornecido pela assinatura de tipo fornecida. É a desfazer lógica de registerExtensionForTypeSignature. Observe que um script deve preferir retornar um objeto typeSignatureExtension de seu método initializeScript em vez de fazer isso de forma imperativa. Qualquer script que faça alterações imperativamente é necessário para ter um método initializeScript para limpo. Um nome de módulo e uma versão opcionais podem restringir o registro. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
unregisterPrototypeForTypeSignature

unregisterPrototypeForTypeSignature(object, typeSignature, [moduleName], [minVersion], [maxVersion])

2 Isso cancela o registro de um protótipo javaScript ou classe ES6 de ser o modelo de dados canônico (por exemplo, visualizador) para um tipo nativo, conforme fornecido pela assinatura de tipo fornecida. É a desfazer lógica de registerPrototypeForTypeSignature. Observe que um script deve preferir retornar um objeto typeSignatureRegistration de seu método initializeScript em vez de fazer isso de forma imperativa. Qualquer script que faça alterações imperativamente é necessário para ter um método uninitializeScript para limpo. Um nome de módulo e uma versão opcionais podem restringir o registro. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".

Funcionalidade de diagnóstico

O subpaspa diagnóstico do objeto host contém o seguinte.

Nome Assinatura Fase Presente Descrição
Debuglog debugLog(object...) 1 Isso fornece a depuração de estilo printf para uma extensão de script. No momento, a saída do depuraçãoLog é roteada para o console de saída do depurador. Em um momento posterior, há planos para fornecer flexibilidade no roteamento dessa saída. OBSERVAÇÃO: isso não deve ser usado como um meio de imprimir a saída do usuário no console. Pode não ser roteado para lá no futuro.

Funcionalidade de memória

O subpasta de memória do objeto host contém o seguinte.

Nome Assinatura Fase Presente Descrição
readMemoryValues

readMemoryValues(location, numElements, [elementSize], [isSigned], [contextInheritor])

2 Isso lê uma matriz bruta de valores do espaço de endereço do destino de depuração e coloca uma matriz tipada sobre a exibição dessa memória. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de local ou um ponteiro nativo. O tamanho da matriz é indicado pelo argumento numElements . O tamanho (e o tipo) de cada elemento da matriz é fornecido pelos argumentos elementSize e isSigned opcionais. Se nenhum desses argumentos for fornecido, o padrão será byte (sem sinal/1 byte). Se o argumento contextInheritor opcional for fornecido, a memória será lida no contexto (por exemplo: espaço de endereço e destino de depuração) indicado pelo argumento; caso contrário, ele será lido do contexto atual do depurador. Observe que usar esse método em valores de 8, 16 e 32 bits resulta em uma exibição com tipo rápido sendo colocada sobre a memória de leitura. Usar esse método em valores de 64 bits resulta na construção de uma matriz de tipos de biblioteca de 64 bits, o que é significativamente mais caro!
Readstring

readString(location, [contextInheritor])

readString(location, [length], [contextInheritor])

2 Isso lê uma cadeia de caracteres estreita (página de código atual) do espaço de endereço de um destino de depuração, converte-a em UTF-16 e retorna o resultado como uma cadeia de caracteres JavaScript. Ele poderá gerar uma exceção se a memória não puder ser lida. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de local ou um caractere nativo. Se o argumento contextInheritor opcional for fornecido, a memória será lida no contexto (por exemplo: espaço de endereço e destino de depuração) indicado pelo argumento; caso contrário, ele será lido do contexto atual do depurador. Se o argumento de comprimento opcional for fornecido, a cadeia de caracteres de leitura será do comprimento especificado.
readWideString

readWideString(location, [contextInheritor])

readWideString(location, [length], [contextInheritor])

2 Isso lê uma cadeia de caracteres wide(UTF-16) do espaço de endereço de um destino de depuração e retorna o resultado como uma cadeia de caracteres JavaScript. Ele poderá gerar uma exceção se a memória não puder ser lida. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de local ou um wchar_t nativo. Se o argumento contextInheritor opcional for fornecido, a memória será lida no contexto (por exemplo: espaço de endereço e destino de depuração) indicado pelo argumento; caso contrário, ele será lido do contexto atual do depurador. Se o argumento de comprimento opcional for fornecido, a cadeia de caracteres de leitura será do comprimento especificado.

Conceitos de modelo de dados em JavaScript

Mapeamento de modelo de dados

Os conceitos de modelo de dados a seguir são mapeados para JavaScript.

Conceito Interface nativa Equivalente a JavaScript
Conversão da cadeia de caracteres IStringDisplayableConcept standard: toString(...) {...}
Iterabilidade IIterableConcept standard: [Symbol.iterator](){...}
Indexabilidade IIndexableConcept protocolo: getDimensionality(...) / getValueAt(...) / setValueAt(...)
Conversão de tipo de runtime IPreferredRuntimeTypeConcept protocolo: getPreferredRuntimeTypedObject(...)

Conversão da cadeia de caracteres

O conceito de conversão de cadeia de caracteres (IStringDisplayableConcept) é convertido diretamente no método javaScript toString padrão. Como todos os objetos JavaScript têm uma conversão de cadeia de caracteres (fornecida por Object.prototype, se não for fornecida em outro lugar), todos os objetos JavaScript retornados ao modelo de dados podem ser convertidos em uma cadeia de caracteres de exibição. Substituir a conversão de cadeia de caracteres simplesmente requer a implementação de seu próprio toString.

class myObject
{
    //
    // This method will be called whenever any native code calls IStringDisplayableConcept::ToDisplayString(...)
    //
    toString()
    { 
        return "This is my own string conversion!";
    }
}

Iterabilidade

O conceito do modelo de dados de se um objeto é iterável ou não é mapeado diretamente para o protocolo ES6 de se um objeto é iterável. Qualquer objeto que tenha um método [Symbol.iterator] é considerado iterável. A implementação desse tipo tornará o objeto iterável.

Um objeto que só pode ser iterável pode ter uma implementação como a seguir.

class myObject
{
    //
    // This method will be called whenever any native code calls IIterableConcept::GetIterator
    //
    *[Symbol.iterator]()
    {
        yield "First Value";
        yield "Second Value";
        yield "Third Value";
    }
}

Deve ser dada uma consideração especial para objetos que são iteráveis e indexáveis, pois os objetos retornados do iterador devem incluir o índice, bem como o valor por meio de um tipo de retorno especial.

Iterável e Indexável

Um objeto que é iterável e indexável requer um valor retornado especial do iterador. Em vez de gerar os valores, o iterador produz instâncias de indexedValue. Os índices são passados como uma matriz no segundo argumento para o construtor indexedValue. Eles podem ser multidimensionais, mas devem corresponder à dimensionalidade retornada no protocolo do indexador.

Este código mostra um exemplo de implementação.

class myObject
{
    //
    // This method will be called whenever any native code calls IIterableConcept::GetIterator
    //
    *[Symbol.iterator]()
    {
        //
        // Consider this a map which mapped 42->"First Value", 99->"Second Value", and 107->"Third Value"
        //
        yield new host.indexedValue("First Value", [42]);
        yield new host.indexedValue("Second Value", [99]);
        yield new host.indexedValue("Third Value", [107]);
    }
}

Indexabilidade

Ao contrário do JavaScript, o modelo de dados faz uma diferenciação muito explícita entre o acesso à propriedade e a indexação. Qualquer objeto JavaScript que deseje se apresentar como indexável no modelo de dados deve implementar um protocolo que consiste em um método getDimensionality que retorna a dimensionalidade do indexador e um par opcional de métodos getValueAt e setValueAt que executam leituras e gravações do objeto em índices fornecidos. É aceitável omitir os métodos getValueAt ou setValueAt se o objeto for somente leitura ou somente gravação

class myObject
{
    //
    // This method will be called whenever any native code calls IIndexableConcept::GetDimensionality or IIterableConcept::GetDefaultIndexDimensionality
    //
    getDimensionality()
    {
        //
        // Pretend we are a two dimensional array.
        //
        return 2;
    } 

    //
    // This method will be called whenever any native code calls IIndexableConcept::GetAt
    //
    getValueAt(row, column)
    {
        return this.__values[row * this.__columnCount + column];
    }

    //
    // This method will be called whenever any native code calls IIndexableConcept::SetAt
    //
    setValueAt(value, row, column)
    {
        this.__values[row * this.__columnCount + column] = value;
    }
}

Conversão de tipo de runtime

Isso só é relevante para protótipos/classes JavaScript que são registrados em tipos de sistema de tipos (nativos). O depurador geralmente é capaz de executar análise (por exemplo, Run-Time rtti (informações de tipo) /análise de tabela v) para determinar o verdadeiro tipo de runtime de um objeto de um tipo estático expresso no código. Um modelo de dados registrado em um tipo nativo pode substituir esse comportamento por meio de uma implementação do IPreferredRuntimeTypeConcept. Da mesma forma, uma classe JavaScript ou um protótipo registrado em um objeto nativo pode fornecer sua própria implementação por meio da implementação de um protocolo que consiste no método getPreferredRuntimeTypedObject.

Observe que, embora esse método possa tecnicamente retornar qualquer coisa, ele é considerado uma forma ruim para retornar algo que não é realmente o tipo de runtime ou um tipo derivado. Isso pode resultar em confusão significativa para os usuários do depurador. Substituir esse método pode, no entanto, ser valioso para coisas como cabeçalho de estilo C+estilos de objeto de implementação etc...

class myNativeModel
{
    //
    // This method will be called whenever the data model calls IPreferredRuntimeTypeConcept::CastToPreferredRuntimeType
    //
    getPreferredRuntimeTypedObject()
    {
        var loc = this.targetLocation;

        //
        // Perform analysis...
        //
        var runtimeLoc = loc.Add(runtimeObjectOffset);
  
        return host.createTypedObject(runtimeLoc, runtimeModule, runtimeTypeName);
    }
}

Confira também

Objetos nativos do depurador em extensões JavaScript

Objetos nativos do depurador em extensões JavaScript – Considerações sobre design e teste

Script do Depurador JavaScript

Scripts de exemplo do depurador JavaScript