Repository: LadybirdBrowser/ladybird
File: Libraries/LibJS/Runtime/Value.cpp (C++)

Code before:
        return false;
    }

    // 3. Return SameValueNonNumber(x, y).
    return same_value_non_number(lhs, rhs);
}

// 7.2.14 IsLooselyEqual ( x, y ), https://tc39.es/ecma262/#sec-islooselyequal
ThrowCompletionOr<bool> is_loosely_equal(VM& vm, Value lhs, Value rhs)
{
    // 1. If Type(x) is the same as Type(y), then
    if (same_type_for_equality(lhs, rhs)) {
        // a. Return IsStrictlyEqual(x, y).
        return is_strictly_equal(lhs, rhs);
    }

    // 2. If x is null and y is undefined, return true.
    // 3. If x is undefined and y is null, return true.
    if (lhs.is_nullish() && rhs.is_nullish())
        return true;

    // 4. NOTE: This step is replaced in section B.3.6.2.
    // B.3.6.2 Changes to IsLooselyEqual, https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec
    // 4. Perform the following steps:
    // a. If Type(x) is Object and x has an [[IsHTMLDDA]] internal slot and y is either null or undefined, return true.
    // OPTIMIZATION: Return early if the [[IsHTMLDDA]] internal slot is not present.
    if (lhs.is_object() && rhs.is_nullish())
        return lhs.as_object().is_htmldda();

    // b. If x is either null or undefined and Type(y) is Object and y has an [[IsHTMLDDA]] internal slot, return true.
    // OPTIMIZATION: Return early if the [[IsHTMLDDA]] internal slot is not present.
    if (lhs.is_nullish() && rhs.is_object())
        return rhs.as_object().is_htmldda();

    // == End of B.3.6.2 ==

    // 5. If Type(x) is Number and Type(y) is String, return ! IsLooselyEqual(x, ! ToNumber(y)).
    if (lhs.is_number() && rhs.is_string())
        return is_loosely_equal(vm, lhs, MUST(rhs.to_number(vm)));

    // 6. If Type(x) is String and Type(y) is Number, return ! IsLooselyEqual(! ToNumber(x), y).
    if (lhs.is_string() && rhs.is_number())
        return is_loosely_equal(vm, MUST(lhs.to_number(vm)), rhs);

    // 7. If Type(x) is BigInt and Type(y) is String, then
    if (lhs.is_bigint() && rhs.is_string()) {
        // a. Let n be StringToBigInt(y).
        auto bigint = string_to_bigint(vm, rhs.as_string().utf8_string_view());

        // b. If n is undefined, return false.
        if (!bigint.has_value())

Review comment (suggestion):
I understand why you can return `lhs.as_object().is_htmldda()` here, but the comment is a bit confusing. When LHS is an object and RHS is nullish, you simply return whether or not LHS is HTML DDA. The early return is not conditional on that.

Code after:
        return false;
    }

    // 3. Return SameValueNonNumber(x, y).
    return same_value_non_number(lhs, rhs);
}

// 7.2.14 IsLooselyEqual ( x, y ), https://tc39.es/ecma262/#sec-islooselyequal
ThrowCompletionOr<bool> is_loosely_equal(VM& vm, Value lhs, Value rhs)
{
    // 1. If Type(x) is the same as Type(y), then
    if (same_type_for_equality(lhs, rhs)) {
        // a. Return IsStrictlyEqual(x, y).
        return is_strictly_equal(lhs, rhs);
    }

    // 2. If x is null and y is undefined, return true.
    // 3. If x is undefined and y is null, return true.
    if (lhs.is_nullish() && rhs.is_nullish())
        return true;

    // 4. NOTE: This step is replaced in section B.3.6.2.
    // B.3.6.2 Changes to IsLooselyEqual, https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec
    // 4. Perform the following steps:
    // a. If Type(x) is Object and x has an [[IsHTMLDDA]] internal slot and y is either null or undefined, return true.
    if (lhs.is_object() && rhs.is_nullish()) {
        if (lhs.as_object().is_htmldda())
            return true;

        // OPTIMIZATION: We can return early here since non-HTMLDDA objects and nullish values are never equal.
        return false;
    }

    // b. If x is either null or undefined and Type(y) is Object and y has an [[IsHTMLDDA]] internal slot, return true.
    if (lhs.is_nullish() && rhs.is_object()) {
        if (rhs.as_object().is_htmldda())
            return true;

        // OPTIMIZATION: We can return early here since non-HTMLDDA objects and nullish values are never equal.
        return false;
    }

    // == End of B.3.6.2 ==

    // 5. If Type(x) is Number and Type(y) is String, return ! IsLooselyEqual(x, ! ToNumber(y)).
    if (lhs.is_number() && rhs.is_string())
        return is_loosely_equal(vm, lhs, MUST(rhs.to_number(vm)));

    // 6. If Type(x) is String and Type(y) is Number, return ! IsLooselyEqual(! ToNumber(x), y).
    if (lhs.is_string() && rhs.is_number())
        return is_loosely_equal(vm, MUST(lhs.to_number(vm)), rhs);