Sdílet prostřednictvím


Nativní objekty ladicího programu v rozšířeních JavaScriptu – Podrobnosti o objektu ladicího programu

Toto téma popisuje další podrobnosti o používání nativních objektů ladicího programu v rozšířeních JavaScriptu.

Nativní objekty ladicího programu představují různé konstrukty a chování prostředí ladicího programu. Objekty lze předat (nebo získat v) javascriptových rozšířeních pro manipulaci se stavem ladicího programu.

Informace o rozšíření javascriptového objektu ladicího programu naleznete v tématu Nativní objekty ladicího programu v rozšířeních Jazyka JavaScript.

Obecné informace o práci s JavaScriptem najdete v tématu Skriptování ladicího programu JavaScriptu.

Například javascriptové skripty a rozšíření hostuje tým ladicího programu úložiště GitHub na adrese https://github.com/Microsoft/WinDbg-Samples.

Objekty ladicího programu v rozšířeních JavaScriptu

Předávání nativních objektů

Objekty ladicího programu lze v rozšířeních JavaScriptu předat nebo získat různými způsoby.

  • Mohou být předány funkcím nebo metodám JavaScriptu.
  • Může se jednat o objekt instance prototypu JavaScriptu (například vizualizéru).
  • Můžou být vráceny z metod hostitele navržených k vytvoření nativních objektů ladicího programu.
  • Mohou být vráceny z metod hostitele navržených k vytvoření nativních objektů ladicího programu.

Objekty ladicího programu, které se předávají rozšíření JavaScriptu, mají sadu funkcí popsaných v této části.

  • Přístup k vlastnostem
  • Projektovaná jména
  • Speciální typy týkající se nativních objektů ladicího programu
  • Další atributy

Přístup k vlastnostem

I když existují některé vlastnosti objektů, které jsou umístěny přímo poskytovatelem JavaScriptu, většina vlastností nativního objektu, který zadává JavaScript, jsou poskytovány datovým modelem. To znamená, že při přístupu k vlastnosti --- object.propertyName nebo object[propertyName] se stane následující.

  • Pokud je propertyName název vlastnosti projektované na objekt samotným poskytovatelem JavaScriptu, nejprve se vyřeší tímto; jinak
  • Pokud propertyName je název klíče projektovaného na objekt datovým modelem (jiným vizualizátorem), bude se k tomuto názvu přiklánět jako k druhé možnosti; jinak
  • Pokud je propertyName názvem pole nativního objektu, bude se vyhodnocovat jako třetí možnost; jinak
  • Pokud je objekt ukazatelem, ukazatel bude dereferencován a výše uvedený cyklus bude pokračovat (projekční vlastnost objektu dereferencovaného následovaná klíčem a pak nativním polem)

Normální prostředky přístupu k vlastnostem v JavaScriptu -- object.propertyName a object[propertyName] – budou mít přístup k podkladovým nativním polím objektu, stejně jako příkaz dx v ladicím programu.

Plánovaná jména

Následující vlastnosti (a metody) jsou projektovány na nativní objekty, které zadávají JavaScript.

Metoda Podpis Popis
hostContext Vlastnictví Vrátí objekt, který představuje kontext, ve kterém se objekt nachází (adresní prostor, cíl ladění atd.).
Umístění cíle Vlastnictví Vrátí objekt, který je abstrakcí místa, kde je objekt v adresní prostoru (virtuální adresa, registr, podregistr atd.).
cílová velikost Vlastnictví Vrátí velikost objektu (efektivně: sizeof(<TYP OBJEKTU>).
addParentModel .addParentModel(object) Přidá do objektu nový nadřazený model (podobá se prototypu JavaScriptu, ale na straně datového modelu).
removeParentModel .removeParentModel(object) Odebere daný nadřazený model z objektu.
runtimeTypedObject (běhově typovaný objekt) Vlastnictví Provede analýzu objektu a pokusí se jej převést na běhový (nejodvozenější) typ.
typ cíle Vlastnictví Rozšíření JavaScriptu mají přímý přístup k systému typů základního jazyka. Tento přístup je vyjádřen pomocí pojmu objekty typu. Další informace naleznete v tématu Nativní objekty ladicího programu v rozšíření javascriptu – objekty typu

Pokud je objekt ukazatelem, následující vlastnosti (a metody) jsou promítnuty na ukazatel, který zadá JavaScript:

Název vlastnosti Podpis Popis
přidat .add(value) Provede matematické sčítání ukazatele mezi ukazatelem a zadanou hodnotou.
adresa Vlastnictví Vrátí adresu ukazatele jako 64bitový pořadový objekt (typ knihovny).
přistoupit přes ukazatel .dereference() Dereferencuje ukazatel a vrátí základní objekt.
isNull Vlastnictví Vrátí informaci, zda hodnota ukazatele je nullptr (0) nebo není.

Speciální typy týkající se nativních objektů ladicího programu

Objekty umístění

Objekt umístění vrácený z vlastnosti targetLocation nativního objektu obsahuje následující vlastnosti (a metody).

Název vlastnosti Podpis Popis
přidat .add(value) Přidá absolutní posun bajtů k pozici.
odečíst .subtract(value) Odečte absolutní posun bajtů od umístění.

Další atributy

Iterovatelnost

Každý objekt, který je datovým modelem chápán jako iterovatelný (je to nativní pole nebo má vizualizér, jako je NatVis, který jej činí iterovatelným), bude mít na sobě umístěnu funkci iterátoru (indexovanou pomocí standardního symbolu ES6 Symbol.iterator). To znamená, že můžete iterovat nativní objekt v JavaScriptu následujícím způsobem.

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

Indexovatelnost

Objekty, které jsou pochopeny jako indexovatelné v jedné dimenzi prostřednictvím řad (např. nativních polí), budou indexovatelné v JavaScriptu prostřednictvím standardního operátoru přístupu k vlastnostem -- object[index]. Pokud je objekt indexovatelný podle názvu nebo je indexovatelný ve více než jedné dimenzi, metody getValueAt a setValueAt se promítnou do objektu, aby kód JavaScriptu mohl indexer využívat.

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

Převod řetězců

Jakýkoli nativní objekt, který má převod řetězce pro zobrazení prostřednictvím podpory IStringDisplayableConcept nebo prvku NatVis DisplayString, bude mít tento převod řetězce přístupný přes standardní metodu toString v JavaScriptu.

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

Vytváření nativních objektů ladicího programu

Jak už bylo zmíněno, javascriptový skript může získat přístup k nativním objektům tak, že je předá do JavaScriptu jedním z několika způsobů nebo je může vytvořit prostřednictvím volání do knihovny hostitelů. K vytvoření nativních objektů ladicího programu použijte následující funkce.

Metoda Podpis Popis

host.getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

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

Vrátí objekt globálního symbolu v určitém modulu. Název modulu a název symbolu jsou řetězce.

Pokud je zadán volitelný argument contextInheritor , modul a symbol se vyhledá ve stejném kontextu (adresní prostor, cíl ladění) jako předaný objekt. Pokud argument není zadaný, modul a symbol se vyhledá v aktuálním kontextu ladicího programu. Rozšíření JavaScriptu, které není jednorázovým testovacím skriptem, by vždy mělo poskytovat explicitní kontext.

Pokud je zadán volitelný argument typeName , bude se předpokládat, že se jedná o předaný typ a typ uvedený v symbolech bude ignorován. Všimněte si, že každý volající, který očekává, že bude pracovat s veřejnými symboly pro modul, by měl vždy zadat explicitní název typu.

host.getModuleContainingSymbol

getModuleContainingSymbol(location; [contextInheritor])

Vrátí symbol (například funkce nebo data), která obsahuje danou adresu. Mějte na paměti, že to bude fungovat jenom v případě, že pro modul obsahující danou adresu existují soukromé symboly.

Pokud je zadán volitelný argument contextInheritor , modul a symbol se vyhledá ve stejném kontextu (adresní prostor, cíl ladění) jako předaný objekt. Pokud argument není zadaný, modul a symbol se vyhledá v aktuálním kontextu ladicího programu. Rozšíření JavaScriptu, které není jednorázovým testovacím skriptem, by vždy mělo poskytovat explicitní kontext.

host.createPointerObject

createPointerObject(adresa, jménoModulu, jménoTypu, [dědicKontextu])

Vytvoří objekt ukazatele na zadané adrese nebo umístění. Název modulu a název typu jsou řetězce.

Pokud je zadán volitelný argument contextInheritor , modul a symbol se vyhledá ve stejném kontextu (adresní prostor, cíl ladění) jako předaný objekt. Pokud argument není zadaný, modul a symbol se vyhledá v aktuálním kontextu ladicího programu. Rozšíření JavaScriptu, které není jednorázovým testovacím skriptem, by vždy mělo poskytovat explicitní kontext.

host.createTypedObject

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

Vytvoří objekt, který představuje nativní typ objektu v adresního prostoru cíle ladění v zadaném umístění. Název modulu a název typu jsou řetězce.

Pokud je zadán volitelný argument contextInheritor , modul a symbol se vyhledá ve stejném kontextu (adresní prostor, cíl ladění) jako předaný objekt. Pokud argument není zadaný, modul a symbol se vyhledá v aktuálním kontextu ladicího programu. Rozšíření JavaScriptu, které není jednorázovým testovacím skriptem, by vždy mělo poskytovat explicitní kontext.

Rozhraní API hostitele pro rozšíření JavaScriptu

Poskytovatel JavaScriptu vloží objekt nazvaný host do globálního prostoru jmen každého skriptu, který načte. Tento objekt poskytuje přístup k zásadním funkcím pro skript a také přístup k jmennému prostoru ladicího programu. Nastavuje se ve dvou fázích.

  • Fáze 1: Před spuštěním jakéhokoli skriptu obsahuje hostitelský objekt pouze minimální sadu funkcí nezbytných pro inicializaci skriptu a registraci bodů rozšiřitelnosti (jak jako producent, tak příjemce). Kořenový a inicializační kód není určen k manipulaci se stavem cíle ladění nebo provádění složitých operací, a proto není hostitel plně naplněn, dokud se nevrátí metoda initializeScript.

  • Fáze 2: Poté, co funkce initializeScript vrátí hodnotu, je objekt hostitele naplněn vším potřebným k manipulaci se stavem ladicích cílů.

Úroveň hostitelského objektu

Několik klíčových funkcí je přímo pod hostitelským objektem. Zbytek je podnázvový prostor. Prostory jmen zahrnují následující položky:

Namespace Popis
Diagnostika Funkce, která pomáhá při diagnostice a ladění kódu skriptu
paměť Funkce umožňující čtení a zápis paměti v rámci cíle ladění

Kořenová úroveň

Přímo v hostitelském objektu lze najít následující vlastnosti, metody a konstruktory.

Název Podpis Fáze, která je k dispozici Popis
vytvořtePointerObjekt

createPointerObject(adresa, jménoModulu, jménoTypu, [dědicKontextu])

2 Vytvoří objekt ukazatele na zadané adrese nebo umístění. Název modulu a název typu jsou řetězce. Volitelný argument contextInheritor funguje stejně jako u getModuleSymbol.
vytvořitTypedObject

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

2 Vytvoří objekt, který představuje nativní typ objektu v adresního prostoru cíle ladění v zadaném umístění. Název modulu a název typu jsou řetězce. Volitelný argument contextInheritor funguje stejně jako u getModuleSymbol.
aktuálníProces

Vlastnictví

2 Vrátí objekt představující aktuální načtený proces ladicího nástroje.
currentSession

Vlastnictví

2 Vrátí objekt představující aktuální relaci, během které je ladicí program (cíl, výpis atd.) laděn.
aktuální vlákno

Vlastnictví

2 Vrátí objekt představující aktuální vlákno ladicího programu.
evaluateExpression

evaluateExpression(expression; [contextInheritor])

2 Toto volání k hostiteli ladění vyhodnotí výraz pouze pomocí jazyka cíle ladění. Pokud je zadán volitelný argument contextInheritor , výraz se vyhodnotí v kontextu (např. adresní prostor a cíl ladění) argumentu; jinak se vyhodnotí v aktuálním kontextu ladicího programu.
evaluateExpressionInContext

evaluateExpressionInContext(context, expression)

2 Toto volání do ladicího hostitele vyhodnotí výraz pouze pomocí jazyka cílového ladění. Kontextový argument označuje implicitní použití tohoto ukazatele pro vyhodnocení. Výraz se vyhodnotí v kontextu (např. adresní prostor a cíl ladění) označený argumentem kontextu .
získatSymbolModulu

getModuleSymbol(moduleName, symbolName, [contextInheritor])

2 Vrátí objekt globálního symbolu v určitém modulu. Název modulu a název symbolu jsou řetězce. Pokud je zadán volitelný argument contextInheritor , modul a symbol se vyhledá ve stejném kontextu (adresní prostor, cíl ladění) jako předaný objekt. Pokud argument není zadaný, modul a symbol se vyhledá v aktuálním kontextu ladicího programu. Rozšíření JavaScriptu, které není jednorázovým skriptem, by vždy mělo poskytovat explicitní kontext.
getNamedModel

getNamedModel(modelName)

2 Vrátí datový model, který byl registrován proti danému názvu. Všimněte si, že je naprosto legální volat proti jménu, který ještě není registrován. Tímto způsobem vytvoříte zástupný objekt pro tento název a manipulace se zástupným objektem bude při registraci provedena na skutečném objektu.
indexovanáHodnota

new indexedValue(value, indicies)

2 Konstruktor pro objekt, který lze vrátit z iterátoru JavaScriptu, aby přiřadil výchozí sadu indikací k iterované hodnotě. Sada indikátů musí být vyjádřena jako pole JavaScriptu.
Int64

new Int64(value; [highValue])

1 Tím se vytvoří typ knihovny Int64. Verze s jedním argumentem přijme libovolnou hodnotu, kterou lze zabalit do Int64 (bez převodu), a umístí ji tam. Pokud je zadán volitelný druhý argument, převede se první argument do nižších 32 bitů a převod druhého argumentu se zabalí do horních 32 bitů.
namedModelParent

new namedModelParent(object, name)

1 Konstruktor objektu určeného k umístění do pole vráceného z initializeScriptu, představuje použití prototypu JavaScriptu nebo třídy ES6 jako nadřazeného rozšíření datového modelu s daným názvem.
RegistracePojmenovanéhoModelu

new namedModelRegistration(object, name)

1 Konstruktor pro objekt určený k umístění do pole vráceného z initializeScriptu, představuje registraci prototypu JavaScriptu nebo třídy ES6 jako datového modelu prostřednictvím známého názvu, aby ostatní rozšíření mohly najít a rozšířit.
názvový prostor

Vlastnictví

2 Poskytuje přímý přístup ke kořenovému oboru názvů ladicího programu. Můžete například získat přístup k seznamu procesů prvního cíle ladění prostřednictvím host.namespace.Debugger.Sessions.First(). Procesy používající tuto vlastnost
registerNamedModel

registerNamedModel(object, modelName)

2 Tím se pod daným názvem zaregistruje prototyp JavaScriptu nebo třída ES6 jako datový model. Tato registrace umožňuje, aby prototyp nebo třída byly umístěny a rozšířeny jinými skripty nebo jinými rozšířeními ladicího programu. Všimněte si, že skript by měl raději vrátit objekt namedModelRegistration ze své metody initializeScript místo toho, aby to dělal imperativně. Všechny skripty, které provádí změny imperativním způsobem, musí mít inicializovatscriptovou metodu, aby bylo možné vyčistit.
registerExtensionForTypeSignature

registerExtensionForTypeSignature(objekt, typPodpisu)

2 Tím se zaregistruje prototyp JavaScriptu nebo třída ES6 jako model dat pro rozšíření pro nativní datový typ, jak je dáno zadanou signaturou typu. Všimněte si, že skript by měl raději vrátit objekt typeSignatureExtension ze své metody initializeScript spíše než to dělat imperativně. Všechny skripty, které provádí změny imperativním způsobem, musí mít inicializovatscriptovou metodu, aby bylo možné vyčistit.
registerPrototypeForTypeSignature

registerPrototypeForTypeSignature(object, typeSignature)

2 Tím se zaregistruje prototyp JavaScriptu nebo třída ES6 jako kanonický datový model (např. vizualizér) pro nativní typ, který je dán zadaným podpisem typu. Všimněte si, že skript by měl raději vrátit objekt typeSignatureRegistration ze své metody initializeScript místo toho, aby to dělal imperativně. Všechny skripty, které provádějí změny imperativně, musí mít metodu uninitializeScript pro účely úklidu.
parseInt64

parseInt64(řetězec, [radix])

1 Tato metoda funguje podobně jako standardní metoda JavaScript parseInt s tím rozdílem, že místo toho vrátí knihovnu Typu Int64. Pokud je zadán radix, parse bude probíhat v základu 2, 8, 10 nebo 16, jak je uvedeno.
rozšířeníPodpisuTypu

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

1 Konstruktor objektu určeného k umístění do pole vráceného z initializeScriptu představuje rozšíření nativního typu popsaného prostřednictvím podpisu typu pomocí prototypu JavaScriptu nebo třídy ES6. Taková registrace "přidá pole" do vizualizace ladicího programu libovolného typu, který odpovídá podpisu, místo aby ho zcela převzala. Volitelný název a verze modulu můžou registraci omezit. Verze jsou specifikovány jako řetězce ve stylu "1.2.3.4".
registraceTypuPodpisu

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

1 Konstruktor objektu určeného k umístění do pole vráceného z initializeScriptu představuje kanonickou registraci prototypu JavaScriptu nebo třídy ES6 proti nativnímu podpisu typu. Taková registrace "převezme" vizualizaci ladicího programu pro libovolný typ, který odpovídá podpisu, a nerozšiřuje ji pouze. Volitelný název a verze modulu můžou registraci omezit. Verze jsou specifikovány jako řetězce ve stylu "1.2.3.4".
zrušitZaregistrovanýModel

unregisterNamedModel(modelName)

2 Tím se zruší registrace datového modelu z vyhledávání podle daného názvu, který vrátí zpět všechny operace prováděné objektem registerNamedModel.
unregisterExtensionForTypeSignature

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

2 Tím se zruší registrace prototypu JavaScriptu nebo třídy ES6 z pozice rozšiřujícího datového modelu pro nativní typ, jak určuje zadaný podpis typu. Jedná se o logické neprovedení akce registerExtensionForTypeSignature. Všimněte si, že skript by měl raději vrátit objekt typeSignatureExtension ze své metody initializeScript spíše než to dělat imperativně. Všechny skripty, které provádí změny imperativním způsobem, musí mít inicializovatscriptovou metodu, aby bylo možné vyčistit. Volitelný název a verze modulu můžou registraci omezit. Verze se uvádějí jako řetězce ve stylu "1.2.3.4".
unregisterPrototypeForTypeSignature

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

2 Tím se zruší registrace prototypu JavaScriptu nebo třídy ES6 jako kanonického datového modelu (např. vizualizéru) pro nativní typ, jak je určen zadaným podpisem typu. Jedná se o logické vrácení zpět registerPrototypeForTypeSignature. Všimněte si, že skript by měl raději vrátit objekt typeSignatureRegistration ze své metody initializeScript místo toho, aby to dělal imperativně. Všechny skripty, které provádějí změny imperativně, musí mít metodu nezainicializovatScript na vyčištění. Volitelný název a verze modulu můžou registraci omezit. Verze jsou specifikovány jako řetězce ve stylu "1.2.3.4".

Diagnostické funkce

Podnázvový prostor diagnostiky hostitelského objektu obsahuje následující položky.

Název Podpis Fáze, která je k dispozici Popis
debugLog debugLog(object...) 1 To poskytuje ladění ve stylu printf pro rozšíření skriptu. V současné době se výstup z debugLogu směruje do výstupní konzoly ladicího programu. V pozdějším bodě v čase existují plány, které poskytují flexibilitu při směrování tohoto výstupu. POZNÁMKA: Tato možnost by neměla být použita jako prostředek tisku výstupu uživatele do konzoly. V budoucnu nemusí být směrováno tam.

Funkce paměti

Podnázvový prostor paměti hostitelského objektu obsahuje následující položky.

Název Podpis Fáze, která je k dispozici Popis
readMemoryValues

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

2 Načte se nezpracované pole hodnot z adresního prostoru cíle ladění a umístí typové pole nad zobrazení této paměti. Zadané umístění může být adresa (64bitová hodnota), objekt umístění nebo nativní ukazatel. Velikost pole je označena argumentem numElements . Velikost (a typ) každého prvku pole je dána volitelnými argumenty elementSize a isSigned. Pokud nejsou zadány žádné takové argumenty, je výchozí bajt (bez znaménka / 1 bajt). Pokud je zadán volitelný argument contextInheritor , paměť bude přečtena v kontextu (např. adresní prostor a cíl ladění) označený argumentem; jinak se načte z aktuálního kontextu ladicího programu. Všimněte si, že použití této metody u 8, 16 a 32bitových hodnot vede k rychlému zobrazení umístěnému přes paměť čtení. Použití této metody u 64bitových hodnot vede k vytvoření pole 64bitových typů knihoven, což je výrazně dražší!
readString

readString(location; [contextInheritor])

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

2 Načte úzký řetězec (podle aktuální znakové stránky) z adresního prostoru ladicího cíle, převede jej na UTF-16 a vrátí výsledek jako řetězec v JavaScriptu. Může vyvolat výjimku, pokud paměť nelze přečíst. Zadané umístění může být adresa (64bitová hodnota), objekt umístění nebo nativní znak. Pokud je zadán volitelný argument contextInheritor , paměť bude přečtena v kontextu (např. adresní prostor a cíl ladění) označený argumentem; jinak se načte z aktuálního kontextu ladicího programu. Pokud je zadán volitelný argument délky , přečtený řetězec bude mít zadanou délku.
readWideString

readWideString(umístění, [contextInheritor])

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

2 Načte široký řetězec (UTF-16) z adresního prostoru cílového objektu ladění a vrátí výsledek jako JavaScript řetězec. Může vyvolat výjimku, pokud paměť nelze přečíst. Zadané umístění může být adresa (64bitová hodnota), objekt umístění nebo nativní wchar_t. Pokud je zadán volitelný argument contextInheritor , paměť bude přečtena v kontextu (např. adresní prostor a cíl ladění) označený argumentem; jinak se načte z aktuálního kontextu ladicího programu. Pokud je zadán volitelný argument délky , přečtený řetězec bude mít zadanou délku.

Koncepty datového modelu v JavaScriptu

Mapování datového modelu

Následující koncepty datového modelu jsou mapovány na JavaScript.

Koncepce Nativní rozhraní Ekvivalent JavaScriptu
Převod řetězců IStringDisplayableConcept standard: toString(...){...}
Iterovatelnost IIterableConcept standard: [Symbol.iterator](){...}
Indexovatelnost IIndexableConcept protokol: getDimensionality(...) / getValueAt(...) / setValueAt(...)
Převod typu modulu runtime IPreferredRuntimeTypeConcept protokol: getPreferredRuntimeTypedObject(...)

Převod řetězců

Koncept konverze řetězců (IStringDisplayableConcept) se přímo překládá na standardní metodu JavaScript toString. Vzhledem k tomu, že všechny javascriptové objekty mají převod řetězce (který poskytuje Object.prototype, pokud není k dispozici jinde), lze každý javascriptový objekt vrácený do datového modelu převést na zobrazovaný řetězec. Přepsání metody pro převod na řetězec jednoduše vyžaduje implementaci vlastní metody toString.

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

Iterovatelnost

Koncept datového modelu o tom, zda je objekt iterovatelný nebo ne, přímo odpovídá protokolu ES6, který určuje, zda je objekt iterovatelný. Jakýkoli objekt, který má metodu [Symbol.iterator] je považován za iterovatelný. Implementace takového objektu bude iterovatelná.

Objekt, který je možné pouze iterovat, může mít implementaci, například následující.

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

U objektů, které je možné iterovat i indexovat, je třeba věnovat zvláštní pozornost, protože objekty vrácené iterátorem musí obsahovat index i hodnotu prostřednictvím speciálního návratového typu.

Iterovatelný a Indexovatelný

Objekt, který je iterovatelný a indexovatelný, vyžaduje speciální návratovou hodnotu z iterátoru. Místo generování hodnot iterátor poskytuje instance indexedValue. Indikáty se předávají jako pole v druhém argumentu konstruktoru indexedValue. Můžou být multidimenzionální, ale musí odpovídat rozměrnosti vrácené v protokolu indexeru.

Tento kód ukazuje příklad implementace.

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

Indexovatelnost

Na rozdíl od JavaScriptu datový model velmi explicitně rozlišuje přístup k vlastnostem a indexování. Jakýkoli javascriptový objekt, který se chce prezentovat jako indexovatelný v datovém modelu, musí implementovat protokol složený z metody getDimensionality, která vrací dimenzionalitu indexeru a volitelnou dvojici metod getValueAt a setValueAt, které provádějí čtení a zápisy objektu v zadaných indikátech. Je přijatelné vynechat metodu getValueAt nebo setValueAt, pokud je objekt jen pro čtení nebo jen pro zápis.

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

Převod typu modulu runtime

To je relevantní pouze pro prototypy a třídy JavaScriptu, které jsou registrovány proti typovým systémem (native) typům. Ladicí program často dokáže provádět analýzu (např. Run-Time Informace o typu (RTTI) / analýza v-table) k určení skutečného běhového typu objektu ze statického typu, který je vyjádřen v kódu. Datový model zaregistrovaný v nativním typu může toto chování přepsat prostřednictvím implementace IPreferredRuntimeTypeConcept. Stejně tak javascriptová třída nebo prototyp zaregistrovaný v nativním objektu může poskytovat vlastní implementaci prostřednictvím implementace protokolu sestávajícího z getPreferredRuntimeTypedObject metody.

Všimněte si, že i když tato metoda může technicky vrátit cokoli, považuje se za nevhodné, aby vrátila něco, co není ve skutečnosti běhovým typem nebo odvozeným typem. To může mít za následek značné nejasnosti pro uživatele ladicího programu. Přepsání této metody však může být užitečné pro věci, jako jsou záhlaví a objektové styly ve stylu C, atd.

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

Viz také

nativní objekty ladicího programu v rozšířeních JavaScriptu

Nativní objekty ladicího programu v rozšířeních JavaScriptu – Aspekty návrhu a testování

Skriptování ladicího programu JavaScriptu

Ukázkové skripty ladicího programu JavaScriptu