Changeset 153457 in webkit


Ignore:
Timestamp:
Jul 29, 2013 9:33:35 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Eager stack trace for error objects.
https://bugs.webkit.org/show_bug.cgi?id=118918

Source/JavaScriptCore:

Patch by Chris Curtis <chris_curtis@apple.com> on 2013-07-29
Reviewed by Geoffrey Garen.

Chrome and Firefox give error objects the stack property and we wanted to match
that functionality. This allows developers to see the stack without throwing an object.

  • runtime/ErrorInstance.cpp:

(JSC::ErrorInstance::finishCreation):

For error objects that are not thrown as an exception, we pass the stackTrace in
as a parameter. This allows the error object to have the stack property.

  • interpreter/Interpreter.cpp:

(JSC::stackTraceAsString):
Helper function used to eliminate duplicate code.

(JSC::Interpreter::addStackTraceIfNecessary):
When an error object is created by the user the vm->exceptionStack is not set.
If the user throws this error object later the stack that is in the error object
may not be the correct stack for the throw, so when we set the vm->exception stack,
the stack property on the error object is set as well.

  • runtime/ErrorConstructor.cpp:

(JSC::constructWithErrorConstructor):
(JSC::callErrorConstructor):

  • runtime/NativeErrorConstructor.cpp:

(JSC::constructWithNativeErrorConstructor):
(JSC::callNativeErrorConstructor):
These functions indicate that the user created an error object. For all error objects
that the user explicitly creates, the topCallFrame is at a new frame created to
handle the user's call. In this case though, the error object needs the caller's
frame to create the stack trace correctly.

  • interpreter/Interpreter.h:
  • runtime/ErrorInstance.h:

(JSC::ErrorInstance::create):

LayoutTests:

Patch by Chris Curtis <chris_curtis@apple.com> on 2013-07-29
Reviewed by Geoffrey Garen.

Added tests to ensure that the stack property was present at creation for all
error Objects. This test will fail without this patch.

  • fast/js/script-tests/stack-at-creation-for-error-objects.js: Added.

(checkStack):

  • fast/js/stack-at-creation-for-error-objects-expected.txt: Added.
  • fast/js/stack-at-creation-for-error-objects.html: Added.
  • inspector/console/console-format-expected.txt:
  • inspector/console/console-format.html:

This test was modified by removing the error object from being evaluated. Prior to this patch
error objects did not have the stack property, so the stack information was not being
displayed. The stack trace includes a file path specific to the machine that is running
the test. The results would have differed from one computer to the next. There
is not an easy way to capture the error object to treat it differently. By removing
the error object there is no need to add extra code to treat it differently.
Also there are other tests inside inspector/console that test the stack trace,
so the testing suite does not lose error testing by removing it.

The .stack property was added to the error objects at creation time.

  • fast/js/exception-properties-expected.txt:
  • fast/js/script-tests/exception-properties.js:

The column numbers are modified in the following test. When error objects are explicitly
invoked, the column number points to the beginning "(" instead of end ")".
Functionality between browsers do not match either. Firefox does not output column
numbers. Chrome points columns numbers to the beginning of the "new" call.

  • fast/js/line-column-numbers-expected.txt:
  • fast/js/stack-trace-expected.txt:
Location:
trunk
Files:
3 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r153437 r153457  
     12013-07-29  Chris Curtis  <chris_curtis@apple.com>
     2
     3        Eager stack trace for error objects.
     4        https://bugs.webkit.org/show_bug.cgi?id=118918
     5
     6        Reviewed by Geoffrey Garen.
     7       
     8        Added tests to ensure that the stack property was present at creation for all
     9        error Objects. This test will fail without this patch.
     10
     11        * fast/js/script-tests/stack-at-creation-for-error-objects.js: Added.
     12        (checkStack):
     13        * fast/js/stack-at-creation-for-error-objects-expected.txt: Added.
     14        * fast/js/stack-at-creation-for-error-objects.html: Added.
     15
     16        * inspector/console/console-format-expected.txt:
     17        * inspector/console/console-format.html:
     18        This test was modified by removing the error object from being evaluated. Prior to this patch
     19        error objects did not have the stack property, so the stack information was not being
     20        displayed. The stack trace includes a file path specific to the machine that is running
     21        the test. The results would have differed from one computer to the next. There
     22        is not an easy way to capture the error object to treat it differently. By removing
     23        the error object there is no need to add extra code to treat it differently.
     24        Also there are other tests inside inspector/console that test the  stack trace,
     25        so the testing suite does not lose error testing by removing it.
     26       
     27        The .stack property was added to the error objects at creation time.
     28        * fast/js/exception-properties-expected.txt:
     29        * fast/js/script-tests/exception-properties.js:
     30       
     31        The column numbers are modified in the following test. When error objects are explicitly
     32        invoked, the column number points to the beginning "(" instead of end ")".
     33        Functionality between browsers do not match either. Firefox does not output column
     34        numbers. Chrome points columns numbers to the beginning of the "new" call.
     35       
     36        * fast/js/line-column-numbers-expected.txt:
     37        * fast/js/stack-trace-expected.txt:
     38
    1392013-07-29  Bem Jones-Bey  <bjonesbe@adobe.com>
    240
  • trunk/LayoutTests/fast/js/exception-properties-expected.txt

    r114702 r153457  
    44
    55
    6 PASS enumerableProperties(error) is []
     6PASS enumerableProperties(error) is ["stack"]
    77PASS enumerableProperties(nativeError) is ["stack", "line", "sourceURL"]
    88PASS Object.getPrototypeOf(nativeError).name is "RangeError"
  • trunk/LayoutTests/fast/js/line-column-numbers-expected.txt

    r153073 r153457  
    142142
    143143--> Case 2 Stack Trace:
    144     0   global code at line-column-numbers.js:7:32
    145 
    146 --> Case 3 Stack Trace:
    147     0   global code at line-column-numbers.js:11:24
    148 
    149 --> Case 3 Stack Trace:
    150     0   global code at line-column-numbers.js:11:88
     144    0   global code at line-column-numbers.js:7:30
     145
     146--> Case 3 Stack Trace:
     147    0   global code at line-column-numbers.js:11:22
     148
     149--> Case 3 Stack Trace:
     150    0   global code at line-column-numbers.js:11:86
    151151
    152152--> Case 4 Stack Trace:
    153     0   doThrow4b at line-column-numbers.js:16:45
     153    0   doThrow4b at line-column-numbers.js:16:43
    154154    1   global code at line-column-numbers.js:17:14
    155155
    156156--> Case 5 Stack Trace:
    157     0   innerFunc at line-column-numbers.js:24:70
     157    0   innerFunc at line-column-numbers.js:24:68
    158158    1   doThrow5b at line-column-numbers.js:24:83
    159159    2   global code at line-column-numbers.js:24:135
    160160
    161161--> Case 6 Stack Trace:
    162     0   innerFunc at line-column-numbers.js:28:70
     162    0   innerFunc at line-column-numbers.js:28:68
    163163    1   doThrow6b at line-column-numbers.js:28:83
    164164    2   global code at line-column-numbers.js:28:135
    165165
    166166--> Case 7 Stack Trace:
    167     0    at line-column-numbers.js:32:43
     167    0    at line-column-numbers.js:32:41
    168168    1   global code at line-column-numbers.js:32:47
    169169
    170170--> Case 8 Stack Trace:
    171     0    at line-column-numbers.js:36:47
     171    0    at line-column-numbers.js:36:45
    172172    1   global code at line-column-numbers.js:36:51
    173173
    174174--> Case 9 Stack Trace:
    175     0    at line-column-numbers.js:40:39
     175    0    at line-column-numbers.js:40:37
    176176    1   global code at line-column-numbers.js:40:43
    177177
    178178--> Case 9 Stack Trace:
    179     0    at line-column-numbers.js:40:124
     179    0    at line-column-numbers.js:40:122
    180180    1   global code at line-column-numbers.js:40:128
    181181
    182182--> Case 10 Stack Trace:
    183     0    at line-column-numbers.js:46:26
     183    0    at line-column-numbers.js:46:24
    184184    1   global code at line-column-numbers.js:47:8
    185185
    186186--> Case 11 Stack Trace:
    187     0    at line-column-numbers.js:56:41
     187    0    at line-column-numbers.js:56:39
    188188    1   doThrow11b at line-column-numbers.js:56:45
    189189    2   global code at line-column-numbers.js:58:15
    190190
    191191--> Case 12 Stack Trace:
    192     0    at line-column-numbers.js:65:53
     192    0    at line-column-numbers.js:65:51
    193193    1    at line-column-numbers.js:65:57
    194194    2   global code at line-column-numbers.js:65:62
    195195
    196196--> Case 13 Stack Trace:
    197     0    at line-column-numbers.js:69:53
     197    0    at line-column-numbers.js:69:51
    198198    1    at line-column-numbers.js:69:57
    199199    2   global code at line-column-numbers.js:69:62
    200200
    201201--> Case 14 Stack Trace:
    202     0    at line-column-numbers.js:73:77
     202    0    at line-column-numbers.js:73:75
    203203    1    at line-column-numbers.js:73:81
    204204    2   doThrow14b at line-column-numbers.js:73:86
  • trunk/LayoutTests/fast/js/script-tests/exception-properties.js

    r114702 r153457  
    1616    var error = new Error("message");
    1717
    18     shouldBe('enumerableProperties(error)', '[]');
     18    shouldBe('enumerableProperties(error)', '["stack"]');
    1919    shouldBe('enumerableProperties(nativeError)', '["stack", "line", "sourceURL"]');
    2020
  • trunk/LayoutTests/fast/js/stack-trace-expected.txt

    r152494 r153457  
    2525
    2626--> Stack Trace:
    27     0   inner at stack-trace.js:28:69
     27    0   inner at stack-trace.js:28:44
    2828    1   global code at stack-trace.js:43:23
    2929
    3030--> Stack Trace:
    31     0   inner at stack-trace.js:28:69
     31    0   inner at stack-trace.js:28:44
    3232    1   outer at stack-trace.js:27:34
    3333    2   global code at stack-trace.js:44:23
     
    3939
    4040--> Stack Trace:
    41     0   htmlInner at stack-trace.html:10:56
     41    0   htmlInner at stack-trace.html:10:39
    4242    1   scripterInner at stack-trace.js:32:37
    4343    2   global code at stack-trace.js:49:20
    4444
    4545--> Stack Trace:
    46     0   htmlInner at stack-trace.html:10:56
     46    0   htmlInner at stack-trace.html:10:39
    4747    1   htmlOuter at stack-trace.html:11:33
    4848    2   scripterOuter at stack-trace.js:33:37
  • trunk/LayoutTests/inspector/console/console-format-expected.txt

    r143179 r153457  
    33CONSOLE MESSAGE: line 22: %O
    44CONSOLE MESSAGE: line 23: Test for zero "%f" in formatter
     5CONSOLE MESSAGE: line 53: /^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')|(?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i
    56CONSOLE MESSAGE: line 54: /^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')|(?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i
    6 CONSOLE MESSAGE: line 55: /^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')|(?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i
     7CONSOLE MESSAGE: line 53: /foo\\bar\sbaz/i
    78CONSOLE MESSAGE: line 54: /foo\\bar\sbaz/i
    8 CONSOLE MESSAGE: line 55: /foo\\bar\sbaz/i
     9CONSOLE MESSAGE: line 53: test
    910CONSOLE MESSAGE: line 54: test
    10 CONSOLE MESSAGE: line 55: test
     11CONSOLE MESSAGE: line 53: test named "test"
    1112CONSOLE MESSAGE: line 54: test named "test"
    12 CONSOLE MESSAGE: line 55: test named "test"
    13 CONSOLE MESSAGE: line 54: Error
    14 CONSOLE MESSAGE: line 55: Error
     13CONSOLE MESSAGE: line 53: [object HTMLParagraphElement]
    1514CONSOLE MESSAGE: line 54: [object HTMLParagraphElement]
    16 CONSOLE MESSAGE: line 55: [object HTMLParagraphElement]
     15CONSOLE MESSAGE: line 53: function () { return 1; }
    1716CONSOLE MESSAGE: line 54: function () { return 1; }
    18 CONSOLE MESSAGE: line 55: function () { return 1; }
     17CONSOLE MESSAGE: line 53: function () {
     18        return 2;
     19    }
    1920CONSOLE MESSAGE: line 54: function () {
    2021        return 2;
    2122    }
    22 CONSOLE MESSAGE: line 55: function () {
    23         return 2;
    24     }
     23CONSOLE MESSAGE: line 53: 0.12
    2524CONSOLE MESSAGE: line 54: 0.12
    26 CONSOLE MESSAGE: line 55: 0.12
     25CONSOLE MESSAGE: line 53: http://webkit.org/
    2726CONSOLE MESSAGE: line 54: http://webkit.org/
    28 CONSOLE MESSAGE: line 55: http://webkit.org/
    29 CONSOLE MESSAGE: line 54: null
    30 CONSOLE MESSAGE: line 55:
    31 CONSOLE MESSAGE: line 54: undefined
    32 CONSOLE MESSAGE: line 55:
     27CONSOLE MESSAGE: line 53: null
     28CONSOLE MESSAGE: line 54:
     29CONSOLE MESSAGE: line 53: undefined
     30CONSOLE MESSAGE: line 54:
     31CONSOLE MESSAGE: line 53: [object Attr]
    3332CONSOLE MESSAGE: line 54: [object Attr]
    34 CONSOLE MESSAGE: line 55: [object Attr]
     33CONSOLE MESSAGE: line 53: [object Attr]
    3534CONSOLE MESSAGE: line 54: [object Attr]
    36 CONSOLE MESSAGE: line 55: [object Attr]
     35CONSOLE MESSAGE: line 53: [object Attr]
    3736CONSOLE MESSAGE: line 54: [object Attr]
    38 CONSOLE MESSAGE: line 55: [object Attr]
     37CONSOLE MESSAGE: line 53: [object Object]
    3938CONSOLE MESSAGE: line 54: [object Object]
    40 CONSOLE MESSAGE: line 55: [object Object]
     39CONSOLE MESSAGE: line 53: NaN
    4140CONSOLE MESSAGE: line 54: NaN
    42 CONSOLE MESSAGE: line 55: NaN
     41CONSOLE MESSAGE: line 53: Infinity
    4342CONSOLE MESSAGE: line 54: Infinity
    44 CONSOLE MESSAGE: line 55: Infinity
     43CONSOLE MESSAGE: line 53: -Infinity
    4544CONSOLE MESSAGE: line 54: -Infinity
    46 CONSOLE MESSAGE: line 55: -Infinity
     45CONSOLE MESSAGE: line 53: test,test2,,,test4,,,,,
    4746CONSOLE MESSAGE: line 54: test,test2,,,test4,,,,,
    48 CONSOLE MESSAGE: line 55: test,test2,,,test4,,,,,
     47CONSOLE MESSAGE: line 53: [object Object]
    4948CONSOLE MESSAGE: line 54: [object Object]
    50 CONSOLE MESSAGE: line 55: [object Object]
     49CONSOLE MESSAGE: line 53: function () {}
    5150CONSOLE MESSAGE: line 54: function () {}
    52 CONSOLE MESSAGE: line 55: function () {}
     51CONSOLE MESSAGE: line 53: [object Object]
    5352CONSOLE MESSAGE: line 54: [object Object]
    54 CONSOLE MESSAGE: line 55: [object Object]
    5553Tests that console logging dumps proper messages.
    5654
     
    5957Array[10] console-format.html:22
    6058Test for zero "0" in formatter console-format.html:23
    61 /^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')|(?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i console-format.html:54
    62 [/^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\…?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i] console-format.html:55
     59/^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')|(?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i console-format.html:53
     60[/^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\…?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i] console-format.html:54
    6361globals[0]
    6462/^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')|(?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i
    65 /foo\\bar\sbaz/i console-format.html:54
    66 [/foo\\bar\sbaz/i] console-format.html:55
     63/foo\\bar\sbaz/i console-format.html:53
     64[/foo\\bar\sbaz/i] console-format.html:54
    6765globals[1]
    6866/foo\\bar\sbaz/i
    69 test console-format.html:54
    70 ["test"] console-format.html:55
     67test console-format.html:53
     68["test"] console-format.html:54
    7169globals[2]
    7270"test"
    73 test named "test" console-format.html:54
    74 ["test named "test""] console-format.html:55
     71test named "test" console-format.html:53
     72["test named "test""] console-format.html:54
    7573globals[3]
    7674"test named "test""
    77 Error {} console-format.html:54
    78 [Error] console-format.html:55
     75<p id="p">Tests that console logging dumps proper messages.</p> console-format.html:53
     76[p#p] console-format.html:54
    7977globals[4]
    80 Error {}
    81 <p id="p">Tests that console logging dumps proper messages.</p> console-format.html:54
    82 [p#p] console-format.html:55
     78<p id="p">Tests that console logging dumps proper messages.</p>
     79function () { return 1; } console-format.html:53
     80[function] console-format.html:54
    8381globals[5]
    84 <p id="p">Tests that console logging dumps proper messages.</p>
    85 function () { return 1; } console-format.html:54
    86 [function] console-format.html:55
    87 globals[6]
    8882function () { return 1; }
    8983function () {
    9084        return 2;
    91     } console-format.html:54
    92 [function] console-format.html:55
    93 globals[7]
     85    } console-format.html:53
     86[function] console-format.html:54
     87globals[6]
    9488function () {
    9589        return 2;
    9690    }
    97 0.12 console-format.html:54
    98 [0.12] console-format.html:55
     910.12 console-format.html:53
     92[0.12] console-format.html:54
     93globals[7]
     940.12
     95http://webkit.org/ console-format.html:53
     96["http://webkit.org/"] console-format.html:54
    9997globals[8]
    100 0.12
    101 http://webkit.org/ console-format.html:54
    102 ["http://webkit.org/"] console-format.html:55
     98"http://webkit.org/"
     99null console-format.html:53
     100[null] console-format.html:54
    103101globals[9]
    104 "http://webkit.org/"
    105 null console-format.html:54
    106 [null] console-format.html:55
     102null
     103undefined console-format.html:53
     104[undefined] console-format.html:54
    107105globals[10]
    108 null
    109 undefined console-format.html:54
    110 [undefined] console-format.html:55
     106undefined
     107attr="" console-format.html:53
     108[attr] console-format.html:54
    111109globals[11]
    112 undefined
    113 attr="" console-format.html:54
    114 [attr] console-format.html:55
     110attr=""
     111attr="value""value" console-format.html:53
     112[attr] console-format.html:54
    115113globals[12]
    116 attr=""
    117 attr="value""value" console-format.html:54
    118 [attr] console-format.html:55
     114attr="value""value"
     115id="x""x" console-format.html:53
     116[id] console-format.html:54
    119117globals[13]
    120 attr="value""value"
    121 id="x""x" console-format.html:54
    122 [id] console-format.html:55
     118id="x""x"
     119Object {} console-format.html:53
     120[Object] console-format.html:54
    123121globals[14]
    124 id="x""x"
    125 Object {} console-format.html:54
    126 [Object] console-format.html:55
     122Object {}
     123NaN console-format.html:53
     124[NaN] console-format.html:54
    127125globals[15]
     126NaN
     127Infinity console-format.html:53
     128[Infinity] console-format.html:54
     129globals[16]
     130Infinity
     131-Infinity console-format.html:53
     132[-Infinity] console-format.html:54
     133globals[17]
     134-Infinity
     135["test", "test2", 4: "test4", foo: Object] console-format.html:53
     136[Array[10]] console-format.html:54
     137globals[18]
     138["test", "test2", undefined × 2, "test4", undefined × 5]
     139Object {} console-format.html:53
     140[Object] console-format.html:54
     141globals[19]
    128142Object {}
    129 NaN console-format.html:54
    130 [NaN] console-format.html:55
    131 globals[16]
    132 NaN
    133 Infinity console-format.html:54
    134 [Infinity] console-format.html:55
    135 globals[17]
    136 Infinity
    137 -Infinity console-format.html:54
    138 [-Infinity] console-format.html:55
    139 globals[18]
    140 -Infinity
    141 ["test", "test2", 4: "test4", foo: Object] console-format.html:54
    142 [Array[10]] console-format.html:55
    143 globals[19]
    144 ["test", "test2", undefined × 2, "test4", undefined × 5]
    145 Object {} console-format.html:54
    146 [Object] console-format.html:55
     143[function] console-format.html:53
     144[Array[1]] console-format.html:54
    147145globals[20]
    148 Object {}
    149 [function] console-format.html:54
    150 [Array[1]] console-format.html:55
     146[function () {}]
     147Object {bar: "bar", foo: "foo"} console-format.html:53
     148[Object] console-format.html:54
    151149globals[21]
    152 [function () {}]
    153 Object {bar: "bar", foo: "foo"} console-format.html:54
    154 [Object] console-format.html:55
    155 globals[22]
    156150Object {bar: "bar", foo: "foo"}
    157151
  • trunk/LayoutTests/inspector/console/console-format.html

    r143179 r153457  
    2727    var str = "test";
    2828    var str2 = "test named \"test\"";
    29     var error = new Error;
    3029    var node = document.getElementById("p");
    3130    var func = function() { return 1; };
     
    4241
    4342    globals = [
    44         regex1, regex2, str, str2, error, node, func, multilinefunc, num, linkify,
     43        regex1, regex2, str, str2, node, func, multilinefunc, num, linkify,
    4544        null, undefined, valuelessAttribute, valuedAttribute, existingAttribute, throwingLengthGetter,
    4645        NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, array, {}, [function() {}], bar
  • trunk/Source/JavaScriptCore/ChangeLog

    r153454 r153457  
     12013-07-29  Chris Curtis  <chris_curtis@apple.com>
     2
     3        Eager stack trace for error objects.
     4        https://bugs.webkit.org/show_bug.cgi?id=118918
     5
     6        Reviewed by Geoffrey Garen.
     7       
     8        Chrome and Firefox give error objects the stack property and we wanted to match
     9        that functionality. This allows developers to see the stack without throwing an object.
     10
     11        * runtime/ErrorInstance.cpp:
     12        (JSC::ErrorInstance::finishCreation):
     13         For error objects that are not thrown as an exception, we pass the stackTrace in
     14         as a parameter. This allows the error object to have the stack property.
     15       
     16        * interpreter/Interpreter.cpp:
     17        (JSC::stackTraceAsString):
     18        Helper function used to eliminate duplicate code.
     19
     20        (JSC::Interpreter::addStackTraceIfNecessary):
     21        When an error object is created by the user the vm->exceptionStack is not set.
     22        If the user throws this error object later the stack that is in the error object
     23        may not be the correct stack for the throw, so when we set the vm->exception stack,
     24        the stack property on the error object is set as well.
     25       
     26        * runtime/ErrorConstructor.cpp:
     27        (JSC::constructWithErrorConstructor):
     28        (JSC::callErrorConstructor):
     29        * runtime/NativeErrorConstructor.cpp:
     30        (JSC::constructWithNativeErrorConstructor):
     31        (JSC::callNativeErrorConstructor):
     32        These functions indicate that the user created an error object. For all error objects
     33        that the user explicitly creates, the topCallFrame is at a new frame created to
     34        handle the user's call. In this case though, the error object needs the caller's
     35        frame to create the stack trace correctly.
     36       
     37        * interpreter/Interpreter.h:
     38        * runtime/ErrorInstance.h:
     39        (JSC::ErrorInstance::create):
     40
    1412013-07-29  Gavin Barraclough  <barraclough@apple.com>
    242
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r153221 r153457  
    558558    }
    559559}
    560 
     560JSString* Interpreter:: stackTraceAsString(ExecState* exec, Vector<StackFrame> stackTrace)
     561{
     562    // FIXME: JSStringJoiner could be more efficient than StringBuilder here.
     563    StringBuilder builder;
     564    for (unsigned i = 0; i < stackTrace.size(); i++) {
     565        builder.append(String(stackTrace[i].toString(exec)));
     566        if (i != stackTrace.size() - 1)
     567            builder.append('\n');
     568    }
     569    return jsString(&exec->vm(), builder.toString());
     570}
     571   
    561572void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSValue error)
    562573{
     
    564575    ASSERT(callFrame == vm->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec());
    565576
    566     if (error.isObject()) {
    567         if (asObject(error)->hasProperty(callFrame, vm->propertyNames->stack))
     577    if (vm->exceptionStack().size()) {
     578        if (!error.isObject() || asObject(error)->hasProperty(callFrame, vm->propertyNames->stack))
    568579            return;
    569580    }
     
    575586        return;
    576587
    577     JSObject* errorObject = asObject(error);
    578     JSGlobalObject* globalObject = 0;
    579     if (isTerminatedExecutionException(error))
    580         globalObject = vm->dynamicGlobalObject;
    581     else
    582         globalObject = errorObject->globalObject();
    583 
    584     // FIXME: JSStringJoiner could be more efficient than StringBuilder here.
    585     StringBuilder builder;
    586     for (unsigned i = 0; i < stackTrace.size(); i++) {
    587         builder.append(String(stackTrace[i].toString(globalObject->globalExec()).impl()));
    588         if (i != stackTrace.size() - 1)
    589             builder.append('\n');
    590     }
    591 
    592     errorObject->putDirect(*vm, vm->propertyNames->stack, jsString(vm, builder.toString()), ReadOnly | DontDelete);
     588    // Note: 'error' might already have a stack property if it was created by the user (e.g. "new Error"). The stack
     589    // now, as the error is thrown, might be different from the stack when it was created, so we overwrite it with
     590    // the current stack unconditionally.
     591    asObject(error)->putDirect(*vm, vm->propertyNames->stack, vm->interpreter->stackTraceAsString(vm->topCallFrame, stackTrace), ReadOnly | DontDelete);
     592
    593593}
    594594
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r153383 r153457  
    221221        NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column);
    222222        static void addStackTraceIfNecessary(CallFrame*, JSValue error);
     223        JSString* stackTraceAsString(ExecState*, Vector<StackFrame>);
    223224
    224225        void dumpSampleData(ExecState* exec);
  • trunk/Source/JavaScriptCore/runtime/ErrorConstructor.cpp

    r148696 r153457  
    2323
    2424#include "ErrorPrototype.h"
     25#include "Interpreter.h"
    2526#include "JSGlobalObject.h"
    2627#include "JSString.h"
     
    5253    JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
    5354    Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
    54     return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
     55    Vector<StackFrame> stackTrace;
     56    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
     57    stackTrace.remove(0);
     58    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
    5559}
    5660
     
    6569    JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
    6670    Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
    67     return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
     71    Vector<StackFrame> stackTrace;
     72    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
     73    stackTrace.remove(0);
     74    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
    6875}
    6976
  • trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp

    r148696 r153457  
    3737}
    3838
     39void ErrorInstance::finishCreation(VM& vm, const String& message, Vector<StackFrame> stackTrace)
     40{
     41    Base::finishCreation(vm);
     42    ASSERT(inherits(&s_info));
     43    if (!message.isNull())
     44        putDirect(vm, vm.propertyNames->message, jsString(&vm, message), DontEnum);
     45   
     46    if (!stackTrace.isEmpty())
     47        putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), ReadOnly | DontDelete);
     48}
     49   
    3950} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ErrorInstance.h

    r148696 r153457  
    2222#define ErrorInstance_h
    2323
     24#include "Interpreter.h"
    2425#include "JSObject.h"
     26#include "SourceProvider.h"
    2527
    2628namespace JSC {
     
    3739        }
    3840
    39         static ErrorInstance* create(VM& vm, Structure* structure, const String& message)
     41        static ErrorInstance* create(VM& vm, Structure* structure, const String& message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
    4042        {
    4143            ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
    42             instance->finishCreation(vm, message);
     44            instance->finishCreation(vm, message, stackTrace);
    4345            return instance;
    4446        }
    4547
    46         static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message)
     48        static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
    4749        {
    48             return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec));
     50            return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), stackTrace);
    4951        }
    5052
     
    5658        explicit ErrorInstance(VM&, Structure*);
    5759
    58         void finishCreation(VM& vm, const String& message)
    59         {
    60             Base::finishCreation(vm);
    61             ASSERT(inherits(&s_info));
    62             if (!message.isNull())
    63                 putDirect(vm, vm.propertyNames->message, jsString(&vm, message), DontEnum);
    64         }
     60        void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());
    6561
    6662        bool m_appendSourceToMessage;
  • trunk/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp

    r139541 r153457  
    5555    Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure();
    5656    ASSERT(errorStructure);
    57     return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
     57    Vector<StackFrame> stackTrace;
     58    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
     59    stackTrace.remove(0);
     60    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
    5861}
    5962
     
    6871    JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
    6972    Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure();
    70     return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
     73    Vector<StackFrame> stackTrace;
     74    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
     75    stackTrace.remove(0);
     76    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
    7177}
    7278
Note: See TracChangeset for help on using the changeset viewer.