Convert while loop to functions in javascript

Refresh

November 2018

Views

120 time

2

I am writing some kind of script editor to work with javascript, and I want the user to have the ability to execute the script. But I also want the user to be able to interrupt the execution of the code, for instance if they input while(true) {} by mistake.

I think there should be a way to automatically instrument the code by transforming this:

...
while(condition) {
    if (condition2) break;
    code;
}
following;

Into something like this:

var stop = false;

var g = function() { 
    if (stop) { throw; }
    following; 
};

var f = function() {
    if (stop) { throw };

    if(condition) {
        if (condition2) { setTimeout(g,0); }
        code;
        setTimeout(f,0);
    }
    else (setTimeout(g,0);
};

f();

2 questions: - Is this feasible in all case? - Is there a known component that would do it? It seems to me that it's hard to get everything right: variable scope, recursions, etc. But it also seems like this would be very useful to a lot of people...

Edited: added the stop flag, the flag could be set by the UI, during a setTimeout function

1 answers

1

Этот ответ не позволяет пользователю прекратить выполнение по требованию, как это было предложен вопрос. Он просто пытается прекратить выполнение, если оно продолжается навсегда (больше, чем разрешенное время).

Есть две разные проблемы, которые необходимо решить:

  1. Определение, если исполнение бесконечно
  2. Выход

Первую проблему невозможно решить с полной точностью, но хороший эвристический, вероятно, достаточно для вас. Вы можете установить ограничение на то, как долго вы позволяете программу для запуска и если она выходит за рамки этого лимита вы считаете, это будет продолжаться вечно, и, таким образом, принудительно-остановить его. Вы можете сделать это путем записи времени начала и инъекционным вызов следующей функции после (или до) каждой команды:

function __checkStop() {
  return Date.now() - __checkStop.__start >= 1000 * 60; // 1 minute
}
__checkStop.__start = Date.now();

Следующий код

var a = 3;
if (a < 2) a++;

Должно быть включены в это:

var a = 3; __checkStop();
if (a < 2) { a++; __checkStop(); }

Если вы не хотите, чтобы построить полную AST, можно вводить вызов функции только в более чувствительных точках, как в начале определений функций или петель.


Вторая проблема также трудно решить. Простое решение было бы бросить ошибку и поймать его (или нет) в глобальном масштабе.

Это не идеальное решение, так как определяется пользователь (или несчастливый) может просто поймать свою ошибку и будет держать его бесконечную программу. Вы можете попытаться совместить это с инъекционным код в Try / улове блоков повторно бросайте конкретную ошибку, если пользователь ловит его по ошибке, с тем, чтобы сделать его труднее победить. Я, например, не знаю, как это решение будет не в состоянии. (Если вы знаете, как сделать это не получится, пожалуйста, комментарий!)