⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 181889 in webkit


Ignore:
Timestamp:
Mar 24, 2015, 12:30:05 AM (11 years ago)
Author:
saambarati1@gmail.com
Message:

Improve error messages in JSC
https://bugs.webkit.org/show_bug.cgi?id=141869

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

JavaScriptCore has some unintuitive error messages associated
with certain common errors. This patch changes some specific
error messages to be more understandable and also creates a
mechanism that will allow for easy modification of error messages
in the future. The specific errors we change are not a function
errors and invalid parameter errors.

(JSC::sizeOfVarargs):

  • jit/JITOperations.cpp:

op_throw_static_error always has a JSString as its argument.
There is no need to dance around this, and we should assert
that this always holds. This JSString represents the error
message we want to display to the user, so there is no need
to pass it into errorDescriptionForValue which will now place
quotes around the string.

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:

(JSC::CommonSlowPaths::opIn):

  • runtime/ErrorInstance.cpp:

(JSC::ErrorInstance::ErrorInstance):

  • runtime/ErrorInstance.h:

(JSC::ErrorInstance::hasSourceAppender):
(JSC::ErrorInstance::sourceAppender):
(JSC::ErrorInstance::setSourceAppender):
(JSC::ErrorInstance::clearSourceAppender):
(JSC::ErrorInstance::setRuntimeTypeForCause):
(JSC::ErrorInstance::runtimeTypeForCause):
(JSC::ErrorInstance::clearRuntimeTypeForCause):
(JSC::ErrorInstance::appendSourceToMessage): Deleted.
(JSC::ErrorInstance::setAppendSourceToMessage): Deleted.
(JSC::ErrorInstance::clearAppendSourceToMessage): Deleted.

  • runtime/ExceptionHelpers.cpp:

(JSC::errorDescriptionForValue):
(JSC::defaultApproximateSourceError):
(JSC::defaultSourceAppender):
(JSC::functionCallBase):
(JSC::notAFunctionSourceAppender):
(JSC::invalidParameterInSourceAppender):
(JSC::invalidParameterInstanceofSourceAppender):
(JSC::createError):
(JSC::createInvalidFunctionApplyParameterError):
(JSC::createInvalidInParameterError):
(JSC::createInvalidInstanceofParameterError):
(JSC::createNotAConstructorError):
(JSC::createNotAFunctionError):
(JSC::createNotAnObjectError):
(JSC::createInvalidParameterError): Deleted.

  • runtime/ExceptionHelpers.h:
  • runtime/JSObject.cpp:

(JSC::JSObject::hasInstance):

  • runtime/RuntimeType.cpp: Added.

(JSC::runtimeTypeForValue):
(JSC::runtimeTypeAsString):

  • runtime/RuntimeType.h: Added.
  • runtime/TypeProfilerLog.cpp:

(JSC::TypeProfilerLog::processLogEntries):

  • runtime/TypeSet.cpp:

(JSC::TypeSet::getRuntimeTypeForValue): Deleted.

  • runtime/TypeSet.h:
  • runtime/VM.cpp:

(JSC::appendSourceToError):
(JSC::VM::throwException):

LayoutTests:

  • fast/dom/NodeList/nodelist-item-call-as-function-expected.txt:
  • fast/dom/call-a-constructor-as-a-function-expected.txt:
  • fast/regex/dom/cross-frame-callable-expected.txt:
  • fast/selectors/closest-general-expected.txt:
  • http/tests/security/xss-DENIED-window-index-assign-expected.txt:
  • js/dom/exception-thrown-from-new-expected.txt:
  • js/exception-for-nonobject-expected.txt:
  • js/exception-function-apply-expected.txt: Added.
  • js/exception-function-apply.html: Added.
  • js/exception-in-expected.txt: Added.
  • js/exception-in.html: Added.
  • js/exception-instanceof-expected.txt: Added.
  • js/exception-instanceof.html: Added.
  • js/instance-of-immediates-expected.txt:
  • js/script-tests/exception-function-apply.js: Added.
  • js/script-tests/exception-in.js: Added.
  • js/script-tests/exception-instanceof.js: Added.
  • js/typedarray-constructors-expected.txt:
  • platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-expected.txt:
  • platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt:
  • platform/mac/css3/selectors3/xhtml/css3-modsel-15c-expected.txt:
  • platform/mac/css3/selectors3/xml/css3-modsel-15c-expected.txt:
  • plugins/npruntime/object-from-destroyed-plugin-expected.txt:
  • plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt:
  • plugins/npruntime/plugin-scriptable-object-invoke-default-expected.txt:
  • sputnik/Conformance/12_Statement/12.1_Block/S12.1_A4_T1-expected.txt:
  • sputnik/Conformance/13_Function_Definition/S13_A17_T2-expected.txt:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A2_T1-expected.txt:
  • sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A3-expected.txt:
  • svg/dom/svgpath-out-of-bounds-getPathSeg-expected.txt:
Location:
trunk
Files:
11 added
40 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r181888 r181889  
     12015-03-24  Saam Barati  <saambarati1@gmail.com>
     2
     3        Improve error messages in JSC
     4        https://bugs.webkit.org/show_bug.cgi?id=141869
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * fast/dom/NodeList/nodelist-item-call-as-function-expected.txt:
     9        * fast/dom/call-a-constructor-as-a-function-expected.txt:
     10        * fast/regex/dom/cross-frame-callable-expected.txt:
     11        * fast/selectors/closest-general-expected.txt:
     12        * http/tests/security/xss-DENIED-window-index-assign-expected.txt:
     13        * js/dom/exception-thrown-from-new-expected.txt:
     14        * js/exception-for-nonobject-expected.txt:
     15        * js/exception-function-apply-expected.txt: Added.
     16        * js/exception-function-apply.html: Added.
     17        * js/exception-in-expected.txt: Added.
     18        * js/exception-in.html: Added.
     19        * js/exception-instanceof-expected.txt: Added.
     20        * js/exception-instanceof.html: Added.
     21        * js/instance-of-immediates-expected.txt:
     22        * js/script-tests/exception-function-apply.js: Added.
     23        * js/script-tests/exception-in.js: Added.
     24        * js/script-tests/exception-instanceof.js: Added.
     25        * js/typedarray-constructors-expected.txt:
     26        * platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-expected.txt:
     27        * platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt:
     28        * platform/mac/css3/selectors3/xhtml/css3-modsel-15c-expected.txt:
     29        * platform/mac/css3/selectors3/xml/css3-modsel-15c-expected.txt:
     30        * plugins/npruntime/object-from-destroyed-plugin-expected.txt:
     31        * plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt:
     32        * plugins/npruntime/plugin-scriptable-object-invoke-default-expected.txt:
     33        * sputnik/Conformance/12_Statement/12.1_Block/S12.1_A4_T1-expected.txt:
     34        * sputnik/Conformance/13_Function_Definition/S13_A17_T2-expected.txt:
     35        * sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A2_T1-expected.txt:
     36        * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A3-expected.txt:
     37        * svg/dom/svgpath-out-of-bounds-getPathSeg-expected.txt:
     38
    1392015-03-23  Yoav Weiss  <yoav@yoav.ws>
    240
  • trunk/LayoutTests/fast/dom/NodeList/nodelist-item-call-as-function-expected.txt

    r152871 r181889  
    44
    55
    6 PASS nodeList(0) threw exception TypeError: NodeList is not a function (evaluating 'nodeList(0)').
     6PASS nodeList(0) threw exception TypeError: nodeList is not a function. (In 'nodeList(0)', 'nodeList' is an instance of NodeList).
    77PASS successfullyParsed is true
    88
  • trunk/LayoutTests/fast/dom/call-a-constructor-as-a-function-expected.txt

    r178310 r181889  
    55
    66SKIP AudioContext is not implemented.
    7 PASS FormData() threw exception TypeError: FormDataConstructor is not a function (evaluating 'FormData()').
    8 PASS EventSource() threw exception TypeError: EventSourceConstructor is not a function (evaluating 'EventSource()').
    9 PASS FileReader() threw exception TypeError: FileReaderConstructor is not a function (evaluating 'FileReader()').
    10 PASS Audio() threw exception TypeError: AudioConstructor is not a function (evaluating 'Audio()').
    11 PASS Image() threw exception TypeError: ImageConstructor is not a function (evaluating 'Image()').
    12 PASS Option() threw exception TypeError: OptionConstructor is not a function (evaluating 'Option()').
    13 PASS MessageChannel() threw exception TypeError: MessageChannelConstructor is not a function (evaluating 'MessageChannel()').
    14 PASS WebKitCSSMatrix() threw exception TypeError: WebKitCSSMatrixConstructor is not a function (evaluating 'WebKitCSSMatrix()').
    15 PASS WebKitPoint() threw exception TypeError: WebKitPointConstructor is not a function (evaluating 'WebKitPoint()').
    16 PASS WebSocket() threw exception TypeError: WebSocketConstructor is not a function (evaluating 'WebSocket()').
    17 PASS Worker() threw exception TypeError: WorkerConstructor is not a function (evaluating 'Worker()').
    18 PASS XMLHttpRequest() threw exception TypeError: XMLHttpRequestConstructor is not a function (evaluating 'XMLHttpRequest()').
    19 PASS XSLTProcessor() threw exception TypeError: XSLTProcessorConstructor is not a function (evaluating 'XSLTProcessor()').
     7PASS FormData() threw exception TypeError: FormData is not a function. (In 'FormData()', 'FormData' is an instance of FormDataConstructor).
     8PASS EventSource() threw exception TypeError: EventSource is not a function. (In 'EventSource()', 'EventSource' is an instance of EventSourceConstructor).
     9PASS FileReader() threw exception TypeError: FileReader is not a function. (In 'FileReader()', 'FileReader' is an instance of FileReaderConstructor).
     10PASS Audio() threw exception TypeError: Audio is not a function. (In 'Audio()', 'Audio' is an instance of AudioConstructor).
     11PASS Image() threw exception TypeError: Image is not a function. (In 'Image()', 'Image' is an instance of ImageConstructor).
     12PASS Option() threw exception TypeError: Option is not a function. (In 'Option()', 'Option' is an instance of OptionConstructor).
     13PASS MessageChannel() threw exception TypeError: MessageChannel is not a function. (In 'MessageChannel()', 'MessageChannel' is an instance of MessageChannelConstructor).
     14PASS WebKitCSSMatrix() threw exception TypeError: WebKitCSSMatrix is not a function. (In 'WebKitCSSMatrix()', 'WebKitCSSMatrix' is an instance of WebKitCSSMatrixConstructor).
     15PASS WebKitPoint() threw exception TypeError: WebKitPoint is not a function. (In 'WebKitPoint()', 'WebKitPoint' is an instance of WebKitPointConstructor).
     16PASS WebSocket() threw exception TypeError: WebSocket is not a function. (In 'WebSocket()', 'WebSocket' is an instance of WebSocketConstructor).
     17PASS Worker() threw exception TypeError: Worker is not a function. (In 'Worker()', 'Worker' is an instance of WorkerConstructor).
     18PASS XMLHttpRequest() threw exception TypeError: XMLHttpRequest is not a function. (In 'XMLHttpRequest()', 'XMLHttpRequest' is an instance of XMLHttpRequestConstructor).
     19PASS XSLTProcessor() threw exception TypeError: XSLTProcessor is not a function. (In 'XSLTProcessor()', 'XSLTProcessor' is an instance of XSLTProcessorConstructor).
    2020PASS successfullyParsed is true
    2121
  • trunk/LayoutTests/fast/regex/dom/cross-frame-callable-expected.txt

    r156066 r181889  
    1 PASS re('a') threw exception TypeError: RegExp is not a function (evaluating 're('a')').
     1PASS re('a') threw exception TypeError: re is not a function. (In 're('a')', 're' is an instance of RegExp).
    22PASS re.exec('a') is ['a']
    33PASS successfullyParsed is true
  • trunk/LayoutTests/fast/selectors/closest-general-expected.txt

    r174324 r181889  
    4444PASS sour.closest("a") is a
    4545PASS document.closest is undefined
    46 PASS document.closest() threw exception TypeError: undefined is not a function (evaluating 'document.closest()').
     46PASS document.closest() threw exception TypeError: document.closest is not a function. (In 'document.closest()', 'document.closest' is undefined).
    4747PASS theTarget.closest() threw exception TypeError: Not enough arguments.
    4848PASS theTarget.closest("") threw exception Error: SyntaxError: DOM Exception 12.
  • trunk/LayoutTests/http/tests/security/xss-DENIED-window-index-assign-expected.txt

    r153526 r181889  
    11ALERT: undefined
    2 CONSOLE MESSAGE: line 1: TypeError: undefined is not a function (evaluating 'parent[0].f()')
     2CONSOLE MESSAGE: line 1: TypeError: parent[0].f is not a function. (In 'parent[0].f()', 'parent[0].f' is undefined)
    33
    44This test passes if the access is forbidden.
  • trunk/LayoutTests/js/dom/exception-thrown-from-new-expected.txt

    r156066 r181889  
    22
    33FAIL: e1 should be 'TypeError: 'undefined' is not a constructor (evaluating 'new f')' but instead is 'TypeError: undefined is not a constructor (evaluating 'new f')'.
    4 FAIL: e2 should be 'TypeError: 'undefined' is not a function (evaluating 'g()')' but instead is 'TypeError: undefined is not a function (evaluating 'g()')'.
     4FAIL: e2 should be 'TypeError: 'undefined' is not a function (evaluating 'g()')' but instead is 'TypeError: g is not a function. (In 'g()', 'g' is undefined)'.
    55
  • trunk/LayoutTests/js/exception-for-nonobject-expected.txt

    r152871 r181889  
    55
    66PASS new {}.undefined threw exception TypeError: undefined is not a constructor (evaluating 'new {}.undefined').
    7 PASS 1 instanceof {}.undefined threw exception TypeError: undefined is not a valid argument for 'instanceof' (evaluating '1 instanceof {}.undefined').
     7PASS 1 instanceof {}.undefined threw exception TypeError: {}.undefined is not a function. (evaluating '1 instanceof {}.undefined').
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/js/instance-of-immediates-expected.txt

    r152871 r181889  
    44
    55
    6 PASS (1 instanceof 1) threw exception TypeError: 1 is not a valid argument for 'instanceof' (evaluating '1 instanceof 1').
    7 PASS ({} instanceof 1) threw exception TypeError: 1 is not a valid argument for 'instanceof' (evaluating '{} instanceof 1').
    8 PASS (obj instanceof 1) threw exception TypeError: 1 is not a valid argument for 'instanceof' (evaluating 'obj instanceof 1').
    9 PASS (1 instanceof {}) threw exception TypeError: Object is not a valid argument for 'instanceof' (evaluating '1 instanceof {}').
    10 PASS ({} instanceof {}) threw exception TypeError: Object is not a valid argument for 'instanceof' (evaluating '{} instanceof {}').
    11 PASS (obj instanceof {}) threw exception TypeError: Object is not a valid argument for 'instanceof' (evaluating 'obj instanceof {}').
     6PASS (1 instanceof 1) threw exception TypeError: 1 is not a function. (evaluating '1 instanceof 1').
     7PASS ({} instanceof 1) threw exception TypeError: 1 is not a function. (evaluating '{} instanceof 1').
     8PASS (obj instanceof 1) threw exception TypeError: 1 is not a function. (evaluating 'obj instanceof 1').
     9PASS (1 instanceof {}) threw exception TypeError: {} is not a function. (evaluating '1 instanceof {}').
     10PASS ({} instanceof {}) threw exception TypeError: {} is not a function. (evaluating '{} instanceof {}').
     11PASS (obj instanceof {}) threw exception TypeError: {} is not a function. (evaluating 'obj instanceof {}').
    1212PASS (1 instanceof Constructor) is false
    1313PASS ({} instanceof Constructor) is false
  • trunk/LayoutTests/js/typedarray-constructors-expected.txt

    r161789 r181889  
    44
    55
    6 PASS Int8Array() threw exception TypeError: Function is not a function (evaluating 'Int8Array()').
     6PASS Int8Array() threw exception TypeError: Int8Array is not a function. (In 'Int8Array()', 'Int8Array' is an instance of Function).
    77PASS new Int8Array() did not throw exception.
    8 PASS Int16Array() threw exception TypeError: Function is not a function (evaluating 'Int16Array()').
     8PASS Int16Array() threw exception TypeError: Int16Array is not a function. (In 'Int16Array()', 'Int16Array' is an instance of Function).
    99PASS new Int16Array() did not throw exception.
    10 PASS Int32Array() threw exception TypeError: Function is not a function (evaluating 'Int32Array()').
     10PASS Int32Array() threw exception TypeError: Int32Array is not a function. (In 'Int32Array()', 'Int32Array' is an instance of Function).
    1111PASS new Int32Array() did not throw exception.
    12 PASS Uint8Array() threw exception TypeError: Function is not a function (evaluating 'Uint8Array()').
     12PASS Uint8Array() threw exception TypeError: Uint8Array is not a function. (In 'Uint8Array()', 'Uint8Array' is an instance of Function).
    1313PASS new Uint8Array() did not throw exception.
    14 PASS Uint16Array() threw exception TypeError: Function is not a function (evaluating 'Uint16Array()').
     14PASS Uint16Array() threw exception TypeError: Uint16Array is not a function. (In 'Uint16Array()', 'Uint16Array' is an instance of Function).
    1515PASS new Uint16Array() did not throw exception.
    16 PASS Uint32Array() threw exception TypeError: Function is not a function (evaluating 'Uint32Array()').
     16PASS Uint32Array() threw exception TypeError: Uint32Array is not a function. (In 'Uint32Array()', 'Uint32Array' is an instance of Function).
    1717PASS new Uint32Array() did not throw exception.
    18 PASS Uint8ClampedArray() threw exception TypeError: Function is not a function (evaluating 'Uint8ClampedArray()').
     18PASS Uint8ClampedArray() threw exception TypeError: Uint8ClampedArray is not a function. (In 'Uint8ClampedArray()', 'Uint8ClampedArray' is an instance of Function).
    1919PASS new Uint8ClampedArray() did not throw exception.
    20 PASS Float32Array() threw exception TypeError: Function is not a function (evaluating 'Float32Array()').
     20PASS Float32Array() threw exception TypeError: Float32Array is not a function. (In 'Float32Array()', 'Float32Array' is an instance of Function).
    2121PASS new Float32Array() did not throw exception.
    22 PASS Float64Array() threw exception TypeError: Function is not a function (evaluating 'Float64Array()').
     22PASS Float64Array() threw exception TypeError: Float64Array is not a function. (In 'Float64Array()', 'Float64Array' is an instance of Function).
    2323PASS new Float64Array() did not throw exception.
    24 PASS DataView(new ArrayBuffer()) threw exception TypeError: Function is not a function (evaluating 'DataView(new ArrayBuffer())').
     24PASS DataView(new ArrayBuffer()) threw exception TypeError: DataView is not a function. (In 'DataView(new ArrayBuffer())', 'DataView' is an instance of Function).
    2525PASS new DataView(new ArrayBuffer()) did not throw exception.
    2626PASS successfullyParsed is true
  • trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-expected.txt

    r152871 r181889  
    66PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
    77PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
    8 PASS testObject() threw exception TypeError: NPObject is not a function (evaluating 'testObject()').
     8PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of NPObject).
    99PASS new testObject(); threw exception TypeError: NPObject is not a constructor (evaluating 'new testObject()').
    1010
  • trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt

    r152871 r181889  
    66 PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
    77PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
    8 PASS testObject() threw exception TypeError: NPObject is not a function (evaluating 'testObject()').
     8PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of NPObject).
    99PASS new testObject(); threw exception TypeError: NPObject is not a constructor (evaluating 'new testObject()').
    1010
  • trunk/LayoutTests/platform/mac/css3/selectors3/xhtml/css3-modsel-15c-expected.txt

    r177774 r181889  
    1 CONSOLE MESSAGE: line 27: TypeError: undefined is not a function (evaluating 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute('title', true)')
     1CONSOLE MESSAGE: line 27: TypeError: document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute is not a function. (In 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute('title', true)', 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute' is undefined)
    22layer at (0,0) size 800x600
    33  RenderView at (0,0) size 800x600
  • trunk/LayoutTests/platform/mac/css3/selectors3/xml/css3-modsel-15c-expected.txt

    r177774 r181889  
    1 CONSOLE MESSAGE: line 9: TypeError: undefined is not a function (evaluating 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute('title', true)')
     1CONSOLE MESSAGE: line 9: TypeError: document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute is not a function. (In 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute('title', true)', 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute' is undefined)
    22layer at (0,0) size 800x600
    33  RenderView at (0,0) size 800x600
  • trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-expected.txt

    r152871 r181889  
    66PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
    77PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
    8 PASS testObject() threw exception TypeError: ProxyRuntimeObject is not a function (evaluating 'testObject()').
     8PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of ProxyRuntimeObject).
    99PASS new testObject(); threw exception TypeError: ProxyRuntimeObject is not a constructor (evaluating 'new testObject()').
    1010
  • trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt

    r152871 r181889  
    66 PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
    77PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
    8 PASS testObject() threw exception TypeError: ProxyRuntimeObject is not a function (evaluating 'testObject()').
     8PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of ProxyRuntimeObject).
    99PASS new testObject(); threw exception TypeError: ProxyRuntimeObject is not a constructor (evaluating 'new testObject()').
    1010
  • trunk/LayoutTests/plugins/npruntime/plugin-scriptable-object-invoke-default-expected.txt

    r152871 r181889  
    88PASS pluginWithInvokeDefault() is 1
    99PASS typeof(pluginWithoutInvokeDefault) is 'object'
    10 PASS pluginWithoutInvokeDefault() threw exception TypeError: HTMLEmbedElement is not a function (evaluating 'pluginWithoutInvokeDefault()').
     10PASS pluginWithoutInvokeDefault() threw exception TypeError: pluginWithoutInvokeDefault is not a function. (In 'pluginWithoutInvokeDefault()', 'pluginWithoutInvokeDefault' is an instance of HTMLEmbedElement).
    1111
  • trunk/LayoutTests/sputnik/Conformance/12_Statement/12.1_Block/S12.1_A4_T1-expected.txt

    r181121 r181889  
    11S12.1_A4_T1
    22
    3 PASS TypeError: Object is not a function (evaluating '{__func}()')
     3PASS TypeError: {__func} is not a function. (In '{__func}()', '{__func}' is an instance of Object)
    44
    55TEST COMPLETE
  • trunk/LayoutTests/sputnik/Conformance/13_Function_Definition/S13_A17_T2-expected.txt

    r152871 r181889  
    11S13_A17_T2
    22
    3 TypeError: undefined is not a function (evaluating '__func()')
     3TypeError: __func is not a function. (In '__func()', '__func' is undefined)
    44PASS
    55
  • trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A2_T1-expected.txt

    r152871 r181889  
    11S15.1_A2_T1
    22
    3 PASS TypeError: Window is not a function (evaluating 'this()')
     3PASS TypeError: this is not a function. (In 'this()', 'this' is an instance of Window)
    44
    55TEST COMPLETE
  • trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A3-expected.txt

    r152871 r181889  
    11S15.2.4_A3
    22
    3 TypeError: Object is not a function (evaluating 'Object.prototype()')
     3TypeError: Object.prototype is not a function. (In 'Object.prototype()', 'Object.prototype' is an instance of Object)
    44PASS
    55
  • trunk/LayoutTests/svg/dom/svgpath-out-of-bounds-getPathSeg-expected.txt

    r152871 r181889  
    66PASS path.pathSegList.initialize(); threw exception TypeError: Not enough arguments.
    77PASS path.getPathSegAtLength(0) is 0
    8 PASS path.insertItemBefore(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.insertItemBefore(null, 0)').
    9 PASS path.replaceItem(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.replaceItem(null, 0)').
    10 PASS path.appendItem(null) threw exception TypeError: undefined is not a function (evaluating 'path.appendItem(null)').
     8PASS path.insertItemBefore(null, 0) threw exception TypeError: path.insertItemBefore is not a function. (In 'path.insertItemBefore(null, 0)', 'path.insertItemBefore' is undefined).
     9PASS path.replaceItem(null, 0) threw exception TypeError: path.replaceItem is not a function. (In 'path.replaceItem(null, 0)', 'path.replaceItem' is undefined).
     10PASS path.appendItem(null) threw exception TypeError: path.appendItem is not a function. (In 'path.appendItem(null)', 'path.appendItem' is undefined).
    1111List correctly initialised.
    1212PASS path.getPathSegAtLength(0) is 0
    13 PASS path.insertItemBefore(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.insertItemBefore(null, 0)').
    14 PASS path.replaceItem(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.replaceItem(null, 0)').
    15 PASS path.appendItem(null) threw exception TypeError: undefined is not a function (evaluating 'path.appendItem(null)').
     13PASS path.insertItemBefore(null, 0) threw exception TypeError: path.insertItemBefore is not a function. (In 'path.insertItemBefore(null, 0)', 'path.insertItemBefore' is undefined).
     14PASS path.replaceItem(null, 0) threw exception TypeError: path.replaceItem is not a function. (In 'path.replaceItem(null, 0)', 'path.replaceItem' is undefined).
     15PASS path.appendItem(null) threw exception TypeError: path.appendItem is not a function. (In 'path.appendItem(null)', 'path.appendItem' is undefined).
    1616PASS successfullyParsed is true
    1717
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r181601 r181889  
    536536    runtime/RegExpObject.cpp
    537537    runtime/RegExpPrototype.cpp
     538    runtime/RuntimeType.cpp
    538539    runtime/SamplingCounter.cpp
    539540    runtime/SetConstructor.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r181887 r181889  
     12015-03-24  Saam Barati  <saambarati1@gmail.com>
     2
     3        Improve error messages in JSC
     4        https://bugs.webkit.org/show_bug.cgi?id=141869
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        JavaScriptCore has some unintuitive error messages associated
     9        with certain common errors. This patch changes some specific
     10        error messages to be more understandable and also creates a
     11        mechanism that will allow for easy modification of error messages
     12        in the future. The specific errors we change are not a function
     13        errors and invalid parameter errors.
     14
     15        * CMakeLists.txt:
     16        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     17        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     18        * JavaScriptCore.xcodeproj/project.pbxproj:
     19        * interpreter/Interpreter.cpp:
     20        (JSC::sizeOfVarargs):
     21        * jit/JITOperations.cpp:
     22        op_throw_static_error always has a JSString as its argument.
     23        There is no need to dance around this, and we should assert
     24        that this always holds. This JSString represents the error
     25        message we want to display to the user, so there is no need
     26        to pass it into errorDescriptionForValue which will now place
     27        quotes around the string.
     28
     29        * llint/LLIntSlowPaths.cpp:
     30        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     31        * runtime/CommonSlowPaths.h:
     32        (JSC::CommonSlowPaths::opIn):
     33        * runtime/ErrorInstance.cpp:
     34        (JSC::ErrorInstance::ErrorInstance):
     35        * runtime/ErrorInstance.h:
     36        (JSC::ErrorInstance::hasSourceAppender):
     37        (JSC::ErrorInstance::sourceAppender):
     38        (JSC::ErrorInstance::setSourceAppender):
     39        (JSC::ErrorInstance::clearSourceAppender):
     40        (JSC::ErrorInstance::setRuntimeTypeForCause):
     41        (JSC::ErrorInstance::runtimeTypeForCause):
     42        (JSC::ErrorInstance::clearRuntimeTypeForCause):
     43        (JSC::ErrorInstance::appendSourceToMessage): Deleted.
     44        (JSC::ErrorInstance::setAppendSourceToMessage): Deleted.
     45        (JSC::ErrorInstance::clearAppendSourceToMessage): Deleted.
     46        * runtime/ExceptionHelpers.cpp:
     47        (JSC::errorDescriptionForValue):
     48        (JSC::defaultApproximateSourceError):
     49        (JSC::defaultSourceAppender):
     50        (JSC::functionCallBase):
     51        (JSC::notAFunctionSourceAppender):
     52        (JSC::invalidParameterInSourceAppender):
     53        (JSC::invalidParameterInstanceofSourceAppender):
     54        (JSC::createError):
     55        (JSC::createInvalidFunctionApplyParameterError):
     56        (JSC::createInvalidInParameterError):
     57        (JSC::createInvalidInstanceofParameterError):
     58        (JSC::createNotAConstructorError):
     59        (JSC::createNotAFunctionError):
     60        (JSC::createNotAnObjectError):
     61        (JSC::createInvalidParameterError): Deleted.
     62        * runtime/ExceptionHelpers.h:
     63        * runtime/JSObject.cpp:
     64        (JSC::JSObject::hasInstance):
     65        * runtime/RuntimeType.cpp: Added.
     66        (JSC::runtimeTypeForValue):
     67        (JSC::runtimeTypeAsString):
     68        * runtime/RuntimeType.h: Added.
     69        * runtime/TypeProfilerLog.cpp:
     70        (JSC::TypeProfilerLog::processLogEntries):
     71        * runtime/TypeSet.cpp:
     72        (JSC::TypeSet::getRuntimeTypeForValue): Deleted.
     73        * runtime/TypeSet.h:
     74        * runtime/VM.cpp:
     75        (JSC::appendSourceToError):
     76        (JSC::VM::throwException):
     77
    1782015-03-23  Filip Pizlo  <fpizlo@apple.com>
    279
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r181841 r181889  
    803803    <ClCompile Include="..\runtime\RegExpObject.cpp" />
    804804    <ClCompile Include="..\runtime\RegExpPrototype.cpp" />
     805    <ClCompile Include="..\runtime\RuntimeType.cpp" />
    805806    <ClCompile Include="..\runtime\SamplingCounter.cpp" />
    806807    <ClCompile Include="..\runtime\SetConstructor.cpp" />
     
    16151616    <ClInclude Include="..\runtime\Reject.h" />
    16161617    <ClInclude Include="..\runtime\RuntimeFlags.h" />
     1618    <ClInclude Include="..\runtime\RuntimeType.h" />
    16171619    <ClInclude Include="..\runtime\SamplingCounter.h" />
    16181620    <ClInclude Include="..\runtime\SetConstructor.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r181628 r181889  
    802802      <Filter>runtime</Filter>
    803803    </ClCompile>
     804    <ClCompile Include="..\runtime\RuntimeType.cpp">
     805      <Filter>runtime</Filter>
     806    </ClCompile>
    804807    <ClCompile Include="..\runtime\SamplingCounter.cpp">
    805808      <Filter>runtime</Filter>
     
    28692872    </ClInclude>
    28702873    <ClInclude Include="..\runtime\RuntimeFlags.h">
     2874      <Filter>runtime</Filter>
     2875    </ClInclude>
     2876    <ClInclude Include="..\runtime\RuntimeType.h">
    28712877      <Filter>runtime</Filter>
    28722878    </ClInclude>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r181841 r181889  
    911911                52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F8D1A031009006A306D /* BasicBlockLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
    912912                52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F901A04177C006A306D /* ControlFlowProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
     913                527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */; };
    913914                52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    914915                52B310FD1974AE870080857C /* FunctionHasExecutedCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */; };
     
    916917                52B311011975B4670080857C /* TypeLocationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B311001975B4670080857C /* TypeLocationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    917918                52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */; };
     919                52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
    918920                52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
    919921                52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
     
    25682570                52678F8D1A031009006A306D /* BasicBlockLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicBlockLocation.h; sourceTree = "<group>"; };
    25692571                52678F901A04177C006A306D /* ControlFlowProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlFlowProfiler.h; sourceTree = "<group>"; };
     2572                527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeType.cpp; sourceTree = "<group>"; };
    25702573                52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionHasExecutedCache.h; sourceTree = "<group>"; };
    25712574                52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionHasExecutedCache.cpp; sourceTree = "<group>"; };
     
    25732576                52B311001975B4670080857C /* TypeLocationCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocationCache.h; sourceTree = "<group>"; };
    25742577                52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ControlFlowProfiler.cpp; sourceTree = "<group>"; };
     2578                52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = "<group>"; };
    25752579                52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = "<group>"; };
    25762580                52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; };
     
    45654569                                0FB7F39115ED8E3800F167B2 /* Reject.h */,
    45664570                                70B0A9D01A9B66200001306A /* RuntimeFlags.h */,
     4571                                527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */,
     4572                                52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */,
    45674573                                0F7700911402FF280078EB39 /* SamplingCounter.cpp */,
    45684574                                0F77008E1402FDD60078EB39 /* SamplingCounter.h */,
     
    54605466                                A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
    54615467                                86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
     5468                                52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */,
    54625469                                C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */,
    54635470                                52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */,
     
    70977104                                0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */,
    70987105                                0FCEFACA1805E75500472CE4 /* InitializeLLVM.cpp in Sources */,
     7106                                527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */,
    70997107                                A513E5B7185B8BD3007E95AD /* InjectedScript.cpp in Sources */,
    71007108                                0FBF158C19B7A53100695DD0 /* DFGBlockSet.cpp in Sources */,
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r180595 r181889  
    143143        length = 0;
    144144    else if (!arguments.isObject()) {
    145         callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments));
     145        callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame, arguments));
    146146        return 0;
    147147    } else if (asObject(arguments)->classInfo() == Arguments::info())
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r181814 r181889  
    201201   
    202202    if (!base->isObject()) {
    203         vm->throwException(exec, createInvalidParameterError(exec, "in", base));
     203        vm->throwException(exec, createInvalidInParameterError(exec, base));
    204204        return JSValue::encode(jsUndefined());
    205205    }
     
    227227
    228228    if (!base->isObject()) {
    229         vm->throwException(exec, createInvalidParameterError(exec, "in", base));
     229        vm->throwException(exec, createInvalidInParameterError(exec, base));
    230230        return JSValue::encode(jsUndefined());
    231231    }
     
    967967    VM& vm = exec->vm();
    968968    NativeCallFrameTracer tracer(&vm, exec);
    969 
    970     String message = errorDescriptionForValue(exec, JSValue::decode(encodedValue))->value(exec);
     969    JSValue errorMessageValue = JSValue::decode(encodedValue);
     970    RELEASE_ASSERT(errorMessageValue.isString());
     971    String errorMessage = asString(errorMessageValue)->value(exec);
    971972    if (referenceErrorFlag)
    972         vm.throwException(exec, createReferenceError(exec, message));
     973        vm.throwException(exec, createReferenceError(exec, errorMessage));
    973974    else
    974         vm.throwException(exec, createTypeError(exec, message));
     975        vm.throwException(exec, createTypeError(exec, errorMessage));
    975976}
    976977
     
    13491350    }
    13501351
    1351     vm.throwException(exec, createInvalidParameterError(exec, "instanceof", baseVal));
     1352    vm.throwException(exec, createInvalidInstanceofParameterError(exec, baseVal));
    13521353    return JSValue::encode(JSValue());
    13531354}
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r181814 r181889  
    559559        }
    560560    }
    561     LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
     561    LLINT_THROW(createInvalidInstanceofParameterError(exec, baseVal));
    562562}
    563563
     
    13061306{
    13071307    LLINT_BEGIN();
     1308    JSValue errorMessageValue = LLINT_OP_C(1).jsValue();
     1309    RELEASE_ASSERT(errorMessageValue.isString());
     1310    String errorMessage = asString(errorMessageValue)->value(exec);
    13081311    if (pc[2].u.operand)
    1309         LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
     1312        LLINT_THROW(createReferenceError(exec, errorMessage));
    13101313    else
    1311         LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
     1314        LLINT_THROW(createTypeError(exec, errorMessage));
    13121315}
    13131316
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r181814 r181889  
    7373{
    7474    if (!baseVal.isObject()) {
    75         exec->vm().throwException(exec, createInvalidParameterError(exec, "in", baseVal));
     75        exec->vm().throwException(exec, createInvalidInParameterError(exec, baseVal));
    7676        return false;
    7777    }
  • trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp

    r171824 r181889  
    3333ErrorInstance::ErrorInstance(VM& vm, Structure* structure)
    3434    : JSNonFinalObject(vm, structure)
    35     , m_appendSourceToMessage(false)
    3635{
    3736}
  • trunk/Source/JavaScriptCore/runtime/ErrorInstance.h

    r173269 r181889  
    2323
    2424#include "Interpreter.h"
    25 #include "JSObject.h"
     25#include "RuntimeType.h"
    2626#include "SourceProvider.h"
    2727
     
    5151    }
    5252
    53     bool appendSourceToMessage() { return m_appendSourceToMessage; }
    54     void setAppendSourceToMessage() { m_appendSourceToMessage = true; }
    55     void clearAppendSourceToMessage() { m_appendSourceToMessage = false; }
     53    enum SourceTextWhereErrorOccurred { FoundExactSource, FoundApproximateSource };
     54    typedef String (*SourceAppender) (const String& originalMessage, const String& sourceText, RuntimeType, SourceTextWhereErrorOccurred);
     55
     56    bool hasSourceAppender() const { return !!m_sourceAppender; }
     57    SourceAppender sourceAppender() const { return m_sourceAppender; }
     58    void setSourceAppender(SourceAppender appender) { m_sourceAppender = appender; }
     59    void clearSourceAppender() { m_sourceAppender = nullptr; }
     60    void setRuntimeTypeForCause(RuntimeType type) { m_runtimeTypeForCause = type; }
     61    RuntimeType runtimeTypeForCause() const { return m_runtimeTypeForCause; }
     62    void clearRuntimeTypeForCause() { m_runtimeTypeForCause = TypeNothing; }
    5663
    5764protected:
     
    6067    void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());
    6168
    62     bool m_appendSourceToMessage;
     69    SourceAppender m_sourceAppender { nullptr };
     70    RuntimeType m_runtimeTypeForCause { TypeNothing };
    6371};
    6472
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r179429 r181889  
    3333#include "CallFrame.h"
    3434#include "ErrorHandlingScope.h"
    35 #include "ErrorInstance.h"
    3635#include "JSGlobalObjectFunctions.h"
    37 #include "JSObject.h"
    3836#include "JSNotAnObject.h"
    3937#include "Interpreter.h"
    4038#include "Nodes.h"
    4139#include "JSCInlines.h"
     40#include "RuntimeType.h"
     41#include <wtf/text/StringBuilder.h>
     42#include <wtf/text/StringView.h>
    4243
    4344namespace JSC {
     
    107108        return vm.smallStrings.falseString();
    108109    if (v.isString())
    109         return jsCast<JSString*>(v.asCell());
     110        return jsString(&vm, makeString('"',  asString(v)->value(exec), '"'));
    110111    if (v.isObject()) {
    111112        CallData callData;
     
    113114        if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
    114115            return vm.smallStrings.functionString();
    115         return jsString(exec, object->methodTable()->className(object));
     116        return jsString(exec, JSObject::calculatedClassName(object));
    116117    }
    117118   
     
    121122}
    122123   
    123 JSObject* createError(ExecState* exec, ErrorFactory errorFactory, JSValue value, const String& message)
     124static String defaultApproximateSourceError(const String& originalMessage, const String& sourceText)
     125{
     126    return makeString(originalMessage, " (near '...", sourceText, "...')");
     127}
     128
     129static String defaultSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
     130{
     131    if (occurrence == ErrorInstance::FoundApproximateSource)
     132        return defaultApproximateSourceError(originalMessage, sourceText);
     133
     134    ASSERT(occurrence == ErrorInstance::FoundExactSource);
     135    return makeString(originalMessage, " (evaluating '", sourceText, "')");
     136}
     137
     138static String functionCallBase(const String& sourceText)
     139{
     140    // This function retrieves the 'foo.bar' substring from 'foo.bar(baz)'.
     141    unsigned idx = sourceText.length() - 1;
     142    if (sourceText[idx] != ')') {
     143        // For function calls that have many new lines in between their open parenthesis
     144        // and their closing parenthesis, the text range passed into the message appender
     145        // will not inlcude the text in between these parentheses, it will just be the desired
     146        // text that precedes the parentheses.
     147        return sourceText;
     148    }
     149
     150    unsigned parenStack = 1;
     151    bool isInMultiLineComment = false;
     152    idx -= 1;
     153    // Note that we're scanning text right to left instead of the more common left to right,
     154    // so syntax detection is backwards.
     155    while (parenStack > 0) {
     156        UChar curChar = sourceText[idx];
     157        if (isInMultiLineComment)  {
     158            if (curChar == '*' && sourceText[idx - 1] == '/') {
     159                isInMultiLineComment = false;
     160                idx -= 1;
     161            }
     162        } else if (curChar == '(')
     163            parenStack -= 1;
     164        else if (curChar == ')')
     165            parenStack += 1;
     166        else if (curChar == '/' && sourceText[idx - 1] == '*') {
     167            isInMultiLineComment = true;
     168            idx -= 1;
     169        }
     170
     171        idx -= 1;
     172    }
     173
     174    return sourceText.left(idx + 1);
     175}
     176
     177static String notAFunctionSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType type, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
     178{
     179    ASSERT(type != TypeFunction);
     180
     181    if (occurrence == ErrorInstance::FoundApproximateSource)
     182        return defaultApproximateSourceError(originalMessage, sourceText);
     183
     184    ASSERT(occurrence == ErrorInstance::FoundExactSource);
     185    auto notAFunctionIndex = originalMessage.reverseFind("is not a function");
     186    RELEASE_ASSERT(notAFunctionIndex != notFound);
     187    StringView displayValue;
     188    if (originalMessage.is8Bit())
     189        displayValue = StringView(originalMessage.characters8(), notAFunctionIndex - 1);
     190    else
     191        displayValue = StringView(originalMessage.characters16(), notAFunctionIndex - 1);
     192
     193    String base = functionCallBase(sourceText);
     194    StringBuilder builder;
     195    builder.append(base);
     196    builder.appendLiteral(" is not a function. (In '");
     197    builder.append(sourceText);
     198    builder.appendLiteral("', '");
     199    builder.append(base);
     200    builder.appendLiteral("' is ");
     201    if (type == TypeObject)
     202        builder.appendLiteral("an instance of ");
     203    builder.append(displayValue);
     204    builder.appendLiteral(")");
     205
     206    return builder.toString();
     207}
     208
     209static String invalidParameterInSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
     210{
     211    ASSERT(type != TypeObject);
     212
     213    if (occurrence == ErrorInstance::FoundApproximateSource)
     214        return defaultApproximateSourceError(originalMessage, sourceText);
     215
     216    ASSERT(occurrence == ErrorInstance::FoundExactSource);
     217    auto inIndex = sourceText.reverseFind("in");
     218    RELEASE_ASSERT(inIndex != notFound);
     219    if (sourceText.find("in") != inIndex)
     220        return makeString(originalMessage, " (evaluating '", sourceText, "')");
     221
     222    static const unsigned inLength = 2;
     223    String rightHandSide = sourceText.substring(inIndex + inLength).simplifyWhiteSpace();
     224    return makeString(rightHandSide, " is not an Object. (evaluating '", sourceText, "')");
     225}
     226
     227static String invalidParameterInstanceofSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
     228{
     229    if (occurrence == ErrorInstance::FoundApproximateSource)
     230        return defaultApproximateSourceError(originalMessage, sourceText);
     231
     232    ASSERT(occurrence == ErrorInstance::FoundExactSource);
     233    auto instanceofIndex = sourceText.reverseFind("instanceof");
     234    RELEASE_ASSERT(instanceofIndex != notFound);
     235    if (sourceText.find("instanceof") != instanceofIndex)
     236        return makeString(originalMessage, " (evaluating '", sourceText, "')");
     237
     238    static const unsigned instanceofLength = 10;
     239    String rightHandSide = sourceText.substring(instanceofIndex + instanceofLength).simplifyWhiteSpace();
     240    return makeString(rightHandSide, " is not a function. (evaluating '", sourceText, "')");
     241}
     242
     243JSObject* createError(ExecState* exec, ErrorFactory errorFactory, JSValue value, const String& message, ErrorInstance::SourceAppender appender)
    124244{
    125245    String errorMessage = makeString(errorDescriptionForValue(exec, value)->value(exec), ' ', message);
    126246    JSObject* exception = errorFactory(exec, errorMessage);
    127247    ASSERT(exception->isErrorInstance());
    128     static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
     248    static_cast<ErrorInstance*>(exception)->setSourceAppender(appender);
     249    static_cast<ErrorInstance*>(exception)->setRuntimeTypeForCause(runtimeTypeForValue(value));
    129250    return exception;
    130251}
    131252
    132 JSObject* createInvalidParameterError(ExecState* exec, const char* op, JSValue value)
    133 {
    134     return createError(exec, createTypeError, value, makeString("is not a valid argument for '", op, '\''));
     253JSObject* createInvalidFunctionApplyParameterError(ExecState* exec, JSValue value)
     254{
     255    JSObject* exception = createTypeError(exec, makeString("second argument to Function.prototype.apply must be an Array-like object"));
     256    ASSERT(exception->isErrorInstance());
     257    static_cast<ErrorInstance*>(exception)->setSourceAppender(defaultSourceAppender);
     258    static_cast<ErrorInstance*>(exception)->setRuntimeTypeForCause(runtimeTypeForValue(value));
     259    return exception;
     260}
     261
     262JSObject* createInvalidInParameterError(ExecState* exec, JSValue value)
     263{
     264    return createError(exec, createTypeError, value, makeString("is not an Object."), invalidParameterInSourceAppender);
     265}
     266
     267JSObject* createInvalidInstanceofParameterError(ExecState* exec, JSValue value)
     268{
     269    return createError(exec, createTypeError, value, makeString("is not a function."), invalidParameterInstanceofSourceAppender);
    135270}
    136271
    137272JSObject* createNotAConstructorError(ExecState* exec, JSValue value)
    138273{
    139     return createError(exec, createTypeError, value, ASCIILiteral("is not a constructor"));
     274    return createError(exec, createTypeError, value, ASCIILiteral("is not a constructor"), defaultSourceAppender);
    140275}
    141276
    142277JSObject* createNotAFunctionError(ExecState* exec, JSValue value)
    143278{
    144     return createError(exec, createTypeError, value, ASCIILiteral("is not a function"));
     279    return createError(exec, createTypeError, value, ASCIILiteral("is not a function"), notAFunctionSourceAppender);
    145280}
    146281
    147282JSObject* createNotAnObjectError(ExecState* exec, JSValue value)
    148283{
    149     return createError(exec, createTypeError, value, ASCIILiteral("is not an object"));
     284    return createError(exec, createTypeError, value, ASCIILiteral("is not an object"), defaultSourceAppender);
    150285}
    151286
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.h

    r171391 r181889  
    3030#define ExceptionHelpers_h
    3131
     32#include "ErrorInstance.h"
    3233#include "JSObject.h"
    3334
     
    3940bool isTerminatedExecutionException(JSObject*);
    4041JS_EXPORT_PRIVATE bool isTerminatedExecutionException(JSValue);
    41 JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorFactory, JSValue, const String&);
     42JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorFactory, JSValue, const String&, ErrorInstance::SourceAppender);
    4243JS_EXPORT_PRIVATE JSObject* createStackOverflowError(ExecState*);
    4344JSObject* createStackOverflowError(JSGlobalObject*);
     
    4546JSObject* createUndefinedVariableError(ExecState*, const Identifier&);
    4647JSObject* createNotAnObjectError(ExecState*, JSValue);
    47 JSObject* createInvalidParameterError(ExecState*, const char* op, JSValue);
     48JSObject* createInvalidFunctionApplyParameterError(ExecState*, JSValue);
     49JSObject* createInvalidInParameterError(ExecState*, JSValue);
     50JSObject* createInvalidInstanceofParameterError(ExecState*, JSValue);
    4851JSObject* createNotAConstructorError(ExecState*, JSValue);
    4952JSObject* createNotAFunctionError(ExecState*, JSValue);
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r180460 r181889  
    14721472    if (info.implementsHasInstance())
    14731473        return methodTable(vm)->customHasInstance(this, exec, value);
    1474     vm.throwException(exec, createInvalidParameterError(exec, "instanceof" , this));
     1474    vm.throwException(exec, createInvalidInstanceofParameterError(exec, this));
    14751475    return false;
    14761476}
  • trunk/Source/JavaScriptCore/runtime/TypeProfilerLog.cpp

    r174789 r181889  
    7676        }
    7777
    78         RuntimeType type = TypeSet::getRuntimeTypeForValue(value);
     78        RuntimeType type = runtimeTypeForValue(value);
    7979        TypeLocation* location = entry->location;
    8080        location->m_lastSeenType = type;
  • trunk/Source/JavaScriptCore/runtime/TypeSet.cpp

    r179621 r181889  
    4343}
    4444
    45 RuntimeType TypeSet::getRuntimeTypeForValue(JSValue v)
    46 {
    47     RuntimeType ret;
    48     if (v.isFunction())
    49         ret = TypeFunction;
    50     else if (v.isUndefined())
    51         ret = TypeUndefined;
    52     else if (v.isNull())
    53         ret = TypeNull;
    54     else if (v.isBoolean())
    55         ret = TypeBoolean;
    56     else if (v.isMachineInt())
    57         ret = TypeMachineInt;
    58     else if (v.isNumber())
    59         ret = TypeNumber;
    60     else if (v.isString())
    61         ret = TypeString;
    62     else if (v.isObject())
    63         ret = TypeObject;
    64     else
    65         ret = TypeNothing;
    66 
    67     return ret;
    68 }
    69 
    7045void TypeSet::addTypeInformation(RuntimeType type, PassRefPtr<StructureShape> prpNewShape, Structure* structure)
    7146{
  • trunk/Source/JavaScriptCore/runtime/TypeSet.h

    r179621 r181889  
    2727#define TypeSet_h
    2828
     29#include "RuntimeType.h"
    2930#include "StructureSet.h"
    3031#include <wtf/HashSet.h>
     
    4647
    4748namespace JSC {
    48 
    49 class JSValue;
    50 
    51 enum RuntimeType : uint8_t {
    52     TypeNothing            = 0x0,
    53     TypeFunction           = 0x1,
    54     TypeUndefined          = 0x2,
    55     TypeNull               = 0x4,
    56     TypeBoolean            = 0x8,
    57     TypeMachineInt         = 0x10,
    58     TypeNumber             = 0x20,
    59     TypeString             = 0x40,
    60     TypeObject             = 0x80
    61 };
    6249
    6350class StructureShape : public RefCounted<StructureShape> {
     
    9986    TypeSet();
    10087    void addTypeInformation(RuntimeType, PassRefPtr<StructureShape>, Structure*);
    101     static RuntimeType getRuntimeTypeForValue(JSValue);
    10288    void invalidateCache();
    10389    String dumpTypes() const;
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r181887 r181889  
    7676#include "RegExpCache.h"
    7777#include "RegExpObject.h"
     78#include "RuntimeType.h"
    7879#include "SimpleTypedArrayController.h"
    7980#include "SourceProviderCache.h"
     
    541542static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
    542543{
    543     exception->clearAppendSourceToMessage();
     544    ErrorInstance::SourceAppender appender = exception->sourceAppender();
     545    exception->clearSourceAppender();
     546    RuntimeType type = exception->runtimeTypeForCause();
     547    exception->clearRuntimeTypeForCause();
    544548   
    545549    if (!callFrame->codeBlock()->hasExpressionInfo())
     
    570574   
    571575    if (expressionStart < expressionStop)
    572         message =  makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
     576        message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop), type, ErrorInstance::FoundExactSource);
    573577    else {
    574578        // No range information, so give a few characters of context.
     
    587591        while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
    588592            stop--;
    589         message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
     593        message = appender(message, codeBlock->source()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource);
    590594    }
    591595   
     
    663667            exception->putDirect(*this, Identifier(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
    664668    }
    665     if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) {
     669    if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->hasSourceAppender()) {
    666670        FindFirstCallerFrameWithCodeblockFunctor functor(exec);
    667671        topCallFrame->iterate(functor);
Note: See TracChangeset for help on using the changeset viewer.