Vk scripts что это

Содержание

VKScript — это не JavaScript. Семантика этого языка кардинально отличается от семантики JavaScript. См. заключение.

Что такое VKScript?

VKScript — скриптовый язык программирования, похожий на JavaScript, который используется в методе execute API ВКонтакте, который дает клиентам возможность загружать ровно ту информацию, которая им нужна. По сути, VKScript — это аналог GraphQL, используемого в Facebook для тех же целей.

Сравнение GraphQL и VKScript:

GraphQL VKScript
Реализации Множество open-source реализаций на разных языках программирования Единственная реализация в рамках API ВКонтакте
Основан на Абсолютно новый язык JavaScript
Возможности Запрос данных, ограниченная фильтрация; аргументы запроса не могут использовать результаты предыдущих запросов Любая пост-обработка данных на усмотрение клиента; запросы к API представлены в виде методов и могут использовать любые данные из предыдущих запросов

Описание VKScript со страницы метода в документации VK API (единственная официальная документация по языку):

Подборка скриптов для ВК | СКРИПТЫ ДЛЯ ВК | БЕСПЛАТНО + БЕЗ ПРОГРАММ

code
код алгоритма в VKScript — формате, похожем на JavaSсript или ActionScript (предполагается совместимость с ECMAScript). Алгоритм должен завершаться командой return %выражение%. Операторы должны быть разделены точкой с запятой.
строка

В приведенной документации указано, что «планируется совместимость с ECMAScript». Но так ли это? Попробуем разобраться, как этот язык работает изнутри.

Виртуальная машина VKScript

Как вообще можно анализировать программу при отсутствии локальной копии? Правильно — отправлять запросы к публичному endpoint’у и анализировать ответы. Попробуем, например, выполнить такой код:

while(1);

Мы получаем ошибку Runtime error occurred during code invocation: Too many operations . Это говорит о том, что в реализации языка присутствует лимит на количество произведенных действий. Попробуем установить точное значение лимита:

var i = 0; while(i < 1000) i = i + 1;

  • Runtime error occurred during code invocation: Too many operations .

var i = 0; while(i < 999) i = i + 1;

Таким образом, лимит на количество операций — порядка 1000 «холостых» циклов. Но, в то же время, понятно, что такой цикл, скорее всего, не является «унитарной» операцией. Попробуем найти операцию, которая не разделяется компилятором на несколько более мелких.

Следующее, что приходит в голову после ; — вычисление какого-нибудь простого выражения (например, так: 1; ). Попробуем добавить несколько таких выражений в наш код:

var i = 0; while(i < 999) i = i + 1; 1; // так еще работает 1; // при добавлении этой строки получаем ошибку «Too many operations»

Таким образом, 2 операции 1; тратят больше операций, чем 50 операция ; . Это подтверждает гипотезу о том, что empty statement не тратит инструкций.

Попробуем уменьшать количество итераций цикла и добавлять дополнительные 1; . Несложно заметить, что на каждую итерацию приходится 5 дополнительных 1; , следовательно, одна итерация цикла тратит в 5 раз больше операций, чем одна операция 1; .

Но нет ли еще более простой операции? Например, добавление унарного оператора ~ не требует вычисления дополнительных выражений, а сама операция выполняется на процессоре. Логично предположить, что добавление в выражение этой операции увеличивает общее количество операций на 1.

Добавим в наш код этот оператор:

var i = 0; while(i < 999) i = i + 1; ~1;

И да, один такой оператор мы добавить можем, а еще одно выражение 1; — уже нет. Следовательно, 1; действительно не является унитарным оператором.

Аналогично оператору 1; , будем уменьшать количество итераций цикла и добавлять операторы ~ . Одна итерация оказалась эквивалентна 10 унитарным операциям ~ , следовательно, выражение 1; тратит 2 операции.

Заметим, что лимит составляет примерно 1000 итераций, то есть примерно 10000 единичных операций. Будем считать, что лимит составляет точно 10000 операций.

Измерение количества операций в коде

Заметим, что теперь мы можем измерять количество операций в любом коде. Для этого нужно добавить этот код после цикла и добавлять/удалять итерации, операторы ~ или всю последнюю строку целиком, пока ошибка Too many operations не исчезнет.

Некоторые результаты измерений:

Код Количество операций
1; 2
~1; 3
1+1; 4
1+1+1; 6
(true?1:1); 5
(false?1:1); 4
if(0)1; 2
if(1)1; 4
if(0)1;else 1; 4
if(1)1;else 1; 5
while(0); 2
i=1; 3
i=i+1; 5
var j = 1; 1
var j = 0;while(j < 1)j=j+1; 15

Определение типа виртуальной машины

Для начала нужно понять, по какому принципу работает интерпретатор VKScript. Есть два более-менее правдоподобных варианта:

  • Интерпретатор рекурсивно обходит синтаксическое дерево и выполняет операцию в каждом узле.
  • Компилятор переводит синтаксическое дерево в последовательность инструкций, которые выполняет интерпретатор.

Несложно понять, что в VKScript используется второй вариант. Рассмотрим выражения (true?1:1); (5 операций) и (false?1:1); (4 операции). В случае с последовательным выполнением инструкций дополнительная операция объясняется переходом, который «обходит» неверный вариант, а в случае с рекурсивным обходом AST оба варианта для интерпретатора равноценны. Аналогичный эффект наблюдается в if/else с разным условием.

Также стоит обратить внимание на пару i = 1; (3 операции) и var j = 1; (1 операция). Создание новой переменной обходится всего в 1 операцию, а присвоение в существующую — в 3? То, что создание переменной обходится в 1 операцию (и то, это, скорее всего, операция загрузки константы), говорит о двух вещах:

  • При создании новой переменной не происходит явного выделения памяти под переменную.
  • При создании новой переменной не происходит загрузки значения в ячейку памяти. Это означает, что место под новую переменную выделяется там, где было вычислено значение выражения, и после этого эта память считается выделенной. Это говорит об использовании стековой машины.

Использованием стека также объясняется то, что выражение var j = 1; выполняется быстрее, чем выражение 1; : последнее выражение тратит дополнительную инструкцию на то, чтобы убрать со стека вычисленное значение.

Определение точного значения лимита

var i = 0; while(i < 1) i = i + 1;
var i = 0; while(i < 999) i = i + 1;
var i = 0; while(i < 999) i = i + 1; ~1;

Стоп, что? Лимит составляет 9998 инструкций?

Мы явно что-то упускаем.

Заметим, что код return 1; выполняется, согласно измерениям, за 0 инструкций. Это легко объясняется: компилятор добавляет в конце кода неявный return null; , и при добавлении своего return’а он не выполняется. Считая, что лимит равен 10000, делаем вывод, что операция return null; занимает 2 инструкции (вероятно, это что-то вроде push null; return; ).

Вложенные блоки кода

Проведем еще несколько измерений:

Код Количество операций
<>; 0
; 2
; 3
; 3
var j = 1; var j = 1; 4
; var j = 1; 3

Обратим внимание на следующие факты:

  • При добавлении переменной в блок тратится одна дополнительная операция.
  • При «объявлении переменной заново» второе объявление отрабатывает как обычное присваивание.
  • Но при этом переменная внутри блока снаружи не видна (см. последний пример).

Несложно понять, что лишняя операция тратится на удаление со стека локальных переменных, объявленных в блоке. Соответственно, когда локальных переменных нет, удалять ничего не нужно.

Объекты, методы, вызовы API

Код Количество операций
«»; 2
«abcdef»; 2
<>; 2
[]; 2
[1, 2, 3]; 5
; 5
API.users.isAppUser(1); 3
«».substr(0, 0); 6
var j=<>;j.x=1; 6
var j=;delete j.x; 6
Еще по теме:  Как удалить все сообщества в ВК сразу

Проанализируем полученные результаты. Можно заметить, что создание строки и пустого массива/объекта занимает 2 операции, так же как и загрузка числа. При создании непустого массива или объекта добавляются операции, потраченные на загрузку элементов массива/объекта. Это говорит о том, что непосредственно создание объекта происходит за одну операцию. При этом на загрузку названий свойств время не тратится, следовательно, их загрузка является частью операции создания объекта.

С вызовом метода API все тоже весьма банально — загрузка единицы, собственно вызов метода, pop результата (можно заметить, что название метода обрабатывается как единое целое, а не как взятие свойств). А вот последние три примера выглядят интересно.

  • «».substr(0, 0); — загрузка строки, загрузка нуля, загрузка нуля, pop результата. На вызов метода почему-то приходится 2 инструкции (почему — см. далее).
  • var j=<>;j.x=1; — создание объекта, загрузка объекта, загрузка единицы, pop единицы после присваивания. Опять-таки, на присваивание приходится 2 инструкции.
  • var j=;delete j.x; — загрузка единицы, создание объекта, загрузка объекта, удаление. На операцию удаления приходится 3 инструкции.

Семантика объектов VKScript

Числа

Вернемся к исходному вопросу: VKScript — это подмножество JavaScript или другой язык? Проведем простой тест:

return 1000000000 + 2000000000;

Как мы видим, целочисленное сложение приводит к переполнению, несмотря на то, что в JavaScript нет целых чисел как таковых. Также несложно убедиться, что деление на 0 приводит к ошибке, а не возвращает Infinity .

Объекты

return <>;

Стоп, что? Мы возвращаем объект и получаем массив? Да, так и есть. В языке VKScript массивы и объекты представлены одним типом, в частности, пустой объект и пустой массив это одно и тоже.

При этом свойство length у объекта работает и возвращает количество свойств.

Интересно посмотреть, как поведут себя методы списка, если вызвать их на объекте?

return .pop();

Метод pop возвращает последнее объявленное свойство, что, впрочем, логично. Поменяем порядок свойств:

return .pop();

Видимо, объекты в VKScript запоминают порядок присвоения свойств. Попробуем использовать числовые свойства:

return .pop();

Теперь посмотрим, как работает push:

var a = ; a.push(‘d’); return a;

Как видим, метод push сортирует численные ключи и добавляет новое значение после последнего численного ключа. «Дыры» при этом не заполняются.

Теперь попробуем объединить два этих метода:

var a = ; a.push(a.pop()); return a;

Как мы видим, элемент не удалился из массива. Однако, если мы разнесем push и pop в разные строки, баг пропадет. We need to go deeper!

Хранение объектов

var x = <>; var y = x; x.y = ‘z’; return y;

Как выяснилось, объекты в VKScript хранятся по значению, в отличие от JavaScript. Теперь понятно странное поведение строки a.push(a.pop()); — видимо, старое значение массива сохранилось на стеке, откуда потом и было взято.

Однако как тогда данные сохраняются в объект, если метод его изменяет? Видимо, «лишняя» инструкция при вызове метода предназначена именно для записи изменений обратно в объект.

Методы массивов

  • отсортировать числовые ключи по значению
  • взять максимальный числовой ключ, прибавить единицу
  • записать аргумент в массив
  • добавить в конец массива нечисловые ключи
  • отсортировать числовые ключи по значению, убрать «дыры» в массиве
  • выполнить соответствующую операцию JavaScript
  • добавить в конец массива нечисловые ключи

При использовании метода slice изменения не сохраняются

Заключение

VKScript — это не JavaScript. В отличие от JavaScript, объекты в нем хранятся по значению, а не по ссылке, и обладают совершенно другой семантикой. Однако при использовании VKScript для цели, для которой он предназначен, разница незаметна.

P.S. Семантика операторов

В комментариях упомянули объединение объектов через + . В связи с этим решил добавить информацию о работе операторов.

  • Если оба аргумента — объекты, создать копию первого объекта и добавить в нее ключи из второго (с заменой).
  • Если оба аргумента — числа, сложить как числа.
  • В противном случае, оба операнда приводятся к строке и складываются как строки.

При операциях с числами (кроме битовых), если операнды — int и double , int приводится к double . Если оба операнда — int , производится операция над знаковыми 32-битными целыми числами (с переполнением).

  • vkscript
  • вконтакте api
  • реверс-инжиниринг
  • JavaScript
  • ВКонтакте API
  • Реверс-инжиниринг

Источник: habr.com

Скрипт для накрутки сообщений ВКонтакте: как его использовать?

Скрипт – это программный файл сценарий, автоматизирующий одну задачу, которую пользователь может делать вручную с использованием интерфейса программы.

что такое скрипт для накрутки вконтакте

Программный файл появился чуть позже после создания JavaScript (мультипарадигменного языка программирования) в 1995 году. Создатель этого языка стал Брендан Эйх – американский программист, работающий «Netscape» с 4 апреля 1995 года.

кто придумал первый скрипт для накрутки вк

Предпосылками к созданию является работа , которая ставила перед собой задачу создать встроенный программный язык.

настройка скрипта динамической обложки определение координат в PSD шаблоне опасность работы со скриптами для накрутки во вконтакте получение ID приложения вконтакте настройка отображения новых подписчиков главные настройки получение токена вставка токена в скрипт динамической обложки

В каких случаях целесообразно использовать скрипты?

Не всегда применение таких программ идет на пользу. В случае перезагрузки приложения программный файл может только замедлить работу браузера или полностью вывести его из строя.

Вот перечень случаев, когда использовать скрипты целесообразно:

  • для управления ресурсом, расширения функционала;
  • для сборки статистических данных;
  • для оптимизации поиска;
  • для организации работы;
  • для изменения структуры сайта;
  • для повышения гибкости изменения приложения.



Установка плагина на примере Google Chrome

Алгоритм использования скрипта практически идентичен во всех браузерах, поэтому мы разберем его один раз на примере самого популярного. Плагин называется . Перейдите на его страницу в магазине и кликните « ». Дальше пошаговая инструкция.

  • Перед вами появится окно. В нем нужно нажать на «Установить расширение».
  • Новое окно запросит доступ к общей информации, сообщениям и списку друзей. Разрешите доступ.
  • Теперь нужно немного подождать, пока плагин полностью проанализирует сообщения. Время ожидания зависит только от количества созданных диалогов и производительности компьютера.
  • Перед вами откроется окно с подробной статистикой сообщений. Показана следующая информация: общее количество сообщений — отправленных и полученных, а так же сумарные значения символов.

Но это еще не все. Чтобы ознакомиться с информацией в удобном формате, необходимо установить другое расширение для браузера. Называется оно VK Messages Visual Statistics. Вся информация по сообщениям будет представлена в виде диаграммы с сортировкой по нисходящей, зависящей от вашей активности в диалоге с разными пользователями. Чтобы отобразить информацию в будущем — просто кликните на иконку в правом верхнем углу.

Как накрутить сообщения в ВКонтакте скриптами?

Если вы думаете, что заниматься программными файлами сценариев могут только программисты, то это не так. С помощью простого алгоритма действий каждый сможет использовать программный файл для накрутки сообщений:

как работает скрипт для накрутки сообщений вконтакте

  1. Заходим в социальную сеть ВКонтакте.
  2. Нажимаем на вкладку «Сообщения», которая располагается в левой стороне.
  3. Открываем код элемента клавишей F.
  4. Внизу странице всплывает окно. В его вверху панель с разделами. Жмем по пункту «Консоль».
  5. Копируем (выделение, Ctrl+С) и скидываем его в нижнюю область для текста (Ctrl+V).
  6. Жмем «Enter» и смотрим, как нам приходят сообщения.
  7. Не закрывайте и не обновляйте страницу. Число СМС может достигать от 100 до 10 тысяч.
  8. Если вы достигли желаемого результата, нажмите «F5».
  9. Обновите страницу.

А о скриптах для накрутки подписчиков вы найдете в материале по ссылке.

Знакомство с PSD шаблоном

Откроем и ознакомимся сначала с PSD шаблоном.

PSD шаблон

Внутри файла все разложено по слоям, любой элемент можно редактировать: менять цвет, размер, форму. Используемый в проекте шрифт есть в папке font со скриптом.

В общем, изменяйте дизайн по своему усмотрению. Только учтите, что скачанный вами скрипт позволяет отображать следующие элементы:

  • Последних подписчиков: от одного до трех;
  • Время: в формате 14:59;
  • Текущую дату: 21 мая 2017;
  • День недели: воскресенье

Где и как скачать скрипты для накрутки сообщений ВКонтакте?

Мы разобрались, как ввести скрипт. То тогда возникает вопрос, а где его взять? Давайте рассмотрим самые распространенные ресурсы:

  1. Заходим на сайт.
  2. Жмем по зеленой кнопке «Первая часть» (при нажатии текст копируется в буфер обмена).
  3. Переходим по ссылке ниже.
  4. Подписываемся на открывшуюся группу.
  5. Открываем консоль разработчика на странице сообщества.
  6. Вставляем текст в поле для текста.
  7. После завершения работы обновляем страницу.
  8. Нажимаем на кнопку «Вторая часть».
  9. Повторяем 5-7 пункт. После нескольких секунд к нам начинают приходить сообщения.
  10. Когда приходит 10 тыс. сообщений, перезагружаем страницу.
Еще по теме:  Как прикрепить карточку музыканта к группе Вконтакте

· https://vk.com/topic-71565317_36606428 – 23 тыс. сообщений.

  1. Переходим по ссылке.
  2. Скачиваем файл/файлы из первого сообщения.
  3. Открываем скаченный текстовый документ и копируем запись.
  4. Проделываем все действия из пункта «Как накрутить сообщения во ВКонтакте», используя скопированный скрипт.
  1. Заходим на сайт через ссылку.
  2. Нажимаем на download и скачиваем файл скрипта, либо копируем его в текстовом поле после кнопки скачивания.
  3. Если вы скачали файл, то открываем его и в буфер обмена автоматически копируется скрипт.
  4. Проделываем все действия из предыдущего пункта по использованию скрипта.
  1. С помощью него можно набрать большое количество сообщений за минуту (около 1500).
  2. Переходим по ссылке.
  3. Копируем скрипт под цифрой «1».
  4. Действуем согласно инструкции, описанной в предыдущем пункте.

Последняя «инстанция»

Если же с вашей машиной и системой все в порядке, но при попытке воспользоваться какими-то функциями популярного ресурса все равно возникает ошибка JavaScript Error «ВКонтакте», как исправить ее в этом случае? Дело, скорее всего, в самом сервисе. Самым лучшим решением будет обратиться за помощью в техническую поддержку сайта «ВКонтакте» и объяснить возникшую ситуацию. Вероятно, там смогут разрешить это недоразумение.

Самый главный совет — предпримите все от вас зависящее, чтобы обеспечить полную безопасность своей компьютерной системы. Регулярно обновляйте антивирус, а также по возможности используйте самые последние версии браузеров. Тогда подобные ошибки будут сведены к минимуму.

Плюсы и минусы накрутки сообщений в ВК скриптами

Для начала пользователь должен определиться, а подходит ли ему такой вид накрутки? Чтобы было все понятно, рассмотрим все положительные и отрицательные стороны, а также риски в таблице:

Плюсы Минусы, риски
Накрутка сообщений обеспечивает заходы на вашу страницу. Возможность подхватить вредоносные файлы, используя непроверенные ссылки.
Создает видимость активности аккаунта и группы. Все пользователи являются лишь ботами, которые не заинтересованы ни в вас, ни в вашей странице.
Мнимая популярность страницы, чтобы «зарисовываться» перед друзьями.

API dog

Статистика диалога вк показывается на одном интересном сайте. Не бойтесь за свои данные, с вашим аккаунтом ничего не случится. Сайт проверенный, пароли не ворует.

Как посмотреть статистику сообщений в диалогах вк:

  1. Зайти на сайт API dog .
  2. Ввести свой логин и пароль от сайта Вконтакте. Если у вас не получилось авторизоваться с новой версии сайта, попробуйте со старой. На нее можно перейти, если кликнуть в самом низу экрана.
  3. Далее перейти на вкладку Сообщения – Анализатор
    .
  4. Здесь можно сделать анализ списка диалогов, анализ диалога с конкретным человек и анализ своей стены. А также сохранить всю переписку.
  5. Всё ¯_(ツ)_/¯.

Возможные проблемы при накрутке

Нередко в работе скриптов случаются неполадки. Рассмотрим самые распространённые проблемы и варианты решений.

Скрипты не работают

Проблема заключается в том, что ни один из алгоритмов не работает. Обычно такое случается в браузере Firefox. Удаление и переустановка в таких случаях не помогает. Чтобы разрешить ситуацию, нужно открыть браузер – инструменты – настройки – содержимое. В поле «Использовать Javascript» ставим галочку и сохраняем настройки.

Затем перезапускаем браузер и все должно заработать.

Скрипт замедляет работу или выводит браузер из строя

Часто после работы программного файла сценария в работе сайтов происходят сбои или они могут вовсе не открываться. В таком случае, следует попробовать почистить кэш. Если не помогло, придется переустанавливать браузер.

Вот и вся информация, которая поможет вам накрутить больше тысячи сообщений ВКонтакте всего за пару минут. Главное – следуйте нашему легкому алгоритму и у вас все получиться.

Рекомендуем также к прочтению статью “Заменяем скрипт для накрутки лайков в Инстаграме безопасными сервисами“.

Заменяем скрипт для накрутки лайков в Инстаграме безопасными сервисами

Как сохранить голосовое сообщение из ВК: все возможные способы сохранения

Для тех, кто не ищет легких путей: накрутка сообщений в ВК через код элемента

Как сделать много сообщений во ВКонтакте?

Программы для скачивания с ВК: какую выбрать и как пользоваться

[Всего: 2 Средний: 3.5/5]

Автор публикации

не в сети 2 года

Типы ошибок JavaScript Error: краткий обзор

Эта незадача может существенно подпортить настроение тем, кто предвкушал насладиться приятной музыкой или скоротать время за вечерним кинопросмотром. Чтобы такого не допустить, давайте разберемся, как исправить JavaScript Error «ВКонтакте» собственными силами. Есть несколько возможных вариантов решения проблемы.

Для начала посмотрим, какого типа ошибки могут появиться:

  • initAddMedia is not defined;
  • cannot read property «length» of undefined;
  • cannot convert «opts.photos» to object;
  • cannot read property parentNode;
  • currentaudioid либо просто undefined.

Это отнюдь не весь перечень возможных сообщений об ошибке, но здесь перечислены наиболее часто встречающиеся варианты. Далее рассмотрим существующие способы их решения.

Источник: vkfake.ru

Анализ языка VKScript: JavaScript, ты ли это?

Анализ языка VKScript: JavaScript, ты ли это?

2019-08-18 в 13:05, admin , рубрики: javascript, vkscript, Вконтакте API, реверс-инжиниринг

TL;DR

VKScript — это не JavaScript. Семантика этого языка кардинально отличается от семантики JavaScript. См. заключение.

Что такое VKScript?

VKScript — скриптовый язык программирования, похожий на JavaScript, который используется в методе execute API ВКонтакте, который дает клиентам возможность загружать ровно ту информацию, которая им нужна. По сути, VKScript — это аналог GraphQL, используемого в Facebook для тех же целей.

Сравнение GraphQL и VKScript:

GraphQL VKScript
Реализации Множество open-source реализаций на разных языках программирования Единственная реализация в рамках API ВКонтакте
Основан на Абсолютно новый язык JavaScript
Возможности Запрос данных, ограниченная фильтрация; аргументы запроса не могут использовать результаты предыдущих запросов Любая пост-обработка данных на усмотрение клиента; запросы к API представлены в виде методов и могут использовать любые данные из предыдущих запросов

Описание VKScript со страницы метода в документации VK API (единственная официальная документация по языку):

code
код алгоритма в VKScript — формате, похожем на JavaSсript или ActionScript (предполагается совместимость с ECMAScript). Алгоритм должен завершаться командой return %выражение%. Операторы должны быть разделены точкой с запятой.
строка

В приведенной документации указано, что «планируется совместимость с ECMAScript». Но так ли это? Попробуем разобраться, как этот язык работает изнутри.

Виртуальная машина VKScript

Как вообще можно анализировать программу при отсутствии локальной копии? Правильно — отправлять запросы к публичному endpoint’у и анализировать ответы. Попробуем, например, выполнить такой код:

while(1);

Мы получаем ошибку Runtime error occurred during code invocation: Too many operations . Это говорит о том, что в реализации языка присутствует лимит на количество произведенных действий. Попробуем установить точное значение лимита:

var i = 0; while(i < 1000) i = i + 1;

  • Runtime error occurred during code invocation: Too many operations .

var i = 0; while(i < 1000) i = i + 1;

Таким образом, лимит на количество операций — порядка 1000 «холостых» циклов. Но, в то же время, понятно, что такой цикл, скорее всего, не является «унитарной» операцией. Попробуем найти операцию, которая не разделяется компилятором на несколько более мелких.

Следующее, что приходит в голову после ; — вычисление какого-нибудь простого выражения (например, так: 1; ). Попробуем добавить несколько таких выражений в наш код:

var i = 0; while(i < 999) i = i + 1; 1; // так еще работает 1; // при добавлении этой строки получаем ошибку «Too many operations»

Таким образом, 2 операции 1; тратят больше операций, чем 50 операция ; . Это подтверждает гипотезу о том, что empty statement не тратит инструкций.

Еще по теме:  Как зайти на чужую страницу в ВК без пароля

Попробуем уменьшать количество итераций цикла и добавлять дополнительные 1; . Несложно заметить, что на каждую итерацию приходится 5 дополнительных 1; , следовательно, одна итерация цикла тратит в 5 раз больше операций, чем одна операция 1; .

Но нет ли еще более простой операции? Например, добавление унарного оператора ~ не требует вычисления дополнительных выражений, а сама операция выполняется на процессоре. Логично предположить, что добавление в выражение этой операции увеличивает общее количество операций на 1.

Добавим в наш код этот оператор:

var i = 0; while(i < 999) i = i + 1; ~1;

И да, один такой оператор мы добавить можем, а еще одно выражение 1; — уже нет. Следовательно, 1; действительно не является унитарным оператором.

Аналогично оператору 1; , будем уменьшать количество итераций цикла и добавлять операторы ~ . Одна итерация оказалась эквивалентна 10 унитарным операциям ~ , следовательно, выражение 1; тратит 2 операции.

Заметим, что лимит составляет примерно 1000 итераций, то есть примерно 10000 единичных операций. Будем считать, что лимит составляет точно 10000 операций.

Измерение количества операций в коде

Заметим, что теперь мы можем измерять количество операций в любом коде. Для этого нужно добавить этот код после цикла и добавлять/удалять итерации, операторы ~ или всю последнюю строку целиком, пока ошибка Too many operations не исчезнет.

Некоторые результаты измерений:

Код Количество операций
1; 2
~1; 3
1+1; 4
1+1+1; 6
(true?1:1); 5
(false?1:1); 4
if(0)1; 2
if(1)1; 4
if(0)1;else 1; 4
if(1)1;else 1; 5
while(0); 2
i=1; 3
i=i+1; 5
var j = 1; 1
var j = 0;while(j < 1)j=j+1; 15

Определение типа виртуальной машины

Для начала нужно понять, по какому принципу работает интерпретатор VKScript. Есть два более-менее правдоподобных варианта:

  • Интерпретатор рекурсивно обходит синтаксическое дерево и выполняет операцию в каждом узле.
  • Компилятор переводит синтаксическое дерево в последовательность инструкций, которые выполняет интерпретатор.

Несложно понять, что в VKScript используется второй вариант. Рассмотрим выражения (true?1:1); (5 операций) и (false?1:1); (4 операции). В случае с последовательным выполнением инструкций дополнительная операция объясняется переходом, который «обходит» неверный вариант, а в случае с рекурсивным обходом AST оба варианта для интерпретатора равноценны. Аналогичный эффект наблюдается в if/else с разным условием.

Также стоит обратить внимание на пару i = 1; (3 операции) и var j = 1; (1 операция). Создание новой переменной обходится всего в 1 операцию, а присвоение в существующую — в 3? То, что создание переменной обходится в 1 операцию (и то, это, скорее всего, операция загрузки константы), говорит о двух вещах:

  • При создании новой переменной не происходит явного выделения памяти под переменную.
  • При создании новой переменной не происходит загрузки значения в ячейку памяти. Это означает, что место под новую переменную выделяется там, где было вычислено значение выражения, и после этого эта память считается выделенной. Это говорит об использовании стековой машины.

Использованием стека также объясняется то, что выражение var j = 1; выполняется быстрее, чем выражение 1; : последнее выражение тратит дополнительную инструкцию на то, чтобы убрать со стека вычисленное значение.

Определение точного значения лимита

var i = 0; while(i < 1) i = i + 1;
var i = 0; while(i < 999) i = i + 1;
var i = 0; while(i < 999) i = i + 1; ~1;

Стоп, что? Лимит составляет 9998 инструкций?

Мы явно что-то упускаем.

Заметим, что код return 1; выполняется, согласно измерениям, за 0 инструкций. Это легко объясняется: компилятор добавляет в конце кода неявный return null; , и при добавлении своего return’а он не выполняется. Считая, что лимит равен 10000, делаем вывод, что операция return null; занимает 2 инструкции (вероятно, это что-то вроде push null; return; ).

Вложенные блоки кода

Проведем еще несколько измерений:

Код Количество операций
<>; 0
; 2
; 3
; 3
var j = 1; var j = 1; 4
; var j = 1; 3

Обратим внимание на следующие факты:

  • При добавлении переменной в блок тратится одна дополнительная операция.
  • При «объявлении переменной заново» второе объявление отрабатывает как обычное присваивание.
  • Но при этом переменная внутри блока снаружи не видна (см. последний пример).

Несложно понять, что лишняя операция тратится на удаление со стека локальных переменных, объявленных в блоке. Соответственно, когда локальных переменных нет, удалять ничего не нужно.

Объекты, методы, вызовы API

Код Количество операций
«»; 2
«abcdef»; 2
<>; 2
[]; 2
[1, 2, 3]; 5
; 5
API.users.isAppUser(1); 3
«».substr(0, 0); 6
var j=<>;j.x=1; 6
var j=;delete j.x; 6

Проанализируем полученные результаты. Можно заметить, что создание строки и пустого массива/объекта занимает 2 операции, так же как и загрузка числа. При создании непустого массива или объекта добавляются операции, потраченные на загрузку элементов массива/объекта. Это говорит о том, что непосредственно создание объекта происходит за одну операцию. При этом на загрузку названий свойств время не тратится, следовательно, их загрузка является частью операции создания объекта.

С вызовом метода API все тоже весьма банально — загрузка единицы, собственно вызов метода, pop результата (можно заметить, что название метода обрабатывается как единое целое, а не как взятие свойств). А вот последние три примера выглядят интересно.

  • «».substr(0, 0); — загрузка строки, загрузка нуля, загрузка нуля, pop результата. На вызов метода почему-то приходится 2 инструкции (почему — см. далее).
  • var j=<>;j.x=1; — создание объекта, загрузка объекта, загрузка единицы, pop единицы после присваивания. Опять-таки, на присваивание приходится 2 инструкции.
  • var j=;delete j.x; — загрузка единицы, создание объекта, загрузка объекта, удаление. На операцию удаления приходится 3 инструкции.

Семантика объектов VKScript

Числа

Вернемся к исходному вопросу: VKScript — это подмножество JavaScript или другой язык? Проведем простой тест:

return 1000000000 + 2000000000;

Как мы видим, целочисленное сложение приводит к переполнению, несмотря на то, что в JavaScript нет целых чисел как таковых. Также несложно убедиться, что деление на 0 приводит к ошибке, а не возвращает Infinity .

Объекты

return <>;

Стоп, что? Мы возвращаем объект и получаем массив? Да, так и есть. В языке VKScript массивы и объекты представлены одним типом, в частности, пустой объект и пустой массив это одно и тоже.

При этом свойство length у объекта работает и возвращает количество свойств.

Интересно посмотреть, как поведут себя методы списка, если вызвать их на объекте?

return .pop();

Метод pop возвращает последнее объявленное свойство, что, впрочем, логично. Поменяем порядок свойств:

return .pop();

Видимо, объекты в VKScript запоминают порядок присвоения свойств. Попробуем использовать числовые свойства:

return .pop();

Теперь посмотрим, как работает push:

var a = ; a.push(‘d’); return a;

Как видим, метод push сортирует численные ключи и добавляет новое значение после последнего численного ключа. «Дыры» при этом не заполняются.

Теперь попробуем объединить два этих метода:

var a = ; a.push(a.pop()); return a;

Как мы видим, элемент не удалился из массива. Однако, если мы разнесем push и pop в разные строки, баг пропадет. We need to go deeper!

Хранение объектов

var x = <>; var y = x; x.y = ‘z’; return y;

Как выяснилось, объекты в VKScript хранятся по значению, в отличие от JavaScript. Теперь понятно странное поведение строки a.push(a.pop()); — видимо, старое значение массива сохранилось на стеке, откуда потом и было взято.

Однако как тогда данные сохраняются в объект, если метод его изменяет? Видимо, «лишняя» инструкция при вызове метода предназначена именно для записи изменений обратно в объект.

Методы массивов

  • отсортировать числовые ключи по значению
  • взять максимальный числовой ключ, прибавить единицу
  • записать аргумент в массив
  • добавить в конец массива нечисловые ключи
  • отсортировать числовые ключи по значению, убрать «дыры» в массиве
  • выполнить соответствующую операцию JavaScript
  • добавить в конец массива нечисловые ключи

При использовании метода slice изменения не сохраняются

Заключение

VKScript — это не JavaScript. В отличие от JavaScript, объекты в нем хранятся по значению, а не по ссылке, и обладают совершенно другой семантикой. Однако при использовании VKScript для цели, для которой он предназначен, разница незаметна.

Источник: www.pvsm.ru

Рейтинг
( Пока оценок нет )
Загрузка ...