зеркало из https://github.com/mozilla/gecko-dev.git
Bug 891107 - Part 11: Show information about type in cast error messages in js-ctypes. r=jorendorff
This commit is contained in:
Родитель
f7870cdfc9
Коммит
0dd2a12852
|
@ -1827,6 +1827,55 @@ TypeOverflow(JSContext* cx, const char* expected, HandleValue actual)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
UndefinedSizeCastError(JSContext* cx, HandleObject targetTypeObj)
|
||||
{
|
||||
AutoString targetTypeSource;
|
||||
JSAutoByteString targetTypeBytes;
|
||||
BuildTypeSource(cx, targetTypeObj, true, targetTypeSource);
|
||||
const char* targetTypeStr = EncodeLatin1(cx, targetTypeSource,
|
||||
targetTypeBytes);
|
||||
if (!targetTypeStr)
|
||||
return false;
|
||||
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
|
||||
CTYPESMSG_UNDEFINED_SIZE_CAST, targetTypeStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
SizeMismatchCastError(JSContext* cx,
|
||||
HandleObject sourceTypeObj, HandleObject targetTypeObj,
|
||||
size_t sourceSize, size_t targetSize)
|
||||
{
|
||||
AutoString sourceTypeSource;
|
||||
JSAutoByteString sourceTypeBytes;
|
||||
BuildTypeSource(cx, sourceTypeObj, true, sourceTypeSource);
|
||||
const char* sourceTypeStr = EncodeLatin1(cx, sourceTypeSource,
|
||||
sourceTypeBytes);
|
||||
if (!sourceTypeStr)
|
||||
return false;
|
||||
|
||||
AutoString targetTypeSource;
|
||||
JSAutoByteString targetTypeBytes;
|
||||
BuildTypeSource(cx, targetTypeObj, true, targetTypeSource);
|
||||
const char* targetTypeStr = EncodeLatin1(cx, targetTypeSource,
|
||||
targetTypeBytes);
|
||||
if (!targetTypeStr)
|
||||
return false;
|
||||
|
||||
char sourceSizeStr[16];
|
||||
char targetSizeStr[16];
|
||||
JS_snprintf(sourceSizeStr, 16, "%u", sourceSize);
|
||||
JS_snprintf(targetSizeStr, 16, "%u", targetSize);
|
||||
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
|
||||
CTYPESMSG_SIZE_MISMATCH_CAST,
|
||||
targetTypeStr, sourceTypeStr,
|
||||
targetSizeStr, sourceSizeStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
UndefinedSizePointerError(JSContext* cx, const char* action, HandleObject obj)
|
||||
{
|
||||
|
@ -7667,7 +7716,7 @@ CData::Cast(JSContext* cx, unsigned argc, Value* vp)
|
|||
return ArgumentTypeMismatch(cx, "first ", "ctypes.cast", "a CData");
|
||||
}
|
||||
RootedObject sourceData(cx, &args[0].toObject());
|
||||
JSObject* sourceType = CData::GetCType(sourceData);
|
||||
RootedObject sourceType(cx, CData::GetCType(sourceData));
|
||||
|
||||
if (args[1].isPrimitive() || !CType::IsCType(&args[1].toObject())) {
|
||||
return ArgumentTypeMismatch(cx, "second ", "ctypes.cast", "a CType");
|
||||
|
@ -7675,11 +7724,12 @@ CData::Cast(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
RootedObject targetType(cx, &args[1].toObject());
|
||||
size_t targetSize;
|
||||
if (!CType::GetSafeSize(targetType, &targetSize) ||
|
||||
targetSize > CType::GetSize(sourceType)) {
|
||||
JS_ReportError(cx,
|
||||
"target CType has undefined or larger size than source CType");
|
||||
return false;
|
||||
if (!CType::GetSafeSize(targetType, &targetSize)) {
|
||||
return UndefinedSizeCastError(cx, targetType);
|
||||
}
|
||||
if (targetSize > CType::GetSize(sourceType)) {
|
||||
return SizeMismatchCastError(cx, sourceType, targetType,
|
||||
CType::GetSize(sourceType), targetSize);
|
||||
}
|
||||
|
||||
// Construct a new CData object with a type of 'targetType' and a referent
|
||||
|
|
|
@ -70,3 +70,7 @@ MSG_DEF(CTYPESMSG_CANNOT_CONSTRUCT,1, JSEXN_TYPEERR, "cannot construct from {0}"
|
|||
MSG_DEF(CTYPESMSG_UNDEFINED_SIZE,2, JSEXN_TYPEERR, "cannot {0} pointer of undefined size {1}")
|
||||
MSG_DEF(CTYPESMSG_NULL_POINTER, 2, JSEXN_TYPEERR, "cannot {0} null pointer {1}")
|
||||
MSG_DEF(CTYPESMSG_NON_STRING_BASE,1, JSEXN_TYPEERR, "base type {0} is not an 8-bit or 16-bit integer or character type")
|
||||
|
||||
/* cast */
|
||||
MSG_DEF(CTYPESMSG_UNDEFINED_SIZE_CAST,1, JSEXN_TYPEERR, "target type {0} has undefined size")
|
||||
MSG_DEF(CTYPESMSG_SIZE_MISMATCH_CAST,4, JSEXN_TYPEERR, "target type {0} has larger size than source type {1} ({2} > {3})")
|
||||
|
|
|
@ -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();
|
|
@ -2204,9 +2204,9 @@ function run_cast_tests() {
|
|||
do_check_eq(i.value, k.value);
|
||||
|
||||
// Test casting to a type of undefined or larger size.
|
||||
do_check_throws(function() { ctypes.cast(i, ctypes.void_t); }, Error);
|
||||
do_check_throws(function() { ctypes.cast(i, ctypes.int32_t.array()); }, Error);
|
||||
do_check_throws(function() { ctypes.cast(i, ctypes.int64_t); }, Error);
|
||||
do_check_throws(function() { ctypes.cast(i, ctypes.void_t); }, TypeError);
|
||||
do_check_throws(function() { ctypes.cast(i, ctypes.int32_t.array()); }, TypeError);
|
||||
do_check_throws(function() { ctypes.cast(i, ctypes.int64_t); }, TypeError);
|
||||
|
||||
// Test casting between special types.
|
||||
let g_t = ctypes.StructType("g_t", [{ a: ctypes.int32_t }, { b: ctypes.double }]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче