Parcourir la source

LibJS: Add spec comments to bitwise_not()

Linus Groh il y a 2 ans
Parent
commit
c23d8c7486
1 fichiers modifiés avec 28 ajouts et 4 suppressions
  1. 28 4
      Userland/Libraries/LibJS/Runtime/Value.cpp

+ 28 - 4
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -1412,12 +1412,36 @@ ThrowCompletionOr<Value> bitwise_xor(VM& vm, Value lhs, Value rhs)
 }
 
 // 13.5.6 Bitwise NOT Operator ( ~ ), https://tc39.es/ecma262/#sec-bitwise-not-operator
+// UnaryExpression : ~ UnaryExpression
 ThrowCompletionOr<Value> bitwise_not(VM& vm, Value lhs)
 {
-    auto lhs_numeric = TRY(lhs.to_numeric(vm));
-    if (lhs_numeric.is_number())
-        return Value(~TRY(lhs_numeric.to_i32(vm)));
-    return BigInt::create(vm, lhs_numeric.as_bigint().big_integer().bitwise_not());
+    // 1. Let expr be ? Evaluation of UnaryExpression.
+    // NOTE: This is handled in the AST or Bytecode interpreter.
+
+    // 2. Let oldValue be ? ToNumeric(? GetValue(expr)).
+
+    auto old_value = TRY(lhs.to_numeric(vm));
+
+    // 3. If oldValue is a Number, then
+    if (old_value.is_number()) {
+        // a. Return Number::bitwiseNOT(oldValue).
+
+        // 6.1.6.1.2 Number::bitwiseNOT ( x ), https://tc39.es/ecma262/#sec-numeric-types-number-bitwiseNOT
+        // 1. Let oldValue be ! ToInt32(x).
+        // 2. Return the result of applying bitwise complement to oldValue. The mathematical value of the result is
+        //    exactly representable as a 32-bit two's complement bit string.
+        return Value(~TRY(old_value.to_i32(vm)));
+    }
+
+    // 4. Else,
+    // a. Assert: oldValue is a BigInt.
+    VERIFY(old_value.is_bigint());
+
+    // b. Return BigInt::bitwiseNOT(oldValue).
+
+    // 6.1.6.2.2 BigInt::bitwiseNOT ( x ), https://tc39.es/ecma262/#sec-numeric-types-bigint-bitwiseNOT
+    // 1. Return -x - 1ℤ.
+    return BigInt::create(vm, old_value.as_bigint().big_integer().bitwise_not());
 }
 
 // 13.5.4 Unary + Operator, https://tc39.es/ecma262/#sec-unary-plus-operator