mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-13 01:59:14 +03:00
LibJS: Throw RangeError on BigInt division/modulo by zero
https://tc39.es/ecma262/#sec-numeric-types-bigint-divide https://tc39.es/ecma262/#sec-numeric-types-bigint-remainder
This commit is contained in:
parent
1d8ab74cbf
commit
11138f5c1f
Notes:
sideshowbarker
2024-07-18 21:17:35 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/11138f5c1ff Pull-request: https://github.com/SerenityOS/serenity/pull/5833
@ -43,6 +43,7 @@
|
||||
M(Convert, "Cannot convert {} to {}") \
|
||||
M(ConvertUndefinedToObject, "Cannot convert undefined to object") \
|
||||
M(DescChangeNonConfigurable, "Cannot change attributes of non-configurable property '{}'") \
|
||||
M(DivisionByZero, "Division by zero") \
|
||||
M(FunctionArgsNotObject, "Argument array must be an object") \
|
||||
M(InOperatorWithObject, "'in' operator must be used on an object") \
|
||||
M(InstanceOfOperatorBadPrototype, "'prototype' property of {} is not an object") \
|
||||
|
@ -882,27 +882,34 @@ Value mul(GlobalObject& global_object, Value lhs, Value rhs)
|
||||
|
||||
Value div(GlobalObject& global_object, Value lhs, Value rhs)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
auto lhs_numeric = lhs.to_numeric(global_object.global_object());
|
||||
if (global_object.vm().exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(global_object.global_object());
|
||||
if (global_object.vm().exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric))
|
||||
return Value(lhs_numeric.as_double() / rhs_numeric.as_double());
|
||||
if (both_bigint(lhs_numeric, rhs_numeric))
|
||||
if (both_bigint(lhs_numeric, rhs_numeric)) {
|
||||
if (rhs_numeric.as_bigint().big_integer() == BIGINT_ZERO) {
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::DivisionByZero);
|
||||
return {};
|
||||
}
|
||||
return js_bigint(global_object.heap(), lhs_numeric.as_bigint().big_integer().divided_by(rhs_numeric.as_bigint().big_integer()).quotient);
|
||||
global_object.vm().throw_exception<TypeError>(global_object.global_object(), ErrorType::BigIntBadOperatorOtherType, "division");
|
||||
}
|
||||
vm.throw_exception<TypeError>(global_object.global_object(), ErrorType::BigIntBadOperatorOtherType, "division");
|
||||
return {};
|
||||
}
|
||||
|
||||
Value mod(GlobalObject& global_object, Value lhs, Value rhs)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
auto lhs_numeric = lhs.to_numeric(global_object.global_object());
|
||||
if (global_object.vm().exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(global_object.global_object());
|
||||
if (global_object.vm().exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
if (lhs_numeric.is_nan() || rhs_numeric.is_nan())
|
||||
@ -912,9 +919,14 @@ Value mod(GlobalObject& global_object, Value lhs, Value rhs)
|
||||
auto trunc = (double)(i32)(index / period);
|
||||
return Value(index - trunc * period);
|
||||
}
|
||||
if (both_bigint(lhs_numeric, rhs_numeric))
|
||||
if (both_bigint(lhs_numeric, rhs_numeric)) {
|
||||
if (rhs_numeric.as_bigint().big_integer() == BIGINT_ZERO) {
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::DivisionByZero);
|
||||
return {};
|
||||
}
|
||||
return js_bigint(global_object.heap(), lhs_numeric.as_bigint().big_integer().divided_by(rhs_numeric.as_bigint().big_integer()).remainder);
|
||||
global_object.vm().throw_exception<TypeError>(global_object.global_object(), ErrorType::BigIntBadOperatorOtherType, "modulo");
|
||||
}
|
||||
vm.throw_exception<TypeError>(global_object.global_object(), ErrorType::BigIntBadOperatorOtherType, "modulo");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -87,4 +87,13 @@ describe("errors", () => {
|
||||
+123n;
|
||||
}).toThrowWithMessage(TypeError, "Cannot convert BigInt to number");
|
||||
});
|
||||
|
||||
test("division by zero", () => {
|
||||
expect(() => {
|
||||
1n / 0n;
|
||||
}).toThrowWithMessage(RangeError, "Division by zero");
|
||||
expect(() => {
|
||||
1n % 0n;
|
||||
}).toThrowWithMessage(RangeError, "Division by zero");
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user