From 25ee8102471b26a04774bb882761cc0d07f42536 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Wed, 19 Jul 2023 02:17:04 -0500 Subject: [PATCH] Issue #1240 - Part 5a - BigInt to Number conversion. https://bugzilla.mozilla.org/show_bug.cgi?id=1466893 --- js/src/jsnum.cpp | 40 +++++++++++++++++++++++++++++++++++----- js/src/jsnum.h | 14 ++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index f103f4dc79..62f694c216 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -524,15 +524,21 @@ Number(JSContext* cx, unsigned argc, Value* vp) bool isConstructing = args.isConstructing(); if (args.length() > 0) { - if (!ToNumber(cx, args[0])) + // BigInt proposal section 6.2, steps 2a-c. + if (!ToNumeric(cx, args[0])) return false; - args.rval().set(args[0]); - } else { - args.rval().setInt32(0); + if (args[0].isBigInt()) + args[0].setNumber(BigInt::numberValue(args[0].toBigInt())); } - if (!isConstructing) + if (!isConstructing) { + if (args.length() > 0) { + args.rval().set(args[0]); + } else { + args.rval().setInt32(0); + } return true; + } RootedObject newTarget(cx, &args.newTarget().toObject()); RootedObject proto(cx); @@ -1492,6 +1498,30 @@ js::ToInt8Slow(JSContext *cx, const HandleValue v, int8_t *out) return true; } +// BigInt proposal section 3.1.6 +bool +js::ToNumericSlow(ExclusiveContext* cx, MutableHandleValue vp) +{ + MOZ_ASSERT(!vp.isNumber()); + MOZ_ASSERT(!vp.isBigInt()); + + // Step 1. + if (!vp.isPrimitive()) { + if (!cx->isJSContext()) + return false; + if (!ToPrimitive(cx->asJSContext(), JSTYPE_NUMBER, vp)) + return false; + } + + // Step 2. + if (vp.isBigInt()) { + return true; + } + + // Step 3. + return ToNumber(cx->asJSContext(), vp); +} + /* * Convert a value to an uint8_t, according to the ToUInt8() function in ES6 * ECMA-262, 7.1.10. Return converted value in *out on success, false on failure. diff --git a/js/src/jsnum.h b/js/src/jsnum.h index f169a9c38d..295d237c22 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -362,6 +362,20 @@ ToNumber(ExclusiveContext* cx, HandleValue v, double* out) return ToNumberSlow(cx, v, out); } +bool +ToNumericSlow(ExclusiveContext* cx, JS::MutableHandleValue vp); + +// BigInt proposal section 3.1.6 +MOZ_ALWAYS_INLINE MOZ_MUST_USE bool +ToNumeric(ExclusiveContext* cx, JS::MutableHandleValue vp) +{ + if (vp.isNumber()) + return true; + if (vp.isBigInt()) + return true; + return ToNumericSlow(cx, vp); +} + void FIX_FPU(); } /* namespace js */