Issue #1240 - Part 5f - Add DataView methods for BigInt access. https://bugzilla.mozilla.org/show_bug.cgi?id=1528582

This commit is contained in:
Brian Smith 2023-07-19 15:27:59 -05:00 committed by roytam1
commit e3ec738471
2 changed files with 149 additions and 1 deletions

View file

@ -1959,6 +1959,8 @@ template <> struct DataToRepType<int16_t> { typedef uint16_t result; };
template <> struct DataToRepType<uint16_t> { typedef uint16_t result; };
template <> struct DataToRepType<int32_t> { typedef uint32_t result; };
template <> struct DataToRepType<uint32_t> { typedef uint32_t result; };
template <> struct DataToRepType<int64_t> { typedef uint64_t result; };
template <> struct DataToRepType<uint64_t> { typedef uint64_t result; };
template <> struct DataToRepType<float> { typedef uint32_t result; };
template <> struct DataToRepType<double> { typedef uint64_t result; };
@ -2058,6 +2060,28 @@ WebIDLCast(JSContext* cx, HandleValue value, NativeType* out)
return true;
}
template <>
inline bool WebIDLCast<int64_t>(JSContext* cx, HandleValue value, int64_t* out)
{
RootedBigInt bi(cx, ToBigInt(cx, value));
if (!bi) {
return false;
}
*out = BigInt::toInt64(bi);
return true;
}
template <>
inline bool WebIDLCast<uint64_t>(JSContext* cx, HandleValue value, uint64_t* out)
{
RootedBigInt bi(cx, ToBigInt(cx, value));
if (!bi) {
return false;
}
*out = BigInt::toUint64(bi);
return true;
}
template <>
inline bool
WebIDLCast<float>(JSContext* cx, HandleValue value, float* out)
@ -2076,6 +2100,8 @@ WebIDLCast<double>(JSContext* cx, HandleValue value, double* out)
return ToNumber(cx, value, out);
}
// https://tc39.github.io/ecma262/#sec-setviewvalue
// SetViewValue ( view, requestIndex, isLittleEndian, type, value )
template<typename NativeType>
/* static */ bool
DataViewObject::write(JSContext* cx, Handle<DataViewObject*> obj,
@ -2089,7 +2115,7 @@ DataViewObject::write(JSContext* cx, Handle<DataViewObject*> obj,
if (!ToIndex(cx, args.get(0), &getIndex))
return false;
// Step 5. Should just call ToNumber (unobservable)
// Step 5. Extended by the BigInt proposal to call either ToBigInt or ToNumber
NativeType value;
if (!WebIDLCast(cx, args.get(1), &value))
return false;
@ -2245,6 +2271,60 @@ DataViewObject::fun_getUint32(JSContext* cx, unsigned argc, Value* vp)
return CallNonGenericMethod<is, getUint32Impl>(cx, args);
}
// BigInt proposal 7.26
// DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )
bool DataViewObject::getBigInt64Impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(is(args.thisv()));
Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
int64_t val;
if (!read(cx, thisView, args, &val, "getBigInt64")) {
return false;
}
BigInt* bi = BigInt::createFromInt64(cx, val);
if (!bi) {
return false;
}
args.rval().setBigInt(bi);
return true;
}
bool DataViewObject::fun_getBigInt64(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<is, getBigInt64Impl>(cx, args);
}
// BigInt proposal 7.27
// DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )
bool DataViewObject::getBigUint64Impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(is(args.thisv()));
Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
int64_t val;
if (!read(cx, thisView, args, &val, "getBigUint64")) {
return false;
}
BigInt* bi = BigInt::createFromUint64(cx, val);
if (!bi) {
return false;
}
args.rval().setBigInt(bi);
return true;
}
bool DataViewObject::fun_getBigUint64(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<is, getBigUint64Impl>(cx, args);
}
bool
DataViewObject::getFloat32Impl(JSContext* cx, const CallArgs& args)
{
@ -2409,6 +2489,48 @@ DataViewObject::fun_setUint32(JSContext* cx, unsigned argc, Value* vp)
return CallNonGenericMethod<is, setUint32Impl>(cx, args);
}
// BigInt proposal 7.28
// DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )
bool DataViewObject::setBigInt64Impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(is(args.thisv()));
Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
if (!write<int64_t>(cx, thisView, args, "setBigInt64")) {
return false;
}
args.rval().setUndefined();
return true;
}
bool DataViewObject::fun_setBigInt64(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<is, setBigInt64Impl>(cx, args);
}
// BigInt proposal 7.29
// DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )
bool DataViewObject::setBigUint64Impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(is(args.thisv()));
Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
if (!write<uint64_t>(cx, thisView, args, "setBigUint64")) {
return false;
}
args.rval().setUndefined();
return true;
}
bool DataViewObject::fun_setBigUint64(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<is, setBigUint64Impl>(cx, args);
}
bool
DataViewObject::setFloat32Impl(JSContext* cx, const CallArgs& args)
{
@ -2820,6 +2942,13 @@ const JSFunctionSpec DataViewObject::jsfuncs[] = {
JS_FS_END
};
const JSFunctionSpec DataViewObject::bigIntMethods[] = {
JS_FN("getBigInt64", DataViewObject::fun_getBigInt64, 1, 0),
JS_FN("getBigUint64", DataViewObject::fun_getBigUint64, 1, 0),
JS_FN("setBigInt64", DataViewObject::fun_setBigInt64, 2, 0),
JS_FN("setBigUint64", DataViewObject::fun_setBigUint64, 2, 0),
JS_FS_END};
template<Value ValueGetter(DataViewObject* view)>
bool
DataViewObject::getterImpl(JSContext* cx, const CallArgs& args)
@ -2888,6 +3017,9 @@ DataViewObject::initClass(JSContext* cx)
if (!JS_DefineFunctions(cx, proto, DataViewObject::jsfuncs))
return false;
if (!JS_DefineFunctions(cx, proto, DataViewObject::bigIntMethods))
return false;
if (!DefineToStringTag(cx, proto, cx->names().DataView))
return false;

View file

@ -521,6 +521,12 @@ class DataViewObject : public NativeObject
static bool getUint32Impl(JSContext* cx, const CallArgs& args);
static bool fun_getUint32(JSContext* cx, unsigned argc, Value* vp);
static bool getBigInt64Impl(JSContext* cx, const CallArgs& args);
static bool fun_getBigInt64(JSContext* cx, unsigned argc, Value* vp);
static bool getBigUint64Impl(JSContext* cx, const CallArgs& args);
static bool fun_getBigUint64(JSContext* cx, unsigned argc, Value* vp);
static bool getFloat32Impl(JSContext* cx, const CallArgs& args);
static bool fun_getFloat32(JSContext* cx, unsigned argc, Value* vp);
@ -545,6 +551,12 @@ class DataViewObject : public NativeObject
static bool setUint32Impl(JSContext* cx, const CallArgs& args);
static bool fun_setUint32(JSContext* cx, unsigned argc, Value* vp);
static bool setBigInt64Impl(JSContext* cx, const CallArgs& args);
static bool fun_setBigInt64(JSContext* cx, unsigned argc, Value* vp);
static bool setBigUint64Impl(JSContext* cx, const CallArgs& args);
static bool fun_setBigUint64(JSContext* cx, unsigned argc, Value* vp);
static bool setFloat32Impl(JSContext* cx, const CallArgs& args);
static bool fun_setFloat32(JSContext* cx, unsigned argc, Value* vp);
@ -564,6 +576,10 @@ class DataViewObject : public NativeObject
private:
static const JSFunctionSpec jsfuncs[];
static const JSFunctionSpec bigIntMethods[];
static bool finishInit(JSContext* cx, JS::HandleObject ctor,
JS::HandleObject proto);
};
static inline int32_t