Title: [181889] trunk
Revision
181889
Author
saambara...@gmail.com
Date
2015-03-24 00:30:05 -0700 (Tue, 24 Mar 2015)

Log Message

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

Reviewed by Geoffrey Garen.

Source/_javascript_Core:

_javascript_Core 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.

* CMakeLists.txt:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
* _javascript_Core.xcodeproj/project.pbxproj:
* interpreter/Interpreter.cpp:
(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:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (181888 => 181889)


--- trunk/LayoutTests/ChangeLog	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/ChangeLog	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,3 +1,41 @@
+2015-03-24  Saam Barati  <saambara...@gmail.com>
+
+        Improve error messages in JSC
+        https://bugs.webkit.org/show_bug.cgi?id=141869
+
+        Reviewed by Geoffrey Garen.
+
+        * 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:
+
 2015-03-23  Yoav Weiss  <y...@yoav.ws>
 
         Update empty image canvas tests and fix a related bug

Modified: trunk/LayoutTests/fast/dom/NodeList/nodelist-item-call-as-function-expected.txt (181888 => 181889)


--- trunk/LayoutTests/fast/dom/NodeList/nodelist-item-call-as-function-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/fast/dom/NodeList/nodelist-item-call-as-function-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -3,7 +3,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS nodeList(0) threw exception TypeError: NodeList is not a function (evaluating 'nodeList(0)').
+PASS nodeList(0) threw exception TypeError: nodeList is not a function. (In 'nodeList(0)', 'nodeList' is an instance of NodeList).
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/dom/call-a-constructor-as-a-function-expected.txt (181888 => 181889)


--- trunk/LayoutTests/fast/dom/call-a-constructor-as-a-function-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/fast/dom/call-a-constructor-as-a-function-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -4,19 +4,19 @@
 
 
 SKIP AudioContext is not implemented.
-PASS FormData() threw exception TypeError: FormDataConstructor is not a function (evaluating 'FormData()').
-PASS EventSource() threw exception TypeError: EventSourceConstructor is not a function (evaluating 'EventSource()').
-PASS FileReader() threw exception TypeError: FileReaderConstructor is not a function (evaluating 'FileReader()').
-PASS Audio() threw exception TypeError: AudioConstructor is not a function (evaluating 'Audio()').
-PASS Image() threw exception TypeError: ImageConstructor is not a function (evaluating 'Image()').
-PASS Option() threw exception TypeError: OptionConstructor is not a function (evaluating 'Option()').
-PASS MessageChannel() threw exception TypeError: MessageChannelConstructor is not a function (evaluating 'MessageChannel()').
-PASS WebKitCSSMatrix() threw exception TypeError: WebKitCSSMatrixConstructor is not a function (evaluating 'WebKitCSSMatrix()').
-PASS WebKitPoint() threw exception TypeError: WebKitPointConstructor is not a function (evaluating 'WebKitPoint()').
-PASS WebSocket() threw exception TypeError: WebSocketConstructor is not a function (evaluating 'WebSocket()').
-PASS Worker() threw exception TypeError: WorkerConstructor is not a function (evaluating 'Worker()').
-PASS XMLHttpRequest() threw exception TypeError: XMLHttpRequestConstructor is not a function (evaluating 'XMLHttpRequest()').
-PASS XSLTProcessor() threw exception TypeError: XSLTProcessorConstructor is not a function (evaluating 'XSLTProcessor()').
+PASS FormData() threw exception TypeError: FormData is not a function. (In 'FormData()', 'FormData' is an instance of FormDataConstructor).
+PASS EventSource() threw exception TypeError: EventSource is not a function. (In 'EventSource()', 'EventSource' is an instance of EventSourceConstructor).
+PASS FileReader() threw exception TypeError: FileReader is not a function. (In 'FileReader()', 'FileReader' is an instance of FileReaderConstructor).
+PASS Audio() threw exception TypeError: Audio is not a function. (In 'Audio()', 'Audio' is an instance of AudioConstructor).
+PASS Image() threw exception TypeError: Image is not a function. (In 'Image()', 'Image' is an instance of ImageConstructor).
+PASS Option() threw exception TypeError: Option is not a function. (In 'Option()', 'Option' is an instance of OptionConstructor).
+PASS MessageChannel() threw exception TypeError: MessageChannel is not a function. (In 'MessageChannel()', 'MessageChannel' is an instance of MessageChannelConstructor).
+PASS WebKitCSSMatrix() threw exception TypeError: WebKitCSSMatrix is not a function. (In 'WebKitCSSMatrix()', 'WebKitCSSMatrix' is an instance of WebKitCSSMatrixConstructor).
+PASS WebKitPoint() threw exception TypeError: WebKitPoint is not a function. (In 'WebKitPoint()', 'WebKitPoint' is an instance of WebKitPointConstructor).
+PASS WebSocket() threw exception TypeError: WebSocket is not a function. (In 'WebSocket()', 'WebSocket' is an instance of WebSocketConstructor).
+PASS Worker() threw exception TypeError: Worker is not a function. (In 'Worker()', 'Worker' is an instance of WorkerConstructor).
+PASS XMLHttpRequest() threw exception TypeError: XMLHttpRequest is not a function. (In 'XMLHttpRequest()', 'XMLHttpRequest' is an instance of XMLHttpRequestConstructor).
+PASS XSLTProcessor() threw exception TypeError: XSLTProcessor is not a function. (In 'XSLTProcessor()', 'XSLTProcessor' is an instance of XSLTProcessorConstructor).
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/regex/dom/cross-frame-callable-expected.txt (181888 => 181889)


--- trunk/LayoutTests/fast/regex/dom/cross-frame-callable-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/fast/regex/dom/cross-frame-callable-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,4 +1,4 @@
-PASS re('a') threw exception TypeError: RegExp is not a function (evaluating 're('a')').
+PASS re('a') threw exception TypeError: re is not a function. (In 're('a')', 're' is an instance of RegExp).
 PASS re.exec('a') is ['a']
 PASS successfullyParsed is true
 

Modified: trunk/LayoutTests/fast/selectors/closest-general-expected.txt (181888 => 181889)


--- trunk/LayoutTests/fast/selectors/closest-general-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/fast/selectors/closest-general-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -43,7 +43,7 @@
 PASS sour.closest("b, a") is b
 PASS sour.closest("a") is a
 PASS document.closest is undefined
-PASS document.closest() threw exception TypeError: undefined is not a function (evaluating 'document.closest()').
+PASS document.closest() threw exception TypeError: document.closest is not a function. (In 'document.closest()', 'document.closest' is undefined).
 PASS theTarget.closest() threw exception TypeError: Not enough arguments.
 PASS theTarget.closest("") threw exception Error: SyntaxError: DOM Exception 12.
 PASS theTarget.closest(".123") threw exception Error: SyntaxError: DOM Exception 12.

Modified: trunk/LayoutTests/http/tests/security/xss-DENIED-window-index-assign-expected.txt (181888 => 181889)


--- trunk/LayoutTests/http/tests/security/xss-DENIED-window-index-assign-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/http/tests/security/xss-DENIED-window-index-assign-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,4 +1,4 @@
 ALERT: undefined
-CONSOLE MESSAGE: line 1: TypeError: undefined is not a function (evaluating 'parent[0].f()')
+CONSOLE MESSAGE: line 1: TypeError: parent[0].f is not a function. (In 'parent[0].f()', 'parent[0].f' is undefined)
 
 This test passes if the access is forbidden.

Modified: trunk/LayoutTests/js/dom/exception-thrown-from-new-expected.txt (181888 => 181889)


--- trunk/LayoutTests/js/dom/exception-thrown-from-new-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/js/dom/exception-thrown-from-new-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,5 +1,5 @@
 This page tests exceptions thrown from 'new' expressions. If the test passes, you'll see a series of PASS messages below.
 
 FAIL: e1 should be 'TypeError: 'undefined' is not a constructor (evaluating 'new f')' but instead is 'TypeError: undefined is not a constructor (evaluating 'new f')'.
-FAIL: e2 should be 'TypeError: 'undefined' is not a function (evaluating 'g()')' but instead is 'TypeError: undefined is not a function (evaluating 'g()')'.
+FAIL: 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)'.
 

Modified: trunk/LayoutTests/js/exception-for-nonobject-expected.txt (181888 => 181889)


--- trunk/LayoutTests/js/exception-for-nonobject-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/js/exception-for-nonobject-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -4,7 +4,7 @@
 
 
 PASS new {}.undefined threw exception TypeError: undefined is not a constructor (evaluating 'new {}.undefined').
-PASS 1 instanceof {}.undefined threw exception TypeError: undefined is not a valid argument for 'instanceof' (evaluating '1 instanceof {}.undefined').
+PASS 1 instanceof {}.undefined threw exception TypeError: {}.undefined is not a function. (evaluating '1 instanceof {}.undefined').
 PASS successfullyParsed is true
 
 TEST COMPLETE

Added: trunk/LayoutTests/js/exception-function-apply-expected.txt (0 => 181889)


--- trunk/LayoutTests/js/exception-function-apply-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/exception-function-apply-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,12 @@
+Test for error messages on function.apply
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS function foo(){}; foo.apply(null, 20) threw exception TypeError: second argument to Function.prototype.apply must be an Array-like object (evaluating 'foo.apply(null, 20)').
+PASS function foo(){}; foo.apply(null, 'hello') threw exception TypeError: second argument to Function.prototype.apply must be an Array-like object (evaluating 'foo.apply(null, 'hello')').
+PASS function foo(){}; foo.apply(null, true) threw exception TypeError: second argument to Function.prototype.apply must be an Array-like object (evaluating 'foo.apply(null, true)').
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/exception-function-apply.html (0 => 181889)


--- trunk/LayoutTests/js/exception-function-apply.html	                        (rev 0)
+++ trunk/LayoutTests/js/exception-function-apply.html	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/exception-in-expected.txt (0 => 181889)


--- trunk/LayoutTests/js/exception-in-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/exception-in-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,14 @@
+Test for error messages for in
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS 20   in   'in in in'   threw exception TypeError: "in in in" is not an Object. (evaluating '20   in   'in in in'').
+PASS 20   in   true   threw exception TypeError: true is not an Object. (evaluating '20   in   true').
+PASS 20   in   {}.foo   threw exception TypeError: {}.foo is not an Object. (evaluating '20   in   {}.foo').
+PASS 20   in   20   threw exception TypeError: 20 is not an Object. (evaluating '20   in   20').
+PASS 20   in   null   threw exception TypeError: null is not an Object. (evaluating '20   in   null').
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/exception-in.html (0 => 181889)


--- trunk/LayoutTests/js/exception-in.html	                        (rev 0)
+++ trunk/LayoutTests/js/exception-in.html	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/exception-instanceof-expected.txt (0 => 181889)


--- trunk/LayoutTests/js/exception-instanceof-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/exception-instanceof-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,14 @@
+Test for error messages for instanceof
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS 'instanceof' instanceof    'instanceof' threw exception TypeError: "instanceof" is not a function. (evaluating ''instanceof' instanceof    'instanceof'').
+PASS 20 instanceof     'hello'   threw exception TypeError: 'hello' is not a function. (evaluating '20 instanceof     'hello'').
+PASS 20 instanceof     {}   threw exception TypeError: {} is not a function. (evaluating '20 instanceof     {}').
+PASS 20 instanceof     {}.foo  threw exception TypeError: {}.foo is not a function. (evaluating '20 instanceof     {}.foo').
+PASS 20 instanceof     true       threw exception TypeError: true is not a function. (evaluating '20 instanceof     true').
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/exception-instanceof.html (0 => 181889)


--- trunk/LayoutTests/js/exception-instanceof.html	                        (rev 0)
+++ trunk/LayoutTests/js/exception-instanceof.html	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/js/instance-of-immediates-expected.txt (181888 => 181889)


--- trunk/LayoutTests/js/instance-of-immediates-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/js/instance-of-immediates-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -3,12 +3,12 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS (1 instanceof 1) threw exception TypeError: 1 is not a valid argument for 'instanceof' (evaluating '1 instanceof 1').
-PASS ({} instanceof 1) threw exception TypeError: 1 is not a valid argument for 'instanceof' (evaluating '{} instanceof 1').
-PASS (obj instanceof 1) threw exception TypeError: 1 is not a valid argument for 'instanceof' (evaluating 'obj instanceof 1').
-PASS (1 instanceof {}) threw exception TypeError: Object is not a valid argument for 'instanceof' (evaluating '1 instanceof {}').
-PASS ({} instanceof {}) threw exception TypeError: Object is not a valid argument for 'instanceof' (evaluating '{} instanceof {}').
-PASS (obj instanceof {}) threw exception TypeError: Object is not a valid argument for 'instanceof' (evaluating 'obj instanceof {}').
+PASS (1 instanceof 1) threw exception TypeError: 1 is not a function. (evaluating '1 instanceof 1').
+PASS ({} instanceof 1) threw exception TypeError: 1 is not a function. (evaluating '{} instanceof 1').
+PASS (obj instanceof 1) threw exception TypeError: 1 is not a function. (evaluating 'obj instanceof 1').
+PASS (1 instanceof {}) threw exception TypeError: {} is not a function. (evaluating '1 instanceof {}').
+PASS ({} instanceof {}) threw exception TypeError: {} is not a function. (evaluating '{} instanceof {}').
+PASS (obj instanceof {}) threw exception TypeError: {} is not a function. (evaluating 'obj instanceof {}').
 PASS (1 instanceof Constructor) is false
 PASS ({} instanceof Constructor) is false
 PASS (obj instanceof Constructor) is true

Added: trunk/LayoutTests/js/script-tests/exception-function-apply.js (0 => 181889)


--- trunk/LayoutTests/js/script-tests/exception-function-apply.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/exception-function-apply.js	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,5 @@
+description("Test for error messages on function.apply");
+
+shouldThrow("function foo(){}; foo.apply(null, 20)");
+shouldThrow("function foo(){}; foo.apply(null, 'hello')");
+shouldThrow("function foo(){}; foo.apply(null, true)");

Added: trunk/LayoutTests/js/script-tests/exception-in.js (0 => 181889)


--- trunk/LayoutTests/js/script-tests/exception-in.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/exception-in.js	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,7 @@
+description("Test for error messages for in");
+
+shouldThrow("20   in   'in in in'  ");
+shouldThrow("20   in   true  ");
+shouldThrow("20   in   {}.foo  ");
+shouldThrow("20   in   20  ");
+shouldThrow("20   in   null  ");

Added: trunk/LayoutTests/js/script-tests/exception-instanceof.js (0 => 181889)


--- trunk/LayoutTests/js/script-tests/exception-instanceof.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/exception-instanceof.js	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,7 @@
+description("Test for error messages for instanceof");
+
+shouldThrow("'instanceof' instanceof    'instanceof'");
+shouldThrow("20 instanceof     'hello'  ");
+shouldThrow("20 instanceof     {}  ");
+shouldThrow("20 instanceof     {}.foo ");
+shouldThrow("20 instanceof     true      ");

Modified: trunk/LayoutTests/js/typedarray-constructors-expected.txt (181888 => 181889)


--- trunk/LayoutTests/js/typedarray-constructors-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/js/typedarray-constructors-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -3,25 +3,25 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Int8Array() threw exception TypeError: Function is not a function (evaluating 'Int8Array()').
+PASS Int8Array() threw exception TypeError: Int8Array is not a function. (In 'Int8Array()', 'Int8Array' is an instance of Function).
 PASS new Int8Array() did not throw exception.
-PASS Int16Array() threw exception TypeError: Function is not a function (evaluating 'Int16Array()').
+PASS Int16Array() threw exception TypeError: Int16Array is not a function. (In 'Int16Array()', 'Int16Array' is an instance of Function).
 PASS new Int16Array() did not throw exception.
-PASS Int32Array() threw exception TypeError: Function is not a function (evaluating 'Int32Array()').
+PASS Int32Array() threw exception TypeError: Int32Array is not a function. (In 'Int32Array()', 'Int32Array' is an instance of Function).
 PASS new Int32Array() did not throw exception.
-PASS Uint8Array() threw exception TypeError: Function is not a function (evaluating 'Uint8Array()').
+PASS Uint8Array() threw exception TypeError: Uint8Array is not a function. (In 'Uint8Array()', 'Uint8Array' is an instance of Function).
 PASS new Uint8Array() did not throw exception.
-PASS Uint16Array() threw exception TypeError: Function is not a function (evaluating 'Uint16Array()').
+PASS Uint16Array() threw exception TypeError: Uint16Array is not a function. (In 'Uint16Array()', 'Uint16Array' is an instance of Function).
 PASS new Uint16Array() did not throw exception.
-PASS Uint32Array() threw exception TypeError: Function is not a function (evaluating 'Uint32Array()').
+PASS Uint32Array() threw exception TypeError: Uint32Array is not a function. (In 'Uint32Array()', 'Uint32Array' is an instance of Function).
 PASS new Uint32Array() did not throw exception.
-PASS Uint8ClampedArray() threw exception TypeError: Function is not a function (evaluating 'Uint8ClampedArray()').
+PASS Uint8ClampedArray() threw exception TypeError: Uint8ClampedArray is not a function. (In 'Uint8ClampedArray()', 'Uint8ClampedArray' is an instance of Function).
 PASS new Uint8ClampedArray() did not throw exception.
-PASS Float32Array() threw exception TypeError: Function is not a function (evaluating 'Float32Array()').
+PASS Float32Array() threw exception TypeError: Float32Array is not a function. (In 'Float32Array()', 'Float32Array' is an instance of Function).
 PASS new Float32Array() did not throw exception.
-PASS Float64Array() threw exception TypeError: Function is not a function (evaluating 'Float64Array()').
+PASS Float64Array() threw exception TypeError: Float64Array is not a function. (In 'Float64Array()', 'Float64Array' is an instance of Function).
 PASS new Float64Array() did not throw exception.
-PASS DataView(new ArrayBuffer()) threw exception TypeError: Function is not a function (evaluating 'DataView(new ArrayBuffer())').
+PASS DataView(new ArrayBuffer()) threw exception TypeError: DataView is not a function. (In 'DataView(new ArrayBuffer())', 'DataView' is an instance of Function).
 PASS new DataView(new ArrayBuffer()) did not throw exception.
 PASS successfullyParsed is true
 

Modified: trunk/LayoutTests/platform/mac/css3/selectors3/xhtml/css3-modsel-15c-expected.txt (181888 => 181889)


--- trunk/LayoutTests/platform/mac/css3/selectors3/xhtml/css3-modsel-15c-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/platform/mac/css3/selectors3/xhtml/css3-modsel-15c-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 27: TypeError: undefined is not a function (evaluating 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute('title', true)')
+CONSOLE 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)
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x186

Modified: trunk/LayoutTests/platform/mac/css3/selectors3/xml/css3-modsel-15c-expected.txt (181888 => 181889)


--- trunk/LayoutTests/platform/mac/css3/selectors3/xml/css3-modsel-15c-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/platform/mac/css3/selectors3/xml/css3-modsel-15c-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 9: TypeError: undefined is not a function (evaluating 'document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0].setIdAttribute('title', true)')
+CONSOLE 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)
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x186

Modified: trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-expected.txt (181888 => 181889)


--- trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -5,6 +5,6 @@
 
 PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
 PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
-PASS testObject() threw exception TypeError: NPObject is not a function (evaluating 'testObject()').
+PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of NPObject).
 PASS new testObject(); threw exception TypeError: NPObject is not a constructor (evaluating 'new testObject()').
 

Modified: trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt (181888 => 181889)


--- trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -5,6 +5,6 @@
 
  PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
 PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
-PASS testObject() threw exception TypeError: NPObject is not a function (evaluating 'testObject()').
+PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of NPObject).
 PASS new testObject(); threw exception TypeError: NPObject is not a constructor (evaluating 'new testObject()').
 

Modified: trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-expected.txt (181888 => 181889)


--- trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -5,6 +5,6 @@
 
 PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
 PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
-PASS testObject() threw exception TypeError: ProxyRuntimeObject is not a function (evaluating 'testObject()').
+PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of ProxyRuntimeObject).
 PASS new testObject(); threw exception TypeError: ProxyRuntimeObject is not a constructor (evaluating 'new testObject()').
 

Modified: trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt (181888 => 181889)


--- trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -5,6 +5,6 @@
 
  PASS testObject.gettingProperty threw exception ReferenceError: Trying to access object from destroyed plug-in..
 PASS testObject.settingProperty = 10 threw exception ReferenceError: Trying to access object from destroyed plug-in..
-PASS testObject() threw exception TypeError: ProxyRuntimeObject is not a function (evaluating 'testObject()').
+PASS testObject() threw exception TypeError: testObject is not a function. (In 'testObject()', 'testObject' is an instance of ProxyRuntimeObject).
 PASS new testObject(); threw exception TypeError: ProxyRuntimeObject is not a constructor (evaluating 'new testObject()').
 

Modified: trunk/LayoutTests/plugins/npruntime/plugin-scriptable-object-invoke-default-expected.txt (181888 => 181889)


--- trunk/LayoutTests/plugins/npruntime/plugin-scriptable-object-invoke-default-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/plugins/npruntime/plugin-scriptable-object-invoke-default-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -7,5 +7,5 @@
 PASS typeof(pluginWithInvokeDefault) is 'function'
 PASS pluginWithInvokeDefault() is 1
 PASS typeof(pluginWithoutInvokeDefault) is 'object'
-PASS pluginWithoutInvokeDefault() threw exception TypeError: HTMLEmbedElement is not a function (evaluating 'pluginWithoutInvokeDefault()').
+PASS pluginWithoutInvokeDefault() threw exception TypeError: pluginWithoutInvokeDefault is not a function. (In 'pluginWithoutInvokeDefault()', 'pluginWithoutInvokeDefault' is an instance of HTMLEmbedElement).
 

Modified: trunk/LayoutTests/sputnik/Conformance/12_Statement/12.1_Block/S12.1_A4_T1-expected.txt (181888 => 181889)


--- trunk/LayoutTests/sputnik/Conformance/12_Statement/12.1_Block/S12.1_A4_T1-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/sputnik/Conformance/12_Statement/12.1_Block/S12.1_A4_T1-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,6 +1,6 @@
 S12.1_A4_T1
 
-PASS TypeError: Object is not a function (evaluating '{__func}()')
+PASS TypeError: {__func} is not a function. (In '{__func}()', '{__func}' is an instance of Object)
 
 TEST COMPLETE
 

Modified: trunk/LayoutTests/sputnik/Conformance/13_Function_Definition/S13_A17_T2-expected.txt (181888 => 181889)


--- trunk/LayoutTests/sputnik/Conformance/13_Function_Definition/S13_A17_T2-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/sputnik/Conformance/13_Function_Definition/S13_A17_T2-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,6 +1,6 @@
 S13_A17_T2
 
-TypeError: undefined is not a function (evaluating '__func()')
+TypeError: __func is not a function. (In '__func()', '__func' is undefined)
 PASS 
 
 TEST COMPLETE

Modified: trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A2_T1-expected.txt (181888 => 181889)


--- trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A2_T1-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A2_T1-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,6 +1,6 @@
 S15.1_A2_T1
 
-PASS TypeError: Window is not a function (evaluating 'this()')
+PASS TypeError: this is not a function. (In 'this()', 'this' is an instance of Window)
 
 TEST COMPLETE
 

Modified: trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A3-expected.txt (181888 => 181889)


--- trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A3-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A3-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,6 +1,6 @@
 S15.2.4_A3
 
-TypeError: Object is not a function (evaluating 'Object.prototype()')
+TypeError: Object.prototype is not a function. (In 'Object.prototype()', 'Object.prototype' is an instance of Object)
 PASS 
 
 TEST COMPLETE

Modified: trunk/LayoutTests/svg/dom/svgpath-out-of-bounds-getPathSeg-expected.txt (181888 => 181889)


--- trunk/LayoutTests/svg/dom/svgpath-out-of-bounds-getPathSeg-expected.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/LayoutTests/svg/dom/svgpath-out-of-bounds-getPathSeg-expected.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -5,14 +5,14 @@
 
 PASS path.pathSegList.initialize(); threw exception TypeError: Not enough arguments.
 PASS path.getPathSegAtLength(0) is 0
-PASS path.insertItemBefore(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.insertItemBefore(null, 0)').
-PASS path.replaceItem(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.replaceItem(null, 0)').
-PASS path.appendItem(null) threw exception TypeError: undefined is not a function (evaluating 'path.appendItem(null)').
+PASS path.insertItemBefore(null, 0) threw exception TypeError: path.insertItemBefore is not a function. (In 'path.insertItemBefore(null, 0)', 'path.insertItemBefore' is undefined).
+PASS path.replaceItem(null, 0) threw exception TypeError: path.replaceItem is not a function. (In 'path.replaceItem(null, 0)', 'path.replaceItem' is undefined).
+PASS path.appendItem(null) threw exception TypeError: path.appendItem is not a function. (In 'path.appendItem(null)', 'path.appendItem' is undefined).
 List correctly initialised.
 PASS path.getPathSegAtLength(0) is 0
-PASS path.insertItemBefore(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.insertItemBefore(null, 0)').
-PASS path.replaceItem(null, 0) threw exception TypeError: undefined is not a function (evaluating 'path.replaceItem(null, 0)').
-PASS path.appendItem(null) threw exception TypeError: undefined is not a function (evaluating 'path.appendItem(null)').
+PASS path.insertItemBefore(null, 0) threw exception TypeError: path.insertItemBefore is not a function. (In 'path.insertItemBefore(null, 0)', 'path.insertItemBefore' is undefined).
+PASS path.replaceItem(null, 0) threw exception TypeError: path.replaceItem is not a function. (In 'path.replaceItem(null, 0)', 'path.replaceItem' is undefined).
+PASS path.appendItem(null) threw exception TypeError: path.appendItem is not a function. (In 'path.appendItem(null)', 'path.appendItem' is undefined).
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (181888 => 181889)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2015-03-24 07:30:05 UTC (rev 181889)
@@ -535,6 +535,7 @@
     runtime/RegExpMatchesArray.cpp
     runtime/RegExpObject.cpp
     runtime/RegExpPrototype.cpp
+    runtime/RuntimeType.cpp
     runtime/SamplingCounter.cpp
     runtime/SetConstructor.cpp
     runtime/SetIteratorConstructor.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (181888 => 181889)


--- trunk/Source/_javascript_Core/ChangeLog	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1,3 +1,80 @@
+2015-03-24  Saam Barati  <saambara...@gmail.com>
+
+        Improve error messages in JSC
+        https://bugs.webkit.org/show_bug.cgi?id=141869
+
+        Reviewed by Geoffrey Garen.
+
+        _javascript_Core 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.
+
+        * CMakeLists.txt:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * interpreter/Interpreter.cpp:
+        (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):
+
 2015-03-23  Filip Pizlo  <fpi...@apple.com>
 
         JSC should have a low-cost asynchronous disassembler

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (181888 => 181889)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-03-24 07:30:05 UTC (rev 181889)
@@ -802,6 +802,7 @@
     <ClCompile Include="..\runtime\RegExpMatchesArray.cpp" />
     <ClCompile Include="..\runtime\RegExpObject.cpp" />
     <ClCompile Include="..\runtime\RegExpPrototype.cpp" />
+    <ClCompile Include="..\runtime\RuntimeType.cpp" />
     <ClCompile Include="..\runtime\SamplingCounter.cpp" />
     <ClCompile Include="..\runtime\SetConstructor.cpp" />
     <ClCompile Include="..\runtime\SetIteratorConstructor.cpp" />
@@ -1614,6 +1615,7 @@
     <ClInclude Include="..\runtime\RegExpPrototype.h" />
     <ClInclude Include="..\runtime\Reject.h" />
     <ClInclude Include="..\runtime\RuntimeFlags.h" />
+    <ClInclude Include="..\runtime\RuntimeType.h" />
     <ClInclude Include="..\runtime\SamplingCounter.h" />
     <ClInclude Include="..\runtime\SetConstructor.h" />
     <ClInclude Include="..\runtime\SetIteratorConstructor.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (181888 => 181889)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2015-03-24 07:30:05 UTC (rev 181889)
@@ -801,6 +801,9 @@
     <ClCompile Include="..\runtime\RegExpPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\RuntimeType.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\SamplingCounter.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
@@ -2870,6 +2873,9 @@
     <ClInclude Include="..\runtime\RuntimeFlags.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\RuntimeType.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\SamplingCounter.h">
       <Filter>runtime</Filter>
     </ClInclude>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (181888 => 181889)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-03-24 07:30:05 UTC (rev 181889)
@@ -910,11 +910,13 @@
 		52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52678F8C1A031009006A306D /* BasicBlockLocation.cpp */; };
 		52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F8D1A031009006A306D /* BasicBlockLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F901A04177C006A306D /* ControlFlowProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */; };
 		52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52B310FD1974AE870080857C /* FunctionHasExecutedCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */; };
 		52B310FF1975B4240080857C /* TypeLocationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FE1975B4240080857C /* TypeLocationCache.cpp */; };
 		52B311011975B4670080857C /* TypeLocationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B311001975B4670080857C /* TypeLocationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */; };
+		52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
 		5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
@@ -2567,11 +2569,13 @@
 		52678F8C1A031009006A306D /* BasicBlockLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BasicBlockLocation.cpp; sourceTree = "<group>"; };
 		52678F8D1A031009006A306D /* BasicBlockLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicBlockLocation.h; sourceTree = "<group>"; };
 		52678F901A04177C006A306D /* ControlFlowProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlFlowProfiler.h; sourceTree = "<group>"; };
+		527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeType.cpp; sourceTree = "<group>"; };
 		52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionHasExecutedCache.h; sourceTree = "<group>"; };
 		52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionHasExecutedCache.cpp; sourceTree = "<group>"; };
 		52B310FE1975B4240080857C /* TypeLocationCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLocationCache.cpp; sourceTree = "<group>"; };
 		52B311001975B4670080857C /* TypeLocationCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocationCache.h; sourceTree = "<group>"; };
 		52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ControlFlowProfiler.cpp; sourceTree = "<group>"; };
+		52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = "<group>"; };
 		52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = "<group>"; };
 		52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; };
 		5540758418F4A37500602A5D /* CompileRuntimeToLLVMIR.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CompileRuntimeToLLVMIR.xcconfig; sourceTree = "<group>"; };
@@ -4564,6 +4568,8 @@
 				0F6B1CB81861244C00845D97 /* RegisterPreservationMode.h */,
 				0FB7F39115ED8E3800F167B2 /* Reject.h */,
 				70B0A9D01A9B66200001306A /* RuntimeFlags.h */,
+				527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */,
+				52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */,
 				0F7700911402FF280078EB39 /* SamplingCounter.cpp */,
 				0F77008E1402FDD60078EB39 /* SamplingCounter.h */,
 				A7299DA317D12858005F5FF9 /* SetConstructor.cpp */,
@@ -5459,6 +5465,7 @@
 				0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
 				A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
 				86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
+				52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */,
 				C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */,
 				52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */,
 				52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */,
@@ -7096,6 +7103,7 @@
 				C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */,
 				0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */,
 				0FCEFACA1805E75500472CE4 /* InitializeLLVM.cpp in Sources */,
+				527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */,
 				A513E5B7185B8BD3007E95AD /* InjectedScript.cpp in Sources */,
 				0FBF158C19B7A53100695DD0 /* DFGBlockSet.cpp in Sources */,
 				A514B2C2185A684400F3C7CB /* InjectedScriptBase.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -142,7 +142,7 @@
     else if (arguments.isUndefinedOrNull())
         length = 0;
     else if (!arguments.isObject()) {
-        callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments));
+        callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame,  arguments));
         return 0;
     } else if (asObject(arguments)->classInfo() == Arguments::info())
         length = asArguments(arguments)->length(callFrame);

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -200,7 +200,7 @@
     NativeCallFrameTracer tracer(vm, exec);
     
     if (!base->isObject()) {
-        vm->throwException(exec, createInvalidParameterError(exec, "in", base));
+        vm->throwException(exec, createInvalidInParameterError(exec, base));
         return JSValue::encode(jsUndefined());
     }
     
@@ -226,7 +226,7 @@
     NativeCallFrameTracer tracer(vm, exec);
 
     if (!base->isObject()) {
-        vm->throwException(exec, createInvalidParameterError(exec, "in", base));
+        vm->throwException(exec, createInvalidInParameterError(exec, base));
         return JSValue::encode(jsUndefined());
     }
 
@@ -966,12 +966,13 @@
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-
-    String message = errorDescriptionForValue(exec, JSValue::decode(encodedValue))->value(exec);
+    JSValue errorMessageValue = JSValue::decode(encodedValue);
+    RELEASE_ASSERT(errorMessageValue.isString());
+    String errorMessage = asString(errorMessageValue)->value(exec);
     if (referenceErrorFlag)
-        vm.throwException(exec, createReferenceError(exec, message));
+        vm.throwException(exec, createReferenceError(exec, errorMessage));
     else
-        vm.throwException(exec, createTypeError(exec, message));
+        vm.throwException(exec, createTypeError(exec, errorMessage));
 }
 
 void JIT_OPERATION operationDebug(ExecState* exec, int32_t debugHookID)
@@ -1348,7 +1349,7 @@
         }
     }
 
-    vm.throwException(exec, createInvalidParameterError(exec, "instanceof", baseVal));
+    vm.throwException(exec, createInvalidInstanceofParameterError(exec, baseVal));
     return JSValue::encode(JSValue());
 }
 

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -558,7 +558,7 @@
             LLINT_RETURN_WITH_PC_ADJUSTMENT(result, pc[4].u.operand);
         }
     }
-    LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
+    LLINT_THROW(createInvalidInstanceofParameterError(exec, baseVal));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
@@ -1305,10 +1305,13 @@
 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
 {
     LLINT_BEGIN();
+    JSValue errorMessageValue = LLINT_OP_C(1).jsValue();
+    RELEASE_ASSERT(errorMessageValue.isString());
+    String errorMessage = asString(errorMessageValue)->value(exec);
     if (pc[2].u.operand)
-        LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
+        LLINT_THROW(createReferenceError(exec, errorMessage));
     else
-        LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
+        LLINT_THROW(createTypeError(exec, errorMessage));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)

Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.h (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.h	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.h	2015-03-24 07:30:05 UTC (rev 181889)
@@ -72,7 +72,7 @@
 inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
 {
     if (!baseVal.isObject()) {
-        exec->vm().throwException(exec, createInvalidParameterError(exec, "in", baseVal));
+        exec->vm().throwException(exec, createInvalidInParameterError(exec, baseVal));
         return false;
     }
 

Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -32,7 +32,6 @@
 
 ErrorInstance::ErrorInstance(VM& vm, Structure* structure)
     : JSNonFinalObject(vm, structure)
-    , m_appendSourceToMessage(false)
 {
 }
 

Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.h (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/ErrorInstance.h	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.h	2015-03-24 07:30:05 UTC (rev 181889)
@@ -22,7 +22,7 @@
 #define ErrorInstance_h
 
 #include "Interpreter.h"
-#include "JSObject.h"
+#include "RuntimeType.h"
 #include "SourceProvider.h"
 
 namespace JSC {
@@ -50,16 +50,24 @@
         return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), stackTrace);
     }
 
-    bool appendSourceToMessage() { return m_appendSourceToMessage; }
-    void setAppendSourceToMessage() { m_appendSourceToMessage = true; }
-    void clearAppendSourceToMessage() { m_appendSourceToMessage = false; }
+    enum SourceTextWhereErrorOccurred { FoundExactSource, FoundApproximateSource };
+    typedef String (*SourceAppender) (const String& originalMessage, const String& sourceText, RuntimeType, SourceTextWhereErrorOccurred);
 
+    bool hasSourceAppender() const { return !!m_sourceAppender; }
+    SourceAppender sourceAppender() const { return m_sourceAppender; }
+    void setSourceAppender(SourceAppender appender) { m_sourceAppender = appender; }
+    void clearSourceAppender() { m_sourceAppender = nullptr; }
+    void setRuntimeTypeForCause(RuntimeType type) { m_runtimeTypeForCause = type; }
+    RuntimeType runtimeTypeForCause() const { return m_runtimeTypeForCause; }
+    void clearRuntimeTypeForCause() { m_runtimeTypeForCause = TypeNothing; }
+
 protected:
     explicit ErrorInstance(VM&, Structure*);
 
     void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());
 
-    bool m_appendSourceToMessage;
+    SourceAppender m_sourceAppender { nullptr };
+    RuntimeType m_runtimeTypeForCause { TypeNothing };
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -32,13 +32,14 @@
 #include "CodeBlock.h"
 #include "CallFrame.h"
 #include "ErrorHandlingScope.h"
-#include "ErrorInstance.h"
 #include "JSGlobalObjectFunctions.h"
-#include "JSObject.h"
 #include "JSNotAnObject.h"
 #include "Interpreter.h"
 #include "Nodes.h"
 #include "JSCInlines.h"
+#include "RuntimeType.h"
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringView.h>
 
 namespace JSC {
 
@@ -106,13 +107,13 @@
     if (v.isFalse())
         return vm.smallStrings.falseString();
     if (v.isString())
-        return jsCast<JSString*>(v.asCell());
+        return jsString(&vm, makeString('"',  asString(v)->value(exec), '"'));
     if (v.isObject()) {
         CallData callData;
         JSObject* object = asObject(v);
         if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
             return vm.smallStrings.functionString();
-        return jsString(exec, object->methodTable()->className(object));
+        return jsString(exec, JSObject::calculatedClassName(object));
     }
     
     // The JSValue should never be empty, so this point in the code should never be reached.
@@ -120,33 +121,167 @@
     return vm.smallStrings.emptyString();
 }
     
-JSObject* createError(ExecState* exec, ErrorFactory errorFactory, JSValue value, const String& message)
+static String defaultApproximateSourceError(const String& originalMessage, const String& sourceText)
 {
+    return makeString(originalMessage, " (near '...", sourceText, "...')");
+}
+
+static String defaultSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
+{
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    return makeString(originalMessage, " (evaluating '", sourceText, "')");
+}
+
+static String functionCallBase(const String& sourceText)
+{ 
+    // This function retrieves the 'foo.bar' substring from 'foo.bar(baz)'.
+    unsigned idx = sourceText.length() - 1;
+    if (sourceText[idx] != ')') {
+        // For function calls that have many new lines in between their open parenthesis
+        // and their closing parenthesis, the text range passed into the message appender 
+        // will not inlcude the text in between these parentheses, it will just be the desired
+        // text that precedes the parentheses.
+        return sourceText;
+    }
+
+    unsigned parenStack = 1;
+    bool isInMultiLineComment = false;
+    idx -= 1;
+    // Note that we're scanning text right to left instead of the more common left to right, 
+    // so syntax detection is backwards.
+    while (parenStack > 0) {
+        UChar curChar = sourceText[idx];
+        if (isInMultiLineComment)  {
+            if (curChar == '*' && sourceText[idx - 1] == '/') {
+                isInMultiLineComment = false;
+                idx -= 1;
+            }
+        } else if (curChar == '(')
+            parenStack -= 1;
+        else if (curChar == ')')
+            parenStack += 1;
+        else if (curChar == '/' && sourceText[idx - 1] == '*') {
+            isInMultiLineComment = true;
+            idx -= 1;
+        }
+
+        idx -= 1;
+    }
+
+    return sourceText.left(idx + 1);
+}
+
+static String notAFunctionSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType type, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
+{
+    ASSERT(type != TypeFunction);
+
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    auto notAFunctionIndex = originalMessage.reverseFind("is not a function");
+    RELEASE_ASSERT(notAFunctionIndex != notFound);
+    StringView displayValue;
+    if (originalMessage.is8Bit()) 
+        displayValue = StringView(originalMessage.characters8(), notAFunctionIndex - 1);
+    else
+        displayValue = StringView(originalMessage.characters16(), notAFunctionIndex - 1);
+
+    String base = functionCallBase(sourceText);
+    StringBuilder builder;
+    builder.append(base);
+    builder.appendLiteral(" is not a function. (In '");
+    builder.append(sourceText);
+    builder.appendLiteral("', '");
+    builder.append(base);
+    builder.appendLiteral("' is ");
+    if (type == TypeObject)
+        builder.appendLiteral("an instance of ");
+    builder.append(displayValue);
+    builder.appendLiteral(")");
+
+    return builder.toString();
+}
+
+static String invalidParameterInSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
+{
+    ASSERT(type != TypeObject);
+
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    auto inIndex = sourceText.reverseFind("in");
+    RELEASE_ASSERT(inIndex != notFound);
+    if (sourceText.find("in") != inIndex)
+        return makeString(originalMessage, " (evaluating '", sourceText, "')");
+
+    static const unsigned inLength = 2;
+    String rightHandSide = sourceText.substring(inIndex + inLength).simplifyWhiteSpace();
+    return makeString(rightHandSide, " is not an Object. (evaluating '", sourceText, "')");
+}
+
+static String invalidParameterInstanceofSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
+{
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    auto instanceofIndex = sourceText.reverseFind("instanceof");
+    RELEASE_ASSERT(instanceofIndex != notFound);
+    if (sourceText.find("instanceof") != instanceofIndex)
+        return makeString(originalMessage, " (evaluating '", sourceText, "')");
+
+    static const unsigned instanceofLength = 10;
+    String rightHandSide = sourceText.substring(instanceofIndex + instanceofLength).simplifyWhiteSpace();
+    return makeString(rightHandSide, " is not a function. (evaluating '", sourceText, "')");
+}
+
+JSObject* createError(ExecState* exec, ErrorFactory errorFactory, JSValue value, const String& message, ErrorInstance::SourceAppender appender)
+{
     String errorMessage = makeString(errorDescriptionForValue(exec, value)->value(exec), ' ', message);
     JSObject* exception = errorFactory(exec, errorMessage);
     ASSERT(exception->isErrorInstance());
-    static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
+    static_cast<ErrorInstance*>(exception)->setSourceAppender(appender);
+    static_cast<ErrorInstance*>(exception)->setRuntimeTypeForCause(runtimeTypeForValue(value));
     return exception;
 }
 
-JSObject* createInvalidParameterError(ExecState* exec, const char* op, JSValue value)
+JSObject* createInvalidFunctionApplyParameterError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, makeString("is not a valid argument for '", op, '\''));
+    JSObject* exception = createTypeError(exec, makeString("second argument to Function.prototype.apply must be an Array-like object"));
+    ASSERT(exception->isErrorInstance());
+    static_cast<ErrorInstance*>(exception)->setSourceAppender(defaultSourceAppender);
+    static_cast<ErrorInstance*>(exception)->setRuntimeTypeForCause(runtimeTypeForValue(value));
+    return exception;
 }
 
+JSObject* createInvalidInParameterError(ExecState* exec, JSValue value)
+{
+    return createError(exec, createTypeError, value, makeString("is not an Object."), invalidParameterInSourceAppender);
+}
+
+JSObject* createInvalidInstanceofParameterError(ExecState* exec, JSValue value)
+{
+    return createError(exec, createTypeError, value, makeString("is not a function."), invalidParameterInstanceofSourceAppender);
+}
+
 JSObject* createNotAConstructorError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, ASCIILiteral("is not a constructor"));
+    return createError(exec, createTypeError, value, ASCIILiteral("is not a constructor"), defaultSourceAppender);
 }
 
 JSObject* createNotAFunctionError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, ASCIILiteral("is not a function"));
+    return createError(exec, createTypeError, value, ASCIILiteral("is not a function"), notAFunctionSourceAppender);
 }
 
 JSObject* createNotAnObjectError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, ASCIILiteral("is not an object"));
+    return createError(exec, createTypeError, value, ASCIILiteral("is not an object"), defaultSourceAppender);
 }
 
 JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const String& propertyName)

Modified: trunk/Source/_javascript_Core/runtime/ExceptionHelpers.h (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/ExceptionHelpers.h	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/ExceptionHelpers.h	2015-03-24 07:30:05 UTC (rev 181889)
@@ -29,6 +29,7 @@
 #ifndef ExceptionHelpers_h
 #define ExceptionHelpers_h
 
+#include "ErrorInstance.h"
 #include "JSObject.h"
 
 namespace JSC {
@@ -38,13 +39,15 @@
 JSObject* createTerminatedExecutionException(VM*);
 bool isTerminatedExecutionException(JSObject*);
 JS_EXPORT_PRIVATE bool isTerminatedExecutionException(JSValue);
-JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorFactory, JSValue, const String&);
+JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorFactory, JSValue, const String&, ErrorInstance::SourceAppender);
 JS_EXPORT_PRIVATE JSObject* createStackOverflowError(ExecState*);
 JSObject* createStackOverflowError(JSGlobalObject*);
 JSObject* createOutOfMemoryError(JSGlobalObject*);
 JSObject* createUndefinedVariableError(ExecState*, const Identifier&);
 JSObject* createNotAnObjectError(ExecState*, JSValue);
-JSObject* createInvalidParameterError(ExecState*, const char* op, JSValue);
+JSObject* createInvalidFunctionApplyParameterError(ExecState*, JSValue);
+JSObject* createInvalidInParameterError(ExecState*, JSValue);
+JSObject* createInvalidInstanceofParameterError(ExecState*, JSValue);
 JSObject* createNotAConstructorError(ExecState*, JSValue);
 JSObject* createNotAFunctionError(ExecState*, JSValue);
 JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const String&);

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -1471,7 +1471,7 @@
         return defaultHasInstance(exec, value, get(exec, exec->propertyNames().prototype));
     if (info.implementsHasInstance())
         return methodTable(vm)->customHasInstance(this, exec, value);
-    vm.throwException(exec, createInvalidParameterError(exec, "instanceof" , this));
+    vm.throwException(exec, createInvalidInstanceofParameterError(exec, this));
     return false;
 }
 

Added: trunk/Source/_javascript_Core/runtime/RuntimeType.cpp (0 => 181889)


--- trunk/Source/_javascript_Core/runtime/RuntimeType.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/RuntimeType.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) Saam Barati <saambara...@gmail.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+
+#include "config.h"
+#include "RuntimeType.h"
+
+#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
+
+namespace JSC {
+
+RuntimeType runtimeTypeForValue(JSValue value)
+{
+    if (value.isUndefined())
+        return TypeUndefined;
+    if (value.isNull())
+        return TypeNull;
+    if (value.isMachineInt())
+        return TypeMachineInt;
+    if (value.isNumber())
+        return TypeNumber;
+    if (value.isString())
+        return TypeString;
+    if (value.isBoolean())
+        return TypeBoolean;
+    if (value.isObject())
+        return TypeObject;
+    if (value.isFunction())
+        return TypeFunction;
+
+    return TypeNothing;
+}
+
+String runtimeTypeAsString(RuntimeType type)
+{
+    if (type == TypeUndefined)
+        return ASCIILiteral("Undefined");
+    if (type == TypeNull)
+        return ASCIILiteral("Null");
+    if (type == TypeMachineInt)
+        return ASCIILiteral("Integer");
+    if (type == TypeNumber)
+        return ASCIILiteral("Number");
+    if (type == TypeString)
+        return ASCIILiteral("String");
+    if (type == TypeObject)
+        return ASCIILiteral("Object");
+    if (type == TypeBoolean)
+        return ASCIILiteral("Boolean");
+    if (type == TypeFunction)
+        return ASCIILiteral("Function");
+    if (type == TypeNothing)
+        return ASCIILiteral("(Nothing)");
+
+    RELEASE_ASSERT_NOT_REACHED();
+    return emptyString();
+}
+
+} // namespace JSC

Added: trunk/Source/_javascript_Core/runtime/RuntimeType.h (0 => 181889)


--- trunk/Source/_javascript_Core/runtime/RuntimeType.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/RuntimeType.h	2015-03-24 07:30:05 UTC (rev 181889)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) Saam Barati <saambara...@gmail.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RuntimeType_h
+#define RuntimeType_h
+
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+enum RuntimeType : uint8_t {
+    TypeNothing            = 0x0,
+    TypeFunction           = 0x1,
+    TypeUndefined          = 0x2,
+    TypeNull               = 0x4,
+    TypeBoolean            = 0x8,
+    TypeMachineInt         = 0x10,
+    TypeNumber             = 0x20,
+    TypeString             = 0x40,
+    TypeObject             = 0x80
+};
+
+class JSValue;
+RuntimeType runtimeTypeForValue(JSValue);
+String runtimeTypeAsString(RuntimeType);
+
+} // namespace JSC
+
+#endif // RuntimeType_h

Modified: trunk/Source/_javascript_Core/runtime/TypeProfilerLog.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/TypeProfilerLog.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/TypeProfilerLog.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -75,7 +75,7 @@
                 shape = iter->value;
         }
 
-        RuntimeType type = TypeSet::getRuntimeTypeForValue(value);
+        RuntimeType type = runtimeTypeForValue(value);
         TypeLocation* location = entry->location;
         location->m_lastSeenType = type;
         if (location->m_globalTypeSet)

Modified: trunk/Source/_javascript_Core/runtime/TypeSet.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/TypeSet.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/TypeSet.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -42,31 +42,6 @@
 {
 }
 
-RuntimeType TypeSet::getRuntimeTypeForValue(JSValue v)
-{
-    RuntimeType ret;
-    if (v.isFunction())
-        ret = TypeFunction;
-    else if (v.isUndefined())
-        ret = TypeUndefined;
-    else if (v.isNull())
-        ret = TypeNull;
-    else if (v.isBoolean())
-        ret = TypeBoolean;
-    else if (v.isMachineInt())
-        ret = TypeMachineInt;
-    else if (v.isNumber())
-        ret = TypeNumber;
-    else if (v.isString())
-        ret = TypeString;
-    else if (v.isObject())
-        ret = TypeObject;
-    else
-        ret = TypeNothing;
-
-    return ret;
-}
-
 void TypeSet::addTypeInformation(RuntimeType type, PassRefPtr<StructureShape> prpNewShape, Structure* structure) 
 {
     RefPtr<StructureShape> newShape = prpNewShape;

Modified: trunk/Source/_javascript_Core/runtime/TypeSet.h (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/TypeSet.h	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/TypeSet.h	2015-03-24 07:30:05 UTC (rev 181889)
@@ -26,6 +26,7 @@
 #ifndef TypeSet_h
 #define TypeSet_h
 
+#include "RuntimeType.h"
 #include "StructureSet.h"
 #include <wtf/HashSet.h>
 #include <wtf/RefCounted.h>
@@ -46,20 +47,6 @@
 
 namespace JSC {
 
-class JSValue;
-
-enum RuntimeType : uint8_t {
-    TypeNothing            = 0x0,
-    TypeFunction           = 0x1,
-    TypeUndefined          = 0x2,
-    TypeNull               = 0x4,
-    TypeBoolean            = 0x8,
-    TypeMachineInt         = 0x10,
-    TypeNumber             = 0x20,
-    TypeString             = 0x40,
-    TypeObject             = 0x80
-};
-
 class StructureShape : public RefCounted<StructureShape> {
     friend class TypeSet;
 
@@ -98,7 +85,6 @@
     static PassRefPtr<TypeSet> create() { return adoptRef(new TypeSet); }
     TypeSet();
     void addTypeInformation(RuntimeType, PassRefPtr<StructureShape>, Structure*);
-    static RuntimeType getRuntimeTypeForValue(JSValue);
     void invalidateCache();
     String dumpTypes() const;
     String displayName() const;

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (181888 => 181889)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2015-03-24 06:47:40 UTC (rev 181888)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2015-03-24 07:30:05 UTC (rev 181889)
@@ -75,6 +75,7 @@
 #include "PropertyMapHashTable.h"
 #include "RegExpCache.h"
 #include "RegExpObject.h"
+#include "RuntimeType.h"
 #include "SimpleTypedArrayController.h"
 #include "SourceProviderCache.h"
 #include "StackVisitor.h"
@@ -540,7 +541,10 @@
 
 static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
 {
-    exception->clearAppendSourceToMessage();
+    ErrorInstance::SourceAppender appender = exception->sourceAppender();
+    exception->clearSourceAppender();
+    RuntimeType type = exception->runtimeTypeForCause();
+    exception->clearRuntimeTypeForCause();
     
     if (!callFrame->codeBlock()->hasExpressionInfo())
         return;
@@ -569,7 +573,7 @@
     String message = asString(jsMessage)->value(callFrame);
     
     if (expressionStart < expressionStop)
-        message =  makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
+        message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop), type, ErrorInstance::FoundExactSource);
     else {
         // No range information, so give a few characters of context.
         const StringImpl* data = ""
@@ -586,7 +590,7 @@
             stop++;
         while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
             stop--;
-        message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
+        message = appender(message, codeBlock->source()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource);
     }
     
     exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
@@ -662,7 +666,7 @@
         if (!stackFrame.sourceURL.isEmpty())
             exception->putDirect(*this, Identifier(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
     }
-    if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) {
+    if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->hasSourceAppender()) {
         FindFirstCallerFrameWithCodeblockFunctor functor(exec);
         topCallFrame->iterate(functor);
         CallFrame* callFrame = functor.foundCallFrame();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to