diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index acbcd07c4c..a4fe244427 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -69,18 +69,21 @@ Value Interpreter::run(const Statement& statement, Vector arguments, S auto& block = static_cast(statement); enter_scope(block, move(arguments), scope_type); - Value last_value = js_undefined(); + m_last_value = {}; for (auto& node : block.children()) { - last_value = node.execute(*this); + m_last_value = node.execute(*this); if (m_unwind_until != ScopeType::None) break; } + bool did_return = m_unwind_until == ScopeType::Function; + if (m_unwind_until == scope_type) m_unwind_until = ScopeType::None; exit_scope(block); - return last_value; + + return did_return ? m_last_value : js_undefined(); } void Interpreter::enter_scope(const ScopeNode& scope_node, Vector arguments, ScopeType scope_type) @@ -180,6 +183,9 @@ void Interpreter::gather_roots(Badge, HashTable& roots) roots.set(m_exception); + if (m_last_value.is_cell()) + roots.set(m_last_value.as_cell()); + for (auto& scope : m_scope_stack) { for (auto& it : scope.variables) { if (it.value.value.is_cell()) diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index 9cbfb1c697..757df0109c 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -154,11 +154,15 @@ public: return throw_exception(heap().allocate(value)); } + Value last_value() const { return m_last_value; } + private: Interpreter(); Heap m_heap; + Value m_last_value; + Vector m_scope_stack; Vector m_call_stack; diff --git a/Userland/js.cpp b/Userland/js.cpp index e5cbfcffa5..946fed5c16 100644 --- a/Userland/js.cpp +++ b/Userland/js.cpp @@ -302,8 +302,8 @@ JS::Value ReplObject::load_file(JS::Interpreter& interpreter) auto program = JS::Parser(JS::Lexer(source)).parse_program(); if (dump_ast) program->dump(0); - auto result = interpreter.run(*program); - print(result); + interpreter.run(*program); + print(interpreter.last_value()); } return JS::Value(true); } @@ -319,13 +319,13 @@ void repl(JS::Interpreter& interpreter) if (dump_ast) program->dump(0); - auto result = interpreter.run(*program); + interpreter.run(*program); if (interpreter.exception()) { printf("Uncaught exception: "); print(interpreter.exception()->value()); interpreter.clear_exception(); } else { - print(result); + print(interpreter.last_value()); } } }