diff options
author | Matthew Olsson <matthewcolsson@gmail.com> | 2020-10-08 13:12:31 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-10-08 23:23:55 +0200 |
commit | d980073122bbb17a805acee3ac34c4f788f87f4b (patch) | |
tree | 12d1dfbcaeba0bb92eafe04c758caebab9f96ab5 /Libraries/LibJS | |
parent | 397e5766ffb6c0c1633d228975c73292939ad92e (diff) | |
download | serenity-d980073122bbb17a805acee3ac34c4f788f87f4b.zip |
LibJS: Handle unwinding in while and do-while statements
For some reason, this was never added. So something like "while (true)
{ return }" would loop infinitely.
Diffstat (limited to 'Libraries/LibJS')
-rw-r--r-- | Libraries/LibJS/AST.cpp | 20 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/return.js | 0 |
2 files changed, 20 insertions, 0 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 60de3d9383..9286c0aaa6 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -262,6 +262,16 @@ Value WhileStatement::execute(Interpreter& interpreter, GlobalObject& global_obj last_value = interpreter.execute_statement(global_object, *m_body); if (interpreter.exception()) return {}; + if (interpreter.vm().should_unwind()) { + if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) { + interpreter.vm().stop_unwind(); + } else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) { + interpreter.vm().stop_unwind(); + break; + } else { + return js_undefined(); + } + } } return last_value; @@ -276,6 +286,16 @@ Value DoWhileStatement::execute(Interpreter& interpreter, GlobalObject& global_o last_value = interpreter.execute_statement(global_object, *m_body); if (interpreter.exception()) return {}; + if (interpreter.vm().should_unwind()) { + if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) { + interpreter.vm().stop_unwind(); + } else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) { + interpreter.vm().stop_unwind(); + break; + } else { + return js_undefined(); + } + } } while (m_test->execute(interpreter, global_object).to_boolean()); return last_value; diff --git a/Libraries/LibJS/Tests/return.js b/Libraries/LibJS/Tests/return.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/Libraries/LibJS/Tests/return.js |