Diff
Modified: trunk/LayoutTests/ChangeLog (182494 => 182495)
--- trunk/LayoutTests/ChangeLog 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/ChangeLog 2015-04-07 21:34:05 UTC (rev 182495)
@@ -1,3 +1,42 @@
+2015-04-07 Matthew Mirman <[email protected]>
+
+ Source and stack information should get appended only to native errors
+ and should be added after construction rather than when thrown.
+ This fixes frozen objects being unfrozen when thrown while conforming to
+ ecma script standard and other browser behavior.
+ rdar://problem/19927293
+ https://bugs.webkit.org/show_bug.cgi?id=141871
+
+ Reviewed by Geoffrey Garen.
+
+ Fixes tests to throw new Errors such that they will contain line, column, and stack information
+ as expected, and fixes the column in the error in the expected output.
+
+ * http/tests/w3c/resources/testharness.js: Other browsers don't expect stack information
+ with this test, but we do, and so the AssertionError should include stack information gathered from Error.
+ This could also have been fixed by changing expectations, but its a good idea to check the stack anyway.
+ * js/dom/exception-linenums-in-html-1.html: Throw "new Error()" rather than "{}".
+ * js/dom/exception-linenums-in-html-2.html: ditto.
+ * js/dom/exception-linenums-in-html-3.html: ditto.
+ * js/dom/script-tests/stack-trace.js: ditto.
+ (throwError): ditto.
+ (h): ditto.
+ (inlineableThrow): ditto.
+ (dfgThing.get willThrow): ditto.
+ (dfgThing.willThrowFunc): ditto.
+ * js/dom/stack-trace-expected.txt: fixed error column expectation.
+ * js/exception-properties-expected.txt: ditto.
+ * js/script-tests/exception-linenums.js:
+ (exceptionInFunction): throw "new Error()" rather than "{}".
+ (firstPropIsGetter.get getter): ditto
+ (secondPropIsGetter.get getter): ditto
+ (firstPropIsSetter.set setter): ditto
+ (secondPropIsSetter.set setter): ditto
+ * js/script-tests/exception-properties.js: now checking that column, line, and sourceURL are existant on a "new Error"
+ since we now add these at error construction rather than at error throwing.
+ * platform/mac/http/tests/media/media-source/mediasource-addsourcebuffer-expected.txt: fixed expectation to match.
+ * platform/mac/http/tests/media/media-source/mediasource-sourcebuffer-mode-expected.txt: ditto.
+
2015-04-07 Joseph Pecoraro <[email protected]>
Web Inspector: ES6: Show Symbol properties on Objects
Modified: trunk/LayoutTests/http/tests/w3c/resources/testharness.js (182494 => 182495)
--- trunk/LayoutTests/http/tests/w3c/resources/testharness.js 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/http/tests/w3c/resources/testharness.js 2015-04-07 21:34:05 UTC (rev 182495)
@@ -2064,6 +2064,8 @@
function AssertionError(message)
{
+ var e = new Error();
+ this.stack = e.stack.substring(e.stack.indexOf('\n')+1, e.stack.length);
this.message = message;
}
Modified: trunk/LayoutTests/js/dom/exception-linenums-in-html-1.html (182494 => 182495)
--- trunk/LayoutTests/js/dom/exception-linenums-in-html-1.html 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/dom/exception-linenums-in-html-1.html 2015-04-07 21:34:05 UTC (rev 182495)
@@ -8,7 +8,7 @@
function exceptionInFunction()
{
- throw Exception();
+ throw new Error();
}
var e = undefined;
Modified: trunk/LayoutTests/js/dom/exception-linenums-in-html-2.html (182494 => 182495)
--- trunk/LayoutTests/js/dom/exception-linenums-in-html-2.html 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/dom/exception-linenums-in-html-2.html 2015-04-07 21:34:05 UTC (rev 182495)
@@ -8,7 +8,7 @@
function exceptionInFunction()
{
- throw Exception();
+ throw new Error();
}
var e = undefined;
Modified: trunk/LayoutTests/js/dom/exception-linenums-in-html-3.html (182494 => 182495)
--- trunk/LayoutTests/js/dom/exception-linenums-in-html-3.html 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/dom/exception-linenums-in-html-3.html 2015-04-07 21:34:05 UTC (rev 182495)
@@ -10,7 +10,7 @@
function exceptionInFunction()
{
- throw Exception();
+ throw new Error();
}
var e = undefined;
Modified: trunk/LayoutTests/js/dom/script-tests/stack-trace.js (182494 => 182495)
--- trunk/LayoutTests/js/dom/script-tests/stack-trace.js 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/dom/script-tests/stack-trace.js 2015-04-07 21:34:05 UTC (rev 182495)
@@ -136,7 +136,7 @@
var callCount = 0;
function throwError() {
- throw {};
+ throw new Error();
}
var object = {
@@ -210,7 +210,7 @@
function h() {
if (callCount++ == 1000)
- throw {};
+ throw new Error();
if (callCount > 1000) {
[].map.apply(undefined, throwError);
}
@@ -299,18 +299,18 @@
}
function inlineableThrow() {
- if (dfgCount > 500) throw {};
+ if (dfgCount > 500) throw new Error();
}
var dfgThing = {
get willThrow() {
if (dfgCount > 500)
- throw {};
+ throw new Error();
},
get willThrowEventually() {
inlineableThrow();
},
- willThrowFunc: function () { if (dfgCount > 500) throw {}; },
+ willThrowFunc: function () { if (dfgCount > 500) throw new Error(); },
willThrowEventuallyFunc: function () { inlineableThrow(); }
}
dfgThing.__defineGetter__("hostWillThrow", hostThrower);
Modified: trunk/LayoutTests/js/dom/stack-trace-expected.txt (182494 => 182495)
--- trunk/LayoutTests/js/dom/stack-trace-expected.txt 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/dom/stack-trace-expected.txt 2015-04-07 21:34:05 UTC (rev 182495)
@@ -258,7 +258,7 @@
2 selfRecursive3 at stack-trace.js
--> Stack Trace:
- 0 throwError at stack-trace.js:139:13
+ 0 throwError at stack-trace.js:139:20
1 valueOf at stack-trace.js:146:27
2 getter1 at stack-trace.js:149:11
3 nonInlineable at stack-trace.js:175:17
@@ -270,7 +270,7 @@
9 global code at stack-trace.js:205:16
--> Stack Trace:
- 0 throwError at stack-trace.js:139:13
+ 0 throwError at stack-trace.js:139:20
1 getter2 at stack-trace.js:155:11
2 nonInlineable at stack-trace.js:177:17
3 inlineable at stack-trace.js:183:27
@@ -281,7 +281,7 @@
8 global code at stack-trace.js:205:16
--> Stack Trace:
- 0 throwError at stack-trace.js:139:13
+ 0 throwError at stack-trace.js:139:20
1 getter3 at stack-trace.js:167:16
2 nonInlineable at stack-trace.js:179:17
3 inlineable at stack-trace.js:183:27
@@ -292,7 +292,7 @@
8 global code at stack-trace.js:205:16
--> Stack Trace:
- 0 throwError at stack-trace.js:139:13
+ 0 throwError at stack-trace.js:139:20
1 valueOf at stack-trace.js:163:27
2 getter3 at stack-trace.js:169:16
3 nonInlineable at stack-trace.js:179:17
@@ -304,7 +304,7 @@
9 global code at stack-trace.js:205:16
--> Stack Trace:
- 0 h at stack-trace.js:213:17
+ 0 h at stack-trace.js:213:24
1 map at [native code]
2 mapTest at stack-trace.js:220:10
3 mapTestDriver at stack-trace.js:226:16
@@ -319,19 +319,19 @@
5 global code at stack-trace.js:237:18
--> Stack Trace:
- 0 throwError at stack-trace.js:139:13
+ 0 throwError at stack-trace.js:139:20
1 dfgFunction at stack-trace.js:246:19
2 map at [native code]
3 global code at stack-trace.js:255:18
--> Stack Trace:
- 0 throwError at stack-trace.js:139:13
+ 0 throwError at stack-trace.js:139:20
1 dfgFunction at stack-trace.js:246:19
2 f at stack-trace.js:264:10
3 global code at stack-trace.js:270:6
--> Stack Trace:
- 0 willThrow at stack-trace.js:308:21
+ 0 willThrow at stack-trace.js:308:28
1 dfg1 at stack-trace.js:319:13
2 dfg2 at stack-trace.js:323:9
3 dfg3 at stack-trace.js:327:9
@@ -339,7 +339,7 @@
5 global code at stack-trace.js:366:8
--> Stack Trace:
- 0 willThrowFunc at stack-trace.js:313:62
+ 0 willThrowFunc at stack-trace.js:313:69
1 dfg4 at stack-trace.js:331:27
2 dfg5 at stack-trace.js:335:9
3 dfg6 at stack-trace.js:339:9
@@ -347,7 +347,7 @@
5 global code at stack-trace.js:367:8
--> Stack Trace:
- 0 inlineableThrow at stack-trace.js:302:33
+ 0 inlineableThrow at stack-trace.js:302:40
1 willThrowEventually at stack-trace.js:311:24
2 dfg7 at stack-trace.js:343:13
3 dfg8 at stack-trace.js:347:9
@@ -356,7 +356,7 @@
6 global code at stack-trace.js:368:8
--> Stack Trace:
- 0 inlineableThrow at stack-trace.js:302:33
+ 0 inlineableThrow at stack-trace.js:302:40
1 willThrowEventuallyFunc at stack-trace.js:314:59
2 dfga at stack-trace.js:355:37
3 dfgb at stack-trace.js:359:9
Modified: trunk/LayoutTests/js/exception-properties-expected.txt (182494 => 182495)
--- trunk/LayoutTests/js/exception-properties-expected.txt 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/exception-properties-expected.txt 2015-04-07 21:34:05 UTC (rev 182495)
@@ -3,7 +3,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS enumerableProperties(error) is []
+PASS enumerableProperties(error).sort() is ["column", "line", "sourceURL"]
PASS enumerableProperties(nativeError).sort() is ["column", "line", "sourceURL"]
PASS Object.getPrototypeOf(nativeError).name is "RangeError"
PASS Object.getPrototypeOf(nativeError).message is ""
Modified: trunk/LayoutTests/js/script-tests/exception-linenums.js (182494 => 182495)
--- trunk/LayoutTests/js/script-tests/exception-linenums.js 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/script-tests/exception-linenums.js 2015-04-07 21:34:05 UTC (rev 182495)
@@ -2,7 +2,7 @@
function exceptionInFunction()
{
- throw Exception();
+ throw new Error();
}
var e = undefined;
@@ -71,18 +71,18 @@
shouldBe("e.line", '64');
var firstPropIsGetter = {
- get getter() { throw {} }
+ get getter() { throw new Error() }
};
var secondPropIsGetter = {
prop: 1,
- get getter() { throw {} }
+ get getter() { throw new Error() }
};
var firstPropIsSetter = {
- set setter(a) { throw {} }
+ set setter(a) { throw new Error() }
};
var secondPropIsSetter = {
prop: 1,
- set setter(a) { throw {} }
+ set setter(a) { throw new Error() }
};
try {
Modified: trunk/LayoutTests/js/script-tests/exception-properties.js (182494 => 182495)
--- trunk/LayoutTests/js/script-tests/exception-properties.js 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/js/script-tests/exception-properties.js 2015-04-07 21:34:05 UTC (rev 182495)
@@ -15,7 +15,7 @@
var nativeError = rangeError;
var error = new Error("message");
- shouldBe('enumerableProperties(error)', '[]');
+ shouldBe('enumerableProperties(error).sort()', '["column", "line", "sourceURL"]');
shouldBe('enumerableProperties(nativeError).sort()', '["column", "line", "sourceURL"]');
shouldBe('Object.getPrototypeOf(nativeError).name', '"RangeError"');
Modified: trunk/LayoutTests/platform/mac/http/tests/media/media-source/mediasource-addsourcebuffer-expected.txt (182494 => 182495)
--- trunk/LayoutTests/platform/mac/http/tests/media/media-source/mediasource-addsourcebuffer-expected.txt 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/platform/mac/http/tests/media/media-source/mediasource-addsourcebuffer-expected.txt 2015-04-07 21:34:05 UTC (rev 182495)
@@ -1,14 +1,14 @@
PASS Test addSourceBuffer() with empty type
PASS Test addSourceBuffer() with unsupported type
-FAIL Test addSourceBuffer() with Vorbis and VP8 assert_true: video/webm;codecs="vp8,vorbis" is supported expected true got false(stack: assert@http://127.0.0.1:8000/w3c/resources/testharness.js:2061:73
+FAIL Test addSourceBuffer() with Vorbis and VP8 assert_true: video/webm;codecs="vp8,vorbis" is supported expected true got false(stack: assert@http://127.0.0.1:8000/w3c/resources/testharness.js:2060:37
assert_true@http://127.0.0.1:8000/w3c/resources/testharness.js:663:15
http://127.0.0.1:8000/media/media-source/mediasource-addsourcebuffer.html:32:26
http://127.0.0.1:8000/media/media-source/mediasource-util.js:339:29
onSourceOpen@http://127.0.0.1:8000/media/media-source/mediasource-util.js:149:21
step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
http://127.0.0.1:8000/w3c/resources/testharness.js:1189:33)
-FAIL Test addSourceBuffer() with Vorbis and VP8 in separate SourceBuffers assert_true: video/webm;codecs="vp8" is supported expected true got false(stack: assert@http://127.0.0.1:8000/w3c/resources/testharness.js:2061:73
+FAIL Test addSourceBuffer() with Vorbis and VP8 in separate SourceBuffers assert_true: video/webm;codecs="vp8" is supported expected true got false(stack: assert@http://127.0.0.1:8000/w3c/resources/testharness.js:2060:37
assert_true@http://127.0.0.1:8000/w3c/resources/testharness.js:663:15
http://127.0.0.1:8000/media/media-source/mediasource-addsourcebuffer.html:46:26
http://127.0.0.1:8000/media/media-source/mediasource-util.js:339:29
Modified: trunk/LayoutTests/platform/mac/http/tests/media/media-source/mediasource-sourcebuffer-mode-expected.txt (182494 => 182495)
--- trunk/LayoutTests/platform/mac/http/tests/media/media-source/mediasource-sourcebuffer-mode-expected.txt 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/LayoutTests/platform/mac/http/tests/media/media-source/mediasource-sourcebuffer-mode-expected.txt 2015-04-07 21:34:05 UTC (rev 182495)
@@ -4,7 +4,7 @@
PASS Test setting a removed SourceBuffer's mode
PASS Test setting SourceBuffer.mode while still updating
PASS Test setting SourceBuffer.mode triggers parent MediaSource 'ended' to 'open' transition.
-FAIL Test setting SourceBuffer.mode and SourceBuffer.timestampOffset while parsing media segment. assert_throws: Setting valid sourceBuffer.mode while still parsing media segment threw InvalidStateError. function "function () { sourceBuffer.mode = 'segments'; }" did not throw(stack: assert@http://127.0.0.1:8000/w3c/resources/testharness.js:2061:73
+FAIL Test setting SourceBuffer.mode and SourceBuffer.timestampOffset while parsing media segment. assert_throws: Setting valid sourceBuffer.mode while still parsing media segment threw InvalidStateError. function "function () { sourceBuffer.mode = 'segments'; }" did not throw(stack: assert@http://127.0.0.1:8000/w3c/resources/testharness.js:2060:37
assert_throws@http://127.0.0.1:8000/w3c/resources/testharness.js:947:19
http://127.0.0.1:8000/media/media-source/mediasource-sourcebuffer-mode.html:114:32
handleWaitCallback_@http://127.0.0.1:8000/media/media-source/mediasource-util.js:97:17
Modified: trunk/Source/_javascript_Core/ChangeLog (182494 => 182495)
--- trunk/Source/_javascript_Core/ChangeLog 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-04-07 21:34:05 UTC (rev 182495)
@@ -1,3 +1,98 @@
+2015-04-07 Matthew Mirman <[email protected]>
+
+ Source and stack information should get appended only to native errors
+ and should be added directly after construction rather than when thrown.
+ This fixes frozen objects being unfrozen when thrown while conforming to
+ ecma script standard and other browser behavior.
+ rdar://problem/19927293
+ https://bugs.webkit.org/show_bug.cgi?id=141871
+
+ Reviewed by Geoffrey Garen.
+
+ Appending stack, source, line, and column information to an object whenever that object is thrown
+ is incorrect because it violates the ecma script standard for the behavior of throw. Suppose for example
+ that the object being thrown already has one of these properties or is frozen. Adding the properties
+ would then violate the frozen contract or overwrite those properties. Other browsers do not do this,
+ and doing this causes unnecessary performance hits in code with heavy use of the throw construct as
+ a control flow construct rather than just an error reporting mechanism.
+
+ Because WebCore adds "native" errors which do not inherit from any JSC native error,
+ appending the error properties as a seperate call after construction of the error is required
+ to avoid having to manually truncate the stack and gather local source information due to
+ the stack being extended by a nested call to construct one of the native jsc error.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * interpreter/Interpreter.h:
+ * parser/ParserError.h:
+ (JSC::ParserError::toErrorObject):
+ * runtime/CommonIdentifiers.h:
+ * runtime/Error.cpp:
+ (JSC::createError):
+ (JSC::createEvalError):
+ (JSC::createRangeError):
+ (JSC::createReferenceError):
+ (JSC::createSyntaxError):
+ (JSC::createTypeError):
+ (JSC::createNotEnoughArgumentsError):
+ (JSC::createURIError):
+ (JSC::createOutOfMemoryError):
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame):
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::index):
+ (JSC::addErrorInfoAndGetBytecodeOffset): Added.
+ (JSC::addErrorInfo): Added special case for appending complete error info
+ to a newly constructed error object.
+ * runtime/Error.h:
+ * runtime/ErrorConstructor.cpp:
+ (JSC::Interpreter::constructWithErrorConstructor):
+ (JSC::Interpreter::callErrorConstructor):
+ * runtime/ErrorInstance.cpp:
+ (JSC::appendSourceToError): Moved from VM.cpp
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame):
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::index):
+ (JSC::addErrorInfoAndGetBytecodeOffset):
+ (JSC::ErrorInstance::finishCreation):
+ * runtime/ErrorInstance.h:
+ (JSC::ErrorInstance::create):
+ * runtime/ErrorPrototype.cpp:
+ (JSC::ErrorPrototype::finishCreation):
+ * runtime/ExceptionFuzz.cpp:
+ (JSC::doExceptionFuzzing):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createError):
+ (JSC::createInvalidFunctionApplyParameterError):
+ (JSC::createInvalidInParameterError):
+ (JSC::createInvalidInstanceofParameterError):
+ (JSC::createNotAConstructorError):
+ (JSC::createNotAFunctionError):
+ (JSC::createNotAnObjectError):
+ (JSC::throwOutOfMemoryError):
+ (JSC::createStackOverflowError): Deleted.
+ (JSC::createOutOfMemoryError): Deleted.
+ * runtime/ExceptionHelpers.h:
+ * runtime/JSArrayBufferConstructor.cpp:
+ (JSC::constructArrayBuffer):
+ * runtime/JSArrayBufferPrototype.cpp:
+ (JSC::arrayBufferProtoFuncSlice):
+ * runtime/JSGenericTypedArrayViewInlines.h:
+ (JSC::JSGenericTypedArrayView<Adaptor>::create):
+ (JSC::JSGenericTypedArrayView<Adaptor>::createUninitialized):
+ * runtime/NativeErrorConstructor.cpp:
+ (JSC::Interpreter::constructWithNativeErrorConstructor):
+ (JSC::Interpreter::callNativeErrorConstructor):
+ * runtime/VM.cpp:
+ (JSC::VM::throwException):
+ (JSC::appendSourceToError): Moved to Error.cpp
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor): Deleted.
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()): Deleted.
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame): Deleted.
+ (JSC::FindFirstCallerFrameWithCodeblockFunctor::index): Deleted.
+ * tests/stress/freeze_leek.js: Added.
+
2015-04-07 Joseph Pecoraro <[email protected]>
Web Inspector: ES6: Show Symbol properties on Objects
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -763,7 +763,7 @@
PropertySlot slot(globalObject);
if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
if (entry)
- return callFrame->vm().throwException(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
+ return callFrame->vm().throwException(callFrame, createUndefinedVariableError(callFrame, JSONPPath[i].m_pathEntryName));
goto failedJSONP;
}
baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (182494 => 182495)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.h 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h 2015-04-07 21:34:05 UTC (rev 182495)
@@ -267,6 +267,8 @@
JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
+ void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
+
private:
enum ExecutionFlag { Normal, InitializeAndReturn };
@@ -274,8 +276,8 @@
JSValue execute(CallFrameClosure&);
- void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
+
void dumpRegisters(CallFrame*);
bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
Modified: trunk/Source/_javascript_Core/parser/ParserError.h (182494 => 182495)
--- trunk/Source/_javascript_Core/parser/ParserError.h 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/parser/ParserError.h 2015-04-07 21:34:05 UTC (rev 182495)
@@ -89,22 +89,23 @@
JSGlobalObject* globalObject, const SourceCode& source,
int overrideLineNumber = -1)
{
+ ExecState* exec = globalObject->globalExec();
switch (m_type) {
case ErrorNone:
return nullptr;
case SyntaxError:
return addErrorInfo(
- globalObject->globalExec(),
- createSyntaxError(globalObject, m_message),
+ exec,
+ createSyntaxError(exec, m_message),
overrideLineNumber == -1 ? m_line : overrideLineNumber, source);
case EvalError:
- return createSyntaxError(globalObject, m_message);
+ return createSyntaxError(exec, m_message);
case StackOverflow: {
ErrorHandlingScope errorScope(globalObject->vm());
- return createStackOverflowError(globalObject);
+ return createStackOverflowError(exec);
}
case OutOfMemory:
- return createOutOfMemoryError(globalObject);
+ return createOutOfMemoryError(exec);
}
CRASH();
return nullptr;
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2015-04-07 21:34:05 UTC (rev 182495)
@@ -82,6 +82,7 @@
macro(clear) \
macro(close) \
macro(closed) \
+ macro(column) \
macro(compilationKind) \
macro(compilations) \
macro(compile) \
@@ -127,6 +128,7 @@
macro(keys) \
macro(lastIndex) \
macro(length) \
+ macro(line) \
macro(message) \
macro(multiline) \
macro(name) \
@@ -153,6 +155,7 @@
macro(size) \
macro(slice) \
macro(source) \
+ macro(sourceURL) \
macro(sourceCode) \
macro(stack) \
macro(subarray) \
Modified: trunk/Source/_javascript_Core/runtime/Error.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/Error.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/Error.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -44,91 +44,150 @@
static const char* linePropertyName = "line";
static const char* sourceURLPropertyName = "sourceURL";
-JSObject* createError(JSGlobalObject* globalObject, const String& message)
+JSObject* createError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->vm(), globalObject->errorStructure(), message);
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(), message, appender, TypeNothing, true);
}
-JSObject* createEvalError(JSGlobalObject* globalObject, const String& message)
+JSObject* createEvalError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->vm(), globalObject->evalErrorConstructor()->errorStructure(), message);
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return ErrorInstance::create(exec, globalObject->vm(), globalObject->evalErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
}
-JSObject* createRangeError(JSGlobalObject* globalObject, const String& message)
+JSObject* createRangeError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->vm(), globalObject->rangeErrorConstructor()->errorStructure(), message);
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return ErrorInstance::create(exec, globalObject->vm(), globalObject->rangeErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
}
-JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message)
+JSObject* createReferenceError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->vm(), globalObject->referenceErrorConstructor()->errorStructure(), message);
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return ErrorInstance::create(exec, globalObject->vm(), globalObject->referenceErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
}
-JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message)
+JSObject* createSyntaxError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->vm(), globalObject->syntaxErrorConstructor()->errorStructure(), message);
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return ErrorInstance::create(exec, globalObject->vm(), globalObject->syntaxErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
}
-JSObject* createTypeError(JSGlobalObject* globalObject, const String& message)
+JSObject* createTypeError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender, RuntimeType type)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->vm(), globalObject->typeErrorConstructor()->errorStructure(), message);
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return ErrorInstance::create(exec, globalObject->vm(), globalObject->typeErrorConstructor()->errorStructure(), message, appender, type, true);
}
-JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject)
+JSObject* createNotEnoughArgumentsError(ExecState* exec, ErrorInstance::SourceAppender appender)
{
- return createTypeError(globalObject, ASCIILiteral("Not enough arguments"));
+ return createTypeError(exec, ASCIILiteral("Not enough arguments"), appender, TypeNothing);
}
-JSObject* createURIError(JSGlobalObject* globalObject, const String& message)
+JSObject* createURIError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->vm(), globalObject->URIErrorConstructor()->errorStructure(), message);
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return ErrorInstance::create(exec, globalObject->vm(), globalObject->URIErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
}
-JSObject* createError(ExecState* exec, const String& message)
+JSObject* createOutOfMemoryError(ExecState* exec, ErrorInstance::SourceAppender appender)
{
- return createError(exec->lexicalGlobalObject(), message);
+ return createError(exec, ASCIILiteral("Out of memory"), appender);
}
-JSObject* createEvalError(ExecState* exec, const String& message)
-{
- return createEvalError(exec->lexicalGlobalObject(), message);
-}
-JSObject* createRangeError(ExecState* exec, const String& message)
-{
- return createRangeError(exec->lexicalGlobalObject(), message);
-}
+class FindFirstCallerFrameWithCodeblockFunctor {
+public:
+ FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame)
+ : m_startCallFrame(startCallFrame)
+ , m_foundCallFrame(nullptr)
+ , m_foundStartCallFrame(false)
+ , m_index(0)
+ { }
-JSObject* createReferenceError(ExecState* exec, const String& message)
-{
- return createReferenceError(exec->lexicalGlobalObject(), message);
-}
+ StackVisitor::Status operator()(StackVisitor& visitor)
+ {
+ if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame))
+ m_foundStartCallFrame = true;
-JSObject* createSyntaxError(ExecState* exec, const String& message)
-{
- return createSyntaxError(exec->lexicalGlobalObject(), message);
-}
+ if (m_foundStartCallFrame) {
+ if (visitor->callFrame()->codeBlock()) {
+ m_foundCallFrame = visitor->callFrame();
+ return StackVisitor::Done;
+ }
+ m_index++;
+ }
-JSObject* createTypeError(ExecState* exec, const String& message)
+ return StackVisitor::Continue;
+ }
+
+ CallFrame* foundCallFrame() const { return m_foundCallFrame; }
+ unsigned index() const { return m_index; }
+
+private:
+ CallFrame* m_startCallFrame;
+ CallFrame* m_foundCallFrame;
+ bool m_foundStartCallFrame;
+ unsigned m_index;
+};
+
+bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bool useCurrentFrame, CallFrame*& callFrame, unsigned &bytecodeOffset)
{
- return createTypeError(exec->lexicalGlobalObject(), message);
-}
+ Vector<StackFrame> stackTrace = Vector<StackFrame>();
-JSObject* createNotEnoughArgumentsError(ExecState* exec)
-{
- return createNotEnoughArgumentsError(exec->lexicalGlobalObject());
+ if (exec && stackTrace.isEmpty())
+ vm.interpreter->getStackTrace(stackTrace);
+
+ if (!stackTrace.isEmpty()) {
+
+ ASSERT(exec == vm.topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
+
+ StackFrame* stackFrame;
+ for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
+ stackFrame = &stackTrace.at(i);
+ if (stackFrame->bytecodeOffset)
+ break;
+ }
+
+ if (bytecodeOffset) {
+ FindFirstCallerFrameWithCodeblockFunctor functor(exec);
+ vm.topCallFrame->iterate(functor);
+ callFrame = functor.foundCallFrame();
+ unsigned stackIndex = functor.index();
+ bytecodeOffset = stackTrace.at(stackIndex).bytecodeOffset;
+ }
+
+ unsigned line;
+ unsigned column;
+ stackFrame->computeLineAndColumn(line, column);
+ obj->putDirect(vm, vm.propertyNames->line, jsNumber(line), ReadOnly | DontDelete);
+ obj->putDirect(vm, vm.propertyNames->column, jsNumber(column), ReadOnly | DontDelete);
+
+ if (!stackFrame->sourceURL.isEmpty())
+ obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(&vm, stackFrame->sourceURL), ReadOnly | DontDelete);
+
+ if (!useCurrentFrame)
+ stackTrace.remove(0);
+ obj->putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum);
+
+ return true;
+ }
+ return false;
}
-JSObject* createURIError(ExecState* exec, const String& message)
+void addErrorInfo(ExecState* exec, JSObject* obj, bool useCurrentFrame)
{
- return createURIError(exec->lexicalGlobalObject(), message);
+ CallFrame* callFrame = nullptr;
+ unsigned bytecodeOffset = 0;
+ addErrorInfoAndGetBytecodeOffset(exec, exec->vm(), obj, useCurrentFrame, callFrame, bytecodeOffset);
}
JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const SourceCode& source)
@@ -160,6 +219,53 @@
return exec->vm().throwException(exec, createSyntaxError(exec, ASCIILiteral("Syntax error")));
}
+
+JSObject* createError(ExecState* exec, const String& message)
+{
+ return createError(exec, message, nullptr);
+}
+
+JSObject* createEvalError(ExecState* exec, const String& message)
+{
+ return createEvalError(exec, message, nullptr);
+}
+
+JSObject* createRangeError(ExecState* exec, const String& message)
+{
+ return createRangeError(exec, message, nullptr);
+}
+
+JSObject* createReferenceError(ExecState* exec, const String& message)
+{
+ return createReferenceError(exec, message, nullptr);
+}
+
+JSObject* createSyntaxError(ExecState* exec, const String& message)
+{
+ return createSyntaxError(exec, message, nullptr);
+}
+
+JSObject* createTypeError(ExecState* exec, const String& message)
+{
+ return createTypeError(exec, message, nullptr, TypeNothing);
+}
+
+JSObject* createNotEnoughArgumentsError(ExecState* exec)
+{
+ return createNotEnoughArgumentsError(exec, nullptr);
+}
+
+JSObject* createURIError(ExecState* exec, const String& message)
+{
+ return createURIError(exec, message, nullptr);
+}
+
+JSObject* createOutOfMemoryError(ExecState* exec)
+{
+ return createOutOfMemoryError(exec, nullptr);
+}
+
+
const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) };
void StrictModeTypeErrorFunction::destroy(JSCell* cell)
Modified: trunk/Source/_javascript_Core/runtime/Error.h (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/Error.h 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/Error.h 2015-04-07 21:34:05 UTC (rev 182495)
@@ -23,11 +23,13 @@
#ifndef Error_h
#define Error_h
+#include "ErrorInstance.h"
#include "InternalFunction.h"
#include "Interpreter.h"
#include "JSObject.h"
#include <stdint.h>
+
namespace JSC {
class ExecState;
@@ -37,28 +39,33 @@
class SourceCode;
class Structure;
-// Methods to create a range of internal errors.
-JSObject* createError(JSGlobalObject*, const String&);
-JSObject* createEvalError(JSGlobalObject*, const String&);
-JSObject* createRangeError(JSGlobalObject*, const String&);
-JSObject* createReferenceError(JSGlobalObject*, const String&);
-JSObject* createSyntaxError(JSGlobalObject*, const String&);
-JSObject* createTypeError(JSGlobalObject*, const String&);
-JSObject* createNotEnoughArgumentsError(JSGlobalObject*);
-JSObject* createURIError(JSGlobalObject*, const String&);
// ExecState wrappers.
+JSObject* createError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createEvalError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createRangeError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createReferenceError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createSyntaxError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createTypeError(ExecState*, const String&, ErrorInstance::SourceAppender, RuntimeType);
+JSObject* createNotEnoughArgumentsError(ExecState*, ErrorInstance::SourceAppender);
+JSObject* createURIError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createOutOfMemoryError(ExecState*, ErrorInstance::SourceAppender);
+
+
JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const String&);
-JSObject* createEvalError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createEvalError(ExecState*, const String&);
JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const String&);
JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const String&);
JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const String&);
JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const String&);
JS_EXPORT_PRIVATE JSObject* createNotEnoughArgumentsError(ExecState*);
-JSObject* createURIError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createURIError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createOutOfMemoryError(ExecState*);
-// Methods to add
+
+bool addErrorInfoAndGetBytecodeOffset(ExecState*, VM&, JSObject*, bool, CallFrame*&, unsigned&);
+
bool hasErrorInfo(ExecState*, JSObject* error);
-// ExecState wrappers.
+JS_EXPORT_PRIVATE void addErrorInfo(ExecState*, JSObject*, bool);
JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
// Methods to throw Errors.
Modified: trunk/Source/_javascript_Core/runtime/ErrorConstructor.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/ErrorConstructor.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/ErrorConstructor.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -52,10 +52,7 @@
{
JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
- Vector<StackFrame> stackTrace;
- exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
- stackTrace.remove(0);
- return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+ return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
}
ConstructType ErrorConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -68,10 +65,7 @@
{
JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
- Vector<StackFrame> stackTrace;
- exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
- stackTrace.remove(0);
- return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+ return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
}
CallType ErrorConstructor::getCallData(JSCell*, CallData& callData)
Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -23,6 +23,8 @@
#include "JSScope.h"
#include "JSCInlines.h"
+#include "JSGlobalObjectFunctions.h"
+#include <wtf/Vector.h>
namespace JSC {
@@ -35,15 +37,156 @@
{
}
-void ErrorInstance::finishCreation(VM& vm, const String& message, Vector<StackFrame> stackTrace)
+static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
{
+ ErrorInstance::SourceAppender appender = exception->sourceAppender();
+ exception->clearSourceAppender();
+ RuntimeType type = exception->runtimeTypeForCause();
+ exception->clearRuntimeTypeForCause();
+
+ if (!callFrame->codeBlock()->hasExpressionInfo())
+ return;
+
+ int startOffset = 0;
+ int endOffset = 0;
+ int divotPoint = 0;
+ unsigned line = 0;
+ unsigned column = 0;
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
+
+ int expressionStart = divotPoint - startOffset;
+ int expressionStop = divotPoint + endOffset;
+
+ const String& sourceString = codeBlock->source()->source();
+ if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
+ return;
+
+ VM* vm = &callFrame->vm();
+ JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
+ if (!jsMessage || !jsMessage.isString())
+ return;
+
+ String message = asString(jsMessage)->value(callFrame);
+ if (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 = ""
+ int dataLength = sourceString.length();
+ int start = expressionStart;
+ int stop = expressionStart;
+ // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
+ // Then strip whitespace.
+ while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
+ start--;
+ while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
+ start++;
+ while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
+ stop++;
+ while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
+ stop--;
+ message = appender(message, codeBlock->source()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource);
+ }
+ exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
+
+}
+
+class FindFirstCallerFrameWithCodeblockFunctor {
+public:
+ FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame)
+ : m_startCallFrame(startCallFrame)
+ , m_foundCallFrame(nullptr)
+ , m_foundStartCallFrame(false)
+ , m_index(0)
+ { }
+
+ StackVisitor::Status operator()(StackVisitor& visitor)
+ {
+ if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame))
+ m_foundStartCallFrame = true;
+
+ if (m_foundStartCallFrame) {
+ if (visitor->callFrame()->codeBlock()) {
+ m_foundCallFrame = visitor->callFrame();
+ return StackVisitor::Done;
+ }
+ m_index++;
+ }
+
+ return StackVisitor::Continue;
+ }
+
+ CallFrame* foundCallFrame() const { return m_foundCallFrame; }
+ unsigned index() const { return m_index; }
+
+private:
+ CallFrame* m_startCallFrame;
+ CallFrame* m_foundCallFrame;
+ bool m_foundStartCallFrame;
+ unsigned m_index;
+};
+
+static bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bool useCurrentFrame, CallFrame*& callFrame, unsigned &bytecodeOffset)
+{
+ Vector<StackFrame> stackTrace = Vector<StackFrame>();
+
+ if (exec && stackTrace.isEmpty())
+ vm.interpreter->getStackTrace(stackTrace);
+
+ if (!stackTrace.isEmpty()) {
+
+ ASSERT(exec == vm.topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
+
+ StackFrame* stackFrame;
+ for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
+ stackFrame = &stackTrace.at(i);
+ if (stackFrame->bytecodeOffset)
+ break;
+ }
+
+ if (bytecodeOffset) {
+ FindFirstCallerFrameWithCodeblockFunctor functor(exec);
+ vm.topCallFrame->iterate(functor);
+ callFrame = functor.foundCallFrame();
+ unsigned stackIndex = functor.index();
+ bytecodeOffset = stackTrace.at(stackIndex).bytecodeOffset;
+ }
+
+ unsigned line;
+ unsigned column;
+ stackFrame->computeLineAndColumn(line, column);
+ obj->putDirect(vm, vm.propertyNames->line, jsNumber(line), ReadOnly | DontDelete);
+ obj->putDirect(vm, vm.propertyNames->column, jsNumber(column), ReadOnly | DontDelete);
+
+ if (!stackFrame->sourceURL.isEmpty())
+ obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(&vm, stackFrame->sourceURL), ReadOnly | DontDelete);
+
+ if (!useCurrentFrame)
+ stackTrace.remove(0);
+ obj->putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum);
+
+ return true;
+ }
+ return false;
+}
+
+void ErrorInstance::finishCreation(ExecState* exec, VM& vm, const String& message, bool useCurrentFrame)
+{
Base::finishCreation(vm);
ASSERT(inherits(info()));
if (!message.isNull())
putDirect(vm, vm.propertyNames->message, jsString(&vm, message), DontEnum);
-
- if (!stackTrace.isEmpty())
- putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum);
+
+ unsigned bytecodeOffset = hasSourceAppender();
+ CallFrame* callFrame = nullptr;
+ bool hasTrace = addErrorInfoAndGetBytecodeOffset(exec, vm, this, useCurrentFrame, callFrame, bytecodeOffset);
+
+ if (hasTrace && callFrame && hasSourceAppender()) {
+ if (callFrame && callFrame->codeBlock())
+ appendSourceToError(callFrame, this, bytecodeOffset);
+ }
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.h (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/ErrorInstance.h 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.h 2015-04-07 21:34:05 UTC (rev 182495)
@@ -24,6 +24,7 @@
#include "Interpreter.h"
#include "RuntimeType.h"
#include "SourceProvider.h"
+#include <wtf/Vector.h>
namespace JSC {
@@ -31,6 +32,9 @@
public:
typedef JSNonFinalObject Base;
+ enum SourceTextWhereErrorOccurred { FoundExactSource, FoundApproximateSource };
+ typedef String (*SourceAppender) (const String& originalMessage, const String& sourceText, RuntimeType, SourceTextWhereErrorOccurred);
+
DECLARE_INFO;
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -38,20 +42,21 @@
return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
}
- static ErrorInstance* create(VM& vm, Structure* structure, const String& message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
+ static ErrorInstance* create(ExecState* exec, VM& vm, Structure* structure, const String& message, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, bool useCurrentFrame = true)
{
ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
- instance->finishCreation(vm, message, stackTrace);
+ instance->m_sourceAppender = appender;
+ instance->m_runtimeTypeForCause = type;
+ instance->finishCreation(exec, vm, message, useCurrentFrame);
return instance;
}
- static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
+ static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, bool useCurrentFrame = true)
{
- return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), stackTrace);
+ return create(exec, exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), appender, type, useCurrentFrame);
}
- enum SourceTextWhereErrorOccurred { FoundExactSource, FoundApproximateSource };
- typedef String (*SourceAppender) (const String& originalMessage, const String& sourceText, RuntimeType, SourceTextWhereErrorOccurred);
+ static void addErrorInfo(ExecState*, VM&, JSObject*, bool = true);
bool hasSourceAppender() const { return !!m_sourceAppender; }
SourceAppender sourceAppender() const { return m_sourceAppender; }
@@ -64,7 +69,7 @@
protected:
explicit ErrorInstance(VM&, Structure*);
- void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());
+ void finishCreation(ExecState*, VM&, const String&, bool useCurrentFrame = true);
SourceAppender m_sourceAppender { nullptr };
RuntimeType m_runtimeTypeForCause { TypeNothing };
Modified: trunk/Source/_javascript_Core/runtime/ErrorPrototype.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/ErrorPrototype.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/ErrorPrototype.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -54,9 +54,9 @@
{
}
-void ErrorPrototype::finishCreation(VM& vm, JSGlobalObject*)
+void ErrorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
{
- Base::finishCreation(vm, "");
+ Base::finishCreation(globalObject->globalExec(), vm, "");
ASSERT(inherits(info()));
putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("Error"))), DontEnum);
}
Modified: trunk/Source/_javascript_Core/runtime/ExceptionFuzz.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/ExceptionFuzz.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/ExceptionFuzz.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -48,7 +48,7 @@
if (fireTarget == s_numberOfExceptionFuzzChecks) {
printf("JSC EXCEPTION FUZZ: Throwing fuzz exception with call frame %p, seen in %s and return address %p.\n", exec, where, returnPC);
exec->vm().throwException(
- exec, createError(exec->lexicalGlobalObject(), ASCIILiteral("Exception Fuzz")));
+ exec, createError(exec, ASCIILiteral("Exception Fuzz")));
}
}
Modified: trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -75,11 +75,6 @@
return createRangeError(exec, ASCIILiteral("Maximum call stack size exceeded."));
}
-JSObject* createStackOverflowError(JSGlobalObject* globalObject)
-{
- return createRangeError(globalObject, ASCIILiteral("Maximum call stack size exceeded."));
-}
-
JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
{
if (exec->propertyNames().isPrivateName(ident)) {
@@ -239,48 +234,44 @@
return makeString(rightHandSide, " is not a function. (evaluating '", sourceText, "')");
}
-JSObject* createError(ExecState* exec, ErrorFactory errorFactory, JSValue value, const String& message, ErrorInstance::SourceAppender appender)
+JSObject* createError(ExecState* exec, JSValue value, const String& message, ErrorInstance::SourceAppender appender)
{
String errorMessage = makeString(errorDescriptionForValue(exec, value)->value(exec), ' ', message);
- JSObject* exception = errorFactory(exec, errorMessage);
+ JSObject* exception = createTypeError(exec, errorMessage, appender, runtimeTypeForValue(value));
ASSERT(exception->isErrorInstance());
- static_cast<ErrorInstance*>(exception)->setSourceAppender(appender);
- static_cast<ErrorInstance*>(exception)->setRuntimeTypeForCause(runtimeTypeForValue(value));
return exception;
}
JSObject* createInvalidFunctionApplyParameterError(ExecState* exec, JSValue value)
{
- JSObject* exception = createTypeError(exec, makeString("second argument to Function.prototype.apply must be an Array-like object"));
+ JSObject* exception = createTypeError(exec, makeString("second argument to Function.prototype.apply must be an Array-like object"), defaultSourceAppender, runtimeTypeForValue(value));
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);
+ return createError(exec, value, makeString("is not an Object."), invalidParameterInSourceAppender);
}
JSObject* createInvalidInstanceofParameterError(ExecState* exec, JSValue value)
{
- return createError(exec, createTypeError, value, makeString("is not a function."), invalidParameterInstanceofSourceAppender);
+ return createError(exec, value, makeString("is not a function."), invalidParameterInstanceofSourceAppender);
}
JSObject* createNotAConstructorError(ExecState* exec, JSValue value)
{
- return createError(exec, createTypeError, value, ASCIILiteral("is not a constructor"), defaultSourceAppender);
+ return createError(exec, value, ASCIILiteral("is not a constructor"), defaultSourceAppender);
}
JSObject* createNotAFunctionError(ExecState* exec, JSValue value)
{
- return createError(exec, createTypeError, value, ASCIILiteral("is not a function"), notAFunctionSourceAppender);
+ return createError(exec, value, ASCIILiteral("is not a function"), notAFunctionSourceAppender);
}
JSObject* createNotAnObjectError(ExecState* exec, JSValue value)
{
- return createError(exec, createTypeError, value, ASCIILiteral("is not an object"), defaultSourceAppender);
+ return createError(exec, value, ASCIILiteral("is not an object"), defaultSourceAppender);
}
JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const String& propertyName)
@@ -288,14 +279,9 @@
return createReferenceError(exec, makeString("Strict mode forbids implicit creation of global property '", propertyName, '\''));
}
-JSObject* createOutOfMemoryError(JSGlobalObject* globalObject)
-{
- return createError(globalObject, ASCIILiteral("Out of memory"));
-}
-
JSObject* throwOutOfMemoryError(ExecState* exec)
{
- return exec->vm().throwException(exec, createOutOfMemoryError(exec->lexicalGlobalObject()));
+ return exec->vm().throwException(exec, createOutOfMemoryError(exec));
}
JSObject* throwStackOverflowError(ExecState* exec)
Modified: trunk/Source/_javascript_Core/runtime/ExceptionHelpers.h (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/ExceptionHelpers.h 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/ExceptionHelpers.h 2015-04-07 21:34:05 UTC (rev 182495)
@@ -34,15 +34,13 @@
namespace JSC {
-typedef JSObject* (*ErrorFactory)(ExecState*, const String&);
+typedef JSObject* (*ErrorFactory)(ExecState*, const String&, ErrorInstance::SourceAppender);
JSObject* createTerminatedExecutionException(VM*);
bool isTerminatedExecutionException(JSObject*);
JS_EXPORT_PRIVATE bool isTerminatedExecutionException(JSValue);
-JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorFactory, JSValue, const String&, ErrorInstance::SourceAppender);
+JS_EXPORT_PRIVATE JSObject* createError(ExecState*, 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* createInvalidFunctionApplyParameterError(ExecState*, JSValue);
Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -92,7 +92,7 @@
RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, 1);
if (!buffer)
- return throwVMError(exec, createOutOfMemoryError(constructor->globalObject()));
+ return throwVMError(exec, createOutOfMemoryError(exec));
JSArrayBuffer* result = JSArrayBuffer::create(
exec->vm(), constructor->globalObject()->arrayBufferStructure(), buffer);
Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferPrototype.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/JSArrayBufferPrototype.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferPrototype.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -60,7 +60,7 @@
RefPtr<ArrayBuffer> newBuffer = thisObject->impl()->slice(begin, end);
if (!newBuffer)
- return throwVMError(exec, createOutOfMemoryError(callee->globalObject()));
+ return throwVMError(exec, createOutOfMemoryError(exec));
Structure* structure = callee->globalObject()->arrayBufferStructure();
Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h 2015-04-07 21:34:05 UTC (rev 182495)
@@ -49,7 +49,7 @@
{
ConstructionContext context(exec->vm(), structure, length, sizeof(typename Adaptor::Type));
if (!context) {
- exec->vm().throwException(exec, createOutOfMemoryError(structure->globalObject()));
+ exec->vm().throwException(exec, createOutOfMemoryError(exec));
return 0;
}
JSGenericTypedArrayView* result =
@@ -67,7 +67,7 @@
exec->vm(), structure, length, sizeof(typename Adaptor::Type),
ConstructionContext::DontInitialize);
if (!context) {
- exec->vm().throwException(exec, createOutOfMemoryError(structure->globalObject()));
+ exec->vm().throwException(exec, createOutOfMemoryError(exec));
return 0;
}
JSGenericTypedArrayView* result =
Modified: trunk/Source/_javascript_Core/runtime/NativeErrorConstructor.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/NativeErrorConstructor.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/NativeErrorConstructor.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -65,10 +65,7 @@
JSValue message = exec->argument(0);
Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure();
ASSERT(errorStructure);
- Vector<StackFrame> stackTrace;
- exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
- stackTrace.remove(0);
- return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+ return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
}
ConstructType NativeErrorConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -81,10 +78,7 @@
{
JSValue message = exec->argument(0);
Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure();
- Vector<StackFrame> stackTrace;
- exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
- stackTrace.remove(0);
- return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+ return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
}
CallType NativeErrorConstructor::getCallData(JSCell*, CallData& callData)
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (182494 => 182495)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -540,98 +540,6 @@
heap.collectAllGarbage();
}
-static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
-{
- ErrorInstance::SourceAppender appender = exception->sourceAppender();
- exception->clearSourceAppender();
- RuntimeType type = exception->runtimeTypeForCause();
- exception->clearRuntimeTypeForCause();
-
- if (!callFrame->codeBlock()->hasExpressionInfo())
- return;
-
- int startOffset = 0;
- int endOffset = 0;
- int divotPoint = 0;
- unsigned line = 0;
- unsigned column = 0;
-
- CodeBlock* codeBlock = callFrame->codeBlock();
- codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
-
- int expressionStart = divotPoint - startOffset;
- int expressionStop = divotPoint + endOffset;
-
- const String& sourceString = codeBlock->source()->source();
- if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
- return;
-
- VM* vm = &callFrame->vm();
- JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
- if (!jsMessage || !jsMessage.isString())
- return;
-
- String message = asString(jsMessage)->value(callFrame);
-
- if (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 = ""
- int dataLength = sourceString.length();
- int start = expressionStart;
- int stop = expressionStart;
- // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
- // Then strip whitespace.
- while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
- start--;
- while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
- start++;
- while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
- stop++;
- while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
- stop--;
- message = appender(message, codeBlock->source()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource);
- }
-
- exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
-}
-
-class FindFirstCallerFrameWithCodeblockFunctor {
-public:
- FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame)
- : m_startCallFrame(startCallFrame)
- , m_foundCallFrame(nullptr)
- , m_foundStartCallFrame(false)
- , m_index(0)
- { }
-
- StackVisitor::Status operator()(StackVisitor& visitor)
- {
- if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame))
- m_foundStartCallFrame = true;
-
- if (m_foundStartCallFrame) {
- if (visitor->callFrame()->codeBlock()) {
- m_foundCallFrame = visitor->callFrame();
- return StackVisitor::Done;
- }
- m_index++;
- }
-
- return StackVisitor::Continue;
- }
-
- CallFrame* foundCallFrame() const { return m_foundCallFrame; }
- unsigned index() const { return m_index; }
-
-private:
- CallFrame* m_startCallFrame;
- CallFrame* m_foundCallFrame;
- bool m_foundStartCallFrame;
- unsigned m_index;
-};
-
JSValue VM::throwException(ExecState* exec, JSValue error)
{
if (Options::breakOnThrow()) {
@@ -645,44 +553,7 @@
interpreter->getStackTrace(stackTrace);
m_exceptionStack = RefCountedArray<StackFrame>(stackTrace);
m_exception = error;
-
- if (stackTrace.isEmpty() || !error.isObject())
- return error;
- JSObject* exception = asObject(error);
-
- StackFrame stackFrame;
- for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
- stackFrame = stackTrace.at(i);
- if (stackFrame.bytecodeOffset)
- break;
- }
- if (!hasErrorInfo(exec, exception)) {
- // FIXME: We should only really be adding these properties to VM generated exceptions,
- // but the inspector currently requires these for all thrown objects.
- unsigned line;
- unsigned column;
- stackFrame.computeLineAndColumn(line, column);
- exception->putDirect(*this, Identifier::fromString(this, "line"), jsNumber(line), ReadOnly | DontDelete);
- exception->putDirect(*this, Identifier::fromString(this, "column"), jsNumber(column), ReadOnly | DontDelete);
- if (!stackFrame.sourceURL.isEmpty())
- exception->putDirect(*this, Identifier::fromString(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
- }
- if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->hasSourceAppender()) {
- FindFirstCallerFrameWithCodeblockFunctor functor(exec);
- topCallFrame->iterate(functor);
- CallFrame* callFrame = functor.foundCallFrame();
- unsigned stackIndex = functor.index();
- if (callFrame && callFrame->codeBlock()) {
- stackFrame = stackTrace.at(stackIndex);
- appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), stackFrame.bytecodeOffset);
- }
- }
-
- if (exception->hasProperty(exec, this->propertyNames->stack))
- return error;
-
- exception->putDirect(*this, propertyNames->stack, interpreter->stackTraceAsString(topCallFrame, stackTrace), DontEnum);
return error;
}
Added: trunk/Source/_javascript_Core/tests/stress/freeze_leek.js (0 => 182495)
--- trunk/Source/_javascript_Core/tests/stress/freeze_leek.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/freeze_leek.js 2015-04-07 21:34:05 UTC (rev 182495)
@@ -0,0 +1,41 @@
+var o = Object.freeze([]),
+ leak = {};
+
+try {
+ throw o;
+} catch (ex) {}
+
+if(o.stack !== undefined)
+ throw new Error("the stack was leaked.");
+
+o.stack = leak;
+
+if(o.stack === leak)
+ throw new Error("the object wasn't frozen.");
+
+o.other = "wrong";
+
+if(o.other === "wrong")
+ throw new Error("the object wasn't frozen.");
+
+
+o = Object.freeze({"hi": "other"});
+
+try {
+ throw o;
+} catch (ex) {}
+o.stack = leak;
+
+
+if(o.stack !== undefined)
+ throw new Error("the stack was leaked.");
+
+o.stack = leak;
+
+if(o.stack === leak)
+ throw new Error("the object wasn't frozen.");
+
+o.other = "wrong";
+
+if(o.other === "wrong")
+ throw new Error("the object wasn't frozen.");
Modified: trunk/Source/WebCore/ChangeLog (182494 => 182495)
--- trunk/Source/WebCore/ChangeLog 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/WebCore/ChangeLog 2015-04-07 21:34:05 UTC (rev 182495)
@@ -1,3 +1,22 @@
+2015-04-07 Matthew Mirman <[email protected]>
+
+ Source and stack information should get appended only to native errors
+ and should be added directly after construction rather than when thrown.
+ This fixes frozen objects being unfrozen when thrown while conforming to
+ ecma script standard and other browser behavior.
+ rdar://problem/19927293
+ https://bugs.webkit.org/show_bug.cgi?id=141871
+
+ Reviewed by Geoffrey Garen.
+
+ Covered by existing tests.
+
+ Sets line, column, source and stack information for DOMExceptions as
+ expected by the webinspector for native errors.
+
+ * bindings/js/JSDOMBinding.cpp:
+ (WebCore::setDOMException):
+
2015-04-07 Brady Eidson <[email protected]>
ContextMenuItem refactoring
Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (182494 => 182495)
--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp 2015-04-07 21:29:00 UTC (rev 182494)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp 2015-04-07 21:34:05 UTC (rev 182495)
@@ -214,8 +214,9 @@
switch (description.type) {
DOM_EXCEPTION_INTERFACES_FOR_EACH(TRY_TO_CREATE_EXCEPTION)
}
-
+
ASSERT(errorObject);
+ addErrorInfo(exec, asObject(errorObject), true);
exec->vm().throwException(exec, errorObject);
}