Bug 40214 - Clean up error construction / throwing in JSC.
Reviewed by Sam Weinig.
The one egregious insanity here is that creating an error requires
a VM-entry-esqe-host call (the string argument is wrapped as a JS
object & pushed on the RegisterFile, then unwrapped back to a
UString). Changing this also means you only require a global
object, not an ExecState, to create an error.
The methods to create error objects are also parameterized
requiring a switch on the type, which can be made cleaner and
faster by moving to a separate method per error type. Code to add
divot information to error had been duplicated, and is coalesced
back into a single function.
Convenience methods added to create & throw type & syntax error
with a default error message, since this is a common case.
Also, errors are currently thrown either using
"throwError(exec, error)" or "exec->setException(error)" - unify
on the former, since this is more commonly used. Add
"throwVMError(exec, error)" equivalents, as a convenience for
cases where the result was being wrapped in "JSValue::encode(...)".
JavaScriptCore:
* API/JSCallbackConstructor.cpp:
(JSC::constructJSCallback):
* API/JSCallbackFunction.cpp:
(JSC::JSCallbackFunction::call):
* API/JSCallbackObjectFunctions.h:
(JSC::::getOwnPropertySlot):
(JSC::::put):
(JSC::::deleteProperty):
(JSC::::construct):
(JSC::::hasInstance):
(JSC::::call):
(JSC::::toNumber):
(JSC::::toString):
(JSC::::staticValueGetter):
(JSC::::staticFunctionGetter):
(JSC::::callbackGetter):
* API/JSObjectRef.cpp:
(JSObjectMakeError):
* JavaScriptCore.exp:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewError):
(JSC::BytecodeGenerator::emitThrowExpressionTooDeepException):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ThrowableExpressionData::emitThrowError):
(JSC::RegExpNode::emitBytecode):
(JSC::PostfixErrorNode::emitBytecode):
(JSC::PrefixErrorNode::emitBytecode):
(JSC::AssignErrorNode::emitBytecode):
(JSC::ForInNode::emitBytecode):
(JSC::ContinueNode::emitBytecode):
(JSC::BreakNode::emitBytecode):
(JSC::ReturnNode::emitBytecode):
(JSC::LabelNode::emitBytecode):
* interpreter/CallFrame.h:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::throwException):
(JSC::Interpreter::privateExecute):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jsc.cpp:
(functionRun):
(functionLoad):
(functionCheckSyntax):
* parser/Nodes.h:
* runtime/ArrayConstructor.cpp:
(JSC::constructArrayWithSizeQuirk):
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncToLocaleString):
(JSC::arrayProtoFuncJoin):
(JSC::arrayProtoFuncFilter):
(JSC::arrayProtoFuncMap):
(JSC::arrayProtoFuncEvery):
(JSC::arrayProtoFuncForEach):
(JSC::arrayProtoFuncSome):
(JSC::arrayProtoFuncReduce):
(JSC::arrayProtoFuncReduceRight):
* runtime/BooleanPrototype.cpp:
(JSC::booleanProtoFuncToString):
(JSC::booleanProtoFuncValueOf):
* runtime/DatePrototype.cpp:
(JSC::dateProtoFuncToString):
(JSC::dateProtoFuncToUTCString):
(JSC::dateProtoFuncToISOString):
(JSC::dateProtoFuncToDateString):
(JSC::dateProtoFuncToTimeString):
(JSC::dateProtoFuncToLocaleString):
(JSC::dateProtoFuncToLocaleDateString):
(JSC::dateProtoFuncToLocaleTimeString):
(JSC::dateProtoFuncGetTime):
(JSC::dateProtoFuncGetFullYear):
(JSC::dateProtoFuncGetUTCFullYear):
(JSC::dateProtoFuncToGMTString):
(JSC::dateProtoFuncGetMonth):
(JSC::dateProtoFuncGetUTCMonth):
(JSC::dateProtoFuncGetDate):
(JSC::dateProtoFuncGetUTCDate):
(JSC::dateProtoFuncGetDay):
(JSC::dateProtoFuncGetUTCDay):
(JSC::dateProtoFuncGetHours):
(JSC::dateProtoFuncGetUTCHours):
(JSC::dateProtoFuncGetMinutes):
(JSC::dateProtoFuncGetUTCMinutes):
(JSC::dateProtoFuncGetSeconds):
(JSC::dateProtoFuncGetUTCSeconds):
(JSC::dateProtoFuncGetMilliSeconds):
(JSC::dateProtoFuncGetUTCMilliseconds):
(JSC::dateProtoFuncGetTimezoneOffset):
(JSC::dateProtoFuncSetTime):
(JSC::setNewValueFromTimeArgs):
(JSC::setNewValueFromDateArgs):
(JSC::dateProtoFuncSetMilliSeconds):
(JSC::dateProtoFuncSetUTCMilliseconds):
(JSC::dateProtoFuncSetSeconds):
(JSC::dateProtoFuncSetUTCSeconds):
(JSC::dateProtoFuncSetMinutes):
(JSC::dateProtoFuncSetUTCMinutes):
(JSC::dateProtoFuncSetHours):
(JSC::dateProtoFuncSetUTCHours):
(JSC::dateProtoFuncSetDate):
(JSC::dateProtoFuncSetUTCDate):
(JSC::dateProtoFuncSetMonth):
(JSC::dateProtoFuncSetUTCMonth):
(JSC::dateProtoFuncSetFullYear):
(JSC::dateProtoFuncSetUTCFullYear):
(JSC::dateProtoFuncSetYear):
(JSC::dateProtoFuncGetYear):
(JSC::dateProtoFuncToJSON):
* runtime/Error.cpp:
(JSC::createError):
(JSC::createEvalError):
(JSC::createRangeError):
(JSC::createReferenceError):
(JSC::createSyntaxError):
(JSC::createTypeError):
(JSC::createURIError):
(JSC::addErrorSourceInfo):
(JSC::addErrorDivotInfo):
(JSC::addErrorInfo):
(JSC::hasErrorInfo):
(JSC::throwError):
(JSC::throwTypeError):
(JSC::throwSyntaxError):
* runtime/Error.h:
(JSC::throwVMError):
(JSC::throwVMTypeError):
* runtime/ErrorConstructor.cpp:
(JSC::constructWithErrorConstructor):
(JSC::callErrorConstructor):
* runtime/ErrorConstructor.h:
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::ErrorInstance):
(JSC::ErrorInstance::create):
* runtime/ErrorInstance.h:
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::ErrorPrototype):
* runtime/ExceptionHelpers.cpp:
(JSC::createStackOverflowError):
(JSC::createUndefinedVariableError):
(JSC::createInvalidParamError):
(JSC::createNotAConstructorError):
(JSC::createNotAFunctionError):
(JSC::createNotAnObjectError):
(JSC::throwOutOfMemoryError):
* runtime/ExceptionHelpers.h:
* runtime/Executable.cpp:
(JSC::EvalExecutable::compile):
(JSC::ProgramExecutable::checkSyntax):
(JSC::ProgramExecutable::compile):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunction):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
(JSC::functionProtoFuncApply):
(JSC::functionProtoFuncCall):
* runtime/Identifier.cpp:
(JSC::Identifier::from):
* runtime/Identifier.h:
* runtime/JSArray.cpp:
(JSC::JSArray::put):
* runtime/JSFunction.cpp:
(JSC::callHostFunctionAsConstructor):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::encode):
(JSC::decode):
(JSC::globalFuncEval):
* runtime/JSONObject.cpp:
(JSC::Stringifier::appendStringifiedValue):
(JSC::Walker::walk):
(JSC::JSONProtoFuncParse):
(JSC::JSONProtoFuncStringify):
* runtime/JSObject.cpp:
(JSC::throwSetterError):
(JSC::JSObject::put):
(JSC::JSObject::putWithAttributes):
(JSC::JSObject::defaultValue):
(JSC::JSObject::hasInstance):
(JSC::JSObject::defineOwnProperty):
* runtime/JSObject.h:
* runtime/JSValue.cpp:
(JSC::JSValue::toObjectSlowCase):
(JSC::JSValue::synthesizeObject):
(JSC::JSValue::synthesizePrototype):
* runtime/NativeErrorConstructor.cpp:
(JSC::constructWithNativeErrorConstructor):
(JSC::callNativeErrorConstructor):
* runtime/NativeErrorConstructor.h:
* runtime/NumberPrototype.cpp:
(JSC::numberProtoFuncToString):
(JSC::numberProtoFuncToLocaleString):
(JSC::numberProtoFuncValueOf):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToPrecision):
* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorGetPrototypeOf):
(JSC::objectConstructorGetOwnPropertyDescriptor):
(JSC::objectConstructorGetOwnPropertyNames):
(JSC::objectConstructorKeys):
(JSC::toPropertyDescriptor):
(JSC::objectConstructorDefineProperty):
(JSC::objectConstructorDefineProperties):
(JSC::objectConstructorCreate):
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncDefineGetter):
(JSC::objectProtoFuncDefineSetter):
* runtime/RegExpConstructor.cpp:
(JSC::constructRegExp):
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::match):
* runtime/RegExpPrototype.cpp:
(JSC::regExpProtoFuncTest):
(JSC::regExpProtoFuncExec):
(JSC::regExpProtoFuncCompile):
(JSC::regExpProtoFuncToString):
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncToString):
WebCore:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSArrayBufferConstructor.h:
(WebCore::construct):
* bindings/js/JSArrayBufferViewHelper.h:
(WebCore::setWebGLArrayHelper):
* bindings/js/JSAudioConstructor.cpp:
(WebCore::constructAudio):
* bindings/js/JSCanvasRenderingContext2DCustom.cpp:
(WebCore::JSCanvasRenderingContext2D::setFillColor):
(WebCore::JSCanvasRenderingContext2D::setStrokeColor):
(WebCore::JSCanvasRenderingContext2D::drawImage):
(WebCore::JSCanvasRenderingContext2D::drawImageFromRect):
(WebCore::JSCanvasRenderingContext2D::setShadow):
(WebCore::JSCanvasRenderingContext2D::createPattern):
(WebCore::JSCanvasRenderingContext2D::fillText):
(WebCore::JSCanvasRenderingContext2D::strokeText):
* bindings/js/JSClipboardCustom.cpp:
(WebCore::JSClipboard::clearData):
(WebCore::JSClipboard::getData):
(WebCore::JSClipboard::setDragImage):
* bindings/js/JSDOMBinding.cpp:
(WebCore::setDOMException):
(WebCore::toJSSequence):
* bindings/js/JSDOMWrapper.cpp:
(WebCore::DOMObject::defineOwnProperty):
* bindings/js/JSDesktopNotificationsCustom.cpp:
(WebCore::JSNotificationCenter::requestPermission):
* bindings/js/JSEventSourceConstructor.cpp:
(WebCore::constructEventSource):
* bindings/js/JSHTMLDocumentCustom.cpp:
(WebCore::JSHTMLDocument::open):
* bindings/js/JSHTMLInputElementCustom.cpp:
(WebCore::JSHTMLInputElement::selectionStart):
(WebCore::JSHTMLInputElement::setSelectionStart):
(WebCore::JSHTMLInputElement::selectionEnd):
(WebCore::JSHTMLInputElement::setSelectionEnd):
(WebCore::JSHTMLInputElement::setSelectionRange):
* bindings/js/JSImageConstructor.cpp:
(WebCore::constructImage):
* bindings/js/JSJavaScriptCallFrameCustom.cpp:
(WebCore::JSJavaScriptCallFrame::evaluate):
* bindings/js/JSMessageChannelConstructor.cpp:
(WebCore::JSMessageChannelConstructor::construct):
* bindings/js/JSMessagePortCustom.cpp:
(WebCore::fillMessagePortArray):
* bindings/js/JSOptionConstructor.cpp:
(WebCore::constructHTMLOptionElement):
* bindings/js/JSSVGMatrixCustom.cpp:
(WebCore::JSSVGMatrix::multiply):
* bindings/js/JSSharedWorkerConstructor.cpp:
(WebCore::constructSharedWorker):
* bindings/js/JSWebGLRenderingContextCustom.cpp:
(WebCore::JSWebGLRenderingContext::bufferData):
(WebCore::JSWebGLRenderingContext::bufferSubData):
(WebCore::getObjectParameter):
(WebCore::JSWebGLRenderingContext::getFramebufferAttachmentParameter):
(WebCore::JSWebGLRenderingContext::getParameter):
(WebCore::JSWebGLRenderingContext::getProgramParameter):
(WebCore::JSWebGLRenderingContext::getShaderParameter):
(WebCore::JSWebGLRenderingContext::getUniform):
(WebCore::JSWebGLRenderingContext::texImage2D):
(WebCore::JSWebGLRenderingContext::texSubImage2D):
(WebCore::dataFunctionf):
(WebCore::dataFunctioni):
(WebCore::dataFunctionMatrix):
* bindings/js/JSWebSocketConstructor.cpp:
(WebCore::constructWebSocket):
* bindings/js/JSWebSocketCustom.cpp:
(WebCore::JSWebSocket::send):
* bindings/js/JSWorkerConstructor.cpp:
(WebCore::constructWorker):
* bindings/js/JSXMLHttpRequestConstructor.cpp:
(WebCore::constructXMLHttpRequest):
* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::JSXMLHttpRequest::open):
* bindings/js/SerializedScriptValue.cpp:
(WebCore::BaseWalker::throwStackOverflow):
(WebCore::BaseWalker::throwInterruptedException):
(WebCore::SerializingTreeWalker::startArray):
(WebCore::SerializingTreeWalker::startObject):
* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::setException):
* bindings/scripts/CodeGeneratorJS.pm:
* bridge/c/c_instance.cpp:
(JSC::Bindings::CInstance::moveGlobalExceptionToExecState):
(JSC::Bindings::CInstance::invokeMethod):
(JSC::Bindings::CInstance::invokeDefaultMethod):
(JSC::Bindings::CInstance::invokeConstruct):
* bridge/jni/jsc/JNIBridgeJSC.cpp:
(JavaField::dispatchValueFromInstance):
(JavaField::dispatchSetValueToInstance):
* bridge/jni/jsc/JavaInstanceJSC.cpp:
(JavaInstance::invokeMethod):
* bridge/objc/objc_instance.mm:
(ObjcInstance::moveGlobalExceptionToExecState):
(ObjcInstance::invokeMethod):
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::ObjcField::valueFromInstance):
(JSC::Bindings::ObjcField::setValueToInstance):
(JSC::Bindings::ObjcArray::setValueAt):
(JSC::Bindings::ObjcArray::valueAt):
(JSC::Bindings::callObjCFallbackObject):
* bridge/objc/objc_utility.h:
* bridge/objc/objc_utility.mm:
(JSC::Bindings::throwError):
* bridge/runtime_array.cpp:
(JSC::RuntimeArray::put):
* bridge/runtime_method.cpp:
(JSC::callRuntimeMethod):
* bridge/runtime_object.cpp:
(JSC::Bindings::RuntimeObject::throwInvalidAccessError):
WebKit/mac:
* Plugins/Hosted/NetscapePluginInstanceProxy.mm:
(WebKit::NetscapePluginInstanceProxy::moveGlobalExceptionToExecState):
* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyInstance::invokeMethod):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@60762 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/runtime/ErrorConstructor.cpp b/JavaScriptCore/runtime/ErrorConstructor.cpp
index a99e187..a0874d4 100644
--- a/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -38,18 +38,12 @@
}
// ECMA 15.9.3
-ErrorInstance* constructError(ExecState* exec, const ArgList& args)
-{
- ErrorInstance* obj = new (exec) ErrorInstance(exec->lexicalGlobalObject()->errorStructure());
- if (!args.at(0).isUndefined())
- obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(0).toString(exec)));
- return obj;
-}
static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState* exec)
{
- ArgList args(exec);
- return JSValue::encode(constructError(exec, args));
+ JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
+ Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
+ return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
}
ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
@@ -60,8 +54,9 @@
static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState* exec)
{
- ArgList args(exec);
- return JSValue::encode(constructError(exec, args));
+ JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
+ Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
+ return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
}
CallType ErrorConstructor::getCallData(CallData& callData)