ソースを参照

LibJS: Fix that '_' no longer accessed the last value in the REPL

This is now also not a concept that VM knows about and handled
completely by the REPL.
davidot 3 年 前
コミット
a5b11f7484
2 ファイル変更23 行追加6 行削除
  1. 0 5
      Userland/Libraries/LibJS/Runtime/VM.h
  2. 23 1
      Userland/Utilities/js.cpp

+ 0 - 5
Userland/Libraries/LibJS/Runtime/VM.h

@@ -156,9 +156,6 @@ public:
 
     const StackInfo& stack_info() const { return m_stack_info; };
 
-    bool underscore_is_last_value() const { return m_underscore_is_last_value; }
-    void set_underscore_is_last_value(bool b) { m_underscore_is_last_value = b; }
-
     u32 execution_generation() const { return m_execution_generation; }
     void finish_execution_generation() { ++m_execution_generation; }
 
@@ -279,8 +276,6 @@ private:
     JS_ENUMERATE_WELL_KNOWN_SYMBOLS
 #undef __JS_ENUMERATE
 
-    bool m_underscore_is_last_value { false };
-
     u32 m_execution_generation { 0 };
 
     OwnPtr<CustomData> m_custom_data;

+ 23 - 1
Userland/Utilities/js.cpp

@@ -71,6 +71,7 @@
 
 RefPtr<JS::VM> vm;
 Vector<String> repl_statements;
+JS::Handle<JS::Value> last_value = JS::make_handle(JS::js_undefined());
 
 class ReplObject final : public JS::GlobalObject {
     JS_OBJECT(ReplObject, JS::GlobalObject);
@@ -86,6 +87,7 @@ private:
     JS_DECLARE_NATIVE_FUNCTION(load_file);
     JS_DECLARE_NATIVE_FUNCTION(save_to_file);
     JS_DECLARE_NATIVE_FUNCTION(load_json);
+    JS_DECLARE_NATIVE_FUNCTION(last_value_getter);
 };
 
 class ScriptObject final : public JS::GlobalObject {
@@ -986,6 +988,9 @@ static bool parse_and_run(JS::Interpreter& interpreter, StringView source, Strin
         }
     };
 
+    if (!result.is_error())
+        last_value = JS::make_handle(result.value());
+
     if (result.is_error()) {
         handle_exception();
         return false;
@@ -1041,6 +1046,24 @@ void ReplObject::initialize_global_object()
     define_native_function("load", load_file, 1, attr);
     define_native_function("save", save_to_file, 1, attr);
     define_native_function("loadJSON", load_json, 1, attr);
+
+    define_native_accessor(
+        "_",
+        [](JS::VM&, JS::GlobalObject&) {
+            return last_value.value();
+        },
+        [](JS::VM& vm, JS::GlobalObject& global_object) -> JS::ThrowCompletionOr<JS::Value> {
+            VERIFY(is<ReplObject>(global_object));
+            outln("Disable writing last value to '_'");
+
+            // We must delete first otherwise this setter gets called recursively.
+            TRY(global_object.internal_delete(JS::PropertyKey { "_" }));
+
+            auto value = vm.argument(0);
+            TRY(global_object.internal_set(JS::PropertyKey { "_" }, value, &global_object));
+            return value;
+        },
+        attr);
 }
 
 JS_DEFINE_NATIVE_FUNCTION(ReplObject::save_to_file)
@@ -1263,7 +1286,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
 #ifdef JS_TRACK_ZOMBIE_CELLS
         interpreter->heap().set_zombify_dead_cells(zombify_dead_cells);
 #endif
-        interpreter->vm().set_underscore_is_last_value(true);
 
         auto& global_environment = interpreter->realm().global_environment();