Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе описываются дополнительные сведения об использовании собственных объектов отладчика в расширениях JavaScript.
Собственные объекты отладчика представляют различные конструкции и поведение среды отладчика. Объекты можно передать в расширения JavaScript или получить из них, чтобы управлять состоянием отладчика.
Сведения о расширениях JavaScript для объектов отладчика см. в разделе "Собственные объекты отладчика" в расширениях 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.
Метод | Подпись | Описание |
---|---|---|
контекст хоста | Недвижимость | Возвращает объект, представляющий контекст, в котором находится объект (адресное пространство, целевой объект отладки и т. д.) |
targetLocation | Недвижимость | Возвращает объект, который является абстракцией местоположения объекта в адресном пространстве (виртуальный адрес, регистр, подрегистр и т. д.). |
targetSize | Недвижимость | Возвращает размер объекта (эффективно: sizeof(<TYPE OF OBJECT>) |
добавитьРодительскуюМодель | .addParentModel(object) | Добавляет новую родительскую модель (напоминающую прототип JavaScript, но на стороне модели данных) в объект |
removeParentModel | .removeParentModel(object) | Удаляет определенную родительскую модель из объекта |
runtimeTypedObject | Недвижимость | Выполняет анализ объекта и пытается преобразовать его в тип среды выполнения (наиболее производный) |
тип цели | Недвижимость | Расширения JavaScript имеют прямой доступ к системе типов базового языка. Этот доступ выражается через понятие объектов типа. Дополнительные сведения см. в разделе "Собственные объекты отладчика" в расширениях JavaScript — Type Objects |
Если объект является указателем, следующие свойства (и методы) проецируются на указатель, который вводит JavaScript:
Название свойства | Подпись | Описание |
---|---|---|
добавить | .add(value) | Выполняет математическое добавление указателя между указателем и указанным значением |
адрес | Недвижимость | Возвращает адрес указателя как 64-разрядный порядковый объект (тип библиотеки) |
разыменовать | .dereference() | Разыменовывает указатель и возвращает базовый объект |
isNull | Недвижимость | Возвращает, является ли значение указателя nullptr (0) или нет. |
Специальные типы, относящиеся к объектам нативного отладчика
Объекты расположения
Объект расположения, возвращаемый из свойства targetLocation собственного объекта, содержит следующие свойства (и методы).
Название свойства | Подпись | Описание |
---|---|---|
добавить | .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 хост-объект заполняется всем необходимым для манипулирования состоянием инкубаторов отладки.
Уровень объекта хоста
Несколько ключевых элементов функциональности находятся непосредственно под объектом хоста. Оставшиеся элементы находятся в подпространстве имен. Пространства имен включают следующие.
Namespace | Описание |
---|---|
Диагностика | Функции, помогающие в диагностике и отладке кода скрипта |
память | Функциональные возможности для включения чтения и записи памяти в целевом объекте отладки |
Корневой уровень
Непосредственно в объекте узла можно найти следующие свойства, методы и конструкторы.
Имя | Подпись | Текущий этап | Описание |
---|---|---|---|
создатьОбъектУказателя | createPointerObject(address, moduleName, typeName, [contextInheritor]) |
2 | Создает объект указателя по указанному адресу или расположению. Имя модуля и имя типа являются строками. Необязательный аргумент contextInheritor работает как с getModuleSymbol. |
создатьТипизированныйОбъект | createTypedObject(location, moduleName, typeName, [contextInheritor]) |
2 | Создает объект, представляющий собственный типизированный объект в адресном пространстве целевого объекта отладки в указанном расположении. Имя модуля и имя типа являются строками. Необязательный аргумент contextInheritor работает как с getModuleSymbol. |
текущий процесс | Недвижимость |
2 | Возвращает объект, представляющий текущий процесс отладчика |
текущая сессия | Недвижимость |
2 | Возвращает объект, представляющий текущий сеанс отладчика, в котором осуществляется отладка (цель, дамп и т. д.). |
currentThread | Недвижимость |
2 | Возвращает объект, представляющий текущий поток отладчика. |
evaluateExpression | evaluateExpression(expression, [contextInheritor]) |
2 | Это вызывает отладчик для вычисления выражения, используя только язык целевого объекта отладки. Если указан необязательный аргумент contextInheritor , выражение будет вычисляться в контексте (например, адресное пространство и целевой объект отладки) аргумента; в противном случае она будет оцениваться в текущем контексте отладчика. |
evaluateExpressionInContext | evaluateExpressionInContext(context, expression) |
2 | Это обращается к отладочному хосту для вычисления выражения с использованием только языка целевой системы отладки. Аргумент контекста указывает на неявный указатель this, который следует использовать для вычисления. Выражение будет оцениваться в контексте (например, адресное пространство и целевой объект отладки), указанный аргументом контекста . |
Получить символ модуля | getModuleSymbol(moduleName, symbolName, [contextInheritor]) |
2 | Возвращает объект для глобального символа в определенном модуле. Имя модуля и имя символа — это строки. Если указан необязательный аргумент contextInheritor , модуль и символ будут находиться в том же контексте (адресном пространстве, целевом объекте отладки), что и переданный объект. Если аргумент не указан, модуль и символ будут искать в текущем контексте отладчика. Расширение JavaScript, которое не является одноразовым скриптом, всегда должно предоставлять явный контекст |
getNamedModel | getNamedModel(modelName) |
2 | Возвращает модель данных, зарегистрированную по заданному имени. Обратите внимание, что совершенно законно использовать имя, которое еще не зарегистрировано. Это приведет к созданию заглушки для этого имени, и манипуляции с заглушкой будут применяться к реальному объекту после регистрации. |
индексированноеЗначение | new indexedValue(value, indicies) |
2 | Конструктор для объекта, который можно вернуть из итератора JavaScript, чтобы назначить набор символов по умолчанию для итерированного значения. Набор символов должен быть выражен как массив JavaScript. |
Int64 | new Int64(value, [highValue]) |
1 | Это создает тип библиотеки Int64. Версия с одним аргументом принимает любое значение, которое может быть помещено в Int64 (без преобразования). Если указан необязательный второй аргумент, преобразование первого аргумента упаковывается в нижние 32-биты, а преобразование второго аргумента упаковывается в верхние 32 бита. |
namedModelParent | new namedModelParent(объект, имя) |
1 | Конструктор объекта, предназначенный для включения в массив, возвращаемый из initializeScript, представляет использование прототипа JavaScript или класса ES6 в качестве родительского расширения модели данных с указанным именем. |
регистрацияНазваннойМодели | new namedModelRegistration(объект, имя) |
1 | Конструктор объекта, предназначенного для размещения в массиве, возвращаемом из initializeScript, представляет собой механизм регистрации прототипа JavaScript или класса ES6 в качестве модели данных через известное имя, чтобы другие расширения могли находить и расширять его. |
пространство имен | Недвижимость |
2 | Предоставляет прямой доступ к корневому пространству имен отладчика. Например, можно получить доступ к списку процессов первого целевого объекта отладки через host.namespace.Debuger.Session.First(). Процессы, использующие это свойство |
registerNamedModel (зарегистрировать именованную модель) | registerNamedModel(object, modelName) |
2 | Это регистрирует прототип JavaScript или класс ES6 в качестве модели данных под заданным именем. Такая регистрация позволяет находить прототип или класс и расширяться другими скриптами или другими расширениями отладчика. Обратите внимание, что скрипт должен предпочесть возвращать объект namedModelRegistration из его метода initializeScript , а не делать это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод initializeScript для очистки. |
registerExtensionForTypeSignature | registerExtensionForTypeSignature(object, typeSignature) |
2 | Это регистрирует прототип JavaScript или класс ES6 в качестве модели данных расширения для собственного типа, как указано предоставленной сигнатурой типа. Обратите внимание, что скрипт должен предпочесть возвращать объект typeSignatureExtension из его метода initializeScript , а не делать это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод initializeScript для очистки. |
registerPrototypeForTypeSignature | зарегистрироватьПрототипДляТипа(object, typeSignature) |
2 | Это регистрирует прототип JavaScript или класс ES6 в качестве канонической модели данных (например, визуализатор) для собственного типа, как указано предоставленной сигнатурой типа. Обратите внимание, что скрипт должен предпочитать возвращать объект typeSignatureRegistration из его метода initializeScript , а не делать это императивно. Любой скрипт, который вносит изменения императивно, должен обладать методом uninitializeScript для очистки. |
parseInt64 | parseInt64(string, [radix]) |
1 | Этот метод действует аналогично стандартному методу синтаксического анализа JavaScript, за исключением того, что он возвращает тип библиотеки Int64. Если предоставляется радикс, синтакс будет выполняться в базовой версии 2, 8, 10 или 16, как указано. |
typeSignatureExtension | new typeSignatureExtension(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
1 | Конструктор объекта, который предназначен для размещения в массиве, возвращаемого из initializeScript, представляет расширение встроенного типа, описанное с помощью сигнатуры типа прототипом JavaScript или классом ES6. Такая регистрация "добавляет поля" в визуализацию отладчика любого типа, который соответствует сигнатуре, а не принимает его полностью. Необязательное имя модуля и версия могут ограничить регистрацию. Версии указаны как строки стиля "1.2.3.4". |
регистрацияПодписиТипа | new typeSignatureRegistration(object, typeSignature, [moduleName], [minVersion], [maxVersion]) - функция регистрации сигнатуры типа для объекта с возможностью указания имени модуля и диапазона версий. |
1 | Конструктор объекта, предназначенного для размещения в массиве, возвращаемом из initializeScript, представляет эталонную регистрацию прототипа JavaScript или класса ES6 согласно сигнатуре собственного типа. Такая регистрация "берет на себя" визуализацию отладчика любого типа, который соответствует сигнатуре, а не просто, чем расширение. Необязательное имя модуля и версия могут ограничить регистрацию. Версии указаны в формате строк в стиле "1.2.3.4". |
отмена регистрацииNamedModel | unregisterNamedModel(modelName) |
2 | Это удаляет модель данных из поиска по заданному имени, отменяя все операции, выполненные registerNamedModel |
отменить регистрацию расширения для сигнатуры типа | unregisterExtensionForTypeSignature(объект, типПодписи, [имяМодуля], [минимальнаяВерсия], [максимальнаяВерсия]) |
2 | Это отменяет регистрацию прототипа JavaScript или класса ES6 в качестве модели данных расширения для встроенного типа, указанной в предоставленной сигнатуре типа. Это логическая отмена registerExtensionForTypeSignature. Обратите внимание, что скрипт должен предпочесть возвращать объект typeSignatureExtension из его метода initializeScript , а не делать это императивно. Любой скрипт, который вносит изменения императивно, должен иметь метод initializeScript для очистки. Необязательное имя модуля и версия могут ограничить регистрацию. Версии указаны в формате строк в стиле "1.2.3.4". |
анрегистрПрототипДляТипаПодписи | отменить регистрацию прототипа для сигнатуры типа(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
2 | Это отменяет регистрацию прототипа JavaScript или класса ES6 от канонической модели данных (например, визуализатора) для собственного типа, как указано предоставленной сигнатурой типа. Это логическое аннулирование функции registerPrototypeForTypeSignature. Обратите внимание, что скрипт должен предпочитать возвращать объект typeSignatureRegistration из его метода initializeScript , а не делать это императивно. Любой скрипт, который вносит изменения в обязательном порядке, должен иметь метод uninitializeScript для очистки. Необязательное имя модуля и версия могут ограничить регистрацию. Версии указаны в формате строк в стиле "1.2.3.4". |
Функции диагностики
Подпространство имен диагностики объекта хоста содержит следующее.
Имя | Подпись | Текущий этап | Описание |
---|---|---|---|
Лог отладки | debugLog(object...) | 1 | Это обеспечивает отладку в стиле printf для расширения скрипта. В настоящее время выходные данные из debugLog направляются в выходную консоль отладчика. На более поздний момент времени планируется обеспечить гибкость в маршрутизации этих выходных данных. ПРИМЕЧАНИЕ. Это не должно использоваться в качестве средства печати выходных данных пользователя в консоли. Он может не быть перенаправлен туда в будущем. |
Функциональные возможности памяти
Подпространство имен памяти объекта узла содержит следующее.
Имя | Подпись | Текущий этап | Описание |
---|---|---|---|
readMemoryValues | readMemoryValues(location, numElements, [elementSize], [isSigned], [contextInheritor]) |
2 | Это считывает необработанный массив значений из адресного пространства цели отладки и накладывает типизированный массив на представление этой памяти. Указанное расположение может быть адресом (64-разрядное значение), объектом расположения или собственным указателем. Размер массива указывается аргументом numElements . Размер (и тип) каждого элемента массива определяется необязательным элементомSize и аргументами isSigned . Если такие аргументы не указаны, по умолчанию используется байт (без знака / 1 байта). Если указан необязательный аргумент contextInheritor , память будет считываться в контексте (например, адресное пространство и целевой объект отладки), указанный аргументом; в противном случае он будет считываться из текущего контекста отладчика. Обратите внимание, что использование этого метода для 8, 16 и 32-разрядных значений приводит к быстрому типизированному представлению, помещаемого в память чтения. Использование этого метода для 64-разрядных значений приводит к построению массива 64-разрядных типов библиотек, что значительно дороже! |
readString | readString(location, [contextInheritor]) readString(location, [length], [contextInheritor]) |
2 | Эта функция считывает строку узкой кодировки (текущей кодовой страницы) из адресного пространства целевого объекта для отладки, преобразует её в формат UTF-16 и возвращает результат в виде строки JavaScript. Он может сгенерировать исключение, если не удалось прочитать память. Указанное расположение может быть адресом (64-разрядное значение), объектом расположения или собственным символом. Если указан необязательный аргумент contextInheritor , память будет считываться в контексте (например, адресное пространство и целевой объект отладки), указанный аргументом; в противном случае он будет считываться из текущего контекста отладчика. Если указан необязательный аргумент длины , строка чтения будет иметь указанную длину. |
readWideString | readWideString(location, [contextInheritor]) readWideString(location, [length], [contextInheritor]) |
2 | Это считывает строку wide(UTF-16) из адресного пространства целевого объекта отладки и возвращает результат в виде строки JavaScript. Это может генерировать исключение, если не удалось прочитать память. Указанное расположение может быть адресом (64-разрядное значение), объектом расположения или встроенным типом wchar_t. Если указан необязательный аргумент contextInheritor , память будет считываться в контексте (например, адресное пространство и целевой объект отладки), указанный аргументом; в противном случае он будет считываться из текущего контекста отладчика. Если указан необязательный аргумент длины , строка чтения будет иметь указанную длину. |
Основные понятия модели данных в JavaScript
Сопоставление моделей данных
Следующие концепции модели данных сопоставляются с JavaScript.
Понятие | Собственный интерфейс | Эквивалент JavaScript |
---|---|---|
Преобразование строк | IStringDisplayableConcept | standard: toString(...){...} |
Итерируемость | IIterableConcept | стандарт: [Symbol.iterator](){...} |
Индексация | IIndexableConcept | protocol: getDimensionality(...) / getValueAt(...) / setValueAt(...) |
Преобразование типов среды выполнения | IPreferredRuntimeTypeConcept | протокол: 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. Они могут быть многомерными, но должны соответствовать размерности, возвращаемой в протоколе индексатора.
В этом коде показан пример реализации.
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);
}
}
См. также
собственные объекты отладчика в расширениях JavaScript