Partager via


Objets de débogage natifs dans les extensions JavaScript - Détails de l’objet débogueur

Cette rubrique décrit des détails supplémentaires sur l’utilisation des objets débogueur natifs dans les extensions JavaScript.

Les objets débogueur natifs représentent différentes constructions et comportements de l’environnement du débogueur. Les objets peuvent être transmis à des extensions JavaScript (ou acquis dans celles-ci) pour manipuler l’état du débogueur.

Pour plus d’informations sur les extensions JavaScript de l’objet Débogueur, consultez Objets de débogueur natifs dans les extensions JavaScript.

Pour obtenir des informations générales sur l’utilisation de JavaScript, consultez Débogueur de scripts JavaScript.

Pour les scripts et extensions JavaScript, par exemple, l’équipe du débogueur héberge un dépôt GitHub à l’adresse https://github.com/Microsoft/WinDbg-Samples.

Objets de débogueur dans les extensions JavaScript

Passage d’objets natifs

Les objets débogueur peuvent être transmis ou acquis dans des extensions JavaScript de différentes façons.

  • Ils peuvent être passés à des fonctions ou méthodes JavaScript
  • Il peut s’agir de l’objet d’instance d’un prototype JavaScript (en tant que visualiseur, par exemple)
  • Ils peuvent être retournés à partir de méthodes hôtes conçues pour créer des objets débogueur natifs
  • Ils peuvent être retournés à partir de méthodes hôtes conçues pour créer des objets natifs du débogueur

Les objets débogueur passés à une extension JavaScript ont un ensemble de fonctionnalités décrites dans cette section.

  • Propriété Access
  • Noms projetés
  • Types spéciaux relatifs aux objets débogueur natifs
  • Attributs supplémentaires

Accès aux propriétés

Bien qu’il existe certaines propriétés sur des objets qui sont placés là par le fournisseur JavaScript lui-même, la majorité des propriétés sur un objet natif qui entre JavaScript sont fournies par le modèle de données. Cela signifie que pour un accès aux propriétés --- object.propertyName ou object[propertyName], les éléments suivants se produisent.

  • Si propertyName est le nom d’une propriété projetée sur l’objet par le fournisseur JavaScript lui-même, cela sera résolu en premier ; autrement
  • Si propertyName est le nom d’une clé projetée sur l’objet par le modèle de données (un autre visualiseur), ce nom sera pris en compte en second ; sinon
  • Si propertyName est le nom d’un champ de l’objet natif, il sera résolu à ce nom en troisième lieu ; autrement
  • Si l’objet est un pointeur, le pointeur sera déréférencé et le cycle ci-dessus continuera (une propriété projetée de l’objet déréférencé suivie d’une clé suivie d’un champ natif).

Le moyen normal d’accès aux propriétés dans JavaScript -- object.propertyName et object[propertyName] - accède aux champs natifs sous-jacents d’un objet, autant que la commande « dx » se trouve dans le débogueur.

Noms projetés

Les propriétés (et méthodes) suivantes sont assignées à des objets natifs qui entrent dans JavaScript.

Méthode Signature Descriptif
contexte d'hôte Propriété Renvoie un objet qui représente le contexte dans lequel l’objet se trouve (l’espace d’adressage, la cible de débogage, etc.)
targetLocation Propriété Renvoie un objet qui est une abstraction de l’emplacement où l’objet se trouve dans un espace d’adressage (adresse virtuelle, registre, sous-registre, etc....)
targetSize Propriété Retourne la taille de l’objet (effectivement : sizeof(<TYPE D’OBJET>)
addParentModel .addParentModel(object) Ajoute un nouveau modèle parent (semblable à un prototype JavaScript, mais côté modèle de données) à l’objet
removeParentModel .removeParentModel(object) Supprime un modèle parent donné de l’objet
objet typé à l'exécution Propriété Effectue une analyse sur l’objet et tente de le convertir en type runtime (le plus dérivé)
targetType Propriété Les extensions JavaScript ont un accès direct au système de type du langage sous-jacent. Cet accès est exprimé par le biais de la notion d’objets de type. Pour plus d’informations, consultez Objets débogueur natifs dans les extensions JavaScript - Types d’objets

Si l’objet est un pointeur, les propriétés (et méthodes) suivantes sont projetées sur le pointeur qui entre JavaScript :

Nom de la propriété Signature Descriptif
ajouter .add(value) Effectue l’ajout mathématique du pointeur entre le pointeur et la valeur spécifiée
adresse Propriété Retourne l’adresse du pointeur en tant qu’objet ordinal 64 bits (type de bibliothèque)
déréférencer .dereference() Déréférence le pointeur et retourne l’objet sous-jacent
isNull Propriété Retourne si la valeur du pointeur est nullptr (0)

Types spéciaux relatifs aux objets débogueur natifs

Objets d’emplacement

L’objet d’emplacement retourné par la propriété targetLocation d’un objet natif contient les propriétés suivantes (et méthodes).

Nom de la propriété Signature Descriptif
ajouter .add(value) Ajoute un décalage d’octet absolu à l’emplacement.
soustraction .soustraire(valeur) Soustrait un octet de décalage absolu de la position.

Attributs supplémentaires

Itérabilité

Tout objet compris comme itérable par le modèle de données (il s’agit d’un tableau natif ou d’un visualiseur (NatVis ou autre) qui le rend itérable) aura une fonction d’itérateur (indexée via le symbol.iterator standard ES6) placée sur celle-ci. Cela signifie que vous pouvez itérer un objet natif en JavaScript comme suit.

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++.
        //
    }
}

Indexabilité

Les objets qui sont considérés comme indexables dans une dimension via des ordinales (par exemple, des tableaux natifs) sont indexables en JavaScript via l’opérateur d’accès aux propriétés standard -- object[index]. Si un objet est indexable par nom ou indexable dans plusieurs dimensions, les méthodes getValueAt et setValueAt sont projetées sur l’objet afin que le code JavaScript puisse utiliser l’indexeur.

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

Conversion de chaîne

Tout objet natif ayant une conversion de chaîne d'affichage grâce à la prise en charge d'IStringDisplayableConcept ou d'un élément NatVis DisplayString pourra accéder à cette conversion de chaîne via la méthode standard toString de JavaScript.

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

Création d’objets débogueur natifs

Comme mentionné, un script JavaScript peut accéder à des objets natifs en les transmettant à JavaScript de plusieurs façons ou en les créant par le biais d’appels à la bibliothèque hôte. Utilisez les fonctions suivantes pour créer des objets débogueur natifs.

Méthode Signature Descriptif

host.getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

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

Retourne un objet pour un symbole global au sein d’un module particulier. Le nom du module et le nom du symbole sont des chaînes.

Si l’argument contextInheritor facultatif est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite.

Si l’argument typeName facultatif est fourni, le symbole est supposé être du type passé et le type indiqué dans les symboles est ignoré. Notez que tout appelant qui s’attend à fonctionner sur des symboles publics pour un module doit toujours fournir un nom de type explicite.

host.getModuleContainingSymbol

getModuleContainingSymbol(emplacement, [héritierContexte])

Retourne le symbole (par exemple, fonction ou données) qui contient l’adresse donnée. Notez que cela fonctionne uniquement s’il existe des symboles privés pour le module contenant l’adresse donnée.

Si l’argument contextInheritor facultatif est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole seront recherchés dans le contexte présent du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite.

host.createPointerObject

createPointerObject(adresse, nomModule, typeNom, [héritierContexte])

Crée un objet pointeur à l’adresse ou à l’emplacement spécifié. Le nom du module et le nom de type sont des chaînes.

Si l’argument contextInheritor facultatif est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite.

host.createTypedObject

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

Crée un objet qui représente un objet typé natif dans l’espace d’adressage d’une cible de débogage à l’emplacement spécifié. Le nom du module et le nom de type sont des chaînes.

Si l’argument contextInheritor facultatif est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l'argument n'est pas fourni, le module ainsi que le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite.

API d’hôte pour les extensions JavaScript

Le fournisseur JavaScript insère un objet appelé hôte dans l’espace de noms global de chaque script qu’il charge. Cet objet fournit l’accès aux fonctionnalités critiques pour le script, ainsi qu’à l’accès à l’espace de noms du débogueur. Il est configuré en deux phases.

  • Phase 1 : avant l’exécution d’un script, l’objet hôte contient uniquement le jeu minimal de fonctionnalités nécessaires pour qu’un script s’initialise et enregistre ses points d’extensibilité (à la fois en tant que producteur et consommateur). Le code racine et d’initialisation n’est pas destiné à manipuler l’état d’une cible de débogage ou à effectuer des opérations complexes et, par conséquent, l’hôte n’est pas entièrement rempli tant qu’une fois la méthode initializeScript retournée.

  • Phase 2 : une fois initializeScript retourné, l’objet hôte est rempli avec tout ce qui est nécessaire pour manipuler l’état des cibles de débogage.

Niveau de l’objet hôte

Quelques éléments clés de fonctionnalités se trouvent directement sous l’objet hôte. Les autres sont sous-espaces de noms. Les espaces de noms comprennent les éléments suivants.

Namespace Descriptif
diagnostiques Fonctionnalité permettant de faciliter le diagnostic et le débogage du code de script
memory Fonctionnalité permettant de lire et d’écrire de la mémoire dans une cible de débogage

Niveau racine

Directement dans l’objet hôte, les propriétés, méthodes et constructeurs suivants sont disponibles.

Nom Signature Phase présente Descriptif
createPointerObject

createPointerObject(adresse, nomModule, typeNom, [héritierContexte])

2 Crée un objet pointeur à l’adresse ou à l’emplacement spécifié. Le nom du module et le nom de type sont des chaînes. L’argument contextInheritor facultatif fonctionne comme avec getModuleSymbol.
créerObjetTypé

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

2 Crée un objet qui représente un objet typé natif dans l’espace d’adressage d’une cible de débogage à l’emplacement spécifié. Le nom du module et le nom de type sont des chaînes. L’argument contextInheritor facultatif fonctionne comme avec getModuleSymbol.
currentProcess

Propriété

2 Retourne l’objet représentant le processus actuel du débogueur
session en cours

Propriété

2 Renvoie l’objet représentant la session actuelle du débogueur où la cible, le vidage, etc., sont en cours de débogage.
currentThread

Propriété

2 Retourne l’objet représentant le thread actuel du débogueur
evaluateExpression

evaluateExpression(expression, [contextInheritor])

2 Cela appelle l’hôte de débogage pour évaluer une expression à l’aide du langage de la cible de débogage uniquement. Si l’argument contextInheritor facultatif est fourni, l’expression est évaluée dans le contexte (par exemple , espace d’adressage et cible de débogage) de l’argument ; sinon, elle sera évaluée dans le contexte actuel du débogueur
evaluateExpressionInContext

évaluerExpressionDansContexte(context, expression)

2 Cela appelle l’hôte de débogage pour évaluer une expression à l’aide du langage de la cible de débogage uniquement. L’argument de contexte indique le pointeur implicite à utiliser pour l’évaluation. L’expression sera évaluée dans le contexte (par exemple, espace d’adressage et cible de débogage) indiqués par l’argument de contexte .
getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

2 Retourne un objet pour un symbole global au sein d’un module particulier. Le nom du module et le nom du symbole sont des chaînes. Si l’argument contextInheritor facultatif est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script unique doit toujours fournir un contexte explicite
getNamedModel

getNamedModel(modelName)

2 Retourne le modèle de données qui a été enregistré sous un nom donné. Notez qu'il est parfaitement légal d'invoquer ceci sur un nom qui n'est pas encore enregistré. Cela créera un stub pour ce nom et les manipulations du stub seront effectuées sur l'objet réel lors de l’enregistrement.
indexedValue

new indexedValue(value, indicies)

2 Constructeur pour un objet qui peut être retourné à partir d’un itérateur JavaScript afin d’affecter un ensemble par défaut d’indicies à la valeur itérée. L’ensemble d’indicies doit être exprimé sous la forme d’un tableau JavaScript.
Int64

nouveau Int64(value, [highValue])

1 Cela construit un type Int64 de bibliothèque. La version d’argument unique prend n’importe quelle valeur qui peut être empaquetée dans un Int64 (sans conversion) et la place dans ce type. Si un deuxième argument facultatif est fourni, une conversion du premier argument est empaquetée en 32 bits inférieurs et une conversion du deuxième argument est empaquetée en 32 bits supérieurs.
nomméModèleParent

new namedModelParent(object, name)

1 Constructeur d’un objet destiné à être placé dans le tableau retourné à partir d’initializeScript, cela représente l’utilisation d’un prototype JavaScript ou d’une classe ES6 comme extension parente de modèle de données d’un modèle de données portant le nom donné
enregistrementModelNomé

Nouvelle namedModelRegistration(objet, nom)

1 Constructeur d’un objet destiné à être placé dans le tableau retourné à partir d’initializeScript, il représente l’inscription d’un prototype JavaScript ou d’une classe ES6 en tant que modèle de données via un nom connu afin que d’autres extensions puissent rechercher et étendre
Namespace

Propriété

2 Fournit un accès direct à l’espace de noms racine du débogueur. Par exemple, vous pouvez accéder à la liste des processus de la première cible de débogage via host.namespace.Debugger.Sessions.First(). Processus utilisant cette propriété
registerNamedModel

registerNamedModel(object, modelName)

2 Cela inscrit un prototype JavaScript ou une classe ES6 en tant que modèle de données sous le nom donné. Une telle inscription permet au prototype ou à la classe d’être localisé et étendu par d’autres scripts ou d’autres extensions de débogueur. Notez qu’un script doit préférer retourner un objet namedModelRegistration à partir de sa méthode initializeScript plutôt que de le faire impérativement. Tout script qui apporte des modifications impérativement doit avoir une méthode initializeScript pour le nettoyage.
registerExtensionForTypeSignature

enregistrerExtensionPourSignatureDeType(objet, signatureDeType)

2 Cela inscrit un prototype JavaScript ou une classe ES6 en tant que modèle de données d’extension pour un type natif, comme indiqué par la signature de type fournie. Notez qu’un script doit préférer retourner un objet typeSignatureExtension à partir de sa méthode initializeScript plutôt que de procéder de façon impérative. ** Tout script qui apporte des modifications impérativement doit inclure une méthode initializeScript pour le nettoyage.
enregistrerPrototypePourSignatureDeType

registerPrototypeForTypeSignature(object, typeSignature)

2 Cela inscrit un prototype JavaScript ou une classe ES6 comme modèle de données canonique (par exemple, visualiseur) pour un type natif tel qu’indiqué par la signature de type fournie. Notez qu’un script doit préférer retourner un objet typeSignatureRegistration à partir de sa méthode initializeScript plutôt que de le faire impérativement. Tout script qui apporte des modifications obligatoirement doit avoir une méthode uninitializeScript afin de nettoyer.
parseInt64

parseInt64(string, [radix])

1 Cette méthode agit de la même façon que la méthode JavaScript standard parseInt, sauf qu’elle retourne un type int64 de bibliothèque à la place. Si un radix est fourni, l’analyse se produit dans la base 2, 8, 10 ou 16 comme indiqué.
typeSignatureExtension

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

1 Constructeur d’un objet destiné à être placé dans le tableau retourné à partir d’initializeScript, il représente une extension d’un type natif décrit via une signature de type par un prototype JavaScript ou une classe ES6. Une telle inscription « ajoute des champs » à la visualisation du débogueur de n’importe quel type qui correspond à la signature plutôt que de la reprendre entièrement. Un nom de module et une version facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ».
typeSignatureRegistration

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

1 Constructeur d’un objet destiné à être placé dans le tableau retourné par initializeScript, il représente une inscription canonique d’un prototype JavaScript ou d’une classe ES6 par rapport à une signature de type native. Une telle inscription « prend le contrôle » de la visualisation du débogueur de tout type correspondant à la signature, plutôt que de simplement l'étendre. Un nom de module et une version facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ».
désenregistrerModèleNommé

désenregistrerModèleNommé(nomModèle)

2 Cette opération désinscrit un modèle de données de la recherche par le nom donné, annulant ainsi toute opération effectuée par registerNamedModel.
désinscrireExtensionPourSignatureDeType

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

2 Cela désinscrit un prototype JavaScript ou une classe ES6 en tant que modèle de données d'extension pour un type natif, selon la signature de type fournie. Il s’agit de l’annulation logique de registerExtensionForTypeSignature. Notez qu’un script doit préférer retourner un objet typeSignatureExtension à partir de sa méthode initializeScript plutôt que de procéder de façon impérative. ** Tout script qui apporte des modifications impérativement doit inclure une méthode initializeScript pour le nettoyage. Un nom de module et une version facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ».
unregisterPrototypeForTypeSignature

unregisterPrototypeForTypeSignature(object, typeSignature, [nomDuModule], [versionMin], [versionMax])

2 Cela annule l’inscription d’un prototype JavaScript ou d’une classe ES6 en tant que modèle de données canonique (par exemple, visualiseur) pour un type natif tel qu’indiqué par la signature de type fournie. Il s’agit de l’annulation logique de registerPrototypeForTypeSignature. Notez qu’un script doit préférer retourner un objet typeSignatureRegistration à partir de sa méthode initializeScript plutôt que de le faire impérativement. Tout script qui effectue des modifications impératives doit inclure une méthode uninitializeScript pour nettoyer. Un nom de module et une version facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ».

Fonctionnalités de diagnostic

Le sous-espace de noms diagnostics de l'objet hôte contient les éléments suivants.

Nom Signature Phase présente Descriptif
debugLog debugLog(object...) 1 Cela fournit un débogage au style printf à une extension de script. À l’heure actuelle, la sortie de debugLog est routée vers la console de sortie du débogueur. À un moment ultérieur, il est prévu de fournir une flexibilité sur le routage de cette sortie. REMARQUE : Cela ne doit pas être utilisé comme moyen d’imprimer la sortie de l’utilisateur dans la console. Il se peut qu’il ne soit pas acheminé là-bas à l’avenir.

Fonctionnalité de mémoire

L'espace de sous-noms de mémoire de l'objet hôte contient les éléments suivants.

Nom Signature Phase présente Descriptif
readMemoryValues

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

2 Cela lit un tableau brut de valeurs à partir de l’espace d’adressage de la cible de débogage et place un tableau typé en haut de la vue de cette mémoire. L’emplacement fourni peut être une adresse (valeur 64 bits), un objet d’emplacement ou un pointeur natif. La taille du tableau est indiquée par l’argument numElements . La taille (et le type) de chaque élément du tableau est donnée par les arguments facultatifs elementSize et isSigned . Si aucun de ces arguments n’est fourni, la valeur par défaut est byte (unsigned / 1 octet). Si l’argument contextInheritor facultatif est fourni, la mémoire est lue dans le contexte (par exemple , espace d’adressage et cible de débogage) indiquée par l’argument ; sinon, il sera lu à partir du contexte actuel du débogueur. Notez que l’utilisation de cette méthode sur les valeurs de 8, 16 et 32 bits entraîne une vue typée rapide placée sur la mémoire lue. L’utilisation de cette méthode sur des valeurs 64 bits entraîne la construction d’un tableau de types de bibliothèques 64 bits, ce qui est beaucoup plus coûteux !
readString

readString(location, [contextInheritor])

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

2 Cette opération lit une chaîne étroite (page de codes actuelle) à partir de l’espace d’adressage d’une cible de débogage, la convertit en UTF-16 et retourne le résultat sous la forme d’une chaîne JavaScript. Elle peut lever une exception si la mémoire n’a pas pu être lue. L’emplacement fourni peut être une adresse (valeur 64 bits), un objet d’emplacement ou un caractère natif. Si l’argument contextInheritor facultatif est fourni, la mémoire est lue dans le contexte (par exemple , espace d’adressage et cible de débogage) indiquée par l’argument ; sinon, il sera lu à partir du contexte actuel du débogueur. Si l’argument de longueur facultatif est fourni, la chaîne de lecture est de la longueur spécifiée.
readWideString

readWideString(location, [contextInheritor])

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

2 Cela lit une chaîne large (UTF-16) à partir de l’espace d’adressage d’une cible de débogage et retourne le résultat sous la forme d’une chaîne JavaScript. Elle peut lever une exception si la mémoire n’a pas pu être lue. L’emplacement fourni peut être une adresse (valeur 64 bits), un objet d’emplacement ou un wchar_t natif. Si l’argument contextInheritor facultatif est fourni, la mémoire est lue dans le contexte (par exemple , espace d’adressage et cible de débogage) indiquée par l’argument ; sinon, il sera lu à partir du contexte actuel du débogueur. Si l’argument de longueur facultatif est fourni, la chaîne de lecture est de la longueur spécifiée.

Concepts du modèle de données en JavaScript

Mappage de modèle de données

Les concepts de modèle de données suivants sont mappés à JavaScript.

Concept Native Interface Équivalent JavaScript
Conversion de chaîne IStringDisplayableConcept standard : toString(...){...}
Itérabilité IIterableConcept standard : [Symbol.iterator](){...}
Capacité d'indexation IIndexableConcept protocole : getDimensionality(...) / getValueAt(...) / setValueAt(...)
Conversion de type au moment de l'exécution IPreferredRuntimeTypeConcept protocole : getPreferredRuntimeTypedObject(...)

Conversion de chaîne

Le concept de conversion de chaîne (IStringDisplayableConcept) se traduit directement en méthode JavaScript toString standard. Comme tous les objets JavaScript ont une conversion de chaîne (fournie par Object.prototype s’il n’est pas fourni ailleurs), chaque objet JavaScript retourné au modèle de données peut être converti en chaîne d’affichage. La redéfinition de la conversion de chaîne nécessite simplement l'implémentation de votre propre toString.

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

Itérabilité

Le concept du modèle de données selon lequel un objet est itérable ou non correspond directement au protocole ES6 indiquant si un objet est itérable. Tout objet qui a une méthode [Symbol.iterator] est considéré comme itérable. L’implémentation de ce type rend l’objet itérable.

Un objet qui n’est itérable que peut avoir une implémentation comme suit.

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";
    }
}

Une considération particulière doit être donnée pour les objets qui sont à la fois itérables et indexables, car les objets retournés par l’itérateur doivent inclure l’index ainsi que la valeur via un type de retour spécial.

Itérable et indexable

Un objet itérable et indexable nécessite une valeur de retour spéciale de l’itérateur. Au lieu de générer les valeurs, l’itérateur génère des instances d’indexedValue. Les indicies sont passées en tant que tableau dans le deuxième argument au constructeur indexedValue. Ils peuvent être multidimensionnels, mais doivent correspondre à la dimensionnalité retournée dans le protocole d’indexeur.

Ce code montre un exemple d’implémentation.

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]);
    }
}

Indexabilité

Contrairement à JavaScript, le modèle de données fait une différenciation très explicite entre l’accès aux propriétés et l’indexation. Tout objet JavaScript qui souhaite se présenter comme indexable dans le modèle de données doit implémenter un protocole constitué d’une méthode getDimensionality qui retourne la dimensionnalité de l’indexeur et une paire facultative de méthodes getValueAt et setValueAt qui effectuent des lectures et des écritures de l’objet à des indicies fournies. Il est acceptable d’omettre les méthodes getValueAt ou setValueAt si l’objet est en lecture seule ou en écriture seule

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;
    }
}

Runtime Type Conversion

Cela s’applique uniquement aux prototypes/classes JavaScript inscrits sur les types système de type (natif). Le débogueur est souvent capable d'effectuer une analyse (par exemple, Run-Time Analyse de type (RTTI) et analyse v-table) pour déterminer le type d'exécution réel d'un objet à partir d'un type statique exprimé en code. Un modèle de données inscrit sur un type natif peut remplacer ce comportement par le biais d’une implémentation de IPreferredRuntimeTypeConcept. De même, une classe JavaScript ou un prototype inscrit sur un objet natif peut fournir sa propre implémentation via l’implémentation d’un protocole constitué de la méthode getPreferredRuntimeTypedObject.

Notez que bien que cette méthode puisse techniquement retourner n'importe quoi, il est considéré comme de mauvais ton qu'elle retourne quelque chose qui n'est pas vraiment le type au moment de l'exécution ou un type dérivé. Cela peut entraîner une confusion significative pour les utilisateurs du débogueur. Toutefois, la substitution de cette méthode peut être utile pour des éléments tels que les styles d'en-têtes et d'objets typiques des implémentations en C, 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);
    }
}

Voir aussi

objets débogueur natifs dans les extensions JavaScript

Objets débogueur natifs dans les extensions JavaScript - Considérations relatives à la conception et au test

Scriptage du débogueur JavaScript

Exemples de scripts du débogueur JavaScript