diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 26099d91916..2fe4187fbfb 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -32,7 +32,6 @@ #endif #include "jscntxt.h" -#include "jsexn.h" #include "jsfun.h" #include "jsnum.h" #include "jsprf.h" @@ -41,8 +40,6 @@ #include "ctypes/Library.h" #include "gc/Zone.h" -#include "jsatominlines.h" - using namespace std; using mozilla::NumericLimits; @@ -879,567 +876,21 @@ GetErrorMessage(void* userRef, const unsigned errorNumber) return nullptr; } -static const char* -EncodeLatin1(JSContext* cx, AutoString& str, JSAutoByteString& bytes) -{ - return bytes.encodeLatin1(cx, NewUCString(cx, str)); -} - -static const char* -CTypesToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes) -{ - if (val.isObject() && - (CType::IsCType(&val.toObject()) || CData::IsCData(&val.toObject()))) { - RootedString str(cx, JS_ValueToSource(cx, val)); - return bytes.encodeLatin1(cx, str); - } - return ValueToSourceForError(cx, val, bytes); -} - -static void -BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj, - HandleString nameStr, unsigned ptrCount, - AutoString& source); - -static void -BuildCStyleTypeSource(JSContext* cx, JSObject* typeObj_, AutoString& source) -{ - RootedObject typeObj(cx, typeObj_); - - MOZ_ASSERT(CType::IsCType(typeObj)); - - switch (CType::GetTypeCode(typeObj)) { -#define BUILD_SOURCE(name, fromType, ffiType) \ - case TYPE_##name: \ - AppendString(source, #name); \ - break; - CTYPES_FOR_EACH_TYPE(BUILD_SOURCE) -#undef BUILD_SOURCE - case TYPE_void_t: - AppendString(source, "void"); - break; - case TYPE_pointer: { - unsigned ptrCount = 0; - TypeCode type; - RootedObject baseTypeObj(cx, typeObj); - do { - baseTypeObj = PointerType::GetBaseType(baseTypeObj); - ptrCount++; - type = CType::GetTypeCode(baseTypeObj); - } while (type == TYPE_pointer || type == TYPE_array); - if (type == TYPE_function) { - BuildCStyleFunctionTypeSource(cx, baseTypeObj, NullPtr(), ptrCount, - source); - break; - } - BuildCStyleTypeSource(cx, baseTypeObj, source); - AppendChars(source, '*', ptrCount); - break; - } - case TYPE_struct: { - RootedString name(cx, CType::GetName(cx, typeObj)); - AppendString(source, "struct "); - AppendString(source, name); - break; - } - case TYPE_function: - BuildCStyleFunctionTypeSource(cx, typeObj, NullPtr(), 0, source); - break; - case TYPE_array: - MOZ_CRASH("TYPE_array shouldn't appear in function type"); - } -} - -static void -BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj, - HandleString nameStr, unsigned ptrCount, - AutoString& source) -{ - MOZ_ASSERT(CType::IsCType(typeObj)); - - FunctionInfo* fninfo = FunctionType::GetFunctionInfo(typeObj); - BuildCStyleTypeSource(cx, fninfo->mReturnType, source); - AppendString(source, " "); - if (nameStr) { - MOZ_ASSERT(ptrCount == 0); - AppendString(source, nameStr); - } else if (ptrCount) { - AppendString(source, "("); - AppendChars(source, '*', ptrCount); - AppendString(source, ")"); - } - AppendString(source, "("); - if (fninfo->mArgTypes.length() > 0) { - for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) { - BuildCStyleTypeSource(cx, fninfo->mArgTypes[i], source); - if (i != fninfo->mArgTypes.length() - 1 || fninfo->mIsVariadic) { - AppendString(source, ", "); - } - } - if (fninfo->mIsVariadic) { - AppendString(source, "..."); - } - } - AppendString(source, ")"); -} - -static void -BuildFunctionTypeSource(JSContext* cx, HandleObject funObj, AutoString& source) -{ - MOZ_ASSERT(CData::IsCData(funObj) || CType::IsCType(funObj)); - - if (CData::IsCData(funObj)) { - jsval slot = JS_GetReservedSlot(funObj, SLOT_REFERENT); - if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) { - slot = JS_GetReservedSlot(funObj, SLOT_FUNNAME); - MOZ_ASSERT(!slot.isUndefined()); - RootedObject typeObj(cx, CData::GetCType(funObj)); - RootedObject baseTypeObj(cx, PointerType::GetBaseType(typeObj)); - RootedString nameStr(cx, slot.toString()); - BuildCStyleFunctionTypeSource(cx, baseTypeObj, nameStr, 0, source); - return; - } - } - - RootedValue funVal(cx, ObjectValue(*funObj)); - RootedString funcStr(cx, JS_ValueToSource(cx, funVal)); - if (!funcStr) { - JS_ClearPendingException(cx); - AppendString(source, "<>"); - return; - } - AppendString(source, funcStr); -} - -enum class ConversionType { - Argument = 0, - Construct, - Finalizer, - Return, - Setter -}; - -static void -BuildConversionPosition(JSContext* cx, ConversionType convType, - HandleObject funObj, unsigned argIndex, - AutoString& source) -{ - switch (convType) { - case ConversionType::Argument: { - MOZ_ASSERT(funObj); - - AppendString(source, " at argument "); - AppendUInt(source, argIndex + 1); - AppendString(source, " of "); - BuildFunctionTypeSource(cx, funObj, source); - break; - } - case ConversionType::Finalizer: - MOZ_ASSERT(funObj); - - AppendString(source, " at argument 1 of "); - BuildFunctionTypeSource(cx, funObj, source); - break; - case ConversionType::Return: - MOZ_ASSERT(funObj); - - AppendString(source, " at the return value of "); - BuildFunctionTypeSource(cx, funObj, source); - break; - default: - MOZ_ASSERT(!funObj); - break; - } -} - -static JSFlatString* -GetFieldName(HandleObject structObj, unsigned fieldIndex) -{ - const FieldInfoHash* fields = StructType::GetFieldInfo(structObj); - for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) { - if (r.front().value().mIndex == fieldIndex) { - return (&r.front())->key(); - } - } - return nullptr; -} - -static void -BuildTypeSource(JSContext* cx, JSObject* typeObj_, bool makeShort, - AutoString& result); - -static bool -ConvError(JSContext* cx, const char* expectedStr, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0, - HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) -{ - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - if (arrObj) { - MOZ_ASSERT(CType::IsCType(arrObj)); - - switch (CType::GetTypeCode(arrObj)) { - case TYPE_array: { - MOZ_ASSERT(!funObj); - - char indexStr[16]; - JS_snprintf(indexStr, 16, "%u", arrIndex); - - AutoString arrSource; - JSAutoByteString arrBytes; - BuildTypeSource(cx, arrObj, true, arrSource); - const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); - if (!arrStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_ARRAY, - valStr, indexStr, arrStr); - break; - } - case TYPE_struct: { - JSFlatString* name = GetFieldName(arrObj, arrIndex); - MOZ_ASSERT(name); - JSAutoByteString nameBytes; - const char* nameStr = nameBytes.encodeLatin1(cx, name); - if (!nameStr) - return false; - - AutoString structSource; - JSAutoByteString structBytes; - BuildTypeSource(cx, arrObj, true, structSource); - const char* structStr = EncodeLatin1(cx, structSource, structBytes); - if (!structStr) - return false; - - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_STRUCT, - valStr, nameStr, expectedStr, structStr, posStr); - break; - } - default: - MOZ_CRASH("invalid arrObj value"); - } - return false; - } - - switch (convType) { - case ConversionType::Argument: { - MOZ_ASSERT(funObj); - - char indexStr[16]; - JS_snprintf(indexStr, 16, "%u", argIndex + 1); - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_ARG, - valStr, indexStr, funStr); - break; - } - case ConversionType::Finalizer: { - MOZ_ASSERT(funObj); - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_FIN, valStr, funStr); - break; - } - case ConversionType::Return: { - MOZ_ASSERT(funObj); - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_RET, valStr, funStr); - break; - } - case ConversionType::Setter: - case ConversionType::Construct: - MOZ_ASSERT(!funObj); - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_SET, valStr, expectedStr); - break; - } - - return false; -} - -static bool -ConvError(JSContext* cx, HandleObject expectedType, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0, - HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) -{ - MOZ_ASSERT(CType::IsCType(expectedType)); - - AutoString expectedSource; - JSAutoByteString expectedBytes; - BuildTypeSource(cx, expectedType, true, expectedSource); - const char* expectedStr = EncodeLatin1(cx, expectedSource, expectedBytes); - if (!expectedStr) - return false; - - return ConvError(cx, expectedStr, actual, convType, funObj, argIndex, - arrObj, arrIndex); -} - -static bool -ArgumentConvError(JSContext* cx, HandleValue actual, const char* funStr, - unsigned argIndex) -{ - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - char indexStr[16]; - JS_snprintf(indexStr, 16, "%u", argIndex + 1); - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_ARG, valStr, indexStr, funStr); - return false; -} - -static bool -ArrayLengthMismatch(JSContext* cx, unsigned expectedLength, HandleObject arrObj, - unsigned actualLength, HandleValue actual, - ConversionType convType) -{ - MOZ_ASSERT(arrObj && CType::IsCType(arrObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - char expectedLengthStr[16]; - JS_snprintf(expectedLengthStr, 16, "%u", expectedLength); - char actualLengthStr[16]; - JS_snprintf(actualLengthStr, 16, "%u", actualLength); - - AutoString arrSource; - JSAutoByteString arrBytes; - BuildTypeSource(cx, arrObj, true, arrSource); - const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); - if (!arrStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_ARRAY_MISMATCH, - valStr, arrStr, expectedLengthStr, actualLengthStr); - return false; -} - -static bool -ArrayLengthOverflow(JSContext* cx, unsigned expectedLength, HandleObject arrObj, - unsigned actualLength, HandleValue actual, - ConversionType convType) -{ - MOZ_ASSERT(arrObj && CType::IsCType(arrObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - char expectedLengthStr[16]; - JS_snprintf(expectedLengthStr, 16, "%u", expectedLength); - char actualLengthStr[16]; - JS_snprintf(actualLengthStr, 16, "%u", actualLength); - - AutoString arrSource; - JSAutoByteString arrBytes; - BuildTypeSource(cx, arrObj, true, arrSource); - const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); - if (!arrStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_ARRAY_OVERFLOW, - valStr, arrStr, expectedLengthStr, actualLengthStr); - return false; -} - -static bool -EmptyFinalizerError(JSContext* cx, ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0) -{ - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_EMPTY_FIN, posStr); - return false; -} - -static bool -FieldCountMismatch(JSContext* cx, - unsigned expectedCount, HandleObject structObj, - unsigned actualCount, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0) -{ - MOZ_ASSERT(structObj && CType::IsCType(structObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - AutoString structSource; - JSAutoByteString structBytes; - BuildTypeSource(cx, structObj, true, structSource); - const char* structStr = EncodeLatin1(cx, structSource, structBytes); - if (!structStr) - return false; - - char expectedCountStr[16]; - JS_snprintf(expectedCountStr, 16, "%u", expectedCount); - char actualCountStr[16]; - JS_snprintf(actualCountStr, 16, "%u", actualCount); - - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_FIELD_MISMATCH, - valStr, structStr, expectedCountStr, actualCountStr, - posStr); - return false; -} - -static bool -FinalizerSizeError(JSContext* cx, HandleObject funObj, HandleValue actual) -{ - MOZ_ASSERT(CType::IsCType(funObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_FIN_SIZE_ERROR, funStr, valStr); - return false; -} - -static bool -NonPrimitiveError(JSContext* cx, HandleObject typeObj) -{ - MOZ_ASSERT(CType::IsCType(typeObj)); - - AutoString typeSource; - JSAutoByteString typeBytes; - BuildTypeSource(cx, typeObj, true, typeSource); - const char* typeStr = EncodeLatin1(cx, typeSource, typeBytes); - if (!typeStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_NON_PRIMITIVE, typeStr); - return false; -} - -static bool -PropNameNonStringError(JSContext* cx, HandleId id, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0) -{ - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - JSAutoByteString idBytes; - RootedValue idVal(cx, IdToValue(id)); - const char* propStr = CTypesToSourceForError(cx, idVal, idBytes); - if (!propStr) - return false; - - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_PROP_NONSTRING, propStr, valStr, posStr); - return false; -} - static bool TypeError(JSContext* cx, const char* expected, HandleValue actual) { + JSString* str = JS_ValueToSource(cx, actual); JSAutoByteString bytes; - const char* src = CTypesToSourceForError(cx, actual, bytes); - if (!src) - return false; + const char* src; + if (str) { + src = bytes.encodeLatin1(cx, str); + if (!src) + return false; + } else { + JS_ClearPendingException(cx); + src = "<>"; + } JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, CTYPESMSG_TYPE_ERROR, expected, src); return false; @@ -2759,7 +2210,8 @@ ConvertToJS(JSContext* cx, // We're about to create a new CData object to return. If the caller doesn't // want this, return early. if (wantPrimitive) { - return NonPrimitiveError(cx, typeObj); + JS_ReportError(cx, "cannot convert to primitive value"); + return false; } JSObject* obj = CData::Create(cx, typeObj, parentObj, data, ownResult); @@ -2824,20 +2276,18 @@ bool CanConvertTypedArrayItemTo(JSObject* baseType, JSObject* valObj, JSContext* // coercion between types. There are two cases in which this function is used: // 1) The target buffer is internal to a CData object; we simply write data // into it. -// 2) We are converting an argument for an ffi call, in which case 'convType' -// will be 'ConversionType::Argument'. This allows us to handle a special -// case: if necessary, we can autoconvert a JS string primitive to a -// pointer-to-character type. In this case, ownership of the allocated string -// is handed off to the caller; 'freePointer' will be set to indicate this. +// 2) We are converting an argument for an ffi call, in which case 'isArgument' +// will be true. This allows us to handle a special case: if necessary, +// we can autoconvert a JS string primitive to a pointer-to-character type. +// In this case, ownership of the allocated string is handed off to the +// caller; 'freePointer' will be set to indicate this. static bool ImplicitConvert(JSContext* cx, HandleValue val, JSObject* targetType_, void* buffer, - ConversionType convType, - bool* freePointer, - HandleObject funObj = NullPtr(), unsigned argIndex = 0, - HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) + bool isArgument, + bool* freePointer) { RootedObject targetType(cx, targetType_); MOZ_ASSERT(CType::IsSizeDefined(targetType)); @@ -2869,7 +2319,8 @@ ImplicitConvert(JSContext* cx, if (!p) { // We have called |dispose| or |forget| already. - return EmptyFinalizerError(cx, convType, funObj, argIndex); + JS_ReportError(cx, "Attempting to convert an empty CDataFinalizer"); + return false; } // If the types are equal, copy the buffer contained within the CData. @@ -2888,8 +2339,7 @@ ImplicitConvert(JSContext* cx, // Programs can convert explicitly, if needed, using `Boolean(v)` or `!!v`. bool result; if (!jsvalToBool(cx, val, &result)) - return ConvError(cx, "boolean", val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "boolean", val); *static_cast(buffer) = result; break; } @@ -2901,15 +2351,13 @@ ImplicitConvert(JSContext* cx, if (val.isString()) { \ JSString* str = val.toString(); \ if (str->length() != 1) \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ JSLinearString* linear = str->ensureLinear(cx); \ if (!linear) \ return false; \ result = linear->latin1OrTwoByteChar(0); \ } else if (!jsvalToInteger(cx, val, &result)) { \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ } \ *static_cast(buffer) = result; \ break; \ @@ -2921,8 +2369,7 @@ ImplicitConvert(JSContext* cx, /* Do not implicitly lose bits. */ \ type result; \ if (!jsvalToInteger(cx, val, &result)) \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ *static_cast(buffer) = result; \ break; \ } @@ -2938,8 +2385,7 @@ ImplicitConvert(JSContext* cx, case TYPE_##name: { \ type result; \ if (!jsvalToFloat(cx, val, &result)) \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ *static_cast(buffer) = result; \ break; \ } @@ -2974,7 +2420,7 @@ ImplicitConvert(JSContext* cx, } } - } else if (convType == ConversionType::Argument && val.isString()) { + } else if (isArgument && val.isString()) { // Convert the string for the ffi call. This requires allocating space // which the caller assumes ownership of. // TODO: Extend this so we can safely convert strings at other times also. @@ -3028,8 +2474,7 @@ ImplicitConvert(JSContext* cx, break; } default: - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "string pointer", val); } break; } else if (val.isObject() && JS_IsArrayBufferObject(valObj)) { @@ -3037,9 +2482,8 @@ ImplicitConvert(JSContext* cx, // when converting an argument to a function call, as it is possible for // the pointer to be invalidated by anything that runs JS code. (It is // invalid to invoke JS code from a ctypes function call.) - if (convType != ConversionType::Argument) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + if (!isArgument) { + return TypeError(cx, "arraybuffer pointer", val); } void* ptr; { @@ -3047,8 +2491,7 @@ ImplicitConvert(JSContext* cx, ptr = JS_GetArrayBufferData(valObj, nogc); } if (!ptr) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "arraybuffer pointer", val); } *static_cast(buffer) = ptr; break; @@ -3056,12 +2499,10 @@ ImplicitConvert(JSContext* cx, // Same as ArrayBuffer, above, though note that this will take the // offset of the view into account. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "typed array with the appropriate type", val); } - if (convType != ConversionType::Argument) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + if (!isArgument) { + return TypeError(cx, "typed array pointer", val); } void* ptr; { @@ -3069,18 +2510,14 @@ ImplicitConvert(JSContext* cx, ptr = JS_GetArrayBufferViewData(valObj, nogc); } if (!ptr) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "typed array pointer", val); } *static_cast(buffer) = ptr; break; } - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "pointer", val); } case TYPE_array: { - MOZ_ASSERT(!funObj); - RootedObject baseType(cx, ArrayType::GetBaseType(targetType)); size_t targetLength = ArrayType::GetLength(targetType); @@ -3102,9 +2539,8 @@ ImplicitConvert(JSContext* cx, return false; if (targetLength < nbytes) { - MOZ_ASSERT(!funObj); - return ArrayLengthOverflow(cx, targetLength, targetType, nbytes, val, - convType); + JS_ReportError(cx, "ArrayType has insufficient length"); + return false; } char* charBuffer = static_cast(buffer); @@ -3120,9 +2556,8 @@ ImplicitConvert(JSContext* cx, // Copy the string data, char16_t for char16_t, including the terminator // if there's space. if (targetLength < sourceLength) { - MOZ_ASSERT(!funObj); - return ArrayLengthOverflow(cx, targetLength, targetType, - sourceLength, val, convType); + JS_ReportError(cx, "ArrayType has insufficient length"); + return false; } char16_t* dest = static_cast(buffer); @@ -3140,8 +2575,7 @@ ImplicitConvert(JSContext* cx, break; } default: - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "array", val); } } else if (val.isObject() && JS_IsArrayObject(cx, valObj)) { @@ -3149,9 +2583,8 @@ ImplicitConvert(JSContext* cx, uint32_t sourceLength; if (!JS_GetArrayLength(cx, valObj, &sourceLength) || targetLength != size_t(sourceLength)) { - MOZ_ASSERT(!funObj); - return ArrayLengthMismatch(cx, targetLength, targetType, - size_t(sourceLength), val, convType); + JS_ReportError(cx, "ArrayType length does not match source array length"); + return false; } // Convert into an intermediate, in case of failure. @@ -3169,8 +2602,7 @@ ImplicitConvert(JSContext* cx, return false; char* data = intermediate.get() + elementSize * i; - if (!ImplicitConvert(cx, item, baseType, data, convType, nullptr, - funObj, argIndex, targetType, i)) + if (!ImplicitConvert(cx, item, baseType, data, false, nullptr)) return false; } @@ -3183,9 +2615,8 @@ ImplicitConvert(JSContext* cx, size_t elementSize = CType::GetSize(baseType); size_t arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { - MOZ_ASSERT(!funObj); - return ArrayLengthMismatch(cx, arraySize, targetType, - size_t(sourceLength), val, convType); + JS_ReportError(cx, "ArrayType length does not match source ArrayBuffer length"); + return false; } JS::AutoCheckCannotGC nogc; memcpy(buffer, JS_GetArrayBufferData(valObj, nogc), sourceLength); @@ -3194,17 +2625,15 @@ ImplicitConvert(JSContext* cx, // Check that array is consistent with type, then // copy the array. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "typed array with the appropriate type", val); } uint32_t sourceLength = JS_GetTypedArrayByteLength(valObj); size_t elementSize = CType::GetSize(baseType); size_t arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { - MOZ_ASSERT(!funObj); - return ArrayLengthMismatch(cx, arraySize, targetType, - size_t(sourceLength), val, convType); + JS_ReportError(cx, "typed array length does not match source TypedArray length"); + return false; } JS::AutoCheckCannotGC nogc; memcpy(buffer, JS_GetArrayBufferViewData(valObj, nogc), sourceLength); @@ -3212,8 +2641,7 @@ ImplicitConvert(JSContext* cx, } else { // Don't implicitly convert to string. Users can implicitly convert // with `String(x)` or `""+x`. - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "array", val); } break; } @@ -3235,9 +2663,8 @@ ImplicitConvert(JSContext* cx, const FieldInfoHash* fields = StructType::GetFieldInfo(targetType); if (props.length() != fields->count()) { - return FieldCountMismatch(cx, fields->count(), targetType, - props.length(), val, convType, - funObj, argIndex); + JS_ReportError(cx, "missing fields"); + return false; } RootedId id(cx); @@ -3245,8 +2672,8 @@ ImplicitConvert(JSContext* cx, id = props[i]; if (!JSID_IS_STRING(id)) { - return PropNameNonStringError(cx, id, val, convType, - funObj, argIndex); + JS_ReportError(cx, "property name is not a string"); + return false; } JSFlatString* name = JSID_TO_FLAT_STRING(id); @@ -3260,8 +2687,7 @@ ImplicitConvert(JSContext* cx, // Convert the field via ImplicitConvert(). char* fieldData = intermediate.get() + field->mOffset; - if (!ImplicitConvert(cx, prop, field->mType, fieldData, convType, - nullptr, funObj, argIndex, targetType, i)) + if (!ImplicitConvert(cx, prop, field->mType, fieldData, false, nullptr)) return false; } @@ -3269,8 +2695,7 @@ ImplicitConvert(JSContext* cx, break; } - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "struct", val); } case TYPE_void_t: case TYPE_function: @@ -3284,11 +2709,10 @@ ImplicitConvert(JSContext* cx, // storing the result in 'buffer'. This function is more forceful than // ImplicitConvert. static bool -ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, - void* buffer, ConversionType convType) +ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, void* buffer) { // If ImplicitConvert succeeds, use that result. - if (ImplicitConvert(cx, val, targetType, buffer, convType, nullptr)) + if (ImplicitConvert(cx, val, targetType, buffer, false, nullptr)) return true; // If ImplicitConvert failed, and there is no pending exception, then assume @@ -3317,7 +2741,7 @@ ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, if (!jsvalToIntegerExplicit(val, &result) && \ (!val.isString() || \ !StringToInteger(cx, val.toString(), &result))) \ - return ConvError(cx, #name, val, convType); \ + return TypeError(cx, #name, val); \ *static_cast(buffer) = result; \ break; \ } @@ -3330,7 +2754,7 @@ ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, // Convert a number, Int64 object, or UInt64 object to a pointer. uintptr_t result; if (!jsvalToPtrExplicit(cx, val, &result)) - return ConvError(cx, targetType, val, convType); + return TypeError(cx, "pointer", val); *static_cast(buffer) = result; break; } @@ -3844,8 +3268,7 @@ CType::ConstructBasic(JSContext* cx, return false; if (args.length() == 1) { - if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result), - ConversionType::Construct)) + if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result))) return false; } @@ -4646,8 +4069,7 @@ PointerType::ConstructData(JSContext* cx, JS_ReportError(cx, "first argument must be a function"); return false; } - return ExplicitConvert(cx, args[0], obj, CData::GetData(result), - ConversionType::Construct); + return ExplicitConvert(cx, args[0], obj, CData::GetData(result)); } // @@ -4831,8 +4253,7 @@ PointerType::ContentsSetter(JSContext* cx, JS::CallArgs args) } args.rval().setUndefined(); - return ImplicitConvert(cx, args.get(0), baseType, data, - ConversionType::Setter, nullptr); + return ImplicitConvert(cx, args.get(0), baseType, data, false, nullptr); } /******************************************************************************* @@ -4999,7 +4420,7 @@ ArrayType::ConstructData(JSContext* cx, length = sourceLength + 1; break; default: - return ConvError(cx, obj, args[0], ConversionType::Construct); + return TypeError(cx, "array", args[0]); } } else { @@ -5020,8 +4441,7 @@ ArrayType::ConstructData(JSContext* cx, args.rval().setObject(*result); if (convertObject) { - if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result), - ConversionType::Construct)) + if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result))) return false; } @@ -5191,8 +4611,7 @@ ArrayType::Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle size_t length = GetLength(typeObj); bool ok = jsidToSize(cx, idval, true, &index); int32_t dummy; - if (!ok && JSID_IS_STRING(idval) && - !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { + if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { // String either isn't a number, or doesn't fit in size_t. // Chances are it's a regular property lookup, so return. return true; @@ -5220,7 +4639,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle // Bail early if we're not an ArrayType. (This setter is present for all // CData, regardless of CType.) - RootedObject typeObj(cx, CData::GetCType(obj)); + JSObject* typeObj = CData::GetCType(obj); if (CType::GetTypeCode(typeObj) != TYPE_array) return result.succeed(); @@ -5229,8 +4648,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle size_t length = GetLength(typeObj); bool ok = jsidToSize(cx, idval, true, &index); int32_t dummy; - if (!ok && JSID_IS_STRING(idval) && - !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { + if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { // String either isn't a number, or doesn't fit in size_t. // Chances are it's a regular property lookup, so return. return result.succeed(); @@ -5240,11 +4658,10 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle return false; } - RootedObject baseType(cx, GetBaseType(typeObj)); + JSObject* baseType = GetBaseType(typeObj); size_t elementSize = CType::GetSize(baseType); char* data = static_cast(CData::GetData(obj)) + elementSize * index; - if (!ImplicitConvert(cx, vp, baseType, data, ConversionType::Setter, - nullptr, NullPtr(), 0, typeObj, index)) + if (!ImplicitConvert(cx, vp, baseType, data, false, nullptr)) return false; return result.succeed(); } @@ -5739,7 +5156,7 @@ StructType::ConstructData(JSContext* cx, // are mutually exclusive, so we can pick the right one. // Try option 1) first. - if (ExplicitConvert(cx, args[0], obj, buffer, ConversionType::Construct)) + if (ExplicitConvert(cx, args[0], obj, buffer)) return true; if (fields->count() != 1) @@ -5764,8 +5181,8 @@ StructType::ConstructData(JSContext* cx, const FieldInfo& field = r.front().value(); STATIC_ASSUME(field.mIndex < fields->count()); /* Quantified invariant */ if (!ImplicitConvert(cx, args[field.mIndex], field.mType, - buffer + field.mOffset, ConversionType::Construct, - nullptr, NullPtr(), 0, obj, field.mIndex)) + buffer + field.mOffset, + false, nullptr)) return false; } @@ -5929,7 +5346,7 @@ StructType::FieldSetter(JSContext* cx, unsigned argc, Value* vp) return false; } - RootedObject typeObj(cx, CData::GetCType(obj)); + JSObject* typeObj = CData::GetCType(obj); if (CType::GetTypeCode(typeObj) != TYPE_struct) { JS_ReportError(cx, "not a StructType"); return false; @@ -5947,8 +5364,7 @@ StructType::FieldSetter(JSContext* cx, unsigned argc, Value* vp) args.rval().setUndefined(); char* data = static_cast(CData::GetData(obj)) + field->mOffset; - return ImplicitConvert(cx, args.get(0), field->mType, data, ConversionType::Setter, nullptr, - NullPtr(), 0, typeObj, field->mIndex); + return ImplicitConvert(cx, args.get(0), field->mType, data, false, nullptr); } bool @@ -6434,8 +5850,6 @@ typedef Array AutoValueAutoArray; static bool ConvertArgument(JSContext* cx, - HandleObject funObj, - unsigned argIndex, HandleValue arg, JSObject* type, AutoValue* value, @@ -6447,9 +5861,7 @@ ConvertArgument(JSContext* cx, } bool freePointer = false; - if (!ImplicitConvert(cx, arg, type, value->mData, - ConversionType::Argument, &freePointer, - funObj, argIndex)) + if (!ImplicitConvert(cx, arg, type, value->mData, true, &freePointer)) return false; if (freePointer) { @@ -6518,8 +5930,7 @@ FunctionType::Call(JSContext* cx, } for (unsigned i = 0; i < argcFixed; ++i) - if (!ConvertArgument(cx, obj, i, args[i], fninfo->mArgTypes[i], - &values[i], &strings)) + if (!ConvertArgument(cx, args[i], fninfo->mArgTypes[i], &values[i], &strings)) return false; if (fninfo->mIsVariadic) { @@ -6544,7 +5955,7 @@ FunctionType::Call(JSContext* cx, !(type = PrepareType(cx, OBJECT_TO_JSVAL(type))) || // Relying on ImplicitConvert only for the limited purpose of // converting one CType to another (e.g., T[] to T*). - !ConvertArgument(cx, obj, i, args[i], type, &values[i], &strings) || + !ConvertArgument(cx, args[i], type, &values[i], &strings) || !(fninfo->mFFITypes[i] = CType::GetFFIType(cx, type))) { // These functions report their own errors. return false; @@ -6770,8 +6181,7 @@ CClosure::Create(JSContext* cx, return nullptr; // Do the value conversion. This might fail, in which case we throw. - if (!ImplicitConvert(cx, errVal, fninfo->mReturnType, errResult.get(), - ConversionType::Return, nullptr, typeObj)) + if (!ImplicitConvert(cx, errVal, fninfo->mReturnType, errResult.get(), false, nullptr)) return nullptr; } @@ -6918,14 +6328,14 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData) RootedValue rval(cx); bool success = JS_CallFunctionValue(cx, thisObj, jsfnVal, argv, &rval); - // Convert the result. Note that we pass 'ConversionType::Return', such that + // Convert the result. Note that we pass 'isArgument = false', such that // ImplicitConvert will *not* autoconvert a JS string into a pointer-to-char // type, which would require an allocation that we can't track. The JS // function must perform this conversion itself and return a PointerType // CData; thusly, the burden of freeing the data is left to the user. if (success && cif->rtype != &ffi_type_void) - success = ImplicitConvert(cx, rval, fninfo->mReturnType, result, - ConversionType::Return, nullptr, typeObj); + success = ImplicitConvert(cx, rval, fninfo->mReturnType, result, false, + nullptr); if (!success) { // Something failed. The callee may have thrown, or it may not have @@ -7152,8 +6562,7 @@ CData::ValueSetter(JSContext* cx, JS::CallArgs args) { RootedObject obj(cx, &args.thisv().toObject()); args.rval().setUndefined(); - return ImplicitConvert(cx, args.get(0), GetCType(obj), GetData(obj), - ConversionType::Setter, nullptr); + return ImplicitConvert(cx, args.get(0), GetCType(obj), GetData(obj), false, nullptr); } bool @@ -7641,7 +7050,7 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) TypeCode typCodePtr = CType::GetTypeCode(objCodePtrType); if (typCodePtr != TYPE_pointer) { return TypeError(cx, "a CData object of a function _pointer_ type", - valCodePtr); + valCodePtrType); } JSObject* objCodeType = PointerType::GetBaseType(objCodePtrType); @@ -7650,12 +7059,12 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) TypeCode typCode = CType::GetTypeCode(objCodeType); if (typCode != TYPE_function) { return TypeError(cx, "a CData object of a _function_ pointer type", - valCodePtr); + valCodePtrType); } uintptr_t code = *reinterpret_cast(CData::GetData(objCodePtr)); if (!code) { return TypeError(cx, "a CData object of a _non-NULL_ function pointer type", - valCodePtr); + valCodePtrType); } FunctionInfo* funInfoFinalizer = @@ -7681,17 +7090,16 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) size_t sizeArg; RootedValue valData(cx, args[0]); if (!CType::GetSafeSize(objArgType, &sizeArg)) { - RootedValue valCodeType(cx, ObjectValue(*objCodeType)); - return TypeError(cx, "a function with one known size argument", - valCodeType); + return TypeError(cx, "(an object with known size)", valData); } ScopedJSFreePtr cargs(malloc(sizeArg)); if (!ImplicitConvert(cx, valData, objArgType, cargs.get(), - ConversionType::Finalizer, &freePointer, - objCodePtrType, 0)) { - return false; + false, &freePointer)) { + RootedValue valArgType(cx, ObjectValue(*objArgType)); + return TypeError(cx, "(an object that can be converted to the following type)", + valArgType); } if (freePointer) { // Note: We could handle that case, if necessary. @@ -7727,7 +7135,7 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) MOZ_CRASH("object with unknown size"); } if (sizeBestArg != sizeArg) { - return FinalizerSizeError(cx, objCodePtrType, valData); + return TypeError(cx, "(an object with the same size as that expected by the C finalization function)", valData); } } } @@ -7838,8 +7246,8 @@ CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval* vp) if (!obj) return false; if (!CDataFinalizer::IsCDataFinalizer(obj)) { - JS_ReportError(cx, "not a CDataFinalizer"); - return false; + RootedValue val(cx, ObjectValue(*obj)); + return TypeError(cx, "a CDataFinalizer", val); } CDataFinalizer::Private* p = (CDataFinalizer::Private*) @@ -7886,8 +7294,8 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval* vp) if (!obj) return false; if (!CDataFinalizer::IsCDataFinalizer(obj)) { - JS_ReportError(cx, "not a CDataFinalizer"); - return false; + RootedValue val(cx, ObjectValue(*obj)); + return TypeError(cx, "a CDataFinalizer", val); } CDataFinalizer::Private* p = (CDataFinalizer::Private*) @@ -8126,9 +7534,8 @@ Int64::Construct(JSContext* cx, } int64_t i = 0; - if (!jsvalToBigInteger(cx, args[0], true, &i)) { - return ArgumentConvError(cx, args[0], "Int64", 0); - } + if (!jsvalToBigInteger(cx, args[0], true, &i)) + return TypeError(cx, "int64", args[0]); // Get ctypes.Int64.prototype from the 'prototype' property of the ctor. RootedValue slot(cx); @@ -8262,9 +7669,9 @@ Int64::Join(JSContext* cx, unsigned argc, jsval* vp) int32_t hi; uint32_t lo; if (!jsvalToInteger(cx, args[0], &hi)) - return ArgumentConvError(cx, args[0], "Int64.join", 0); + return TypeError(cx, "int32", args[0]); if (!jsvalToInteger(cx, args[1], &lo)) - return ArgumentConvError(cx, args[1], "Int64.join", 1); + return TypeError(cx, "uint32", args[1]); int64_t i = (int64_t(hi) << 32) + int64_t(lo); @@ -8297,9 +7704,8 @@ UInt64::Construct(JSContext* cx, } uint64_t u = 0; - if (!jsvalToBigInteger(cx, args[0], true, &u)) { - return ArgumentConvError(cx, args[0], "UInt64", 0); - } + if (!jsvalToBigInteger(cx, args[0], true, &u)) + return TypeError(cx, "uint64", args[0]); // Get ctypes.UInt64.prototype from the 'prototype' property of the ctor. RootedValue slot(cx); @@ -8429,9 +7835,9 @@ UInt64::Join(JSContext* cx, unsigned argc, jsval* vp) uint32_t hi; uint32_t lo; if (!jsvalToInteger(cx, args[0], &hi)) - return ArgumentConvError(cx, args[0], "UInt64.join", 0); + return TypeError(cx, "uint32_t", args[0]); if (!jsvalToInteger(cx, args[1], &lo)) - return ArgumentConvError(cx, args[1], "UInt64.join", 1); + return TypeError(cx, "uint32_t", args[1]); uint64_t u = (uint64_t(hi) << 32) + uint64_t(lo); diff --git a/js/src/ctypes/CTypes.h b/js/src/ctypes/CTypes.h index 7c6c971e076..40e9fb0bbf4 100644 --- a/js/src/ctypes/CTypes.h +++ b/js/src/ctypes/CTypes.h @@ -10,7 +10,6 @@ #include "ffi.h" #include "jsalloc.h" -#include "jsprf.h" #include "prlink.h" #include "ctypes/typedefs.h" @@ -54,32 +53,6 @@ AppendString(Vector& v, const char (&array)[ArrayLength]) v[i + vlen] = array[i]; } -template -void -AppendChars(Vector& v, const char c, size_t count) -{ - size_t vlen = v.length(); - if (!v.resize(vlen + count)) - return; - - for (size_t i = 0; i < count; ++i) - v[i + vlen] = c; -} - -template -void -AppendUInt(Vector& v, unsigned n) -{ - char array[16]; - size_t alen = JS_snprintf(array, 16, "%u", n); - size_t vlen = v.length(); - if (!v.resize(vlen + alen)) - return; - - for (size_t i = 0; i < alen; ++i) - v[i + vlen] = array[i]; -} - template void AppendString(Vector& v, Vector& w) @@ -402,7 +375,6 @@ enum CDataSlot { SLOT_REFERENT = 1, // JSObject this object must keep alive, if any SLOT_DATA = 2, // pointer to a buffer containing the binary data SLOT_OWNS = 3, // JSVAL_TRUE if this CData owns its own buffer - SLOT_FUNNAME = 4, // JSString representing the function name CDATA_SLOTS }; diff --git a/js/src/ctypes/Library.cpp b/js/src/ctypes/Library.cpp index 688c8a03d83..80a2d2d7321 100644 --- a/js/src/ctypes/Library.cpp +++ b/js/src/ctypes/Library.cpp @@ -321,7 +321,7 @@ Library::Declare(JSContext* cx, unsigned argc, jsval* vp) void* data; PRFuncPtr fnptr; - RootedString nameStr(cx, args[0].toString()); + JSString* nameStr = args[0].toString(); AutoCString symbol; if (isFunction) { // Build the symbol, with mangling if necessary. @@ -352,9 +352,6 @@ Library::Declare(JSContext* cx, unsigned argc, jsval* vp) if (!result) return false; - if (isFunction) - JS_SetReservedSlot(result, SLOT_FUNNAME, StringValue(nameStr)); - args.rval().setObject(*result); // Seal the CData object, to prevent modification of the function pointer. diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg index aa1a709fe0f..7178fcb26b3 100644 --- a/js/src/ctypes/ctypes.msg +++ b/js/src/ctypes/ctypes.msg @@ -10,25 +10,5 @@ */ MSG_DEF(CTYPESMSG_PLACEHOLDER_0, 0, JSEXN_NONE, NULL) +MSG_DEF(CTYPESMSG_TYPE_ERROR, 2, JSEXN_TYPEERR, "expected type {0}, got {1}") -/* type conversion */ -MSG_DEF(CTYPESMSG_CONV_ERROR_ARG,3, JSEXN_TYPEERR, "can't pass {0} to argument {1} of {2}") -MSG_DEF(CTYPESMSG_CONV_ERROR_ARRAY,3, JSEXN_TYPEERR, "can't convert {0} to element {1} of the type {2}") -MSG_DEF(CTYPESMSG_CONV_ERROR_FIN,2, JSEXN_TYPEERR, "can't convert {0} to the type of argument 1 of {1}") -MSG_DEF(CTYPESMSG_CONV_ERROR_RET,2, JSEXN_TYPEERR, "can't convert {0} to the return type of {1}") -MSG_DEF(CTYPESMSG_CONV_ERROR_SET,2, JSEXN_TYPEERR, "can't convert {0} to the type {1}") -MSG_DEF(CTYPESMSG_CONV_ERROR_STRUCT,5, JSEXN_TYPEERR, "can't convert {0} to the '{1}' field ({2}) of {3}{4}") -MSG_DEF(CTYPESMSG_NON_PRIMITIVE, 1, JSEXN_TYPEERR, ".value only works on character and numeric types, not `{0}`") -MSG_DEF(CTYPESMSG_TYPE_ERROR, 2, JSEXN_TYPEERR, "expected {0}, got {1}") - -/* array */ -MSG_DEF(CTYPESMSG_ARRAY_MISMATCH,4, JSEXN_TYPEERR, "length of {0} does not match to the length of the type {1} (expected {2}, got {3})") -MSG_DEF(CTYPESMSG_ARRAY_OVERFLOW,4, JSEXN_TYPEERR, "length of {0} does not fit to the length of the type {1} (expected {2} or lower, got {3})") - -/* struct */ -MSG_DEF(CTYPESMSG_FIELD_MISMATCH,5, JSEXN_TYPEERR, "property count of {0} does not match to field count of the type {1} (expected {2}, got {3}){4}") -MSG_DEF(CTYPESMSG_PROP_NONSTRING,3, JSEXN_TYPEERR, "property name {0} of {1} is not a string{2}") - -/* data finalizer */ -MSG_DEF(CTYPESMSG_EMPTY_FIN, 1, JSEXN_TYPEERR, "attempting to convert an empty CDataFinalizer{0}") -MSG_DEF(CTYPESMSG_FIN_SIZE_ERROR,2, JSEXN_TYPEERR, "expected an object with the same size as argument 1 of {0}, got {1}") diff --git a/js/src/jit-test/lib/asserts.js b/js/src/jit-test/lib/asserts.js index c183a446fc0..a8736454221 100644 --- a/js/src/jit-test/lib/asserts.js +++ b/js/src/jit-test/lib/asserts.js @@ -65,23 +65,3 @@ if (typeof assertNoWarning === 'undefined') { } }; } - -if (typeof assertTypeErrorMessage === 'undefined') { - var assertTypeErrorMessage = function assertTypeErrorMessage(f, test) { - try { - f(); - } catch (e) { - if (!(e instanceof TypeError)) - throw new Error("Assertion failed: expected exception TypeError, got " + e); - if (typeof test == "string") { - if (test != e.message) - throw new Error("Assertion failed: expeceted " + test + ", got " + e.message); - } else { - if (!test.test(e.message)) - throw new Error("Assertion failed: expeceted " + test.toString() + ", got " + e.message); - } - return; - } - throw new Error("Assertion failed: expected exception TypeError, no exception thrown"); - }; -} diff --git a/js/src/jit-test/tests/ctypes/conversion-array.js b/js/src/jit-test/tests/ctypes/conversion-array.js deleted file mode 100644 index 840c1a0feb4..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-array.js +++ /dev/null @@ -1,36 +0,0 @@ -// 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 to 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 to 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 deleted file mode 100644 index a6823fe5ce8..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-error.js +++ /dev/null @@ -1,14 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - let obj = { - toSource() { - throw 1; - } - }; - assertTypeErrorMessage(() => { ctypes.double().value = obj; }, - "can't convert <> 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 deleted file mode 100644 index a04a40cfa20..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-finalizer.js +++ /dev/null @@ -1,61 +0,0 @@ -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 deleted file mode 100644 index cd90f1b6068..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-function.js +++ /dev/null @@ -1,33 +0,0 @@ -// 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 deleted file mode 100644 index f1751bdc054..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-int64.js +++ /dev/null @@ -1,20 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.Int64("0xfffffffffffffffffffffff"); }, - "can't pass the string \"0xfffffffffffffffffffffff\" to argument 1 of 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"); - - assertTypeErrorMessage(() => { ctypes.UInt64("0xfffffffffffffffffffffff"); }, - "can't pass the string \"0xfffffffffffffffffffffff\" to argument 1 of 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 deleted file mode 100644 index d2196813e90..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-native-function.js +++ /dev/null @@ -1,37 +0,0 @@ -// 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("c")); - } 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 deleted file mode 100644 index cfdcc8ed87a..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-pointer.js +++ /dev/null @@ -1,29 +0,0 @@ -// 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 = 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 deleted file mode 100644 index aaaa95e6b8b..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-primitive.js +++ /dev/null @@ -1,44 +0,0 @@ -// 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"); - assertTypeErrorMessage(() => { ctypes.int32_t("0xfffffffffffffffffffffff"); }, - "can't convert the string \"0xfffffffffffffffffffffff\" to 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 deleted file mode 100644 index f5e43ffa563..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-struct.js +++ /dev/null @@ -1,36 +0,0 @@ -// 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 deleted file mode 100644 index cdb9a4a051d..00000000000 --- a/js/src/jit-test/tests/ctypes/conversion-to-primitive.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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/jsexn.cpp b/js/src/jsexn.cpp index 703ff7de5f3..a1fdab346a0 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -930,43 +930,3 @@ JS::CreateError(JSContext* cx, JSExnType type, HandleObject stack, HandleString rval.setObject(*obj); return true; } - -const char* -js::ValueToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes) -{ - if (val.isUndefined()) { - return "undefined"; - } - if (val.isNull()) { - return "null"; - } - - RootedString str(cx, JS_ValueToSource(cx, val)); - if (!str) { - JS_ClearPendingException(cx); - return "<>"; - } - - StringBuffer sb(cx); - if (val.isObject()) { - RootedObject valObj(cx, val.toObjectOrNull()); - if (JS_IsArrayObject(cx, valObj)) { - sb.append("the array "); - } else if (JS_IsArrayBufferObject(valObj)) { - sb.append("the array buffer "); - } else if (JS_IsArrayBufferViewObject(valObj)) { - sb.append("the typed array "); - } else { - sb.append("the object "); - } - } else if (val.isNumber()) { - sb.append("the number "); - } else if (val.isString()) { - sb.append("the string "); - } else { - MOZ_ASSERT(val.isBoolean() || val.isSymbol()); - return bytes.encodeLatin1(cx, str); - } - sb.append(str); - return bytes.encodeLatin1(cx, sb.finishString()); -} diff --git a/js/src/jsexn.h b/js/src/jsexn.h index 3bcf29abd38..1cdcac947e5 100644 --- a/js/src/jsexn.h +++ b/js/src/jsexn.h @@ -129,9 +129,6 @@ class AutoClearPendingException } }; -extern const char* -ValueToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes); - } // namespace js #endif /* jsexn_h */ diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index 5ddeab5297d..911e8e4b251 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -1166,7 +1166,7 @@ function run_char_tests(library, t, name, size, signed, limits) { do_check_eq(s.constructor.length, literal.length + 1); s = t.array(50)(literal); do_check_eq(s.readString(), literal); - do_check_throws(function() { t.array(3)(literal); }, TypeError); + do_check_throws(function() { t.array(3)(literal); }, Error); do_check_throws(function() { t.ptr(literal); }, TypeError); let p = t.ptr(s); @@ -1258,7 +1258,7 @@ function run_char16_tests(library, t, name, limits) { do_check_eq(s.constructor.length, literal.length + 1); s = t.array(50)(literal); do_check_eq(s.readString(), literal); - do_check_throws(function() { t.array(3)(literal); }, TypeError); + do_check_throws(function() { t.array(3)(literal); }, Error); do_check_throws(function() { t.ptr(literal); }, TypeError); let p = t.ptr(s); @@ -1587,25 +1587,25 @@ function run_StructType_tests() { do_check_eq(s.b.b, s2.b.b); // Test that structs can be set from an object using 'value'. - do_check_throws(function() { s.value; }, TypeError); + do_check_throws(function() { s.value; }, Error); let s_init = { "a": 2, "b": { "a": 9, "b": 5 }, "c": 13 }; s.value = s_init; do_check_eq(s.b.a, 9); do_check_eq(s.c, 13); do_check_throws(function() { s.value = 5; }, TypeError); do_check_throws(function() { s.value = ctypes.int32_t(); }, TypeError); - do_check_throws(function() { s.value = {}; }, TypeError); - do_check_throws(function() { s.value = { "a": 2 }; }, TypeError); + do_check_throws(function() { s.value = {}; }, Error); + do_check_throws(function() { s.value = { "a": 2 }; }, Error); do_check_throws(function() { s.value = { "a": 2, "b": 5, "c": 10 }; }, TypeError); do_check_throws(function() { s.value = { "5": 2, "b": { "a": 9, "b": 5 }, "c": 13 }; - }, TypeError); + }, Error); do_check_throws(function() { s.value = { "a": 2, "b": { "a": 9, "b": 5 }, "c": 13, "d": 17 }; - }, TypeError); + }, Error); do_check_throws(function() { s.value = { "a": 2, "b": { "a": 9, "b": 5, "e": 9 }, "c": 13 }; - }, TypeError); + }, Error); // Test that structs can be constructed similarly through ExplicitConvert, // and that the single-field case is disambiguated correctly. @@ -1682,7 +1682,7 @@ function run_PointerType_tests() { // Test ExplicitConvert. let p = p_t(); - do_check_throws(function() { p.value; }, TypeError); + do_check_throws(function() { p.value; }, Error); do_check_eq(ptrValue(p), 0); do_check_throws(function() { p.contents; }, Error); do_check_throws(function() { p.contents = g; }, Error); @@ -1798,10 +1798,10 @@ function run_PointerType_tests() { let array_type_too_large = item_type.array(number_of_items + 1); let array_type_too_small = item_type.array(number_of_items - 1); - do_check_throws(function() { array_type_too_large(c_arraybuffer); }, TypeError); - do_check_throws(function() { array_type_too_small(c_arraybuffer); }, TypeError); - do_check_throws(function() { array_type_too_large(view); }, TypeError); - do_check_throws(function() { array_type_too_small(view); }, TypeError); + do_check_throws(function() { array_type_too_large(c_arraybuffer); }, Error); + do_check_throws(function() { array_type_too_small(c_arraybuffer); }, Error); + do_check_throws(function() { array_type_too_large(view); }, Error); + do_check_throws(function() { array_type_too_small(view); }, Error); // Convert subarray of typed array to array of right size and check contents c_array = array_type_too_small(view.subarray(1)); @@ -1884,7 +1884,7 @@ function run_FunctionType_tests() { // Test ExplicitConvert. let f = fp_t(); - do_check_throws(function() { f.value; }, TypeError); + do_check_throws(function() { f.value; }, Error); do_check_eq(ptrValue(f), 0); f = fp_t(5); do_check_eq(ptrValue(f), 5); @@ -2067,11 +2067,11 @@ function run_ArrayType_tests() { c.value = c; do_check_eq(c[3], 4); - do_check_throws(function() { c.value; }, TypeError); - do_check_throws(function() { c.value = [1, 2, 3, 4, 5]; }, TypeError); - do_check_throws(function() { c.value = [1, 2, 3, 4, 5, 6, 7]; }, TypeError); + do_check_throws(function() { c.value; }, Error); + do_check_throws(function() { c.value = [1, 2, 3, 4, 5]; }, Error); + do_check_throws(function() { c.value = [1, 2, 3, 4, 5, 6, 7]; }, Error); do_check_throws(function() { c.value = [1, 2, 7.4, 4, 5, 6]; }, TypeError); - do_check_throws(function() { c.value = []; }, TypeError); + do_check_throws(function() { c.value = []; }, Error); } function run_type_toString_tests() {