Ignore:
Timestamp:
Jun 6, 2010, 4:34:36 PM (15 years ago)
Author:
[email protected]
Message:

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):

(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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r60117 r60762  
    7474}
    7575
    76 static JSValue createError(ExecState* exec, ErrorType e, const char* msg)
     76JSObject* createStackOverflowError(ExecState* exec)
    7777{
    78     return Error::create(exec, e, msg, -1, -1, UString());
    79 }
    80 
    81 JSValue createStackOverflowError(ExecState* exec)
    82 {
    83     return createError(exec, RangeError, "Maximum call stack size exceeded.");
    84 }
    85 
    86 JSValue createTypeError(ExecState* exec, const char* message)
    87 {
    88     return createError(exec, TypeError, message);
     78    return createRangeError(exec, "Maximum call stack size exceeded.");
    8979}
    9080
     
    9585    int divotPoint = 0;
    9686    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    97     JSObject* exception = Error::create(exec, ReferenceError, makeString("Can't find variable: ", ident.ustring()), line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    98     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    99     exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
    100     exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
     87    UString message(makeString("Can't find variable: ", ident.ustring()));
     88    JSObject* exception = addErrorInfo(exec, createReferenceError(exec, message), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
    10189    return exception;
    10290}
     
    134122    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    135123    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'"));
    136     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    137     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    138     exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
    139     exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
     124    JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
    140125    return exception;
    141126}
     
    155140   
    156141    UString errorMessage = createErrorMessage(exec, codeBlock, line, startPoint, divotPoint, value, "not a constructor");
    157     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    158     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    159     exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
    160     exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
     142    JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
    161143    return exception;
    162144}
     
    169151    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    170152    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, value, "not a function");
    171     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());   
    172     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    173     exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
    174     exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
     153    JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
    175154    return exception;
    176155}
     
    199178    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    200179    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object");
    201     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    202     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    203     exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
    204     exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
     180    JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
    205181    return exception;
    206182}
     
    208184JSValue throwOutOfMemoryError(ExecState* exec)
    209185{
    210     return throwError(exec, GeneralError, "Out of memory");
     186    return throwError(exec, createError(exec, "Out of memory"));
    211187}
    212188
Note: See TracChangeset for help on using the changeset viewer.