diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 2d2f0c76cbdd..d58b2e971bf1 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -291,38 +291,6 @@ IsTypedDatumOfKind(JSObject &obj, TypeRepresentation::Kind kind) return repr->kind() == kind; } -static bool -TypeEquivalent(JSContext *cx, unsigned int argc, Value *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - - RootedObject thisObj(cx, ToObjectIfObject(args.thisv())); - if (!thisObj || !IsTypeObject(*thisObj)) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, - JSMSG_INCOMPATIBLE_PROTO, - "Type", "equivalent", - InformalValueTypeName(args.thisv())); - return false; - } - - if (args.length() < 1) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED, - "Type.equivalent", "1", "s"); - return false; - } - - RootedObject otherObj(cx, ToObjectIfObject(args[0])); - if (!otherObj || !IsTypeObject(*otherObj)) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_NOT_TYPE_OBJECT); - return false; - } - - TypeRepresentation *thisRepr = typeRepresentation(*thisObj); - TypeRepresentation *otherRepr = typeRepresentation(*otherObj); - args.rval().setBoolean(thisRepr == otherRepr); - return true; -} - #define BINARYDATA_NUMERIC_CLASSES(constant_, type_, name_) \ { \ #name_, \ @@ -344,6 +312,7 @@ TypeEquivalent(JSContext *cx, unsigned int argc, Value *vp) static const JSFunctionSpec NumericTypeObjectMethods[] = { {"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"}, + {"equivalent", {nullptr, nullptr}, 1, 0, "TypeObjectEquivalent"}, JS_FS_END }; @@ -549,6 +518,7 @@ const JSFunctionSpec ArrayType::typeObjectMethods[] = { {"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"}, JS_FN("repeat", ArrayType::repeat, 1, 0), JS_FN("toSource", ArrayType::toSource, 0, 0), + {"equivalent", {nullptr, nullptr}, 1, 0, "TypeObjectEquivalent"}, JS_FS_END }; @@ -790,13 +760,6 @@ InitializeCommonTypeDescriptorProperties(JSContext *cx, TypeRepresentation *typeRepr = TypeRepresentation::fromOwnerObject(*typeReprOwnerObj); - // equivalent() - if (!JS_DefineFunction(cx, obj, "equivalent", - TypeEquivalent, 1, 0)) - { - return false; - } - // byteLength RootedValue typeByteLength(cx, NumberValue(typeRepr->size())); if (!JSObject::defineProperty(cx, obj, cx->names().byteLength, @@ -980,6 +943,7 @@ const JSPropertySpec StructType::typeObjectProperties[] = { const JSFunctionSpec StructType::typeObjectMethods[] = { {"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"}, JS_FN("toSource", StructType::toSource, 0, 0), + {"equivalent", {nullptr, nullptr}, 1, 0, "TypeObjectEquivalent"}, JS_FS_END }; diff --git a/js/src/builtin/TypedObject.js b/js/src/builtin/TypedObject.js index 8b69aae76caa..3a80d6873ea4 100644 --- a/js/src/builtin/TypedObject.js +++ b/js/src/builtin/TypedObject.js @@ -404,6 +404,15 @@ function FillTypedArrayWithValue(destArray, fromValue) { Memcpy(destArray, offset, destArray, 0, elementSize); } +// Warning: user exposed! +function TypeObjectEquivalent(otherTypeObj) { + if (!IsObject(this) || !ObjectIsTypeObject(this)) + ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, "this", "type object"); + if (!IsObject(otherTypeObj) || !ObjectIsTypeObject(otherTypeObj)) + ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, "1", "type object"); + return TYPE_TYPE_REPR(this) === TYPE_TYPE_REPR(otherTypeObj); +} + /////////////////////////////////////////////////////////////////////////// // Handles // diff --git a/js/src/tests/ecma_6/TypedObject/arrayequiv.js b/js/src/tests/ecma_6/TypedObject/arrayequiv.js new file mode 100644 index 000000000000..65a6e5f00921 --- /dev/null +++ b/js/src/tests/ecma_6/TypedObject/arrayequiv.js @@ -0,0 +1,59 @@ +// |reftest| skip-if(!this.hasOwnProperty("TypedObject")) +var BUGNUMBER = 922216; +var summary = 'TypedObjects Equivalent ArrayTypes'; + +var ArrayType = TypedObject.ArrayType; +var StructType = TypedObject.StructType; +var uint8 = TypedObject.uint8; +var uint16 = TypedObject.uint16; +var uint32 = TypedObject.uint32; +var uint8Clamped = TypedObject.uint8Clamped; +var int8 = TypedObject.int8; +var int16 = TypedObject.int16; +var int32 = TypedObject.int32; +var float32 = TypedObject.float32; +var float64 = TypedObject.float64; + +function assertEquivalent(t1, t2) { + assertEq(true, t1.equivalent(t2)); + assertEq(true, t2.equivalent(t1)); +} + +function assertNotEquivalent(t1, t2) { + assertEq(false, t1.equivalent(t2)); + assertEq(false, t2.equivalent(t1)); +} + +function runTests() { + print(BUGNUMBER + ": " + summary); + + // Create a line: + var PixelType1 = new StructType({x: uint8, y: uint8}); + var PixelsType1 = new ArrayType(PixelType1, 22); + + // Sanity checks about type equivalence: + assertEquivalent(PixelType1, PixelType1); + assertEquivalent(PixelsType1, PixelsType1); + assertNotEquivalent(PixelType1, PixelsType1); + + // Define the same two types again. Equivalent. + var PixelType2 = new StructType({x: uint8, y: uint8}); + var PixelsType2 = new ArrayType(PixelType2, 22); + assertEquivalent(PixelType1, PixelType2); + assertEquivalent(PixelsType1, PixelsType2); + + // Define the pixel type with field order reversed. Not equivalent. + var PixelType3 = new StructType({y: uint8, x: uint8}); + var PixelsType3 = new ArrayType(PixelType3, 22); + assertNotEquivalent(PixelType1, PixelType3); + assertNotEquivalent(PixelsType1, PixelsType3); + + // Define the pixels type with different number of elements. Not equivalent. + var PixelsType3 = new ArrayType(PixelType1, 23); + assertNotEquivalent(PixelsType1, PixelsType3); + + reportCompare(true, true); + print("Tests complete"); +} + +runTests(); diff --git a/js/src/tests/ecma_6/TypedObject/simpleequiv.js b/js/src/tests/ecma_6/TypedObject/simpleequiv.js new file mode 100644 index 000000000000..d8fb3c2f1195 --- /dev/null +++ b/js/src/tests/ecma_6/TypedObject/simpleequiv.js @@ -0,0 +1,34 @@ +// |reftest| skip-if(!this.hasOwnProperty("TypedObject")) +var BUGNUMBER = 922216; +var summary = 'TypedObjects Equivalent Numeric Types'; + +var ArrayType = TypedObject.ArrayType; +var StructType = TypedObject.StructType; +var uint8 = TypedObject.uint8; +var uint16 = TypedObject.uint16; +var uint32 = TypedObject.uint32; +var uint8Clamped = TypedObject.uint8Clamped; +var int8 = TypedObject.int8; +var int16 = TypedObject.int16; +var int32 = TypedObject.int32; +var float32 = TypedObject.float32; +var float64 = TypedObject.float64; + +function runTests() { + print(BUGNUMBER + ": " + summary); + + var scalarTypes = [ + int8, int16, int32, + uint8, uint16, uint32, + float32, float64 + ]; + + for (var i = 0; i < scalarTypes.length; i++) + for (var j = 0; j < scalarTypes.length; j++) + assertEq(i == j, scalarTypes[i].equivalent(scalarTypes[j])); + + reportCompare(true, true); + print("Tests complete"); +} + +runTests(); diff --git a/js/src/tests/ecma_6/TypedObject/structequiv.js b/js/src/tests/ecma_6/TypedObject/structequiv.js index add0e1a53e04..6881e3ba37a6 100644 --- a/js/src/tests/ecma_6/TypedObject/structequiv.js +++ b/js/src/tests/ecma_6/TypedObject/structequiv.js @@ -1,5 +1,5 @@ // |reftest| skip-if(!this.hasOwnProperty("TypedObject")) -var BUGNUMBER = 578700; +var BUGNUMBER = 922216; var summary = 'TypedObjects Equivalent StructTypes'; var ArrayType = TypedObject.ArrayType;