Browse Source

LibJS/Bytecode: Move GetByValue implementation to CommonImplementations

Andreas Kling 1 year ago
parent
commit
e8190105db

+ 26 - 0
Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp

@@ -60,4 +60,30 @@ ThrowCompletionOr<Value> get_by_id(Bytecode::Interpreter& interpreter, Identifie
     return value;
 }
 
+ThrowCompletionOr<Value> get_by_value(Bytecode::Interpreter& interpreter, Value base_value, Value property_key_value)
+{
+    auto& vm = interpreter.vm();
+    auto object = TRY(base_object_for_get(interpreter, base_value));
+
+    // OPTIMIZATION: Fast path for simple Int32 indexes in array-like objects.
+    if (property_key_value.is_int32()
+        && property_key_value.as_i32() >= 0
+        && !object->may_interfere_with_indexed_property_access()
+        && object->indexed_properties().has_index(property_key_value.as_i32())) {
+        auto value = object->indexed_properties().get(property_key_value.as_i32())->value;
+        if (!value.is_accessor())
+            return value;
+    }
+
+    auto property_key = TRY(property_key_value.to_property_key(vm));
+
+    if (base_value.is_string()) {
+        auto string_value = TRY(base_value.as_string().get(vm, property_key));
+        if (string_value.has_value())
+            return *string_value;
+    }
+
+    return TRY(object->internal_get(property_key, base_value));
+}
+
 }

+ 1 - 0
Userland/Libraries/LibJS/Bytecode/CommonImplementations.h

@@ -13,5 +13,6 @@ namespace JS::Bytecode {
 
 ThrowCompletionOr<NonnullGCPtr<Object>> base_object_for_get(Bytecode::Interpreter&, Value base_value);
 ThrowCompletionOr<Value> get_by_id(Bytecode::Interpreter&, IdentifierTableIndex, Value base_value, Value this_value, u32 cache_index);
+ThrowCompletionOr<Value> get_by_value(Bytecode::Interpreter&, Value base_value, Value property_key_value);
 
 }

+ 1 - 31
Userland/Libraries/LibJS/Bytecode/Interpreter.cpp

@@ -1483,37 +1483,7 @@ ThrowCompletionOr<void> Await::execute_impl(Bytecode::Interpreter& interpreter)
 
 ThrowCompletionOr<void> GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const
 {
-    auto& vm = interpreter.vm();
-
-    // NOTE: Get the property key from the accumulator before side effects have a chance to overwrite it.
-    auto property_key_value = interpreter.accumulator();
-
-    auto base_value = interpreter.reg(m_base);
-    auto object = TRY(base_object_for_get(interpreter, base_value));
-
-    // OPTIMIZATION: Fast path for simple Int32 indexes in array-like objects.
-    if (property_key_value.is_int32()
-        && property_key_value.as_i32() >= 0
-        && !object->may_interfere_with_indexed_property_access()
-        && object->indexed_properties().has_index(property_key_value.as_i32())) {
-        auto value = object->indexed_properties().get(property_key_value.as_i32())->value;
-        if (!value.is_accessor()) {
-            interpreter.accumulator() = value;
-            return {};
-        }
-    }
-
-    auto property_key = TRY(property_key_value.to_property_key(vm));
-
-    if (base_value.is_string()) {
-        auto string_value = TRY(base_value.as_string().get(vm, property_key));
-        if (string_value.has_value()) {
-            interpreter.accumulator() = *string_value;
-            return {};
-        }
-    }
-
-    interpreter.accumulator() = TRY(object->internal_get(property_key, base_value));
+    interpreter.accumulator() = TRY(get_by_value(interpreter, interpreter.reg(m_base), interpreter.accumulator()));
     return {};
 }
 

+ 2 - 0
Userland/Libraries/LibJS/Bytecode/Op.h

@@ -727,6 +727,8 @@ public:
     ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
     DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
 
+    Register base() const { return m_base; }
+
 private:
     Register m_base;
 };