소스 검색

LibJS: Make Array.prototype.lastIndexOf() generic

Linus Groh 5 년 전
부모
커밋
e78bc2f6fd
2개의 변경된 파일22개의 추가작업 그리고 12개의 파일을 삭제
  1. 12 12
      Libraries/LibJS/Runtime/ArrayPrototype.cpp
  2. 10 0
      Libraries/LibJS/Tests/Array.prototype-generic-functions.js

+ 12 - 12
Libraries/LibJS/Runtime/ArrayPrototype.cpp

@@ -526,32 +526,32 @@ Value ArrayPrototype::reverse(Interpreter& interpreter)
 
 Value ArrayPrototype::last_index_of(Interpreter& interpreter)
 {
-    auto* array = array_from(interpreter);
-    if (!array)
+    auto* this_object = interpreter.this_value().to_object(interpreter);
+    if (!this_object)
         return {};
-
-    i32 array_size = static_cast<i32>(array->elements().size());
-    if (array_size == 0)
+    i32 length = get_length(interpreter, *this_object);
+    if (interpreter.exception())
+        return {};
+    if (length == 0)
         return Value(-1);
-
-    i32 from_index = array_size - 1;
+    i32 from_index = length - 1;
     if (interpreter.argument_count() >= 2) {
         from_index = interpreter.argument(1).to_i32(interpreter);
         if (interpreter.exception())
             return {};
         if (from_index >= 0)
-            from_index = min(from_index, array_size - 1);
+            from_index = min(from_index, length - 1);
         else
-            from_index = array_size + from_index;
+            from_index = length + from_index;
     }
-
     auto search_element = interpreter.argument(0);
     for (i32 i = from_index; i >= 0; --i) {
-        auto& element = array->elements().at(i);
+        auto element = this_object->get_by_index(i);
+        if (interpreter.exception())
+            return {};
         if (strict_eq(interpreter, element, search_element))
             return Value(i);
     }
-
     return Value(-1);
 }
 

+ 10 - 0
Libraries/LibJS/Tests/Array.prototype-generic-functions.js

@@ -52,6 +52,16 @@ try {
         assert(Array.prototype.indexOf.call({ length: 5, 2: "foo", 4: "foo" }, "foo", 3) === 4);
     }
 
+    {
+        assert(Array.prototype.lastIndexOf.call({}) === -1);
+        assert(Array.prototype.lastIndexOf.call({ 0: undefined }) === -1);
+        assert(Array.prototype.lastIndexOf.call({ length: 1, 0: undefined }) === 0);
+        assert(Array.prototype.lastIndexOf.call({ length: 1, 2: "foo" }, "foo") === -1);
+        assert(Array.prototype.lastIndexOf.call({ length: 5, 2: "foo" }, "foo") === 2);
+        assert(Array.prototype.lastIndexOf.call({ length: 5, 2: "foo", 4: "foo" }, "foo") === 4);
+        assert(Array.prototype.lastIndexOf.call({ length: 5, 2: "foo", 4: "foo" }, "foo", -2) === 2);
+    }
+
     const o = { length: 5, 0: "foo", 1: "bar", 3: "baz" };
 
     {