diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /js/src/jit-test/tests/ctypes | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/jit-test/tests/ctypes')
45 files changed, 962 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/ctypes/AddressOfField.js b/js/src/jit-test/tests/ctypes/AddressOfField.js new file mode 100644 index 000000000..52f4d1cd1 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/AddressOfField.js @@ -0,0 +1,12 @@ +load(libdir + 'asserts.js'); + +function test() { + let strcut = ctypes.StructType("a", [ { "x": ctypes.int32_t, } ])(); + for (let arg of [1, undefined, null, false, {}, [], Symbol("foo")]) { + assertThrowsInstanceOf(() => { struct.addressOfField(arg); }, + Error); + } +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-abi.js b/js/src/jit-test/tests/ctypes/argument-length-abi.js new file mode 100644 index 000000000..a18a8059e --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-abi.js @@ -0,0 +1,9 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.default_abi.toSource(1); }, + "ABI.prototype.toSource takes no arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-array.js b/js/src/jit-test/tests/ctypes/argument-length-array.js new file mode 100644 index 000000000..5afbcc46e --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-array.js @@ -0,0 +1,15 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.ArrayType(); }, + "ArrayType takes one or two arguments"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)(1, 2); }, + "size defined ArrayType constructor takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.array()(1, 2); }, + "size undefined ArrayType constructor takes one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)().addressOfElement(); }, + "ArrayType.prototype.addressOfElement takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-cdata.js b/js/src/jit-test/tests/ctypes/argument-length-cdata.js new file mode 100644 index 000000000..56a1497f4 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-cdata.js @@ -0,0 +1,15 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t(0).address(1); }, + "CData.prototype.address takes no arguments"); + assertTypeErrorMessage(() => { ctypes.char.array(10)().readString(1); }, + "CData.prototype.readString takes no arguments"); + assertTypeErrorMessage(() => { ctypes.char.array(10)().readStringReplaceMalformed(1); }, + "CData.prototype.readStringReplaceMalformed takes no arguments"); + assertTypeErrorMessage(() => { ctypes.int32_t(0).toSource(1); }, + "CData.prototype.toSource takes no arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-ctypes.js b/js/src/jit-test/tests/ctypes/argument-length-ctypes.js new file mode 100644 index 000000000..84b0b9ea5 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-ctypes.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.cast(); }, + "ctypes.cast takes two arguments"); + assertTypeErrorMessage(() => { ctypes.getRuntime(); }, + "ctypes.getRuntime takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-finalizer.js b/js/src/jit-test/tests/ctypes/argument-length-finalizer.js new file mode 100644 index 000000000..70e15bf8f --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-finalizer.js @@ -0,0 +1,16 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(1); }, + "CDataFinalizer constructor takes two arguments"); + + let fin = ctypes.CDataFinalizer(ctypes.int32_t(0), ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.int32_t]).ptr(x => x)); + assertTypeErrorMessage(() => { fin.forget(1); }, + "CDataFinalizer.prototype.forget takes no arguments"); + assertTypeErrorMessage(() => { fin.dispose(1); }, + "CDataFinalizer.prototype.dispose takes no arguments"); + fin.forget(); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-function.js b/js/src/jit-test/tests/ctypes/argument-length-function.js new file mode 100644 index 000000000..2d2659662 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-function.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.FunctionType(); }, + "FunctionType takes two or three arguments"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, []).ptr({}, 1); }, + "FunctionType constructor takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-int64.js b/js/src/jit-test/tests/ctypes/argument-length-int64.js new file mode 100644 index 000000000..888713acc --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-int64.js @@ -0,0 +1,36 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.Int64(1).toString(1, 2); }, + "Int64.prototype.toString takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.Int64(1).toSource(1); }, + "Int64.prototype.toSource takes no arguments"); + assertTypeErrorMessage(() => { ctypes.Int64(); }, + "Int64 constructor takes one argument"); + assertTypeErrorMessage(() => { ctypes.Int64.compare(); }, + "Int64.compare takes two arguments"); + assertTypeErrorMessage(() => { ctypes.Int64.lo(); }, + "Int64.lo takes one argument"); + assertTypeErrorMessage(() => { ctypes.Int64.hi(); }, + "Int64.hi takes one argument"); + assertTypeErrorMessage(() => { ctypes.Int64.join(); }, + "Int64.join takes two arguments"); + + assertTypeErrorMessage(() => { ctypes.UInt64(1).toString(1, 2); }, + "UInt64.prototype.toString takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64(1).toSource(1); }, + "UInt64.prototype.toSource takes no arguments"); + assertTypeErrorMessage(() => { ctypes.UInt64(); }, + "UInt64 constructor takes one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64.compare(); }, + "UInt64.compare takes two arguments"); + assertTypeErrorMessage(() => { ctypes.UInt64.lo(); }, + "UInt64.lo takes one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64.hi(); }, + "UInt64.hi takes one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64.join(); }, + "UInt64.join takes two arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-pointer.js b/js/src/jit-test/tests/ctypes/argument-length-pointer.js new file mode 100644 index 000000000..8ac404aaf --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-pointer.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.PointerType(); }, + "PointerType takes one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(1, 2, 3, 4); }, + "PointerType constructor takes 0, 1, 2, or 3 arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-primitive.js b/js/src/jit-test/tests/ctypes/argument-length-primitive.js new file mode 100644 index 000000000..161ebd880 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-primitive.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t(1, 2, 3); }, + "CType constructor takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(1, 2); }, + "CType.prototype.array takes at most one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-struct.js b/js/src/jit-test/tests/ctypes/argument-length-struct.js new file mode 100644 index 000000000..0e8efbb6a --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-struct.js @@ -0,0 +1,17 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.StructType(); }, + "StructType takes one or two arguments"); + assertTypeErrorMessage(() => { ctypes.StructType("a").define(); }, + "StructType.prototype.define takes one argument"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [])(1, 2, 3); }, + "StructType constructor takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ {"x": ctypes.int32_t }, {"y": ctypes.int32_t }, {"z": ctypes.int32_t }])(1, 2); }, + "StructType constructor takes 0, 1, or 3 arguments"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ {"x": ctypes.int32_t } ])().addressOfField(); }, + "StructType.prototype.addressOfField takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-array.js b/js/src/jit-test/tests/ctypes/argument-type-array.js new file mode 100644 index 000000000..e78578d86 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-array.js @@ -0,0 +1,17 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t.array({}); }, + "argument of CType.prototype.array must be a nonnegative integer"); + assertTypeErrorMessage(() => { ctypes.ArrayType(1); }, + "first argument of ArrayType must be a CType"); + assertTypeErrorMessage(() => { ctypes.ArrayType(ctypes.int32_t, {}); }, + "second argument of ArrayType must be a nonnegative integer"); + assertTypeErrorMessage(() => { ctypes.char.array()({}); }, + "argument of size undefined ArrayType constructor must be an array object or integer"); + assertTypeErrorMessage(() => { ctypes.char.array()(false); }, + "argument of size undefined ArrayType constructor must be an array object or integer"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-ctypes.js b/js/src/jit-test/tests/ctypes/argument-type-ctypes.js new file mode 100644 index 000000000..168c8fb74 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-ctypes.js @@ -0,0 +1,13 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.cast(1, 2); }, + "first argument of ctypes.cast must be a CData"); + assertTypeErrorMessage(() => { ctypes.cast(ctypes.int32_t(0), 2); }, + "second argument of ctypes.cast must be a CType"); + assertTypeErrorMessage(() => { ctypes.getRuntime(1); }, + "argument of ctypes.getRuntime must be a CType"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-function.js b/js/src/jit-test/tests/ctypes/argument-type-function.js new file mode 100644 index 000000000..a341415f1 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-function.js @@ -0,0 +1,9 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, 1); }, + "third argument of FunctionType must be an array"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-int64.js b/js/src/jit-test/tests/ctypes/argument-type-int64.js new file mode 100644 index 000000000..e147b98a4 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-int64.js @@ -0,0 +1,28 @@ +load(libdir + 'asserts.js'); + +function test() { + assertRangeErrorMessage(() => { ctypes.Int64(0).toString("a"); }, + "argument of Int64.prototype.toString must be an integer at least 2 and no greater than 36"); + assertTypeErrorMessage(() => { ctypes.Int64.compare(1, 2); }, + "first argument of Int64.compare must be a Int64"); + assertTypeErrorMessage(() => { ctypes.Int64.compare(ctypes.Int64(0), 2); }, + "second argument of Int64.compare must be a Int64"); + assertTypeErrorMessage(() => { ctypes.Int64.lo(1); }, + "argument of Int64.lo must be a Int64"); + assertTypeErrorMessage(() => { ctypes.Int64.hi(1); }, + "argument of Int64.hi must be a Int64"); + + assertRangeErrorMessage(() => { ctypes.UInt64(0).toString("a"); }, + "argument of UInt64.prototype.toString must be an integer at least 2 and no greater than 36"); + assertTypeErrorMessage(() => { ctypes.UInt64.compare(1, 2); }, + "first argument of UInt64.compare must be a UInt64"); + assertTypeErrorMessage(() => { ctypes.UInt64.compare(ctypes.UInt64(0), 2); }, + "second argument of UInt64.compare must be a UInt64"); + assertTypeErrorMessage(() => { ctypes.UInt64.lo(1); }, + "argument of UInt64.lo must be a UInt64"); + assertTypeErrorMessage(() => { ctypes.UInt64.hi(1); }, + "argument of UInt64.hi must be a UInt64"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-pointer.js b/js/src/jit-test/tests/ctypes/argument-type-pointer.js new file mode 100644 index 000000000..80f96ad90 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-pointer.js @@ -0,0 +1,9 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.PointerType({}); }, + "argument of PointerType must be a CType"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-struct.js b/js/src/jit-test/tests/ctypes/argument-type-struct.js new file mode 100644 index 000000000..703c0f059 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-struct.js @@ -0,0 +1,17 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.StructType(1); }, + "first argument of StructType must be a string"); + assertTypeErrorMessage(() => { ctypes.StructType("a", 1); }, + "second argument of StructType must be an array"); + assertTypeErrorMessage(() => { ctypes.StructType("a").define(1); }, + "argument of StructType.prototype.define must be an array"); + assertTypeErrorMessage(() => { ctypes.StructType("a").define({}); }, + "argument of StructType.prototype.define must be an array"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [{x:ctypes.int32_t}])().addressOfField(1); }, + "argument of StructType.prototype.addressOfField must be a string"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/array-index.js b/js/src/jit-test/tests/ctypes/array-index.js new file mode 100644 index 000000000..e70add1a0 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/array-index.js @@ -0,0 +1,29 @@ +load(libdir + 'asserts.js'); + +function test() { + let a = ctypes.int32_t.array(10)(); + assertTypeErrorMessage(() => { let x = a[-1]; }, + "the string \"-1\" is not a valid array index"); + assertTypeErrorMessage(() => { a[-1] = 1; }, + "the string \"-1\" is not a valid array index"); + assertTypeErrorMessage(() => { a.addressOfElement(-1); }, + "the number -1 is not a valid array index"); + + assertRangeErrorMessage(() => { let x = a[10]; }, + "array index 10 is out of bounds for array of length 10"); + assertRangeErrorMessage(() => { a[10] = 1; }, + "array index 10 is out of bounds for array of length 10"); + assertRangeErrorMessage(() => { a.addressOfElement(10); }, + "array index 10 is out of bounds for array of length 10"); + + let obj = { + toSource() { + throw 1; + } + }; + assertTypeErrorMessage(() => { a.addressOfElement(obj); }, + "<<error converting value to string>> is not a valid array index"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/bug1155985.js b/js/src/jit-test/tests/ctypes/bug1155985.js new file mode 100644 index 000000000..54c24d4ba --- /dev/null +++ b/js/src/jit-test/tests/ctypes/bug1155985.js @@ -0,0 +1,14 @@ +function test() { + for (let i = 0; i < 100; i++) { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }, + { "bar": ctypes.uint32_t }]); + + try { + new test_struct("foo", "x"); + } catch (e) { + } + } +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/cast.js b/js/src/jit-test/tests/ctypes/cast.js new file mode 100644 index 000000000..c483d3793 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/cast.js @@ -0,0 +1,12 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.cast(ctypes.int32_t(0), ctypes.StructType("foo")); }, + "target type foo has undefined size"); + + assertTypeErrorMessage(() => { ctypes.cast(ctypes.int32_t(0), ctypes.StructType("foo", [ { x: ctypes.int32_t }, { y: ctypes.int32_t } ])); }, + "target type foo has larger size than source type ctypes.int32_t (8 > 4)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/construct.js b/js/src/jit-test/tests/ctypes/construct.js new file mode 100644 index 000000000..cfabdf24d --- /dev/null +++ b/js/src/jit-test/tests/ctypes/construct.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.void_t(); }, + "cannot construct from void_t"); + assertTypeErrorMessage(() => { ctypes.CType(); }, + "cannot construct from abstract type"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-array.js b/js/src/jit-test/tests/ctypes/conversion-array.js new file mode 100644 index 000000000..cb6e2ce0b --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-array.js @@ -0,0 +1,36 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + // constructor + assertTypeErrorMessage(() => { ctypes.int32_t.array()("foo"); }, + "can't convert the string \"foo\" to the type ctypes.int32_t.array()"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)("foo"); }, + "can't convert the string \"foo\" to the type ctypes.int32_t.array(10)"); + assertTypeErrorMessage(() => { ctypes.char.array(2)("foo"); }, + "length of the string \"foo\" does not fit in the length of the type ctypes.char.array(2) (expected 2 or lower, got 3)"); + assertTypeErrorMessage(() => { ctypes.char16_t.array(2)("foo"); }, + "length of the string \"foo\" does not fit in the length of the type ctypes.char16_t.array(2) (expected 2 or lower, got 3)"); + assertTypeErrorMessage(() => { ctypes.int8_t.array(2)(new ArrayBuffer(8)); }, + "length of the array buffer ({}) does not match to the length of the type ctypes.int8_t.array(2) (expected 2, got 8)"); + assertTypeErrorMessage(() => { ctypes.int8_t.array(2)(new Int8Array(8)); }, + "length of the typed array ({0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0}) does not match to the length of the type ctypes.int8_t.array(2) (expected 2, got 8)"); + + // elem setter + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)()[0] = "foo"; }, + "can't convert the string \"foo\" to element 0 of the type ctypes.int32_t.array(10)"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)()[1] = "foo"; }, + "can't convert the string \"foo\" to element 1 of the type ctypes.int32_t.array(10)"); + + // value setter + assertTypeErrorMessage(() => { ctypes.int32_t.array(1)().value = ["foo"]; }, + "can't convert the string \"foo\" to element 0 of the type ctypes.int32_t.array(1)"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(1)().value = [2, "foo"]; }, + "length of the array [2, \"foo\"] does not match to the length of the type ctypes.int32_t.array(1) (expected 1, got 2)"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(2)().value = [2, "foo"]; }, + "can't convert the string \"foo\" to element 1 of the type ctypes.int32_t.array(2)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-error.js b/js/src/jit-test/tests/ctypes/conversion-error.js new file mode 100644 index 000000000..a6823fe5c --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-error.js @@ -0,0 +1,14 @@ +load(libdir + 'asserts.js'); + +function test() { + let obj = { + toSource() { + throw 1; + } + }; + assertTypeErrorMessage(() => { ctypes.double().value = obj; }, + "can't convert <<error converting value to string>> to the type double"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-finalizer.js b/js/src/jit-test/tests/ctypes/conversion-finalizer.js new file mode 100644 index 000000000..a04a40cfa --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-finalizer.js @@ -0,0 +1,61 @@ +load(libdir + 'asserts.js'); + +function test() { + // non object + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, "foo"); }, + "expected _a CData object_ of a function pointer type, got the string \"foo\""); + // non CData object + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ["foo"]); }, + "expected a _CData_ object of a function pointer type, got the array [\"foo\"]"); + + // a CData which is not a pointer + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ctypes.int32_t(0)); }, + "expected a CData object of a function _pointer_ type, got ctypes.int32_t(0)"); + // a pointer CData which is not a function + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ctypes.int32_t.ptr(0)); }, + "expected a CData object of a _function_ pointer type, got ctypes.int32_t.ptr(ctypes.UInt64(\"0x0\"))"); + + // null function + let func_type = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t, ctypes.int32_t]).ptr; + let f0 = func_type(0); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f0); }, + "expected a CData object of a _non-NULL_ function pointer type, got ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t, ctypes.int32_t]).ptr(ctypes.UInt64(\"0x0\"))"); + + // a function with 2 arguments + let f1 = func_type(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f1); }, + "expected a function accepting exactly one argument, got ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t, ctypes.int32_t])"); + + // non CData in argument 1 + let func_type2 = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t.ptr]).ptr; + let f2 = func_type2(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f2); }, + "can't convert the number 0 to the type of argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t.ptr]).ptr"); + + // wrong struct in argument 1 + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let func_type3 = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [test_struct]).ptr; + let f3 = func_type3(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer({ "x": "foo" }, f3); }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct at argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [test_struct]).ptr"); + + // different size in argument 1 + let func_type4 = ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, + [ctypes.int32_t]).ptr; + let f4 = func_type4(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(ctypes.int16_t(0), f4); }, + "expected an object with the same size as argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.int32_t]).ptr, got ctypes.int16_t(0)"); + + let fin = ctypes.CDataFinalizer(ctypes.int32_t(0), f4); + fin.dispose(); + assertTypeErrorMessage(() => { ctypes.int32_t(0).value = fin; }, + "attempting to convert an empty CDataFinalizer"); + assertTypeErrorMessage(() => { f4(fin); }, + /attempting to convert an empty CDataFinalizer at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[ctypes\.int32_t\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-function.js b/js/src/jit-test/tests/ctypes/conversion-function.js new file mode 100644 index 000000000..cd90f1b60 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-function.js @@ -0,0 +1,33 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + // Note: js shell cannot handle the exception in return value. + + // primitive + let func_type = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t]).ptr; + let f1 = func_type(function() {}); + assertTypeErrorMessage(() => { f1("foo"); }, + /can't pass the string "foo" to argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.voidptr_t, \[ctypes\.int32_t\]\)\.ptr\(ctypes\.UInt64\("[x0-9A-Fa-f]+"\)\)/); + + // struct + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let func_type2 = ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, + [test_struct]).ptr; + let f2 = func_type2(function() {}); + assertTypeErrorMessage(() => { f2({ "x": "foo" }); }, + /can't convert the string \"foo\" to the 'x' field \(int32_t\) of test_struct at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); + assertTypeErrorMessage(() => { f2({ "x": "foo", "y": "bar" }); }, + /property count of the object \(\{x:\"foo\", y:\"bar\"\}\) does not match to field count of the type test_struct \(expected 1, got 2\) at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); + assertTypeErrorMessage(() => { f2({ 0: "foo" }); }, + /property name the number 0 of the object \(\{0:\"foo\"\}\) is not a string at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); + + // error sentinel + assertTypeErrorMessage(() => { func_type(function() {}, null, "foo"); }, + "can't convert the string \"foo\" to the return type of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t])"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-int64.js b/js/src/jit-test/tests/ctypes/conversion-int64.js new file mode 100644 index 000000000..89a14fef9 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-int64.js @@ -0,0 +1,20 @@ +load(libdir + 'asserts.js'); + +function test() { + assertRangeErrorMessage(() => { ctypes.Int64("0xfffffffffffffffffffffff"); }, + "the string \"0xfffffffffffffffffffffff\" does not fit in the type int64"); + assertTypeErrorMessage(() => { ctypes.Int64.join("foo", 0); }, + "can't pass the string \"foo\" to argument 1 of Int64.join"); + assertTypeErrorMessage(() => { ctypes.Int64.join(0, "foo"); }, + "can't pass the string \"foo\" to argument 2 of Int64.join"); + + assertRangeErrorMessage(() => { ctypes.UInt64("0xfffffffffffffffffffffff"); }, + "the string \"0xfffffffffffffffffffffff\" does not fit in the type uint64"); + assertTypeErrorMessage(() => { ctypes.UInt64.join("foo", 0); }, + "can't pass the string \"foo\" to argument 1 of UInt64.join"); + assertTypeErrorMessage(() => { ctypes.UInt64.join(0, "foo"); }, + "can't pass the string \"foo\" to argument 2 of UInt64.join"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-native-function.js b/js/src/jit-test/tests/ctypes/conversion-native-function.js new file mode 100644 index 000000000..b005596c2 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-native-function.js @@ -0,0 +1,37 @@ +// Type conversion error for native function should report its name and type +// in C style. + +load(libdir + 'asserts.js'); + +function test() { + let lib; + try { + lib = ctypes.open(ctypes.libraryName("m")); + } catch (e) { + } + if (!lib) + return; + + let func = lib.declare("hypot", + ctypes.default_abi, + ctypes.double, + ctypes.double, ctypes.double); + assertTypeErrorMessage(() => { func(1, "xyzzy"); }, + "can't pass the string \"xyzzy\" to argument 2 of double hypot(double, double)"); + + // test C style source for various types + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let test_func = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t]).ptr; + func = lib.declare("hypot", + ctypes.default_abi, + ctypes.double, + ctypes.double, ctypes.int32_t.ptr.ptr.ptr.array(), + test_struct, test_struct.ptr.ptr, + test_func, test_func.ptr.ptr.ptr, "..."); + assertTypeErrorMessage(() => { func("xyzzy", 1, 2, 3, 4, 5); }, + "can't pass the string \"xyzzy\" to argument 1 of double hypot(double, int32_t****, struct test_struct, struct test_struct**, void* (*)(int32_t), void* (****)(int32_t), ...)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-pointer.js b/js/src/jit-test/tests/ctypes/conversion-pointer.js new file mode 100644 index 000000000..d2583b878 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-pointer.js @@ -0,0 +1,29 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let struct_val = test_struct(); + + // constructor + assertTypeErrorMessage(() => { ctypes.int32_t.ptr("foo"); }, + "can't convert the string \"foo\" to the type ctypes.int32_t.ptr"); + + // value setter + assertTypeErrorMessage(() => { test_struct.ptr().value = "foo"; }, + "can't convert the string \"foo\" to the type test_struct.ptr"); + assertTypeErrorMessage(() => { test_struct.ptr().value = {}; }, + "can't convert the object ({}) to the type test_struct.ptr"); + assertTypeErrorMessage(() => { test_struct.ptr().value = [1, 2]; }, + "can't convert the array [1, 2] to the type test_struct.ptr"); + assertTypeErrorMessage(() => { test_struct.ptr().value = new Int8Array([1, 2]); }, + "can't convert the typed array ({0:1, 1:2}) to the type test_struct.ptr"); + + // contents setter + assertTypeErrorMessage(() => { ctypes.int32_t().address().contents = {}; }, + "can't convert the object ({}) to the type int32_t"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-primitive.js b/js/src/jit-test/tests/ctypes/conversion-primitive.js new file mode 100644 index 000000000..38512f9c4 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-primitive.js @@ -0,0 +1,44 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + // constructor + assertTypeErrorMessage(() => { ctypes.int32_t("foo"); }, + "can't convert the string \"foo\" to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(null); }, + "can't convert null to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(undefined); }, + "can't convert undefined to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t({}); }, + "can't convert the object ({}) to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t([]); }, + "can't convert the array [] to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(new Int8Array([])); }, + "can't convert the typed array ({}) to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(ctypes.int32_t); }, + "can't convert ctypes.int32_t to the type int32_t"); + assertRangeErrorMessage(() => { ctypes.int32_t("0xfffffffffffffffffffffff"); }, + "the string \"0xfffffffffffffffffffffff\" does not fit in the type int32_t"); + if (typeof Symbol === "function") { + assertTypeErrorMessage(() => { ctypes.int32_t(Symbol.iterator); }, + "can't convert Symbol.iterator to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(Symbol("foo")); }, + "can't convert Symbol(\"foo\") to the type int32_t"); + } + + // value setter + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let struct_val = test_struct(); + assertTypeErrorMessage(() => { ctypes.bool().value = struct_val; }, + "can't convert test_struct(0) to the type boolean"); + assertTypeErrorMessage(() => { ctypes.char16_t().value = struct_val; }, + "can't convert test_struct(0) to the type char16_t"); + assertTypeErrorMessage(() => { ctypes.int8_t().value = struct_val; }, + "can't convert test_struct(0) to the type int8_t"); + assertTypeErrorMessage(() => { ctypes.double().value = struct_val; }, + "can't convert test_struct(0) to the type double"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-struct.js b/js/src/jit-test/tests/ctypes/conversion-struct.js new file mode 100644 index 000000000..f5e43ffa5 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-struct.js @@ -0,0 +1,36 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }, + { "bar": ctypes.int32_t }]); + + // constructor + assertTypeErrorMessage(() => { new test_struct("foo"); }, + "can't convert the string \"foo\" to the type test_struct"); + assertTypeErrorMessage(() => { new test_struct("foo", "x"); }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { new test_struct({ "x": "foo", "bar": 1 }); }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { new test_struct({ 0: 1, "bar": 1 }); }, + "property name the number 0 of the object ({0:1, bar:1}) is not a string"); + + // field setter + let struct_val = test_struct(); + assertTypeErrorMessage(() => { struct_val.x = "foo"; }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { struct_val.bar = "foo"; }, + "can't convert the string \"foo\" to the 'bar' field (int32_t) of test_struct"); + + // value setter + assertTypeErrorMessage(() => { struct_val.value = { "x": "foo" }; }, + "property count of the object ({x:\"foo\"}) does not match to field count of the type test_struct (expected 2, got 1)"); + assertTypeErrorMessage(() => { struct_val.value = { "x": "foo", "bar": 1 }; }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { struct_val.value = "foo"; }, + "can't convert the string \"foo\" to the type test_struct"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-to-primitive.js b/js/src/jit-test/tests/ctypes/conversion-to-primitive.js new file mode 100644 index 000000000..cdb9a4a05 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-to-primitive.js @@ -0,0 +1,20 @@ +// Accessing `value` property of non primitive type should report its type. + +load(libdir + 'asserts.js'); + +function test() { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.voidptr_t }]); + assertTypeErrorMessage(() => test_struct().value, + ".value only works on character and numeric types, not `test_struct`"); + + let test_array = ctypes.ArrayType(test_struct); + assertTypeErrorMessage(() => test_array(10).value, + ".value only works on character and numeric types, not `test_struct.array(10)`"); + + let test_pointer = ctypes.PointerType(test_struct); + assertTypeErrorMessage(() => test_pointer(10).value, + ".value only works on character and numeric types, not `test_struct.ptr`"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/function-definition.js b/js/src/jit-test/tests/ctypes/function-definition.js new file mode 100644 index 000000000..4df317a09 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/function-definition.js @@ -0,0 +1,47 @@ +load(libdir + 'asserts.js'); + +function test() { + assertRangeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, []).ptr(x=>1)(1); }, + "number of arguments does not match declaration of ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t) (expected 0, got 1)"); + + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [1]); }, + "the type of argument 1 is not a ctypes type (got the number 1)"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.void_t]); }, + "the type of argument 1 cannot be void or function (got ctypes.void)"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [])]); }, + "the type of argument 1 cannot be void or function (got ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t))"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.StructType("a")]); }, + "the type of argument 1 must have defined size (got ctypes.StructType(\"a\"))"); + + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [])(); }, + "cannot construct from FunctionType; use FunctionType.ptr instead"); + + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, 1, []); }, + "return type is not a ctypes type (got the number 1)"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t.array(), []); }, + "return type cannot be an array or function (got ctypes.int32_t.array())"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, []), []); }, + "return type cannot be an array or function (got ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t))"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.StructType("a"), []); }, + "return type must have defined size (got ctypes.StructType(\"a\"))"); + + let lib; + try { + lib = ctypes.open(ctypes.libraryName("c")); + } catch (e) { + } + if (!lib) + return; + + let func = lib.declare("hypot", + ctypes.default_abi, + ctypes.double, + ctypes.double, "..."); + assertRangeErrorMessage(() => { func(); }, + "number of arguments does not match declaration of double hypot(double, ...) (expected 1 or more, got 0)"); + assertTypeErrorMessage(() => { func(1, 2); }, + "variadic argument 2 must be a CData object (got the number 2)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-abi.js b/js/src/jit-test/tests/ctypes/incompatible-abi.js new file mode 100644 index 000000000..2d9cc0ce7 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-abi.js @@ -0,0 +1,9 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.default_abi.toSource.call(1); }, + "ABI.prototype.toSource called on incompatible Number"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-array.js b/js/src/jit-test/tests/ctypes/incompatible-array.js new file mode 100644 index 000000000..a066a424c --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-array.js @@ -0,0 +1,13 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t.array.call(1); }, + "CType.prototype.array called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)().addressOfElement.call(1); }, + "ArrayType.prototype.addressOfElement called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)().addressOfElement.call(ctypes.int32_t(0)); }, + "ArrayType.prototype.addressOfElement called on non-ArrayType CData, got ctypes.int32_t(0)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-cdata.js b/js/src/jit-test/tests/ctypes/incompatible-cdata.js new file mode 100644 index 000000000..c94fdfa88 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-cdata.js @@ -0,0 +1,24 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t(0).address.call(1); }, + "CData.prototype.address called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.char.array(10)("abc").readString.call(1); }, + "CData.prototype.readString called on incompatible object, got the object (new Number(1))"); + + assertTypeErrorMessage(() => { ctypes.char.array(10)("abc").readStringReplaceMalformed.call(1); }, + "CData.prototype.readStringReplaceMalformed called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.int32_t(0).toSource.call(1); }, + "CData.prototype.toSource called on incompatible Number"); + + let p = Object.getPrototypeOf(ctypes.int32_t()); + let o = {}; + Object.setPrototypeOf(o, p); + assertTypeErrorMessage(() => { o.readString(); }, + "CData.prototype.readString called on incompatible object, got <<error converting value to string>>"); + assertTypeErrorMessage(() => { o.readStringReplaceMalformed(); }, + "CData.prototype.readStringReplaceMalformed called on incompatible object, got <<error converting value to string>>"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-ctype.js b/js/src/jit-test/tests/ctypes/incompatible-ctype.js new file mode 100644 index 000000000..ad7516714 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-ctype.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t.toString.call(1); }, + "CType.prototype.toString called on incompatible Number"); + assertTypeErrorMessage(() => { ctypes.int32_t.toSource.call(1); }, + "CType.prototype.toSource called on incompatible Number"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-finalizer.js b/js/src/jit-test/tests/ctypes/incompatible-finalizer.js new file mode 100644 index 000000000..11e95886a --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-finalizer.js @@ -0,0 +1,24 @@ +load(libdir + 'asserts.js'); + +function test() { + let fin = ctypes.CDataFinalizer(ctypes.int32_t(0), ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.int32_t]).ptr(x => x)); + assertTypeErrorMessage(() => { fin.toSource.call(1); }, + "CDataFinalizer.prototype.toSource called on incompatible Number"); + assertTypeErrorMessage(() => { fin.toString.call(1); }, + "CDataFinalizer.prototype.toString called on incompatible Number"); + assertTypeErrorMessage(() => { fin.forget.call(1); }, + "CDataFinalizer.prototype.forget called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { fin.dispose.call(1); }, + "CDataFinalizer.prototype.dispose called on incompatible object, got the object (new Number(1))"); + fin.forget(); + + assertTypeErrorMessage(() => { fin.readString(); }, + "CDataFinalizer.prototype.readString called on empty CDataFinalizer"); + assertTypeErrorMessage(() => { fin.dispose(); }, + "CDataFinalizer.prototype.dispose called on empty CDataFinalizer"); + assertTypeErrorMessage(() => { fin.forget(); }, + "CDataFinalizer.prototype.forget called on empty CDataFinalizer"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-function.js b/js/src/jit-test/tests/ctypes/incompatible-function.js new file mode 100644 index 000000000..cd31cc5e7 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-function.js @@ -0,0 +1,13 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t).call.call(1); }, + "Function.prototype.call called on incompatible number"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t).call.call(ctypes.int32_t(0)); }, + "FunctionType.prototype.call called on non-PointerType CData, got ctypes.int32_t(0)"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t).call.call(ctypes.int32_t.ptr(0)); }, + "FunctionType.prototype.call called on non-FunctionType pointer, got ctypes.int32_t.ptr(ctypes.UInt64(\"0x0\"))"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-int64.js b/js/src/jit-test/tests/ctypes/incompatible-int64.js new file mode 100644 index 000000000..3d53efba6 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-int64.js @@ -0,0 +1,24 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.Int64(0).toString.call(1); }, + "Int64.prototype.toString called on incompatible Number"); + assertTypeErrorMessage(() => { ctypes.Int64(0).toString.call(ctypes.int32_t(0)); }, + "Int64.prototype.toString called on non-Int64 CData"); + assertTypeErrorMessage(() => { ctypes.Int64(0).toSource.call(1); }, + "Int64.prototype.toSource called on incompatible Number"); + assertTypeErrorMessage(() => { ctypes.Int64(0).toSource.call(ctypes.int32_t(0)); }, + "Int64.prototype.toSource called on non-Int64 CData"); + + assertTypeErrorMessage(() => { ctypes.UInt64(0).toString.call(1); }, + "UInt64.prototype.toString called on incompatible Number"); + assertTypeErrorMessage(() => { ctypes.UInt64(0).toString.call(ctypes.int32_t(0)); }, + "UInt64.prototype.toString called on non-UInt64 CData"); + assertTypeErrorMessage(() => { ctypes.UInt64(0).toSource.call(1); }, + "UInt64.prototype.toSource called on incompatible Number"); + assertTypeErrorMessage(() => { ctypes.UInt64(0).toSource.call(ctypes.int32_t(0)); }, + "UInt64.prototype.toSource called on non-UInt64 CData"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-pointer.js b/js/src/jit-test/tests/ctypes/incompatible-pointer.js new file mode 100644 index 000000000..bfacbd852 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-pointer.js @@ -0,0 +1,19 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(0).isNull.call(1); }, + "PointerType.prototype.isNull called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(0).isNull.call({}); }, + "PointerType.prototype.isNull called on incompatible object, got the object ({})"); + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(0).increment.call(1); }, + "PointerType.prototype.increment called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(0).increment.call(ctypes.int32_t(0)); }, + "PointerType.prototype.increment called on non-PointerType CData, got ctypes.int32_t(0)"); + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(0).decrement.call(1); }, + "PointerType.prototype.decrement called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(0).decrement.call(ctypes.int32_t(0)); }, + "PointerType.prototype.decrement called on non-PointerType CData, got ctypes.int32_t(0)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/incompatible-struct.js b/js/src/jit-test/tests/ctypes/incompatible-struct.js new file mode 100644 index 000000000..8bb0a2cd6 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/incompatible-struct.js @@ -0,0 +1,31 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.StructType("a").define.call(1); }, + "StructType.prototype.define called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.StructType("a").define.call(ctypes.int32_t); }, + "StructType.prototype.define called on non-StructType, got ctypes.int32_t"); + + let p = Object.getPrototypeOf(ctypes.StructType("a", [ { "x": ctypes.int32_t, } ])()); + let o = {}; + Object.setPrototypeOf(o, p); + assertTypeErrorMessage(() => { let a = o.x; }, + "StructType property getter called on incompatible object, got <<error converting value to string>>"); + assertTypeErrorMessage(() => { o.x = 1; }, + "StructType property setter called on incompatible object, got <<error converting value to string>>"); + + o = ctypes.int32_t(0); + Object.setPrototypeOf(o, p); + assertTypeErrorMessage(() => { let a = o.x; }, + "StructType property getter called on non-StructType CData, got ctypes.int32_t(0)"); + assertTypeErrorMessage(() => { o.x = 1; }, + "StructType property setter called on non-StructType CData, got ctypes.int32_t(0)"); + + assertTypeErrorMessage(() => { ctypes.StructType("a", [])().addressOfField.call(1); }, + "StructType.prototype.addressOfField called on incompatible object, got the object (new Number(1))"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [])().addressOfField.call(ctypes.int32_t(0)); }, + "StructType.prototype.addressOfField called on non-StructType CData, got ctypes.int32_t(0)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/pointer.js b/js/src/jit-test/tests/ctypes/pointer.js new file mode 100644 index 000000000..da0685f07 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/pointer.js @@ -0,0 +1,31 @@ +load(libdir + 'asserts.js'); + +function test() { + let p = ctypes.StructType("foo").ptr(0); + + assertTypeErrorMessage(() => { p.increment(); }, + "cannot modify pointer of undefined size foo.ptr(ctypes.UInt64(\"0x0\"))"); + assertTypeErrorMessage(() => { p.decrement(); }, + "cannot modify pointer of undefined size foo.ptr(ctypes.UInt64(\"0x0\"))"); + + assertTypeErrorMessage(() => { let a = p.contents; }, + "cannot get contents of pointer of undefined size foo.ptr(ctypes.UInt64(\"0x0\"))"); + assertTypeErrorMessage(() => { p.contents = 1; }, + "cannot set contents of pointer of undefined size foo.ptr(ctypes.UInt64(\"0x0\"))"); + + let p2 = ctypes.int32_t.ptr(0); + assertTypeErrorMessage(() => { let a = p2.contents; }, + "cannot read contents of null pointer ctypes.int32_t.ptr(ctypes.UInt64(\"0x0\"))"); + assertTypeErrorMessage(() => { p2.contents = 1; }, + "cannot write contents to null pointer ctypes.int32_t.ptr(ctypes.UInt64(\"0x0\"))"); + assertTypeErrorMessage(() => { p2.readString(); }, + "cannot read contents of null pointer ctypes.int32_t.ptr(ctypes.UInt64(\"0x0\"))"); + + assertTypeErrorMessage(() => { ctypes.int32_t(0).readString(); }, + "expected PointerType or ArrayType, got ctypes.int32_t(0)"); + assertTypeErrorMessage(() => { ctypes.int32_t(0).address().readString(); }, + /base type ctypes\.int32_t\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\) is not an 8-bit or 16-bit integer or character type/); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/size-overflow-array.js b/js/src/jit-test/tests/ctypes/size-overflow-array.js new file mode 100644 index 000000000..290046a6e --- /dev/null +++ b/js/src/jit-test/tests/ctypes/size-overflow-array.js @@ -0,0 +1,18 @@ +load(libdir + 'asserts.js'); + +function test() { + if (getBuildConfiguration()["pointer-byte-size"] == 4) { + let big_array = ctypes.int32_t.array(0xfffffff); + assertRangeErrorMessage(() => { big_array.array(0xfffffff); }, + "array size does not fit in size_t"); + } else if (getBuildConfiguration()["pointer-byte-size"] == 8) { + let big_array = ctypes.int32_t.array(0xfffffff); + assertRangeErrorMessage(() => { big_array.array(0xfffffff); }, + "array size does not fit in JavaScript number"); + assertRangeErrorMessage(() => { big_array.array(0xfffffffff); }, + "array size does not fit in size_t"); + } +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/size-overflow-struct.js b/js/src/jit-test/tests/ctypes/size-overflow-struct.js new file mode 100644 index 000000000..a40f925a7 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/size-overflow-struct.js @@ -0,0 +1,24 @@ +load(libdir + 'asserts.js'); + +function test() { + if (getBuildConfiguration()["pointer-byte-size"] == 4) { + let big_array = ctypes.int32_t.array(0xfffffff); + assertRangeErrorMessage(() => { ctypes.StructType("x", [{a: big_array}, + {b: big_array}, + {c: big_array}, + {d: big_array}, + {e: big_array}]); }, + "struct size does not fit in size_t"); + } else if (getBuildConfiguration()["pointer-byte-size"] == 8) { + let big_array = ctypes.int32_t.array(0xfffffffffffffff); + assertRangeErrorMessage(() => { ctypes.StructType("x", [{a: big_array}, + {b: big_array}, + {c: big_array}, + {d: big_array}, + {e: big_array}]); }, + "struct size does not fit in size_t"); + } +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/struct-field.js b/js/src/jit-test/tests/ctypes/struct-field.js new file mode 100644 index 000000000..2b2089e43 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/struct-field.js @@ -0,0 +1,21 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.StructType("a", [ 1 ]); }, + "struct field descriptors require a valid name and type (got the number 1)"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ { x: 1, y: 2 } ]); }, + "struct field descriptors must contain one property (got the object ({x:1, y:2}) with 2 properties)"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ { 1: 1 } ]); }, + "the number 1 is not a valid name of struct field descriptors"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ { "x": 1 } ]); }, + "the number 1 is not a valid type of struct field descriptors for 'x' field"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ { "x": ctypes.StructType("b") } ]); }, + "struct field type must have defined and nonzero size (got ctypes.StructType(\"b\") for 'x' field)"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ { "x": ctypes.int32_t, }, { "x": ctypes.int32_t } ]); }, + "struct fields must have unique names, 'x' field appears twice"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ { "x": ctypes.int32_t, } ])().addressOfField("z"); }, + "ctypes.StructType(\"a\", [{ \"x\": ctypes.int32_t }]) does not have a field named 'z'"); +} + +if (typeof ctypes === "object") + test(); |