Просмотр исходного кода

LibJS: Don't return the "last computed value" from Interpreter::run()

Only return whatever a "return" statment told us to return.
The last computed value is now available in Interpreter::last_value()
instead, where the REPL can pick it up.
Andreas Kling 5 лет назад
Родитель
Сommit
2db8716a6f
3 измененных файлов с 17 добавлено и 7 удалено
  1. 9 3
      Libraries/LibJS/Interpreter.cpp
  2. 4 0
      Libraries/LibJS/Interpreter.h
  3. 4 4
      Userland/js.cpp

+ 9 - 3
Libraries/LibJS/Interpreter.cpp

@@ -69,18 +69,21 @@ Value Interpreter::run(const Statement& statement, Vector<Argument> arguments, S
     auto& block = static_cast<const ScopeNode&>(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<Argument> arguments, ScopeType scope_type)
@@ -180,6 +183,9 @@ void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& 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())

+ 4 - 0
Libraries/LibJS/Interpreter.h

@@ -154,11 +154,15 @@ public:
         return throw_exception(heap().allocate<Exception>(value));
     }
 
+    Value last_value() const { return m_last_value; }
+
 private:
     Interpreter();
 
     Heap m_heap;
 
+    Value m_last_value;
+
     Vector<ScopeFrame> m_scope_stack;
     Vector<CallFrame> m_call_stack;
 

+ 4 - 4
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());
         }
     }
 }