Собственные объекты отладчика в расширениях JavaScript — сведения об объекте отладчика
В этом разделе описываются дополнительные сведения об использовании собственных объектов отладчика в расширениях JavaScript.
Собственные объекты отладчика представляют различные конструкции и поведения среды отладчика. Объекты могут передаваться в расширения JavaScript (или получать их в) для управления состоянием отладчика.
Сведения о расширениях JavaScript для объекта debugger см. в разделе Собственные объекты отладчика в расширениях JavaScript.
Общие сведения о работе с JavaScript см. в разделе Скрипты отладчика JavaScript.
Например, скрипты и расширения JavaScript команда отладчика размещает репозиторий GitHub по адресу https://github.com/Microsoft/WinDbg-Samples.
Объекты отладчика в расширениях JavaScript
Передача собственных объектов
Объекты отладчика можно передавать в расширения JavaScript или получать их различными способами.
- Их можно передавать в функции или методы JavaScript.
- Они могут быть объектом экземпляра для прототипа JavaScript (например, в виде визуализатора).
- Их можно возвращать из методов узла, предназначенных для создания собственных объектов отладчика.
- Их можно возвращать из методов узла, предназначенных для создания собственных объектов отладчика.
Объекты отладчика, передаваемые в расширение JavaScript, имеют набор функциональных возможностей, описанных в этом разделе.
- Доступ к свойствам
- Проецируемые имена
- Специальные типы, относящиеся к объектам собственного отладчика
- Дополнительные атрибуты
Доступ к свойствам
Хотя в объектах есть некоторые свойства, которые помещаются в них самим поставщиком JavaScript, большинство свойств в собственном объекте, который входит в JavaScript, предоставляются моделью данных. Это означает, что для доступа к свойству --- object.propertyName или object[propertyName] произойдет следующее.
- Если propertyName — это имя свойства, проецируемого на объект самим поставщиком JavaScript, оно сначала будет разрешаться в это свойство; Иначе
- Если propertyName — это имя ключа, проецируемого на объект моделью данных (другим визуализатором), оно будет разрешаться в это имя во второй раз; Иначе
- Если propertyName является именем поля собственного объекта, оно будет разрешаться в это имя в третьем; Иначе
- Если объект является указателем, указатель будет разыменовыменован, и цикл, описанный выше, продолжится (проецированное свойство разыменованного объекта, за которым следует ключ, за которым следует собственное поле).
Обычные средства доступа к свойствам в JavaScript — object.propertyName и object[propertyName] — будут обращаться к базовым собственным полям объекта так же, как команда dx в отладчике.
Проецируемые имена
Следующие свойства (и методы) проецируются на собственные объекты, которые входят в JavaScript.
Метод | Подпись | Описание |
---|---|---|
hostContext | Свойство | Возвращает объект , представляющий контекст, в котором находится объект (адресное пространство, целевой объект отладки и т. д.). |
targetLocation | Свойство | Возвращает объект, являющийся абстракцией расположения объекта в адресном пространстве (виртуальный адрес, регистр, подрегистрация и т. д.). |
targetSize | Свойство | Возвращает размер объекта (фактически: sizeof(<TYPE OF OBJECT>) |
addParentModel | .addParentModel(object) | Добавляет новую родительскую модель (сродни прототипу JavaScript, но на стороне модели данных) в объект |
removeParentModel | .removeParentModel(object) | Удаляет заданную родительскую модель из объекта . |
runtimeTypedObject | Свойство | Выполняет анализ объекта и пытается преобразовать его в тип среды выполнения (наиболее производный) |
targetType | Свойство | Расширения JavaScript имеют прямой доступ к системе типов базового языка. Этот доступ выражается через понятие объектов типа. Дополнительные сведения см. в разделе Собственные объекты отладчика в расширениях JavaScript — объекты типов. |
Если объект является указателем, следующие свойства (и методы) проецируются на указатель, который входит в JavaScript:
Имя свойства | Подпись | Описание |
---|---|---|
add | .add(value) | Выполняет математическое сложение указателя между указателем и указанным значением |
address | Свойство | Возвращает адрес указателя в виде 64-разрядного порядкового объекта (тип библиотеки) |
Разыменования | .dereference() | Разыменовывает указатель и возвращает базовый объект. |
Isnull | Свойство | Возвращает значение, указывающее, имеет ли значение указателя nullptr (0) |
Специальные типы, относящиеся к объектам собственного отладчика
Объекты расположения
Объект location, возвращаемый из свойства targetLocation собственного объекта, содержит следующие свойства (и методы).
Имя свойства | Подпись | Описание |
---|---|---|
add | .add(value) | Добавляет к расположению абсолютное смещение байтов. |
вычитание | .subtract(value) | Вычитает из расположения абсолютное смещение в байтах. |
Дополнительные атрибуты
Итерируемость
Любой объект, который понимается моделью данных как итерируемый (это собственный массив или имеет визуализатор (NatVis или иное), что делает его итератором), будет иметь функцию итератора (индексированную с помощью стандартного ES6 Symbol.iterator). Это означает, что можно выполнить итерацию собственного объекта в JavaScript следующим образом.
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++.
//
}
}
Индексируемость
Объекты, которые понимаются как индексируемые в одном измерении через порядковые номера (например, собственные массивы), будут индексироваться в JavaScript с помощью стандартного оператора доступа к свойству — object[index]. Если объект индексируется по имени или индексируется в нескольких измерениях, методы getValueAt и setValueAt проецируются на объект, чтобы код JavaScript смог использовать индексатор.
function indexNative(nativeArray)
{
var first = nativeArray[0];
}
Преобразование строк
Любой собственный объект, имеющий преобразование отображаемых строк с помощью поддержки IStringDisplayableConcept или элемента NatVis DisplayString, будет иметь доступ к преобразованию строк с помощью стандартного метода JavaScript toString.
function stringifyNative(nativeObject)
{
var myString = nativeObject.toString();
}
Создание собственных объектов отладчика
Как уже упоминалось, скрипт JavaScript может получить доступ к собственным объектам, передав их в JavaScript одним из нескольких способов, или создать их с помощью вызовов в хост-библиотеку. Используйте следующие функции для создания собственных объектов отладчика.
Метод | Подпись | Описание |
---|---|---|
host.getModuleSymbol |
getModuleSymbol(moduleName, symbolName, [contextInheritor]) getModuleSymbol(moduleName, symbolName, [typeName], [contextInheritor]) |
Возвращает объект для глобального символа в определенном модуле. Имя модуля и имя символа являются строками. Если указан необязательный аргумент contextInheritor , модуль и символ будут находиться в том же контексте (адресное пространство, целевой объект отладки), что и переданный объект. Если аргумент не указан, модуль и символ будут искаться в текущем контексте отладчика. Расширение JavaScript, которое не является одноразовым скриптом тестирования, всегда должно предоставлять явный контекст. Если указан необязательный аргумент typeName , предполагается, что символ имеет переданный тип, а тип, указанный в символах, будет игнорироваться. Обратите внимание, что любой вызывающий объект, который ожидает работать с открытыми символами для модуля, всегда должен предоставлять явное имя типа. |
host.getModuleContainingSymbol |
getModuleContainingSymbol(location, [contextInheritor]) | Возвращает символ (например, функцию или данные), который содержит указанный адрес. Обратите внимание, что это будет работать только при наличии закрытых символов для модуля, содержащего указанный адрес. Если указан необязательный аргумент contextInheritor , модуль и символ будут находиться в том же контексте (адресное пространство, целевой объект отладки), что и переданный объект. Если аргумент не указан, модуль и символ будут искаться в текущем контексте отладчика. Расширение JavaScript, которое не является одноразовым скриптом тестирования, всегда должно предоставлять явный контекст. |
host.createPointerObject |
createPointerObject(address, moduleName, typeName, [contextInheritor]) |
Создает объект указателя по указанному адресу или расположению. Имя модуля и имя типа являются строками. Если указан необязательный аргумент contextInheritor , модуль и символ будут находиться в том же контексте (адресное пространство, целевой объект отладки), что и переданный объект. Если аргумент не указан, модуль и символ будут искаться в текущем контексте отладчика. Расширение JavaScript, которое не является одноразовым скриптом тестирования, всегда должно предоставлять явный контекст. |
host.createTypedObject |
createTypedObject(location, moduleName, typeName, [contextInheritor]) |
Создает объект , представляющий собственный типизированный объект в диапазоне адресов целевого объекта отладки в указанном расположении. Имя модуля и имя типа являются строками. Если указан необязательный аргумент contextInheritor , модуль и символ будут находиться в том же контексте (адресное пространство, целевой объект отладки), что и переданный объект. Если аргумент не указан, модуль и символ будут искаться в текущем контексте отладчика. Расширение JavaScript, которое не является одноразовым скриптом тестирования, всегда должно предоставлять явный контекст. |
API узла для расширений JavaScript
Поставщик JavaScript вставляет объект host в глобальное пространство имен каждого загружаемого скрипта. Этот объект предоставляет доступ к критически важным функциям скрипта, а также к пространству имен отладчика. Она настраивается в два этапа.
Этап 1. Перед выполнением любого скрипта главный объект содержит только минимальный набор функциональных возможностей, необходимых для инициализации скрипта и регистрации его точек расширяемости (как в качестве производителя, так и в качестве потребителя). Корневой код и инициализации не предназначен для управления состоянием целевого объекта отладки или выполнения сложных операций. Таким образом, узел не заполняется полностью до тех пор, пока не будет возвращен метод initializeScript.
Этап 2. После возврата initializeScript объект узла заполняется всем необходимым для управления состоянием целевых объектов отладки.
Уровень объекта узла
Несколько ключевых компонентов функциональных возможностей находятся непосредственно под объектом ведущего приложения. Остальные являются вложенными пространствами имен. К пространствам имен относятся следующие.
Пространство имен | Описание |
---|---|
диагностика | Функциональные возможности, помогающие в диагностике и отладке кода скрипта |
Память | Функциональные возможности для чтения и записи в памяти в целевом объекте отладки |
Корневой уровень
Непосредственно в объекте узла можно найти следующие свойства, методы и конструкторы.
Имя | Сигнатура | Презентация этапа | Описание |
---|---|---|---|
createPointerObject | createPointerObject(address, moduleName, typeName, [contextInheritor]) |
2 | Создает объект указателя по указанному адресу или расположению. Имя модуля и имя типа являются строками. Необязательный аргумент contextInheritor работает так же, как и в getModuleSymbol. |
createTypedObject | createTypedObject(location, moduleName, typeName, [contextInheritor]) |
2 | Создает объект , представляющий собственный типизированный объект в диапазоне адресов целевого объекта отладки в указанном расположении. Имя модуля и имя типа являются строками. Необязательный аргумент contextInheritor работает так же, как и в getModuleSymbol. |
currentProcess | Свойство |
2 | Возвращает объект , представляющий текущий процесс отладчика. |
currentSession | Свойство |
2 | Возвращает объект , представляющий текущий сеанс отладчика (целевой объект, дамп и т. д.), который выполняет отладку. |
currentThread | Свойство |
2 | Возвращает объект , представляющий текущий поток отладчика. |
evaluateExpression | evaluateExpression(expression, [contextInheritor]) |
2 | Это вызывает узел отладки для вычисления выражения только с использованием языка целевого объекта отладки. Если указан необязательный аргумент contextInheritor , выражение будет вычисляться в контексте (например, адресное пространство и целевой объект отладки) аргумента; в противном случае он будет оцениваться в текущем контексте отладчика. |
evaluateExpressionInContext | evaluateExpressionInContext(context, expression) |
2 | Это вызывает узел отладки для вычисления выражения только с использованием языка целевого объекта отладки. Аргумент контекста указывает неявный этот указатель, который будет использоваться для оценки. Выражение будет вычисляться в контексте (например, адресное пространство и целевой объект отладки), указанном аргументом контекста . |
getModuleSymbol | getModuleSymbol(moduleName, symbolName, [contextInheritor]) |
2 | Возвращает объект для глобального символа в определенном модуле. Имя модуля и имя символа являются строками. Если указан необязательный аргумент contextInheritor , модуль и символ будут находиться в том же контексте (адресное пространство, целевой объект отладки), что и переданный объект. Если аргумент не указан, модуль и символ будут искаться в текущем контексте отладчика. Расширение JavaScript, которое не является одноразовым скриптом, всегда должно предоставлять явный контекст |
getNamedModel | getNamedModel(modelName) |
2 | Возвращает модель данных, зарегистрированную для заданного имени. Обратите внимание, что это совершенно законно для имени, которое еще не зарегистрировано. Это приведет к созданию заглушки для этого имени, и манипуляции с заглушки будут выполняться с фактическим объектом после регистрации. |
indexedValue | new indexedValue(value, indicies) |
2 | Конструктор для объекта, который может быть возвращен из итератора JavaScript, чтобы назначить набор атрибутов по умолчанию итерированному значению. Набор атрибутов должен быть выражен в виде массива JavaScript. |
Int64 | new Int64(value, [highValue]) |
1 | При этом создается тип библиотеки Int64. Версия с одним аргументом принимает любое значение, которое может упаковываться в int64 (без преобразования) и помещать его в такую версию. Если указан необязательный второй аргумент, преобразование первого аргумента упаковывается в нижние 32 бита, а преобразование второго аргумента упаковывается в верхние 32 бита. |
namedModelParent | new namedModelParent(object, name) |
1 | Конструктор для объекта, предназначенного для размещения в массиве, возвращаемом из initializeScript. Это представляет собой использование прототипа JavaScript или класса ES6 в качестве родительского расширения модели данных для модели данных с заданным именем. |
namedModelRegistration | new namedModelRegistration(object, name) |
1 | Конструктор для объекта, предназначенного для размещения в массиве, возвращаемом из initializeScript, представляет собой регистрацию прототипа JavaScript или класса ES6 в качестве модели данных с помощью известного имени, чтобы другие расширения могли находить и расширять |
пространство имен | Свойство |
2 | Предоставляет прямой доступ к корневому пространству имен отладчика. Например, можно получить доступ к списку процессов первого целевого объекта отладки через host.namespace.Debugger.Sessions.First(). Процессы, использующие это свойство |
registerNamedModel | registerNamedModel(object, modelName) |
2 | При этом регистрируется прототип JavaScript или класс ES6 в качестве модели данных под заданным именем. Такая регистрация позволяет находить прототип или класс и расширяться другими скриптами или другими расширениями отладчика. Обратите внимание, что скрипт должен предпочесть возвращать объект namedModelRegistration из метода initializeScript , а не выполнять это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод initializeScript для очистки. |
registerExtensionForTypeSignature | registerExtensionForTypeSignature(object, typeSignature) |
2 | При этом регистрируется прототип JavaScript или класс ES6 в качестве модели данных расширения для собственного типа, заданного предоставленной сигнатурой типа. Обратите внимание, что скрипт должен предпочесть возвращать объект typeSignatureExtension из метода initializeScript , а не делать это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод initializeScript для очистки. |
registerPrototypeForTypeSignature | registerPrototypeForTypeSignature(object, typeSignature) |
2 | Это регистрирует прототип JavaScript или класс ES6 в качестве канонической модели данных (например, визуализатора) для собственного типа, как указано предоставленной сигнатурой типа. Обратите внимание, что скрипт должен предпочесть возвращать объект typeSignatureRegistration из метода initializeScript , а не выполнять это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод uninitializeScriptдля очистки. |
parseInt64 | parseInt64(string, [radix]) |
1 | Этот метод действует аналогично стандартному методу javaScript parseInt, за исключением того, что он возвращает тип библиотеки Int64. Если указан радикс, синтакс будет выполняться в базе 2, 8, 10 или 16, как указано. |
typeSignatureExtension | new typeSignatureExtension(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
1 | Конструктор для объекта, предназначенного для размещения в массиве, возвращенном из initializeScript, представляет собой расширение собственного типа, описываемого с помощью сигнатуры типа прототипом JavaScript или классом ES6. Такая регистрация "добавляет поля" в визуализацию отладчика любого типа, который соответствует сигнатуре, а не полностью перебирает ее. Необязательное имя и версия модуля могут ограничить регистрацию. Версии указываются как строки стиля "1.2.3.4". |
typeSignatureRegistration | new typeSignatureRegistration(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
1 | Конструктор для объекта, предназначенного для размещения в массиве, возвращенном из initializeScript, представляет каноническую регистрацию прототипа JavaScript или класса ES6 для собственной сигнатуры типа. Такая регистрация "берет на себя" визуализацию отладчика любого типа, который соответствует сигнатуре, а не просто расширяет ее. Необязательное имя и версия модуля могут ограничить регистрацию. Версии указываются как строки стиля "1.2.3.4". |
unregisterNamedModel | unregisterNamedModel(modelName) |
2 | Это отменяет регистрацию модели данных из поиска по заданному имени, отменяя все операции, выполняемые registerNamedModel. |
unregisterExtensionForTypeSignature | unregisterExtensionForTypeSignature(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
2 | Это отменяет регистрацию прототипа JavaScript или класса ES6 в качестве модели данных расширения для собственного типа, заданного предоставленной сигнатурой типа. Это логическая отмена registerExtensionForTypeSignature. Обратите внимание, что скрипт должен предпочесть возвращать объект typeSignatureExtension из метода initializeScript , а не делать это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод initializeScript для очистки. Необязательное имя и версия модуля могут ограничить регистрацию. Версии указываются как строки стиля "1.2.3.4". |
unregisterPrototypeForTypeSignature | unregisterPrototypeForTypeSignature(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
2 | Это отменяет регистрацию прототипа JavaScript или класса ES6 от канонической модели данных (например, визуализатора) для собственного типа, как указано предоставленной сигнатурой типа. Это логическая отмена registerPrototypeForTypeSignature. Обратите внимание, что скрипт должен предпочесть возвращать объект typeSignatureRegistration из метода initializeScript , а не выполнять это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод uninitializeScript для очистки. Необязательное имя и версия модуля могут ограничить регистрацию. Версии указываются как строки стиля "1.2.3.4". |
Функциональные возможности диагностики
Подпространство имен диагностика объекта узла содержит следующее.
Имя | Сигнатура | Этап "Присутствует" | Описание |
---|---|---|---|
debugLog | debugLog(object...) | 1 | Это обеспечивает отладку в стиле printf в расширении скрипта. В настоящее время выходные данные из debugLog направляются в консоль вывода отладчика. Позже планируется обеспечить гибкость при маршрутизации этих выходных данных. ПРИМЕЧАНИЕ. Его не следует использовать в качестве средства печати выходных данных пользователя в консоль. Она не может быть направлена туда в будущем. |
Функции памяти
Подпространство имен памяти объекта узла содержит следующее.
Имя | Сигнатура | Презентация этапа | Описание |
---|---|---|---|
readMemoryValues | readMemoryValues(location, numElements, [elementSize], [isSigned], [contextInheritor]) |
2 | Он считывает необработанный массив значений из адресного пространства целевого объекта отладки и помещает типизированный массив поверх представления этой памяти. Указанное расположение может быть адресом (64-разрядное значение), объектом расположения или собственным указателем. Размер массива определяется аргументом numElements . Размер (и тип) каждого элемента массива задается необязательными аргументами elementSize и isSigned . Если такие аргументы не указаны, по умолчанию используется байт (без знака / 1 байт). Если указан необязательный аргумент contextInheritor , память будет считываться в контексте (например, адресное пространство и целевой объект отладки), указанном аргументом ; в противном случае он будет считываться из текущего контекста отладчика. Обратите внимание, что использование этого метода для 8, 16 и 32-разрядных значений приводит к тому, что быстрое типизированное представление помещается в память для чтения. Использование этого метода для 64-разрядных значений приводит к построению массива типов 64-разрядных библиотек, что значительно дороже! |
Readstring | readString(location, [contextInheritor]) readString(location, [length], [contextInheritor]) |
2 | Он считывает узкую строку (текущая кодовая страница) из адресного пространства целевого объекта отладки, преобразует ее в UTF-16 и возвращает результат в виде строки JavaScript. Если не удалось прочитать память, может возникнуть исключение. Указанное расположение может быть адресом (64-разрядное значение), объектом расположения или собственным символом. Если указан необязательный аргумент contextInheritor , память будет считываться в контексте (например, адресное пространство и целевой объект отладки), указанном аргументом ; в противном случае он будет считываться из текущего контекста отладчика. Если указан необязательный аргумент length , строка чтения будет иметь указанную длину. |
readWideString | readWideString(location, [contextInheritor]) readWideString(location, [length], [contextInheritor]) |
2 | Он считывает строку wide (UTF-16) из адресного пространства целевого объекта отладки и возвращает результат в виде строки JavaScript. Если не удалось прочитать память, может возникнуть исключение. Указанное расположение может быть адресом (64-разрядное значение), объектом расположения или собственным wchar_t. Если указан необязательный аргумент contextInheritor , память будет считываться в контексте (например, адресное пространство и целевой объект отладки), указанном аргументом ; в противном случае он будет считываться из текущего контекста отладчика. Если указан необязательный аргумент length , строка чтения будет иметь указанную длину. |
Основные понятия модели данных в JavaScript
Сопоставление модели данных
Следующие концепции модели данных соответствуют JavaScript.
Концепция | Собственный интерфейс | Эквивалент JavaScript |
---|---|---|
Преобразование строк | IStringDisplayableConcept | standard: toString(...) {...} |
Итерируемость | IIterableConcept | standard: [Symbol.iterator](){...} |
Индексируемость | IIndexableConcept | protocol: getDimensionality(...) / getValueAt(...) / setValueAt(...) |
Преобразование типов среды выполнения | IPreferredRuntimeTypeConcept | protocol: getPreferredRuntimeTypedObject(...) |
Преобразование строк
Концепция преобразования строк (IStringDisplayableConcept) напрямую преобразуется в стандартный метод JavaScript toString . Так как все объекты JavaScript имеют преобразование строк (предоставляется Object.prototype, если оно не указано в другом месте), каждый объект JavaScript, возвращенный в модель данных, можно преобразовать в отображаемую строку. Для переопределения преобразования строк просто требуется реализовать собственный toString.
class myObject
{
//
// This method will be called whenever any native code calls IStringDisplayableConcept::ToDisplayString(...)
//
toString()
{
return "This is my own string conversion!";
}
}
Итерируемость
Концепция модели данных о том, является ли объект итерируемым или нет, напрямую соответствует протоколу ES6 о том, является ли объект итерируемым. Любой объект, имеющий метод [Symbol.iterator], считается итерируемым. Реализация этого метода сделает объект итерируемым.
Объект, который является только итерируемым, может иметь реализацию, как показано ниже.
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";
}
}
Особое внимание следует уделять объектам, которые являются итерируемыми и индексируемыми, так как объекты, возвращаемые итератором, должны включать индекс, а также значение через специальный тип возвращаемого значения.
Итерируемые и индексируемые
Объект, который является итерируемым и индексируемым, требует специального возвращаемого значения от итератора. Вместо того, чтобы возвращать значения, итератор возвращает экземпляры indexedValue. Индексы передаются в виде массива во втором аргументе конструктору indexedValue. Они могут быть многомерными, но должны соответствовать размерности, возвращаемой в протоколе индексатора.
В этом коде показан пример реализации.
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]);
}
}
Индексируемость
В отличие от JavaScript, модель данных делает очень явное различие между доступом к свойствам и индексированием. Любой объект JavaScript, который хочет представить себя как индексируемый в модели данных, должен реализовывать протокол, состоящий из метода getDimensionality, который возвращает размерность индексатора, и необязательной пары методов getValueAt и setValueAt, которые выполняют операции чтения и записи объекта в указанных объектах. Допустимо пропускать методы getValueAt или setValueAt, если объект доступен только для чтения или только для записи.
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;
}
}
Преобразование типов среды выполнения
Это относится только к прототипам и классам JavaScript, которые зарегистрированы в системных (собственных) типах. Отладчик часто может выполнять анализ (например, анализ сведений о типе Run-Time (RTTI) или v-table), чтобы определить истинный тип среды выполнения объекта из статического типа, выраженного в коде. Модель данных, зарегистрированная в собственном типе, может переопределить это поведение с помощью реализации IPreferredRuntimeTypeConcept. Аналогичным образом класс Или прототип JavaScript, зарегистрированные в собственном объекте, могут предоставлять собственную реализацию через реализацию протокола, состоящего из метода getPreferredRuntimeTypedObject.
Обратите внимание, что хотя этот метод технически может возвращать что-либо, он считается неправильным, чтобы он возвращал то, что на самом деле не является типом среды выполнения или производным типом. Это может привести к значительной путанице для пользователей отладчика. Однако переопределение этого метода может быть полезным для таких вещей, как заголовок В стиле C и стили объектов реализации и т. д.
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);
}
}