[JSC] Unify how we throw TypeError from C++
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jul 2016 03:12:37 +0000 (03:12 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jul 2016 03:12:37 +0000 (03:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=159500

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-07-06
Reviewed by Saam Barati.

Source/JavaScriptCore:

Throwing a TypeError is an uncommon case. We should minimize the impact
on the call sites.

This patch does that by:
-Replace the 2 calls createTypeError()->throwException() by throwTypeError().
-Use ASCIILiteral when possible.
-Add an overload of throwTypeError() taking ASCIILiteral directly
 (that way, the String creation and destruction is done by the callee).

On x86_64, this reduces the __TEXT__ segment by 29kb.

* inspector/JSInjectedScriptHost.cpp:
(Inspector::JSInjectedScriptHost::evaluateWithScopeExtension):
* inspector/JSJavaScriptCallFrame.cpp:
(Inspector::JSJavaScriptCallFrame::evaluateWithScopeExtension):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jit/JITOperations.cpp:
* runtime/DatePrototype.cpp:
(JSC::dateProtoFuncToJSON):
* runtime/Error.cpp:
(JSC::throwConstructorCannotBeCalledAsFunctionTypeError):
(JSC::throwTypeError):
* runtime/Error.h:
(JSC::throwVMTypeError):
* runtime/JSArrayBufferPrototype.cpp:
(JSC::arrayBufferProtoFuncSlice):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::putToPrimitive):
(JSC::JSValue::toStringSlowCase):
* runtime/JSCJSValueInlines.h:
(JSC::toPreferredPrimitiveType):
* runtime/JSDataViewPrototype.cpp:
(JSC::getData):
(JSC::setData):
* runtime/JSFunction.cpp:
(JSC::JSFunction::defineOwnProperty):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewFromIterator):
(JSC::constructGenericTypedArrayViewWithArguments):
(JSC::constructGenericTypedArrayView):
* runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
(JSC::speciesConstruct):
(JSC::genericTypedArrayViewProtoFuncSet):
(JSC::genericTypedArrayViewProtoFuncCopyWithin):
(JSC::genericTypedArrayViewProtoFuncIndexOf):
(JSC::genericTypedArrayViewProtoFuncLastIndexOf):
(JSC::genericTypedArrayViewProtoFuncSubarray):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncProtoGetter):
(JSC::globalFuncProtoSetter):
* runtime/JSONObject.cpp:
(JSC::Stringifier::appendStringifiedValue):
* runtime/JSObject.cpp:
(JSC::JSObject::setPrototypeWithCycleCheck):
(JSC::callToPrimitiveFunction):
(JSC::JSObject::ordinaryToPrimitive):
(JSC::JSObject::defaultHasInstance):
(JSC::validateAndApplyPropertyDescriptor):
* runtime/JSTypedArrayViewConstructor.cpp:
(JSC::constructTypedArrayView):
* runtime/JSTypedArrayViewPrototype.cpp:
(JSC::typedArrayViewPrivateFuncLength):
(JSC::typedArrayViewProtoFuncSet):
(JSC::typedArrayViewProtoFuncCopyWithin):
(JSC::typedArrayViewProtoFuncFill):
(JSC::typedArrayViewProtoFuncLastIndexOf):
(JSC::typedArrayViewProtoFuncIndexOf):
(JSC::typedArrayViewProtoFuncJoin):
(JSC::typedArrayViewProtoGetterFuncBuffer):
(JSC::typedArrayViewProtoGetterFuncLength):
(JSC::typedArrayViewProtoGetterFuncByteLength):
(JSC::typedArrayViewProtoGetterFuncByteOffset):
(JSC::typedArrayViewProtoFuncReverse):
(JSC::typedArrayViewProtoFuncSubarray):
(JSC::typedArrayViewProtoFuncSlice):
* runtime/ObjectConstructor.cpp:
(JSC::toPropertyDescriptor):
(JSC::objectConstructorDefineProperty):
(JSC::objectConstructorDefineProperties):
(JSC::objectConstructorCreate):
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncDefineGetter):
(JSC::objectProtoFuncDefineSetter):
* runtime/RegExpPrototype.cpp:
(JSC::regExpProtoFuncCompile):
* runtime/Symbol.cpp:
(JSC::Symbol::toNumber):

Source/WebCore:

* bindings/js/JSBiquadFilterNodeCustom.cpp:
(WebCore::JSBiquadFilterNode::setType):
* bindings/js/JSBlobCustom.cpp:
(WebCore::constructJSBlob):
* bindings/js/JSCryptoKeySerializationJWK.cpp:
(WebCore::getBigIntegerVectorFromJSON):
(WebCore::JSCryptoKeySerializationJWK::JSCryptoKeySerializationJWK):
(WebCore::tryJWKKeyOpsValue):
(WebCore::JSCryptoKeySerializationJWK::reconcileUsages):
(WebCore::JSCryptoKeySerializationJWK::keyDataOctetSequence):
(WebCore::JSCryptoKeySerializationJWK::keyDataRSAComponents):
(WebCore::JSCryptoKeySerializationJWK::keyData):
(WebCore::addJWKAlgorithmToJSON):
(WebCore::JSCryptoKeySerializationJWK::serialize):
* bindings/js/JSCryptoOperationData.cpp:
(WebCore::cryptoOperationDataFromJSValue):
* bindings/js/JSDOMBinding.cpp:
(WebCore::enforceRange):
(WebCore::throwTypeError):
(WebCore::throwArgumentMustBeEnumError):
(WebCore::throwArgumentMustBeFunctionError):
(WebCore::throwArgumentTypeError):
(WebCore::throwArrayElementTypeError):
(WebCore::throwGetterTypeError):
(WebCore::throwThisTypeError):
* bindings/js/JSDataCueCustom.cpp:
(WebCore::constructJSDataCue):
* bindings/js/JSDocumentCustom.cpp:
(WebCore::JSDocument::defineElement):
* bindings/js/JSFileCustom.cpp:
(WebCore::constructJSFile):
* bindings/js/JSModuleLoader.cpp:
(WebCore::JSModuleLoader::evaluate):
* bindings/js/JSMutationObserverCustom.cpp:
(WebCore::constructJSMutationObserver):
* bindings/js/JSOscillatorNodeCustom.cpp:
(WebCore::JSOscillatorNode::setType):
* bindings/js/JSPannerNodeCustom.cpp:
(WebCore::JSPannerNode::setPanningModel):
(WebCore::JSPannerNode::setDistanceModel):
* bindings/js/JSReadableStreamPrivateConstructors.cpp:
(WebCore::constructJSReadableStreamController):
(WebCore::constructJSReadableStreamReader):
* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::cryptoKeyFormatFromJSValue):
(WebCore::importKey):
(WebCore::exportKey):
* bindings/js/ReadableStreamController.cpp:
(WebCore::ReadableStreamController::invoke):
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::throwValidationError):
(WebCore::SerializedScriptValue::maybeThrowExceptionIfSerializationFailed):
* bridge/c/c_instance.cpp:
(JSC::Bindings::CInstance::invokeMethod):
* bridge/objc/objc_instance.mm:
(ObjcInstance::invokeMethod):
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::ObjcArray::setValueAt):

Source/WebKit/mac:

* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyInstance::invokeMethod):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@202890 268f45cc-cd09-0410-ab3c-d52691b4dbfc

46 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp
Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/runtime/DatePrototype.cpp
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/Error.h
Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp
Source/JavaScriptCore/runtime/JSCJSValue.cpp
Source/JavaScriptCore/runtime/JSCJSValueInlines.h
Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
Source/JavaScriptCore/runtime/JSONObject.cpp
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSTypedArrayViewConstructor.cpp
Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/ObjectPrototype.cpp
Source/JavaScriptCore/runtime/RegExpPrototype.cpp
Source/JavaScriptCore/runtime/Symbol.cpp
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSBiquadFilterNodeCustom.cpp
Source/WebCore/bindings/js/JSBlobCustom.cpp
Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp
Source/WebCore/bindings/js/JSCryptoOperationData.cpp
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDataCueCustom.cpp
Source/WebCore/bindings/js/JSDocumentCustom.cpp
Source/WebCore/bindings/js/JSFileCustom.cpp
Source/WebCore/bindings/js/JSModuleLoader.cpp
Source/WebCore/bindings/js/JSMutationObserverCustom.cpp
Source/WebCore/bindings/js/JSOscillatorNodeCustom.cpp
Source/WebCore/bindings/js/JSPannerNodeCustom.cpp
Source/WebCore/bindings/js/JSReadableStreamPrivateConstructors.cpp
Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp
Source/WebCore/bindings/js/ReadableStreamController.cpp
Source/WebCore/bindings/js/SerializedScriptValue.cpp
Source/WebCore/bridge/c/c_instance.cpp
Source/WebCore/bridge/objc/objc_instance.mm
Source/WebCore/bridge/objc/objc_runtime.mm
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Plugins/Hosted/ProxyInstance.mm

index cbbf701..a474ca2 100644 (file)
@@ -1,3 +1,99 @@
+2016-07-06  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Unify how we throw TypeError from C++
+        https://bugs.webkit.org/show_bug.cgi?id=159500
+
+        Reviewed by Saam Barati.
+
+        Throwing a TypeError is an uncommon case. We should minimize the impact
+        on the call sites.
+
+        This patch does that by:
+        -Replace the 2 calls createTypeError()->throwException() by throwTypeError().
+        -Use ASCIILiteral when possible.
+        -Add an overload of throwTypeError() taking ASCIILiteral directly
+         (that way, the String creation and destruction is done by the callee).
+
+        On x86_64, this reduces the __TEXT__ segment by 29kb.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::evaluateWithScopeExtension):
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::evaluateWithScopeExtension):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * jit/JITOperations.cpp:
+        * runtime/DatePrototype.cpp:
+        (JSC::dateProtoFuncToJSON):
+        * runtime/Error.cpp:
+        (JSC::throwConstructorCannotBeCalledAsFunctionTypeError):
+        (JSC::throwTypeError):
+        * runtime/Error.h:
+        (JSC::throwVMTypeError):
+        * runtime/JSArrayBufferPrototype.cpp:
+        (JSC::arrayBufferProtoFuncSlice):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::putToPrimitive):
+        (JSC::JSValue::toStringSlowCase):
+        * runtime/JSCJSValueInlines.h:
+        (JSC::toPreferredPrimitiveType):
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::getData):
+        (JSC::setData):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::constructGenericTypedArrayViewFromIterator):
+        (JSC::constructGenericTypedArrayViewWithArguments):
+        (JSC::constructGenericTypedArrayView):
+        * runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
+        (JSC::speciesConstruct):
+        (JSC::genericTypedArrayViewProtoFuncSet):
+        (JSC::genericTypedArrayViewProtoFuncCopyWithin):
+        (JSC::genericTypedArrayViewProtoFuncIndexOf):
+        (JSC::genericTypedArrayViewProtoFuncLastIndexOf):
+        (JSC::genericTypedArrayViewProtoFuncSubarray):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncProtoGetter):
+        (JSC::globalFuncProtoSetter):
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::appendStringifiedValue):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::setPrototypeWithCycleCheck):
+        (JSC::callToPrimitiveFunction):
+        (JSC::JSObject::ordinaryToPrimitive):
+        (JSC::JSObject::defaultHasInstance):
+        (JSC::validateAndApplyPropertyDescriptor):
+        * runtime/JSTypedArrayViewConstructor.cpp:
+        (JSC::constructTypedArrayView):
+        * runtime/JSTypedArrayViewPrototype.cpp:
+        (JSC::typedArrayViewPrivateFuncLength):
+        (JSC::typedArrayViewProtoFuncSet):
+        (JSC::typedArrayViewProtoFuncCopyWithin):
+        (JSC::typedArrayViewProtoFuncFill):
+        (JSC::typedArrayViewProtoFuncLastIndexOf):
+        (JSC::typedArrayViewProtoFuncIndexOf):
+        (JSC::typedArrayViewProtoFuncJoin):
+        (JSC::typedArrayViewProtoGetterFuncBuffer):
+        (JSC::typedArrayViewProtoGetterFuncLength):
+        (JSC::typedArrayViewProtoGetterFuncByteLength):
+        (JSC::typedArrayViewProtoGetterFuncByteOffset):
+        (JSC::typedArrayViewProtoFuncReverse):
+        (JSC::typedArrayViewProtoFuncSubarray):
+        (JSC::typedArrayViewProtoFuncSlice):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::toPropertyDescriptor):
+        (JSC::objectConstructorDefineProperty):
+        (JSC::objectConstructorDefineProperties):
+        (JSC::objectConstructorCreate):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        * runtime/RegExpPrototype.cpp:
+        (JSC::regExpProtoFuncCompile):
+        * runtime/Symbol.cpp:
+        (JSC::Symbol::toNumber):
+
 2016-07-06  Saam Barati  <sbarati@apple.com>
 
         InlineAccess::sizeForLengthAccess() is wrong on some platforms because it should also consider "length" not being array length
index 4a7d592..dd52959 100644 (file)
@@ -97,7 +97,7 @@ JSValue JSInjectedScriptHost::evaluateWithScopeExtension(ExecState* exec)
 {
     JSValue scriptValue = exec->argument(0);
     if (!scriptValue.isString())
-        return throwTypeError(exec, "InjectedScriptHost.evaluateWithScopeExtension first argument must be a string.");
+        return throwTypeError(exec, ASCIILiteral("InjectedScriptHost.evaluateWithScopeExtension first argument must be a string."));
 
     String program = scriptValue.toString(exec)->value(exec);
     if (exec->hadException())
index a1dab51..8e63454 100644 (file)
@@ -79,7 +79,7 @@ JSValue JSJavaScriptCallFrame::evaluateWithScopeExtension(ExecState* exec)
 {
     JSValue scriptValue = exec->argument(0);
     if (!scriptValue.isString())
-        return throwTypeError(exec, "JSJavaScriptCallFrame.evaluateWithScopeExtension first argument must be a string.");
+        return throwTypeError(exec, ASCIILiteral("JSJavaScriptCallFrame.evaluateWithScopeExtension first argument must be a string."));
 
     String script = scriptValue.toString(exec)->value(exec);
     if (exec->hadException())
index 74f8c53..a112363 100644 (file)
@@ -1185,8 +1185,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
             const Identifier& ident = codeBlock->variable(i);
             PropertySlot slot(globalLexicalEnvironment, PropertySlot::InternalMethodType::VMInquiry);
             if (JSGlobalLexicalEnvironment::getOwnPropertySlot(globalLexicalEnvironment, callFrame, ident, slot)) {
-                return checkedReturn(callFrame->vm().throwException(callFrame,
-                    createTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(ident.impl()), "'"))));
+                return checkedReturn(throwTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(ident.impl()), "'")));
             }
         }
 
@@ -1194,8 +1193,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
             FunctionExecutable* function = codeBlock->functionDecl(i);
             PropertySlot slot(globalLexicalEnvironment, PropertySlot::InternalMethodType::VMInquiry);
             if (JSGlobalLexicalEnvironment::getOwnPropertySlot(globalLexicalEnvironment, callFrame, function->name(), slot)) {
-                return checkedReturn(callFrame->vm().throwException(callFrame,
-                    createTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(function->name().impl()), "'"))));
+                return checkedReturn(throwTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(function->name().impl()), "'")));
             }
         }
     }
index 01f3c3d..eb4e381 100644 (file)
@@ -1172,7 +1172,7 @@ void JIT_OPERATION operationThrowStaticError(ExecState* exec, EncodedJSValue enc
     if (referenceErrorFlag)
         vm.throwException(exec, createReferenceError(exec, errorMessage));
     else
-        vm.throwException(exec, createTypeError(exec, errorMessage));
+        throwTypeError(exec, errorMessage);
 }
 
 void JIT_OPERATION operationDebug(ExecState* exec, int32_t debugHookID)
@@ -1873,7 +1873,7 @@ size_t JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue encoded
         return false;
     bool couldDelete = baseObj->methodTable(vm)->deleteProperty(baseObj, exec, Identifier::fromUid(&vm, uid));
     if (!couldDelete && exec->codeBlock()->isStrictMode())
-        vm.throwException(exec, createTypeError(exec, ASCIILiteral("Unable to delete property.")));
+        throwTypeError(exec, ASCIILiteral("Unable to delete property."));
     return couldDelete;
 }
 
@@ -1905,7 +1905,7 @@ size_t JIT_OPERATION operationDeleteByVal(ExecState* exec, EncodedJSValue encode
         couldDelete = baseObj->methodTable(vm)->deleteProperty(baseObj, exec, property);
     }
     if (!couldDelete && exec->codeBlock()->isStrictMode())
-        vm.throwException(exec, createTypeError(exec, ASCIILiteral("Unable to delete property.")));
+        throwTypeError(exec, ASCIILiteral("Unable to delete property."));
     return couldDelete;
 }
 
index 9936515..f621891 100644 (file)
@@ -1112,13 +1112,13 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec)
     CallData callData;
     CallType callType = getCallData(toISOValue, callData);
     if (callType == CallType::None)
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("toISOString is not a function")));
+        return throwVMTypeError(exec, ASCIILiteral("toISOString is not a function"));
 
     JSValue result = call(exec, asObject(toISOValue), callType, callData, object, exec->emptyList());
     if (exec->hadException())
         return JSValue::encode(jsNull());
     if (result.isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("toISOString did not return a primitive value")));
+        return throwVMTypeError(exec, ASCIILiteral("toISOString did not return a primitive value"));
     return JSValue::encode(result);
 }
 
index b330791..93a50db 100644 (file)
@@ -208,7 +208,7 @@ bool hasErrorInfo(ExecState* exec, JSObject* error)
 
 JSObject* throwConstructorCannotBeCalledAsFunctionTypeError(ExecState* exec, const char* constructorName)
 {
-    return exec->vm().throwException(exec, createTypeError(exec, makeString("calling ", constructorName, " constructor without new is invalid")));
+    return throwTypeError(exec, makeString("calling ", constructorName, " constructor without new is invalid"));
 }
 
 JSObject* throwTypeError(ExecState* exec)
@@ -216,6 +216,11 @@ JSObject* throwTypeError(ExecState* exec)
     return exec->vm().throwException(exec, createTypeError(exec));
 }
 
+JSObject* throwTypeError(ExecState* exec, ASCIILiteral errorMessage)
+{
+    return throwTypeError(exec, String(errorMessage));
+}
+
 JSObject* throwTypeError(ExecState* exec, const String& message)
 {
     return exec->vm().throwException(exec, createTypeError(exec, message));
index 1e5857d..6e9becb 100644 (file)
@@ -74,6 +74,7 @@ JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&)
 // Convenience wrappers, create an throw an exception with a default message.
 JS_EXPORT_PRIVATE JSObject* throwConstructorCannotBeCalledAsFunctionTypeError(ExecState*, const char* constructorName);
 JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
+JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, ASCIILiteral errorMessage);
 JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, const String& errorMessage);
 JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
 JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*, const String& errorMessage);
@@ -83,6 +84,7 @@ inline JSObject* throwRangeError(ExecState* state, const String& errorMessage) {
 inline void throwVMError(ExecState* exec, Exception* exception) { exec->vm().throwException(exec, exception); }
 inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(exec->vm().throwException(exec, error)); }
 inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
+inline EncodedJSValue throwVMTypeError(ExecState* exec, ASCIILiteral errorMessage) { return JSValue::encode(throwTypeError(exec, errorMessage)); }
 inline EncodedJSValue throwVMTypeError(ExecState* exec, const String& errorMessage) { return JSValue::encode(throwTypeError(exec, errorMessage)); }
 inline EncodedJSValue throwVMRangeError(ExecState* state, const String& errorMessage) { return JSValue::encode(throwRangeError(state, errorMessage)); }
 
index d29e283..f0e3741 100644 (file)
@@ -41,10 +41,10 @@ static EncodedJSValue JSC_HOST_CALL arrayBufferProtoFuncSlice(ExecState* exec)
     
     JSArrayBuffer* thisObject = jsDynamicCast<JSArrayBuffer*>(exec->thisValue());
     if (!thisObject)
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Receiver of slice must be an array buffer.")));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver of slice must be an array buffer."));
     
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Slice requires at least one argument.")));
+        return throwVMTypeError(exec, ASCIILiteral("Slice requires at least one argument."));
     
     int32_t begin = exec->argument(0).toInt32(exec);
     if (exec->hadException())
index ddf3b5f..b8dd22a 100644 (file)
@@ -157,7 +157,7 @@ bool JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
         if (offset != invalidOffset) {
             if (attributes & ReadOnly) {
                 if (slot.isStrictMode())
-                    exec->vm().throwException(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+                    throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
                 return false;
             }
 
@@ -346,7 +346,7 @@ JSString* JSValue::toStringSlowCase(ExecState* exec, bool returnEmptyStringOnErr
     if (isUndefined())
         return vm.smallStrings.undefinedString();
     if (isSymbol()) {
-        throwTypeError(exec, "Cannot convert a symbol to a string");
+        throwTypeError(exec, ASCIILiteral("Cannot convert a symbol to a string"));
         return errorValue();
     }
 
index 7ce3457..802eb27 100644 (file)
@@ -632,7 +632,7 @@ inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType pref
 inline PreferredPrimitiveType toPreferredPrimitiveType(ExecState* exec, JSValue value)
 {
     if (!value.isString()) {
-        throwTypeError(exec, "Primitive hint is not a string.");
+        throwTypeError(exec, ASCIILiteral("Primitive hint is not a string."));
         return NoPreference;
     }
 
@@ -647,7 +647,7 @@ inline PreferredPrimitiveType toPreferredPrimitiveType(ExecState* exec, JSValue
     if (WTF::equal(hintString, "string"))
         return PreferString;
 
-    throwTypeError(exec, "Expected primitive hint to match one of 'default', 'number', 'string'.");
+    throwTypeError(exec, ASCIILiteral("Expected primitive hint to match one of 'default', 'number', 'string'."));
     return NoPreference;
 }
 
index 13872bd..4d58e0d 100644 (file)
@@ -124,10 +124,10 @@ EncodedJSValue getData(ExecState* exec)
 {
     JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue());
     if (!dataView)
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Receiver of DataView method must be a DataView")));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver of DataView method must be a DataView"));
     
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Need at least one argument (the byteOffset)")));
+        return throwVMTypeError(exec, ASCIILiteral("Need at least one argument (the byteOffset)"));
     
     unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec);
     if (exec->hadException())
@@ -169,10 +169,10 @@ EncodedJSValue setData(ExecState* exec)
 {
     JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue());
     if (!dataView)
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Receiver of DataView method must be a DataView")));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver of DataView method must be a DataView"));
     
     if (exec->argumentCount() < 2)
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Need at least two argument (the byteOffset and value)")));
+        return throwVMTypeError(exec, ASCIILiteral("Need at least two argument (the byteOffset and value)"));
     
     unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec);
     if (exec->hadException())
index ef03ecd..58bf23a 100644 (file)
@@ -506,27 +506,27 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa
      
     if (descriptor.configurablePresent() && descriptor.configurable()) {
         if (throwException)
-            exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property.")));
+            throwTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property."));
         return false;
     }
     if (descriptor.enumerablePresent() && descriptor.enumerable()) {
         if (throwException)
-            exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
+            throwTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property."));
         return false;
     }
     if (descriptor.isAccessorDescriptor()) {
         if (throwException)
-            exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral(UnconfigurablePropertyChangeAccessMechanismError)));
+            throwTypeError(exec, ASCIILiteral(UnconfigurablePropertyChangeAccessMechanismError));
         return false;
     }
     if (descriptor.writablePresent() && descriptor.writable()) {
         if (throwException)
-            exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
+            throwTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property."));
         return false;
     }
     if (!valueCheck) {
         if (throwException)
-            exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
+            throwTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property."));
         return false;
     }
     return true;
index 316c8ac..902b06b 100644 (file)
@@ -81,7 +81,7 @@ template<typename ViewClass>
 inline JSObject* constructGenericTypedArrayViewFromIterator(ExecState* exec, Structure* structure, JSValue iterator)
 {
     if (!iterator.isObject())
-        return throwTypeError(exec, "Symbol.Iterator for the first argument did not return an object.");
+        return throwTypeError(exec, ASCIILiteral("Symbol.Iterator for the first argument did not return an object."));
 
     MarkedArgumentBuffer storage;
     while (true) {
@@ -139,7 +139,7 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
     ASSERT(!offset && !lengthOpt);
     
     if (ViewClass::TypedArrayStorageType == TypeDataView)
-        return throwTypeError(exec, "Expected ArrayBuffer for the first argument.");
+        return throwTypeError(exec, ASCIILiteral("Expected ArrayBuffer for the first argument."));
     
     // For everything but DataView, we allow construction with any of:
     // - Another array. This creates a copy of the of that array.
@@ -174,7 +174,7 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
                     CallData callData;
                     CallType callType = getCallData(iteratorFunc, callData);
                     if (callType == CallType::None)
-                        return throwTypeError(exec, "Symbol.Iterator for the first argument cannot be called.");
+                        return throwTypeError(exec, ASCIILiteral("Symbol.Iterator for the first argument cannot be called."));
 
                     ArgList arguments;
                     JSValue iterator = call(exec, iteratorFunc, callType, callData, object, arguments);
@@ -206,11 +206,11 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
     if (firstValue.isInt32())
         length = firstValue.asInt32();
     else if (!firstValue.isNumber())
-        return throwTypeError(exec, "Invalid array length argument");
+        return throwTypeError(exec, ASCIILiteral("Invalid array length argument"));
     else {
         length = static_cast<int>(firstValue.asNumber());
         if (length != firstValue.asNumber())
-            return throwTypeError(exec, "Invalid array length argument (fractional lengths not allowed)");
+            return throwTypeError(exec, ASCIILiteral("Invalid array length argument (fractional lengths not allowed)"));
     }
 
     if (length < 0)
@@ -234,7 +234,7 @@ EncodedJSValue JSC_HOST_CALL constructGenericTypedArrayView(ExecState* exec)
 
     if (!argCount) {
         if (ViewClass::TypedArrayStorageType == TypeDataView)
-            return throwVMError(exec, createTypeError(exec, "DataView constructor requires at least one argument."));
+            return throwVMTypeError(exec, ASCIILiteral("DataView constructor requires at least one argument."));
 
         return JSValue::encode(ViewClass::create(exec, structure, 0));
     }
index 0b023d8..1f9bc24 100644 (file)
@@ -56,7 +56,7 @@ inline JSArrayBufferView* speciesConstruct(ExecState* exec, JSObject* exemplar,
     if (constructor.isUndefined())
         return defaultConstructor();
     if (!constructor.isObject()) {
-        throwTypeError(exec, "constructor Property should not be null");
+        throwTypeError(exec, ASCIILiteral("constructor Property should not be null"));
         return nullptr;
     }
 
@@ -74,7 +74,7 @@ inline JSArrayBufferView* speciesConstruct(ExecState* exec, JSObject* exemplar,
     if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(result))
         return view;
 
-    throwTypeError(exec, "species constructor did not return a TypedArray View");
+    throwTypeError(exec, ASCIILiteral("species constructor did not return a TypedArray View"));
     return nullptr;
 }
 
@@ -99,7 +99,7 @@ EncodedJSValue JSC_HOST_CALL genericTypedArrayViewProtoFuncSet(ExecState* exec)
     ViewClass* thisObject = jsCast<ViewClass*>(exec->thisValue());
 
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, "Expected at least one argument"));
+        return throwVMTypeError(exec, ASCIILiteral("Expected at least one argument"));
 
     unsigned offset;
     if (exec->argumentCount() >= 2) {
@@ -117,7 +117,7 @@ EncodedJSValue JSC_HOST_CALL genericTypedArrayViewProtoFuncSet(ExecState* exec)
 
     JSObject* sourceArray = jsDynamicCast<JSObject*>(exec->uncheckedArgument(0));
     if (!sourceArray)
-        return throwVMError(exec, createTypeError(exec, "First argument should be an object"));
+        return throwVMTypeError(exec, ASCIILiteral("First argument should be an object"));
 
     unsigned length;
     if (isTypedView(sourceArray->classInfo()->typedArrayStorageType)) {
@@ -145,7 +145,7 @@ EncodedJSValue JSC_HOST_CALL genericTypedArrayViewProtoFuncCopyWithin(ExecState*
         return throwVMTypeError(exec, typedArrayBufferHasBeenDetachedErrorMessage);
 
     if (exec->argumentCount() < 2)
-        return throwVMError(exec, createTypeError(exec, "Expected at least two arguments"));
+        return throwVMTypeError(exec, ASCIILiteral("Expected at least two arguments"));
 
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
@@ -200,7 +200,7 @@ EncodedJSValue JSC_HOST_CALL genericTypedArrayViewProtoFuncIndexOf(ExecState* ex
         return throwVMTypeError(exec, typedArrayBufferHasBeenDetachedErrorMessage);
 
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, "Expected at least one argument"));
+        return throwVMTypeError(exec, ASCIILiteral("Expected at least one argument"));
 
     unsigned length = thisObject->length();
 
@@ -264,7 +264,7 @@ EncodedJSValue JSC_HOST_CALL genericTypedArrayViewProtoFuncLastIndexOf(ExecState
         return throwVMTypeError(exec, typedArrayBufferHasBeenDetachedErrorMessage);
 
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, "Expected at least one argument"));
+        return throwVMTypeError(exec, ASCIILiteral("Expected at least one argument"));
 
     unsigned length = thisObject->length();
 
@@ -442,7 +442,7 @@ EncodedJSValue JSC_HOST_CALL genericTypedArrayViewProtoFuncSubarray(ExecState* e
         return throwVMTypeError(exec, typedArrayBufferHasBeenDetachedErrorMessage);
 
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, "Expected at least one argument"));
+        return throwVMTypeError(exec, ASCIILiteral("Expected at least one argument"));
 
     // Get the length here; later assert that the length didn't change.
     unsigned thisLength = thisObject->length();
index cfd5f68..fdb3e7b 100644 (file)
@@ -888,7 +888,7 @@ private:
 EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState* exec)
 {
     if (exec->thisValue().isUndefinedOrNull()) 
-        return throwVMError(exec, createTypeError(exec, "Can't convert undefined or null to object"));
+        return throwVMTypeError(exec, ASCIILiteral("Can't convert undefined or null to object"));
 
     JSObject* thisObject = jsDynamicCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode));
 
@@ -945,7 +945,7 @@ bool checkProtoSetterAccessAllowed(ExecState* exec, JSObject* object)
 EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec)
 {
     if (exec->thisValue().isUndefinedOrNull()) 
-        return throwVMError(exec, createTypeError(exec, "Can't convert undefined or null to object"));
+        return throwVMTypeError(exec, ASCIILiteral("Can't convert undefined or null to object"));
 
     JSValue value = exec->argument(0);
 
index 1b820af..5e42d0e 100644 (file)
@@ -368,7 +368,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
     // Handle cycle detection, and put the holder on the stack.
     for (unsigned i = 0; i < m_holderStack.size(); i++) {
         if (m_holderStack[i].object() == object) {
-            m_exec->vm().throwException(m_exec, createTypeError(m_exec, ASCIILiteral("JSON.stringify cannot serialize cyclic structures.")));
+            throwTypeError(m_exec, ASCIILiteral("JSON.stringify cannot serialize cyclic structures."));
             return StringifyFailed;
         }
     }
index d7d5365..c4f2f7a 100644 (file)
@@ -1357,7 +1357,7 @@ bool JSObject::setPrototypeWithCycleCheck(VM& vm, ExecState* exec, JSValue proto
 
     if (!isExtensible) {
         if (shouldThrowIfCantSet)
-            throwVMError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
         return false;
     }
 
@@ -1640,7 +1640,7 @@ static ALWAYS_INLINE JSValue callToPrimitiveFunction(ExecState* exec, const JSOb
     if (exec->hadException())
         return exec->exception();
     if (result.isObject())
-        return mode == TypeHintMode::DoesNotTakeHint ? JSValue() : throwTypeError(exec, "Symbol.toPrimitive returned an object");
+        return mode == TypeHintMode::DoesNotTakeHint ? JSValue() : throwTypeError(exec, ASCIILiteral("Symbol.toPrimitive returned an object"));
     return result;
 }
 
@@ -1670,7 +1670,7 @@ JSValue JSObject::ordinaryToPrimitive(ExecState* exec, PreferredPrimitiveType hi
 
     ASSERT(!exec->hadException());
 
-    return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("No default value")));
+    return throwTypeError(exec, ASCIILiteral("No default value"));
 }
 
 JSValue JSObject::defaultValue(const JSObject* object, ExecState* exec, PreferredPrimitiveType hint)
@@ -1756,7 +1756,7 @@ bool JSObject::defaultHasInstance(ExecState* exec, JSValue value, JSValue proto)
         return false;
 
     if (!proto.isObject()) {
-        exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("instanceof called on an object with an invalid prototype property.")));
+        throwTypeError(exec, ASCIILiteral("instanceof called on an object with an invalid prototype property."));
         return false;
     }
 
@@ -2943,7 +2943,7 @@ bool validateAndApplyPropertyDescriptor(ExecState* exec, JSObject* object, Prope
         // Step 2.a
         if (!isExtensible) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")));
+                throwTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible."));
             return false;
         }
         if (!object)
@@ -2966,12 +2966,12 @@ bool validateAndApplyPropertyDescriptor(ExecState* exec, JSObject* object, Prope
     if (!current.configurable()) {
         if (descriptor.configurable()) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property.")));
+                throwTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property."));
             return false;
         }
         if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
+                throwTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property."));
             return false;
         }
     }
@@ -2991,7 +2991,7 @@ bool validateAndApplyPropertyDescriptor(ExecState* exec, JSObject* object, Prope
     if (descriptor.isDataDescriptor() != current.isDataDescriptor()) {
         if (!current.configurable()) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral(UnconfigurablePropertyChangeAccessMechanismError)));
+                throwTypeError(exec, ASCIILiteral(UnconfigurablePropertyChangeAccessMechanismError));
             return false;
         }
 
@@ -3008,13 +3008,13 @@ bool validateAndApplyPropertyDescriptor(ExecState* exec, JSObject* object, Prope
         if (!current.configurable()) {
             if (!current.writable() && descriptor.writable()) {
                 if (throwException)
-                    exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
+                    throwTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property."));
                 return false;
             }
             if (!current.writable()) {
                 if (descriptor.value() && !sameValue(exec, current.value(), descriptor.value())) {
                     if (throwException)
-                        exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
+                        throwTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property."));
                     return false;
                 }
             }
@@ -3033,17 +3033,17 @@ bool validateAndApplyPropertyDescriptor(ExecState* exec, JSObject* object, Prope
     if (!current.configurable()) {
         if (descriptor.setterPresent() && !(current.setterPresent() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change the setter of an unconfigurable property.")));
+                throwTypeError(exec, ASCIILiteral("Attempting to change the setter of an unconfigurable property."));
             return false;
         }
         if (descriptor.getterPresent() && !(current.getterPresent() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change the getter of an unconfigurable property.")));
+                throwTypeError(exec, ASCIILiteral("Attempting to change the getter of an unconfigurable property."));
             return false;
         }
         if (current.attributes() & CustomAccessor) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral(UnconfigurablePropertyChangeAccessMechanismError)));
+                throwTypeError(exec, ASCIILiteral(UnconfigurablePropertyChangeAccessMechanismError));
             return false;
         }
     }
index 96e3fe1..99d5659 100644 (file)
@@ -71,15 +71,15 @@ static EncodedJSValue JSC_HOST_CALL constructTypedArrayView(ExecState* exec)
 
     JSObject* object = jsDynamicCast<JSObject*>(value);
     if (!object)
-        return JSValue::encode(throwTypeError(exec, "new.target passed to TypedArray is not an object."));
+        return JSValue::encode(throwTypeError(exec, ASCIILiteral("new.target passed to TypedArray is not an object.")));
 
     ConstructData data;
     if (object->methodTable()->getConstructData(object, data) == ConstructType::None)
-        return JSValue::encode(throwTypeError(exec, "new.target passed to TypedArray is not a valid constructor."));
+        return JSValue::encode(throwTypeError(exec, ASCIILiteral("new.target passed to TypedArray is not a valid constructor.")));
 
     for (; !value.isNull(); value = jsCast<JSObject*>(value)->getPrototypeDirect()) {
         if (jsDynamicCast<JSTypedArrayViewConstructor*>(value))
-            return JSValue::encode(throwTypeError(exec, "Unable to find TypedArray constructor that inherits from TypedArray."));
+            return JSValue::encode(throwTypeError(exec, ASCIILiteral("Unable to find TypedArray constructor that inherits from TypedArray.")));
         if (jsDynamicCast<JSGenericTypedArrayViewConstructor<JSInt8Array>*>(value))
             return constructGenericTypedArrayView<JSInt8Array>(exec);
         if (jsDynamicCast<JSGenericTypedArrayViewConstructor<JSInt16Array>*>(value))
@@ -100,7 +100,7 @@ static EncodedJSValue JSC_HOST_CALL constructTypedArrayView(ExecState* exec)
             return constructGenericTypedArrayView<JSFloat64Array>(exec);
     }
     
-    return JSValue::encode(throwTypeError(exec, "Unable to find TypedArray constructor in prototype-chain, hit null."));
+    return JSValue::encode(throwTypeError(exec, ASCIILiteral("Unable to find TypedArray constructor in prototype-chain, hit null.")));
 }
 
 ConstructType JSTypedArrayViewConstructor::getConstructData(JSCell*, ConstructData& constructData)
index 42be36d..6fe5c4b 100644 (file)
@@ -58,8 +58,8 @@ namespace JSC {
         return functionName<JSUint16Array>(exec);                                               \
     case NotTypedArray:                                                                         \
     case TypeDataView:                                                                          \
-        return throwVMError(exec, createTypeError(exec,                                         \
-            "Receiver should be a typed array view"));                                          \
+        return throwVMTypeError(exec,                                                           \
+            ASCIILiteral("Receiver should be a typed array view"));                             \
     }                                                                                           \
     RELEASE_ASSERT_NOT_REACHED();                                                               \
 } while (false)
@@ -78,7 +78,7 @@ EncodedJSValue JSC_HOST_CALL typedArrayViewPrivateFuncLength(ExecState* exec)
 
     JSArrayBufferView* thisObject = jsCast<JSArrayBufferView*>(argument);
     if (!thisObject || thisObject->mode() == DataViewMode)
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view"));
     if (thisObject->isNeutered())
         return throwVMTypeError(exec, "Underlying ArrayBuffer has been detached from the view");
 
@@ -103,7 +103,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncSet(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncSet);
 }
 
@@ -111,7 +111,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncCopyWithin(ExecState*
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncCopyWithin);
 }
 
@@ -119,7 +119,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncFill(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncFill);
 }
 
@@ -127,7 +127,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncLastIndexOf(ExecState
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncLastIndexOf);
 }
 
@@ -135,7 +135,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncIndexOf(ExecState* ex
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncIndexOf);
 }
 
@@ -143,7 +143,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncJoin(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncJoin);
 }
 
@@ -151,7 +151,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoGetterFuncBuffer(ExecStat
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoGetterFuncBuffer);
 }
 
@@ -159,7 +159,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoGetterFuncLength(ExecStat
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoGetterFuncLength);
 }
 
@@ -167,7 +167,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoGetterFuncByteLength(Exec
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoGetterFuncByteLength);
 }
 
@@ -175,7 +175,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoGetterFuncByteOffset(Exec
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoGetterFuncByteOffset);
 }
 
@@ -183,7 +183,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncReverse(ExecState* ex
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncReverse);
 }
 
@@ -191,7 +191,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncSubarray(ExecState* e
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncSubarray);
 }
 
@@ -199,7 +199,7 @@ static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoFuncSlice(ExecState* exec
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.isObject())
-        return throwVMError(exec, createTypeError(exec, "Receiver should be a typed array view but was not an object"));
+        return throwVMTypeError(exec, ASCIILiteral("Receiver should be a typed array view but was not an object"));
     CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION(genericTypedArrayViewProtoFuncSlice);
 }
 
index 3c293fb..c795049 100644 (file)
@@ -335,7 +335,7 @@ bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
 {
     VM& vm = exec->vm();
     if (!in.isObject()) {
-        vm.throwException(exec, createTypeError(exec, ASCIILiteral("Property description must be an object.")));
+        throwTypeError(exec, ASCIILiteral("Property description must be an object."));
         return false;
     }
     JSObject* description = asObject(in);
@@ -380,7 +380,7 @@ bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
         if (!get.isUndefined()) {
             CallData callData;
             if (getCallData(get, callData) == CallType::None) {
-                vm.throwException(exec, createTypeError(exec, ASCIILiteral("Getter must be a function.")));
+                throwTypeError(exec, ASCIILiteral("Getter must be a function."));
                 return false;
             }
         }
@@ -395,7 +395,7 @@ bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
         if (!set.isUndefined()) {
             CallData callData;
             if (getCallData(set, callData) == CallType::None) {
-                vm.throwException(exec, createTypeError(exec, ASCIILiteral("Setter must be a function.")));
+                throwTypeError(exec, ASCIILiteral("Setter must be a function."));
                 return false;
             }
         }
@@ -407,12 +407,12 @@ bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
         return true;
 
     if (desc.value()) {
-        vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property.  'value' present on property with getter or setter.")));
+        throwTypeError(exec, ASCIILiteral("Invalid property.  'value' present on property with getter or setter."));
         return false;
     }
 
     if (desc.writablePresent()) {
-        vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property.  'writable' present on property with getter or setter.")));
+        throwTypeError(exec, ASCIILiteral("Invalid property.  'writable' present on property with getter or setter."));
         return false;
     }
     return true;
@@ -421,7 +421,7 @@ bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
 EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec)
 {
     if (!exec->argument(0).isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
+        return throwVMTypeError(exec, ASCIILiteral("Properties can only be defined on Objects."));
     JSObject* O = asObject(exec->argument(0));
     auto propertyName = exec->argument(1).toPropertyKey(exec);
     if (exec->hadException())
@@ -476,7 +476,7 @@ static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* pro
 EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec)
 {
     if (!exec->argument(0).isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
+        return throwVMTypeError(exec, ASCIILiteral("Properties can only be defined on Objects."));
     JSObject* targetObj = asObject(exec->argument(0));
     JSObject* props = exec->argument(1).toObject(exec);
     if (!props)
@@ -488,14 +488,14 @@ EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec)
 {
     JSValue proto = exec->argument(0);
     if (!proto.isObject() && !proto.isNull())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null.")));
+        return throwVMTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null."));
     JSObject* newObject = proto.isObject()
         ? constructEmptyObject(exec, asObject(proto))
         : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
     if (exec->argument(1).isUndefined())
         return JSValue::encode(newObject);
     if (!exec->argument(1).isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Property descriptor list must be an Object.")));
+        return throwVMTypeError(exec, ASCIILiteral("Property descriptor list must be an Object."));
     return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1))));
 }
 
index c49f6d0..6e0e7cb 100644 (file)
@@ -134,7 +134,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec)
     JSValue get = exec->argument(1);
     CallData callData;
     if (getCallData(get, callData) == CallType::None)
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid getter usage")));
+        return throwVMTypeError(exec, ASCIILiteral("invalid getter usage"));
 
     auto propertyName = exec->argument(0).toPropertyKey(exec);
     if (exec->hadException())
@@ -160,7 +160,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec)
     JSValue set = exec->argument(1);
     CallData callData;
     if (getCallData(set, callData) == CallType::None)
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid setter usage")));
+        return throwVMTypeError(exec, ASCIILiteral("invalid setter usage"));
 
     auto propertyName = exec->argument(0).toPropertyKey(exec);
     if (exec->hadException())
index cc3a202..afc3ed7 100644 (file)
@@ -143,7 +143,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
     
     if (arg0.inherits(RegExpObject::info())) {
         if (!arg1.isUndefined())
-            return throwVMError(exec, createTypeError(exec, ASCIILiteral("Cannot supply flags when constructing one RegExp from another.")));
+            return throwVMTypeError(exec, ASCIILiteral("Cannot supply flags when constructing one RegExp from another."));
         regExp = asRegExpObject(arg0)->regExp();
     } else {
         String pattern = !exec->argumentCount() ? emptyString() : arg0.toString(exec)->value(exec);
index cd051a7..6ac790a 100644 (file)
@@ -79,7 +79,7 @@ JSObject* Symbol::toObject(ExecState* exec, JSGlobalObject* globalObject) const
 
 double Symbol::toNumber(ExecState* exec) const
 {
-    throwTypeError(exec, "Cannot convert a symbol to a number");
+    throwTypeError(exec, ASCIILiteral("Cannot convert a symbol to a number"));
     return 0.0;
 }
 
index 295cb4c..59e42c5 100644 (file)
@@ -1,3 +1,69 @@
+2016-07-06  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Unify how we throw TypeError from C++
+        https://bugs.webkit.org/show_bug.cgi?id=159500
+
+        Reviewed by Saam Barati.
+
+        * bindings/js/JSBiquadFilterNodeCustom.cpp:
+        (WebCore::JSBiquadFilterNode::setType):
+        * bindings/js/JSBlobCustom.cpp:
+        (WebCore::constructJSBlob):
+        * bindings/js/JSCryptoKeySerializationJWK.cpp:
+        (WebCore::getBigIntegerVectorFromJSON):
+        (WebCore::JSCryptoKeySerializationJWK::JSCryptoKeySerializationJWK):
+        (WebCore::tryJWKKeyOpsValue):
+        (WebCore::JSCryptoKeySerializationJWK::reconcileUsages):
+        (WebCore::JSCryptoKeySerializationJWK::keyDataOctetSequence):
+        (WebCore::JSCryptoKeySerializationJWK::keyDataRSAComponents):
+        (WebCore::JSCryptoKeySerializationJWK::keyData):
+        (WebCore::addJWKAlgorithmToJSON):
+        (WebCore::JSCryptoKeySerializationJWK::serialize):
+        * bindings/js/JSCryptoOperationData.cpp:
+        (WebCore::cryptoOperationDataFromJSValue):
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::enforceRange):
+        (WebCore::throwTypeError):
+        (WebCore::throwArgumentMustBeEnumError):
+        (WebCore::throwArgumentMustBeFunctionError):
+        (WebCore::throwArgumentTypeError):
+        (WebCore::throwArrayElementTypeError):
+        (WebCore::throwGetterTypeError):
+        (WebCore::throwThisTypeError):
+        * bindings/js/JSDataCueCustom.cpp:
+        (WebCore::constructJSDataCue):
+        * bindings/js/JSDocumentCustom.cpp:
+        (WebCore::JSDocument::defineElement):
+        * bindings/js/JSFileCustom.cpp:
+        (WebCore::constructJSFile):
+        * bindings/js/JSModuleLoader.cpp:
+        (WebCore::JSModuleLoader::evaluate):
+        * bindings/js/JSMutationObserverCustom.cpp:
+        (WebCore::constructJSMutationObserver):
+        * bindings/js/JSOscillatorNodeCustom.cpp:
+        (WebCore::JSOscillatorNode::setType):
+        * bindings/js/JSPannerNodeCustom.cpp:
+        (WebCore::JSPannerNode::setPanningModel):
+        (WebCore::JSPannerNode::setDistanceModel):
+        * bindings/js/JSReadableStreamPrivateConstructors.cpp:
+        (WebCore::constructJSReadableStreamController):
+        (WebCore::constructJSReadableStreamReader):
+        * bindings/js/JSSubtleCryptoCustom.cpp:
+        (WebCore::cryptoKeyFormatFromJSValue):
+        (WebCore::importKey):
+        (WebCore::exportKey):
+        * bindings/js/ReadableStreamController.cpp:
+        (WebCore::ReadableStreamController::invoke):
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneDeserializer::throwValidationError):
+        (WebCore::SerializedScriptValue::maybeThrowExceptionIfSerializationFailed):
+        * bridge/c/c_instance.cpp:
+        (JSC::Bindings::CInstance::invokeMethod):
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::invokeMethod):
+        * bridge/objc/objc_runtime.mm:
+        (JSC::Bindings::ObjcArray::setValueAt):
+
 2016-07-06  Tim Horton  <timothy_horton@apple.com>
 
         Email from June 1st containing text 'Today @ 7:10PM' is linkified, but shouldn't be
index 921baef..0d5d939 100644 (file)
@@ -43,7 +43,7 @@ void JSBiquadFilterNode::setType(ExecState& state, JSValue value)
     if (value.isNumber()) {
         uint32_t type = value.toUInt32(&state);
         if (!wrapped().setType(type))
-            state.vm().throwException(&state, createTypeError(&state, "Illegal BiquadFilterNode type"));
+            throwTypeError(&state, "Illegal BiquadFilterNode type");
         return;
     }
 #endif
@@ -56,7 +56,7 @@ void JSBiquadFilterNode::setType(ExecState& state, JSValue value)
         }
     }
     
-    state.vm().throwException(&state, createTypeError(&state, "Illegal BiquadFilterNode type"));
+    throwTypeError(&state, "Illegal BiquadFilterNode type");
 }
 
 } // namespace WebCore
index a933587..cd4db96 100644 (file)
@@ -84,7 +84,7 @@ EncodedJSValue JSC_HOST_CALL constructJSBlob(ExecState* exec)
         JSValue blobPropertyBagValue = exec->argument(1);
 
         if (!blobPropertyBagValue.isObject())
-            return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type Object"));
+            return throwVMTypeError(exec, "Second argument of the constructor is not of type Object");
 
         // Given the above test, this will always yield an object.
         JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec);
@@ -99,7 +99,7 @@ EncodedJSValue JSC_HOST_CALL constructJSBlob(ExecState* exec)
 
         if (containsEndings) {
             if (endings != "transparent" && endings != "native")
-                return throwVMError(exec, createTypeError(exec, "The endings property must be either \"transparent\" or \"native\""));
+                return throwVMTypeError(exec, "The endings property must be either \"transparent\" or \"native\"");
         }
 
         // Attempt to get the type property.
index 565d63c..10aa914 100644 (file)
@@ -117,12 +117,12 @@ static bool getBigIntegerVectorFromJSON(ExecState* exec, JSObject* json, const c
         return false;
 
     if (!base64URLDecode(base64urlEncodedNumber, result)) {
-        throwTypeError(exec, "Cannot decode base64url key data in JWK");
+        throwTypeError(exec, ASCIILiteral("Cannot decode base64url key data in JWK"));
         return false;
     }
 
     if (result[0] == 0) {
-        throwTypeError(exec, "JWK BigInteger must utilize the minimum number of octets to represent the value");
+        throwTypeError(exec, ASCIILiteral("JWK BigInteger must utilize the minimum number of octets to represent the value"));
         return false;
     }
 
@@ -137,7 +137,7 @@ JSCryptoKeySerializationJWK::JSCryptoKeySerializationJWK(ExecState* exec, const
         return;
 
     if (!jsonValue || !jsonValue.isObject()) {
-        throwTypeError(exec, "Invalid JWK serialization");
+        throwTypeError(exec, ASCIILiteral("Invalid JWK serialization"));
         return;
     }
 
@@ -253,7 +253,7 @@ static bool tryJWKKeyOpsValue(ExecState* exec, CryptoKeyUsage& usages, const Str
 {
     if (operation == tryOperation) {
         if (usages & tryUsage) {
-            throwTypeError(exec, "JWK key_ops contains a duplicate operation");
+            throwTypeError(exec, ASCIILiteral("JWK key_ops contains a duplicate operation"));
             return false;
         }
         usages |= tryUsage;
@@ -272,7 +272,7 @@ void JSCryptoKeySerializationJWK::reconcileUsages(CryptoKeyUsage& suggestedUsage
             String operation;
             if (!jsValue.getString(m_exec, operation)) {
                 if (!m_exec->hadException())
-                    throwTypeError(m_exec, "JWK key_ops attribute could not be processed");
+                    throwTypeError(m_exec, ASCIILiteral("JWK key_ops attribute could not be processed"));
                 return;
             }
             if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("sign"), CryptoKeyUsageSign))
@@ -362,13 +362,13 @@ std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataOctetSequence
     String keyBase64URL;
     if (!getStringFromJSON(m_exec, m_json.get(), "k", keyBase64URL)) {
         if (!m_exec->hadException())
-            throwTypeError(m_exec, "Secret key data is not present is JWK");
+            throwTypeError(m_exec, ASCIILiteral("Secret key data is not present is JWK"));
         return nullptr;
     }
 
     Vector<uint8_t> octetSequence;
     if (!base64URLDecode(keyBase64URL, octetSequence)) {
-        throwTypeError(m_exec, "Cannot decode base64url key data in JWK");
+        throwTypeError(m_exec, ASCIILiteral("Cannot decode base64url key data in JWK"));
         return nullptr;
     }
 
@@ -388,7 +388,7 @@ std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataRSAComponents
 
     if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "n", modulus)) {
         if (!m_exec->hadException())
-            throwTypeError(m_exec, "Required JWK \"n\" member is missing");
+            throwTypeError(m_exec, ASCIILiteral("Required JWK \"n\" member is missing"));
         return nullptr;
     }
 
@@ -399,7 +399,7 @@ std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataRSAComponents
 
     if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "e", exponent)) {
         if (!m_exec->hadException())
-            throwTypeError(m_exec, "Required JWK \"e\" member is missing");
+            throwTypeError(m_exec, ASCIILiteral("Required JWK \"e\" member is missing"));
         return nullptr;
     }
 
@@ -455,22 +455,22 @@ std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataRSAComponents
         if (m_exec->hadException())
             return nullptr;
         if (!element.isObject()) {
-            throwTypeError(m_exec, "JWK \"oth\" array member is not an object");
+            throwTypeError(m_exec, ASCIILiteral("JWK \"oth\" array member is not an object"));
             return nullptr;
         }
         if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "r", info.primeFactor)) {
             if (!m_exec->hadException())
-                throwTypeError(m_exec, "Cannot get prime factor for a prime in \"oth\" dictionary");
+                throwTypeError(m_exec, ASCIILiteral("Cannot get prime factor for a prime in \"oth\" dictionary"));
             return nullptr;
         }
         if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "d", info.factorCRTExponent)) {
             if (!m_exec->hadException())
-                throwTypeError(m_exec, "Cannot get factor CRT exponent for a prime in \"oth\" dictionary");
+                throwTypeError(m_exec, ASCIILiteral("Cannot get factor CRT exponent for a prime in \"oth\" dictionary"));
             return nullptr;
         }
         if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "t", info.factorCRTCoefficient)) {
             if (!m_exec->hadException())
-                throwTypeError(m_exec, "Cannot get factor CRT coefficient for a prime in \"oth\" dictionary");
+                throwTypeError(m_exec, ASCIILiteral("Cannot get factor CRT coefficient for a prime in \"oth\" dictionary"));
             return nullptr;
         }
         otherPrimeInfos.append(info);
@@ -484,7 +484,7 @@ std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyData() const
     String jwkKeyType;
     if (!getStringFromJSON(m_exec, m_json.get(), "kty", jwkKeyType)) {
         if (!m_exec->hadException())
-            throwTypeError(m_exec, "Required JWK \"kty\" member is missing");
+            throwTypeError(m_exec, ASCIILiteral("Required JWK \"kty\" member is missing"));
         return nullptr;
     }
 
@@ -649,7 +649,7 @@ static void addJWKAlgorithmToJSON(ExecState* exec, JSObject* json, const CryptoK
 
     if (jwkAlgorithm.isNull()) {
         // The spec doesn't currently tell whether export should fail, or just skip "alg" (which is an optional key in JWK).
-        throwTypeError(exec, "Key algorithm and size do not map to any JWK algorithm identifier");
+        throwTypeError(exec, ASCIILiteral("Key algorithm and size do not map to any JWK algorithm identifier"));
         return;
     }
 
@@ -689,7 +689,7 @@ String JSCryptoKeySerializationJWK::serialize(ExecState* exec, const CryptoKey&
     std::unique_ptr<CryptoKeyData> keyData = key.exportData();
     if (!keyData) {
         // This generally shouldn't happen as long as all key types implement exportData(), but as underlying libraries return errors, there may be some rare failure conditions.
-        throwTypeError(exec, "Couldn't export key material");
+        throwTypeError(exec, ASCIILiteral("Couldn't export key material"));
         return String();
     }
 
@@ -710,7 +710,7 @@ String JSCryptoKeySerializationJWK::serialize(ExecState* exec, const CryptoKey&
     else if (is<CryptoKeyDataRSAComponents>(*keyData))
         buildJSONForRSAComponents(exec, downcast<CryptoKeyDataRSAComponents>(*keyData), result);
     else {
-        throwTypeError(exec, "Key doesn't support exportKey");
+        throwTypeError(exec, ASCIILiteral("Key doesn't support exportKey"));
         return String();
     }
     if (exec->hadException())
index 85b17b5..b4d4e98 100644 (file)
@@ -41,7 +41,7 @@ bool cryptoOperationDataFromJSValue(ExecState* exec, JSValue value, CryptoOperat
     else if (RefPtr<ArrayBufferView> bufferView = toArrayBufferView(value))
         result = std::make_pair(static_cast<uint8_t*>(bufferView->baseAddress()), bufferView->byteLength());
     else {
-        throwTypeError(exec, "Only ArrayBuffer and ArrayBufferView objects can be passed as CryptoOperationData");
+        throwTypeError(exec, ASCIILiteral("Only ArrayBuffer and ArrayBufferView objects can be passed as CryptoOperationData"));
         return false;
     }
     return true;
index 152d0f4..d820e23 100644 (file)
@@ -374,12 +374,12 @@ static String rangeErrorString(double value, double min, double max)
 static double enforceRange(ExecState& state, double x, double minimum, double maximum)
 {
     if (std::isnan(x) || std::isinf(x)) {
-        state.vm().throwException(&state, createTypeError(&state, rangeErrorString(x, minimum, maximum)));
+        throwTypeError(&state, rangeErrorString(x, minimum, maximum));
         return 0;
     }
     x = trunc(x);
     if (x < minimum || x > maximum) {
-        state.vm().throwException(&state, createTypeError(&state, rangeErrorString(x, minimum, maximum)));
+        throwTypeError(&state, rangeErrorString(x, minimum, maximum));
         return 0;
     }
     return x;
@@ -736,7 +736,7 @@ bool BindingSecurity::shouldAllowAccessToNode(JSC::ExecState* state, Node* targe
     
 static EncodedJSValue throwTypeError(JSC::ExecState& state, const String& errorMessage)
 {
-    return throwVMError(&state, createTypeError(&state, errorMessage));
+    return throwVMTypeError(&state, errorMessage);
 }
 
 static void appendArgumentMustBe(StringBuilder& builder, unsigned argumentIndex, const char* argumentName, const char* interfaceName, const char* functionName)
@@ -791,7 +791,7 @@ JSC::EncodedJSValue throwArgumentMustBeEnumError(JSC::ExecState& state, unsigned
     appendArgumentMustBe(builder, argumentIndex, argumentName, functionInterfaceName, functionName);
     builder.appendLiteral("one of: ");
     builder.append(expectedValues);
-    return throwTypeError(state, builder.toString());
+    return throwVMTypeError(&state, builder.toString());
 }
 
 JSC::EncodedJSValue throwArgumentMustBeFunctionError(JSC::ExecState& state, unsigned argumentIndex, const char* argumentName, const char* interfaceName, const char* functionName)
@@ -799,7 +799,7 @@ JSC::EncodedJSValue throwArgumentMustBeFunctionError(JSC::ExecState& state, unsi
     StringBuilder builder;
     appendArgumentMustBe(builder, argumentIndex, argumentName, interfaceName, functionName);
     builder.appendLiteral("a function");
-    return throwTypeError(state, builder.toString());
+    return throwVMTypeError(&state, builder.toString());
 }
 
 JSC::EncodedJSValue throwArgumentTypeError(JSC::ExecState& state, unsigned argumentIndex, const char* argumentName, const char* functionInterfaceName, const char* functionName, const char* expectedType)
@@ -808,12 +808,12 @@ JSC::EncodedJSValue throwArgumentTypeError(JSC::ExecState& state, unsigned argum
     appendArgumentMustBe(builder, argumentIndex, argumentName, functionInterfaceName, functionName);
     builder.appendLiteral("an instance of ");
     builder.append(expectedType);
-    return throwTypeError(state, builder.toString());
+    return throwVMTypeError(&state, builder.toString());
 }
 
 void throwArrayElementTypeError(JSC::ExecState& state)
 {
-    throwTypeError(state, "Invalid Array element type");
+    throwTypeError(state, ASCIILiteral("Invalid Array element type"));
 }
 
 void throwAttributeTypeError(JSC::ExecState& state, const char* interfaceName, const char* attributeName, const char* expectedType)
@@ -829,7 +829,7 @@ JSC::EncodedJSValue throwConstructorDocumentUnavailableError(JSC::ExecState& sta
 
 JSC::EncodedJSValue throwGetterTypeError(JSC::ExecState& state, const char* interfaceName, const char* attributeName)
 {
-    return throwTypeError(state, makeString("The ", interfaceName, '.', attributeName, " getter can only be used on instances of ", interfaceName));
+    return throwVMTypeError(&state, makeString("The ", interfaceName, '.', attributeName, " getter can only be used on instances of ", interfaceName));
 }
 
 void throwSequenceTypeError(JSC::ExecState& state)
@@ -850,7 +850,7 @@ bool throwSetterTypeError(JSC::ExecState& state, const char* interfaceName, cons
 
 EncodedJSValue throwThisTypeError(JSC::ExecState& state, const char* interfaceName, const char* functionName)
 {
-    return throwTypeError(state, makeString("Can only call ", interfaceName, '.', functionName, " on instances of ", interfaceName));
+    return throwVMTypeError(&state, makeString("Can only call ", interfaceName, '.', functionName, " on instances of ", interfaceName));
 }
 
 void callFunctionWithCurrentArguments(JSC::ExecState& state, JSC::JSObject& thisObject, JSC::JSFunction& function)
index 6efbde5..05b9dd6 100644 (file)
@@ -69,7 +69,7 @@ EncodedJSValue JSC_HOST_CALL constructJSDataCue(ExecState* exec)
 #if ENABLE(DATACUE_VALUE)
     if (exec->argumentCount() > 3) {
         if (!exec->argument(3).isString())
-            return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type String"));
+            return throwVMTypeError(exec, ASCIILiteral("Second argument of the constructor is not of type String"));
         type = exec->argument(3).getString(exec);
     }
 #endif
index d974157..8129f05 100644 (file)
@@ -154,7 +154,7 @@ JSValue JSDocument::defineElement(ExecState& state)
     JSObject* object = state.argument(1).getObject();
     ConstructData callData;
     if (!object || object->methodTable()->getConstructData(object, callData) == ConstructType::None)
-        return throwTypeError(&state, "The second argument must be a constructor");
+        return throwTypeError(&state, ASCIILiteral("The second argument must be a constructor"));
 
     Document& document = wrapped();
     if (!document.domWindow()) {
index cf75d25..ed9372f 100644 (file)
@@ -49,7 +49,7 @@ EncodedJSValue JSC_HOST_CALL constructJSFile(ExecState* exec)
 
     JSValue arg = exec->argument(0);
     if (arg.isUndefinedOrNull())
-        return throwVMError(exec, createTypeError(exec, "First argument to File constructor must be a valid sequence, was undefined or null"));
+        return throwVMTypeError(exec, ASCIILiteral("First argument to File constructor must be a valid sequence, was undefined or null"));
 
     unsigned blobPartsLength = 0;
     JSObject* blobParts = toJSSequence(exec, arg, blobPartsLength);
@@ -59,7 +59,7 @@ EncodedJSValue JSC_HOST_CALL constructJSFile(ExecState* exec)
 
     arg = exec->argument(1);
     if (arg.isUndefined())
-        return throwVMError(exec, createTypeError(exec, "Second argument to File constructor must be a valid string, was undefined"));
+        return throwVMTypeError(exec, ASCIILiteral("Second argument to File constructor must be a valid string, was undefined"));
 
     String filename = arg.toWTFString(exec).replace('/', ':');
     if (exec->hadException())
@@ -72,7 +72,7 @@ EncodedJSValue JSC_HOST_CALL constructJSFile(ExecState* exec)
     if (!arg.isUndefinedOrNull()) {
         JSObject* filePropertyBagObject = arg.getObject();
         if (!filePropertyBagObject)
-            return throwVMError(exec, createTypeError(exec, "Third argument of the constructor is not of type Object"));
+            return throwVMTypeError(exec, ASCIILiteral("Third argument of the constructor is not of type Object"));
 
         // Create the dictionary wrapper from the initializer object.
         JSDictionary dictionary(exec, filePropertyBagObject);
index 5457e7e..4669425 100644 (file)
@@ -116,10 +116,10 @@ JSC::JSValue JSModuleLoader::evaluate(JSC::JSGlobalObject*, JSC::ExecState* exec
     else if (moduleKeyValue.isString())
         sourceUrl = URL(URL(), asString(moduleKeyValue)->value(exec));
     else
-        return JSC::throwTypeError(exec, "Module key is not Symbol or String.");
+        return JSC::throwTypeError(exec, ASCIILiteral("Module key is not Symbol or String."));
 
     if (!sourceUrl.isValid())
-        return JSC::throwTypeError(exec, "Module key is an invalid URL.");
+        return JSC::throwTypeError(exec, ASCIILiteral("Module key is an invalid URL."));
 
     // FIXME: Implement evaluating module code.
 
index c150ea0..e2fb1c7 100644 (file)
@@ -50,7 +50,7 @@ EncodedJSValue JSC_HOST_CALL constructJSMutationObserver(ExecState* exec)
     JSObject* object = exec->argument(0).getObject();
     CallData callData;
     if (!object || object->methodTable()->getCallData(object, callData) == CallType::None)
-        return throwVMError(exec, createTypeError(exec, "Callback argument must be a function"));
+        return throwVMTypeError(exec, ASCIILiteral("Callback argument must be a function"));
 
     DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec->callee());
     auto callback = JSMutationCallback::create(object, jsConstructor->globalObject());
index 3adf802..7c9c676 100644 (file)
@@ -45,7 +45,7 @@ void JSOscillatorNode::setType(ExecState& state, JSValue value)
     if (value.isNumber()) {
         uint32_t type = value.toUInt32(&state);
         if (!imp.setType(type))
-            state.vm().throwException(&state, createTypeError(&state, "Illegal OscillatorNode type"));
+            throwTypeError(&state, ASCIILiteral("Illegal OscillatorNode type"));
         return;
     }
 #endif
@@ -58,7 +58,7 @@ void JSOscillatorNode::setType(ExecState& state, JSValue value)
         }
     }
     
-    state.vm().throwException(&state, createTypeError(&state, "Illegal OscillatorNode type"));
+    throwTypeError(&state, ASCIILiteral("Illegal OscillatorNode type"));
 }
 
 } // namespace WebCore
index 6790f84..d60845b 100644 (file)
@@ -45,7 +45,7 @@ void JSPannerNode::setPanningModel(ExecState& state, JSValue value)
     if (value.isNumber()) {
         uint32_t model = value.toUInt32(&state);
         if (!imp.setPanningModel(model))
-            state.vm().throwException(&state, createTypeError(&state, "Illegal panningModel"));
+            throwTypeError(&state, ASCIILiteral("Illegal panningModel"));
         return;
     }
 #endif
@@ -58,7 +58,7 @@ void JSPannerNode::setPanningModel(ExecState& state, JSValue value)
         }
     }
     
-    state.vm().throwException(&state, createTypeError(&state, "Illegal panningModel"));
+    throwTypeError(&state, ASCIILiteral("Illegal panningModel"));
 }
 
 void JSPannerNode::setDistanceModel(ExecState& state, JSValue value)
@@ -69,7 +69,7 @@ void JSPannerNode::setDistanceModel(ExecState& state, JSValue value)
     if (value.isNumber()) {
         uint32_t model = value.toUInt32(&state);
         if (!imp.setDistanceModel(model))
-            state.vm().throwException(&state, createTypeError(&state, "Illegal distanceModel"));
+            throwTypeError(&state, ASCIILiteral("Illegal distanceModel"));
         return;
     }
 #endif
@@ -82,7 +82,7 @@ void JSPannerNode::setDistanceModel(ExecState& state, JSValue value)
         }
     }
     
-    state.vm().throwException(&state, createTypeError(&state, "Illegal distanceModel"));
+    throwTypeError(&state, ASCIILiteral("Illegal distanceModel"));
 }
 
 } // namespace WebCore
index c660861..ba2c774 100644 (file)
@@ -36,14 +36,14 @@ namespace WebCore {
 // Public JS ReadableStreamReder and ReadableStreamController constructor callbacks.
 EncodedJSValue JSC_HOST_CALL constructJSReadableStreamController(ExecState* state)
 {
-    return throwVMError(state, createTypeError(state, ASCIILiteral("ReadableStreamController constructor should not be called directly")));
+    return throwVMTypeError(state, ASCIILiteral("ReadableStreamController constructor should not be called directly"));
 }
 
 EncodedJSValue JSC_HOST_CALL constructJSReadableStreamReader(ExecState* state)
 {
     JSReadableStream* stream = jsDynamicCast<JSReadableStream*>(state->argument(0));
     if (!stream)
-        return throwVMError(state, createTypeError(state, ASCIILiteral("ReadableStreamReader constructor parameter is not a ReadableStream")));
+        return throwVMTypeError(state, ASCIILiteral("ReadableStreamReader constructor parameter is not a ReadableStream"));
 
     JSValue jsFunction = stream->get(state, Identifier::fromString(state, "getReader"));
 
index 8c6d88a..03351d5 100644 (file)
@@ -89,7 +89,7 @@ static bool cryptoKeyFormatFromJSValue(ExecState& state, JSValue value, CryptoKe
     else if (keyFormatString == "jwk")
         result = CryptoKeyFormat::JWK;
     else {
-        throwTypeError(&state, "Unknown key format");
+        throwTypeError(&state, ASCIILiteral("Unknown key format"));
         return false;
     }
     return true;
@@ -453,7 +453,7 @@ static void importKey(ExecState& state, CryptoKeyFormat keyFormat, CryptoOperati
     case CryptoKeyFormat::JWK: {
         String jwkString = String::fromUTF8(data.first, data.second);
         if (jwkString.isNull()) {
-            throwTypeError(&state, "JWK JSON serialization is not valid UTF-8");
+            throwTypeError(&state, ASCIILiteral("JWK JSON serialization is not valid UTF-8"));
             return;
         }
         keySerialization = std::make_unique<JSCryptoKeySerializationJWK>(&state, jwkString);
@@ -462,7 +462,7 @@ static void importKey(ExecState& state, CryptoKeyFormat keyFormat, CryptoOperati
         break;
     }
     default:
-        throwTypeError(&state, "Unsupported key format for import");
+        throwTypeError(&state, ASCIILiteral("Unsupported key format for import"));
         return;
     }
 
@@ -470,14 +470,14 @@ static void importKey(ExecState& state, CryptoKeyFormat keyFormat, CryptoOperati
 
     if (!keySerialization->reconcileAlgorithm(algorithm, parameters)) {
         if (!state.hadException())
-            throwTypeError(&state, "Algorithm specified in key is not compatible with one passed to importKey as argument");
+            throwTypeError(&state, ASCIILiteral("Algorithm specified in key is not compatible with one passed to importKey as argument"));
         return;
     }
     if (state.hadException())
         return;
 
     if (!algorithm) {
-        throwTypeError(&state, "Neither key nor function argument has crypto algorithm specified");
+        throwTypeError(&state, ASCIILiteral("Neither key nor function argument has crypto algorithm specified"));
         return;
     }
     ASSERT(parameters);
@@ -566,7 +566,7 @@ JSValue JSSubtleCrypto::importKey(ExecState& state)
 static void exportKey(ExecState& state, CryptoKeyFormat keyFormat, const CryptoKey& key, CryptoAlgorithm::VectorCallback callback, CryptoAlgorithm::VoidCallback failureCallback)
 {
     if (!key.extractable()) {
-        throwTypeError(&state, "Key is not extractable");
+        throwTypeError(&state, ASCIILiteral("Key is not extractable"));
         return;
     }
 
@@ -590,7 +590,7 @@ static void exportKey(ExecState& state, CryptoKeyFormat keyFormat, const CryptoK
         break;
     }
     default:
-        throwTypeError(&state, "Unsupported key format for export");
+        throwTypeError(&state, ASCIILiteral("Unsupported key format for export"));
         break;
     }
 }
index d78cd91..c0cbf95 100644 (file)
@@ -55,7 +55,7 @@ JSC::JSValue ReadableStreamController::invoke(JSC::ExecState& state, JSC::JSObje
 
     if (!function.isFunction()) {
         if (!function.isUndefined())
-            throwVMError(&state, createTypeError(&state, ASCIILiteral("ReadableStream trying to call a property that is not callable")));
+            throwTypeError(&state, ASCIILiteral("ReadableStream trying to call a property that is not callable"));
         return JSC::jsUndefined();
     }
 
index bbf9637..dbf752e 100644 (file)
@@ -1569,7 +1569,7 @@ private:
 
     void throwValidationError()
     {
-        m_exec->vm().throwException(m_exec, createTypeError(m_exec, "Unable to deserialize data."));
+        throwTypeError(m_exec, ASCIILiteral("Unable to deserialize data."));
     }
 
     bool isValid() const { return m_version <= CurrentVersion; }
@@ -2763,7 +2763,7 @@ void SerializedScriptValue::maybeThrowExceptionIfSerializationFailed(ExecState*
         exec->vm().throwException(exec, createStackOverflowError(exec));
         break;
     case ValidationError:
-        exec->vm().throwException(exec, createTypeError(exec, "Unable to deserialize data."));
+        throwTypeError(exec, ASCIILiteral("Unable to deserialize data."));
         break;
     case DataCloneError:
         setDOMException(exec, DATA_CLONE_ERR);
index faa88d2..d3b5ba9 100644 (file)
@@ -155,7 +155,7 @@ JSValue CInstance::getMethod(ExecState* exec, PropertyName propertyName)
 JSValue CInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
 {
     if (!asObject(runtimeMethod)->inherits(CRuntimeMethod::info()))
-        return exec->vm().throwException(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
+        return throwTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object.");
 
     CMethod* method = static_cast<CMethod*>(runtimeMethod->method());
     ASSERT(method);
index 6a632f4..81d2caf 100644 (file)
@@ -206,7 +206,7 @@ JSC::JSValue ObjcInstance::getMethod(ExecState* exec, PropertyName propertyName)
 JSC::JSValue ObjcInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
 {
     if (!asObject(runtimeMethod)->inherits(ObjCRuntimeMethod::info()))
-        return exec->vm().throwException(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
+        return throwTypeError(exec, ASCIILiteral("Attempt to invoke non-plug-in method on plug-in object."));
 
     ObjcMethod *method = static_cast<ObjcMethod*>(runtimeMethod->method());
     ASSERT(method);
index 590f225..b53842d 100644 (file)
@@ -157,7 +157,7 @@ ObjcArray::ObjcArray(ObjectStructPtr a, RefPtr<RootObject>&& rootObject)
 bool ObjcArray::setValueAt(ExecState* exec, unsigned int index, JSValue aValue) const
 {
     if (![_array.get() respondsToSelector:@selector(insertObject:atIndex:)]) {
-        exec->vm().throwException(exec, createTypeError(exec, "Array is not mutable."));
+        throwTypeError(exec, ASCIILiteral("Array is not mutable."));
         return false;
     }
 
index 2832bcb..1238efd 100644 (file)
@@ -1,3 +1,13 @@
+2016-07-06  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Unify how we throw TypeError from C++
+        https://bugs.webkit.org/show_bug.cgi?id=159500
+
+        Reviewed by Saam Barati.
+
+        * Plugins/Hosted/ProxyInstance.mm:
+        (WebKit::ProxyInstance::invokeMethod):
+
 2016-07-01  Youenn Fablet  <youennf@gmail.com>
 
         Add a runtime flag for DOM iterators
index 6714e8c..5ad8ac7 100644 (file)
@@ -220,7 +220,7 @@ JSValue ProxyInstance::getMethod(JSC::ExecState* exec, PropertyName propertyName
 JSValue ProxyInstance::invokeMethod(ExecState* exec, JSC::RuntimeMethod* runtimeMethod)
 {
     if (!asObject(runtimeMethod)->inherits(ProxyRuntimeMethod::info()))
-        return exec->vm().throwException(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
+        return throwTypeError(exec, ASCIILiteral("Attempt to invoke non-plug-in method on plug-in object."));
 
     ProxyMethod* method = static_cast<ProxyMethod*>(runtimeMethod->method());
     ASSERT(method);