Changeset 159520 in webkit


Ignore:
Timestamp:
Nov 19, 2013 1:55:16 PM (10 years ago)
Author:
mark.lam@apple.com
Message:

Add tracking of endColumn for Executables.
https://bugs.webkit.org/show_bug.cgi?id=124245.

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

  1. Fixed computation of columns to take into account the startColumn from <script> tags. Previously, we were only computing the column relative to the char after the <script> tag. Now, the column number that JSC computes is always the column number you'll see when viewing the source in a text editor (assuming the first column position is 1, not 0).
  1. Previously, unlinkedExecutables kept the a base-1 startColumn for ProgramExecutables and EvalExecutables, but uses base-0 columns for FunctionExecutables. This has been fixed so that they all use base-0 columns. When the executable gets linked, the column is adjusted into a base-1 value.
  1. In the UnlinkedFunctionExecutable, renamed m_functionStartOffset to m_unlinkedFunctionNameStart because it actually points to the start column in the name part of the function declaration.

Similarly, renamed m_functionStartColumn to m_unlinkedBodyStartColumn
because it points to the first character in the function body. This is
usually '{' except for functions created from "global code" which
excludes its braces. See FunctionExecutable::fromGlobalCode().

The exclusion of braces for the global code case is needed so that

computed start and end columns will more readily map to what a JS
developer would expect them to be. Otherwise, the first column of the
function source will not be 1 (includes prepended characters added in
constructFunctionSkippingEvalEnabledCheck()).

Also, similarly, a m_unlinkedBodyEndColumn has been added to track the
end column of the UnlinkedFunctionExecutable.

  1. For unlinked executables, end column values are either:
    1. Relative to the start of the last line if (last line != first line).
    2. Relative to the start column position if (last line == first line).

The second case is needed so that we can add an appropriate adjustment
to the end column value (just like we do for the start column) when we
link the executable.

  1. This is not new to this patch, but it worth noting that the lineCount values used through this patch has the following meaning:
    • a lineCount of 0 means the source for this code block is on 1 line.
    • a lineCount of N means there are N + l lines of source.

This interpretation is janky, but was present before this patch. We can
clean that up later in another patch.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • In order to implement WebCore::Internals::parserMetaData(), we need to move some seemingly unrelated header files from the Project section to the Private section so that they can be #include'd by the forwarding CodeBlock.h from WebCore.
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::sourceCodeForTools):
(JSC::CodeBlock::CodeBlock):

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::generateFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):

  • m_isFromGlobalCode is needed to support the exclusion of the open brace / prepended code for functions created from "global code".

(JSC::UnlinkedFunctionExecutable::link):
(JSC::UnlinkedFunctionExecutable::fromGlobalCode):
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedFunctionExecutable::create):
(JSC::UnlinkedFunctionExecutable::unlinkedFunctionNameStart):
(JSC::UnlinkedFunctionExecutable::unlinkedBodyStartColumn):
(JSC::UnlinkedFunctionExecutable::unlinkedBodyEndColumn):
(JSC::UnlinkedFunctionExecutable::recordParse):
(JSC::UnlinkedCodeBlock::recordParse):
(JSC::UnlinkedCodeBlock::endColumn):

  • bytecompiler/NodesCodegen.cpp:

(JSC::FunctionBodyNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createFunctionBody):
(JSC::ASTBuilder::setFunctionNameStart):

  • parser/Lexer.cpp:

(JSC::::shiftLineTerminator):

  • Removed an unused SourceCode Lexer<T>::sourceCode() function.
  • parser/Lexer.h:

(JSC::Lexer::positionBeforeLastNewline):
(JSC::Lexer::prevTerminator):

  • Added tracking of m_positionBeforeLastNewline in the Lexer to enable us to exclude the close brace / appended code for functions created from "global code".
  • parser/Nodes.cpp:

(JSC::ProgramNode::ProgramNode):
(JSC::ProgramNode::create):
(JSC::EvalNode::EvalNode):
(JSC::EvalNode::create):
(JSC::FunctionBodyNode::FunctionBodyNode):
(JSC::FunctionBodyNode::create):
(JSC::FunctionBodyNode::setEndPosition):

  • setEndPosition() is needed to fixed up the end position so that we can exclude the close brace / appended code for functions created from "global code".
  • parser/Nodes.h:

(JSC::ProgramNode::startColumn):
(JSC::ProgramNode::endColumn):
(JSC::EvalNode::startColumn):
(JSC::EvalNode::endColumn):
(JSC::FunctionBodyNode::setFunctionNameStart):
(JSC::FunctionBodyNode::functionNameStart):
(JSC::FunctionBodyNode::endColumn):

  • parser/Parser.cpp:

(JSC::::parseFunctionBody):
(JSC::::parseFunctionInfo):

  • parser/Parser.h:

(JSC::Parser::positionBeforeLastNewline):
(JSC::::parse):

  • Subtracted 1 from startColumn here to keep the node column values consistently base-0. See note 2 above.

(JSC::parse):

  • parser/SourceProviderCacheItem.h:

(JSC::SourceProviderCacheItem::SourceProviderCacheItem):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createFunctionBody):
(JSC::SyntaxChecker::setFunctionNameStart):

  • runtime/CodeCache.cpp:

(JSC::CodeCache::getGlobalCodeBlock):
(JSC::CodeCache::getProgramCodeBlock):
(JSC::CodeCache::getEvalCodeBlock):
(JSC::CodeCache::getFunctionExecutableFromGlobalCode):

  • runtime/CodeCache.h:
  • runtime/Executable.cpp:

(JSC::ScriptExecutable::newCodeBlockFor):
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::ProgramExecutable::initializeGlobalProperties):
(JSC::FunctionExecutable::fromGlobalCode):

  • runtime/Executable.h:

(JSC::ExecutableBase::isEvalExecutable):
(JSC::ExecutableBase::isProgramExecutable):
(JSC::ScriptExecutable::ScriptExecutable):
(JSC::ScriptExecutable::endColumn):
(JSC::ScriptExecutable::recordParse):
(JSC::FunctionExecutable::create):
(JSC::FunctionExecutable::bodyIncludesBraces):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunctionSkippingEvalEnabledCheck):

  • runtime/FunctionPrototype.cpp:

(JSC::insertSemicolonIfNeeded):
(JSC::functionProtoFuncToString):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::createProgramCodeBlock):
(JSC::JSGlobalObject::createEvalCodeBlock):

Source/WebCore:

Test: js/dom/script-start-end-locations.html

  • ForwardingHeaders/bytecode: Added.
  • ForwardingHeaders/bytecode/CodeBlock.h: Added.
  • WebCore.exp.in:
  • testing/Internals.cpp:

(WebCore::GetCallerCodeBlockFunctor::GetCallerCodeBlockFunctor):
(WebCore::GetCallerCodeBlockFunctor::operator()):
(WebCore::GetCallerCodeBlockFunctor::codeBlock):
(WebCore::Internals::parserMetaData):

  • testing/Internals.h:
  • testing/Internals.idl:

Source/WebKit:

  • WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
  • Added an exported symbol to make the Win32 build happy. The Win64 symbol is currently a copy of the Win32 one. It'll need to be updated if the mangled symbol is different for Win64.

LayoutTests:

  • fast/events/window-onerror2-expected.txt:
  • inspector-protocol/debugger/setBreakpoint-actions-expected.txt:
  • js/dom/script-start-end-locations-expected.txt: Added.
  • js/dom/script-start-end-locations.html: Added.
  • js/dom/script-tests/script-start-end-locations.js: Added.
  • js/dom/stack-trace-expected.txt:
  • js/dom/stack-trace.html:
  • Changed tabs to spaces. The tabs were making it hard to visually confirm the exected column values for 2 functions.
Location:
trunk
Files:
5 added
34 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r159519 r159520  
     12013-11-19  Mark Lam  <mark.lam@apple.com>
     2
     3        Add tracking of endColumn for Executables.
     4        https://bugs.webkit.org/show_bug.cgi?id=124245.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * fast/events/window-onerror2-expected.txt:
     9        * inspector-protocol/debugger/setBreakpoint-actions-expected.txt:
     10        * js/dom/script-start-end-locations-expected.txt: Added.
     11        * js/dom/script-start-end-locations.html: Added.
     12        * js/dom/script-tests/script-start-end-locations.js: Added.
     13        * js/dom/stack-trace-expected.txt:
     14        * js/dom/stack-trace.html:
     15        - Changed tabs to spaces. The tabs were making it hard to visually confirm
     16          the exected column values for 2 functions.
     17
    1182013-11-15  Jer Noble  <jer.noble@apple.com>
    219
  • trunk/LayoutTests/fast/events/window-onerror2-expected.txt

    r153480 r159520  
    22
    33Main frame window.onerror: Error: Inline script exception at window-onerror2.html, line: 34, column: 47
    4 Main frame window.onerror: Exception in onload at window-onerror2.html, line: 2, column: 150
     4Main frame window.onerror: Exception in onload at window-onerror2.html, line: 2, column: 66
    55Main frame window.onerror: Error: Exception in setTimeout at window-onerror2.html, line: 29, column: 47
    66
  • trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions-expected.txt

    r155132 r159520  
    1515Running breakpointActions to triggering the breakpoint actions
    1616inside breakpointActions a:(12) b:([object Object])
    17 PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-before","location":"breakpoint.js:19:1"}
     17PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-before","location":"breakpoint.js:19:2"}
    1818PASS: Console Message: {"source":"console-api","level":"log","text":"eval-action","location":"???:1:26","parameters":[{"type":"string"},{"type":"number"},{"type":"object"}]}
    19 PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-after","location":"breakpoint.js:19:1"}
     19PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-after","location":"breakpoint.js:19:2"}
    2020inside breakpointActions a:(100) b:([object HTMLBodyElement])
    21 PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-before","location":"breakpoint.js:19:1"}
     21PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-before","location":"breakpoint.js:19:2"}
    2222PASS: Console Message: {"source":"console-api","level":"log","text":"eval-action","location":"???:1:26","parameters":[{"type":"string"},{"type":"number"},{"type":"object","subtype":"node"}]}
    23 PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-after","location":"breakpoint.js:19:1"}
     23PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-after","location":"breakpoint.js:19:2"}
    2424
  • trunk/LayoutTests/js/dom/stack-trace-expected.txt

    r156066 r159520  
    3939
    4040--> Stack Trace:
    41     0   htmlInner at stack-trace.html:10:39
     41    0   htmlInner at stack-trace.html:10:51
    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:39
    47     1   htmlOuter at stack-trace.html:11:33
     46    0   htmlInner at stack-trace.html:10:51
     47    1   htmlOuter at stack-trace.html:11:45
    4848    2   scripterOuter at stack-trace.js:33:37
    4949    3   global code at stack-trace.js:50:20
  • trunk/LayoutTests/js/dom/stack-trace.html

    r156066 r159520  
    66
    77<body>
    8         <p id="description"></p>
    9         <p id="console"></p>
    10         <script>function htmlInner() { throw new Error("Error in HTML"); }</script>
    11         <script>function htmlOuter() { htmlInner(); }</script>
    12         <script src="script-tests/stack-trace.js"></script>
     8    <p id="description"></p>
     9    <p id="console"></p>
     10    <script>function htmlInner() { throw new Error("Error in HTML"); }</script>
     11    <script>function htmlOuter() { htmlInner(); }</script>
     12    <script src="script-tests/stack-trace.js"></script>
    1313</body>
    1414</html>
  • trunk/Source/JavaScriptCore/ChangeLog

    r159515 r159520  
     12013-11-19  Mark Lam  <mark.lam@apple.com>
     2
     3        Add tracking of endColumn for Executables.
     4        https://bugs.webkit.org/show_bug.cgi?id=124245.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        1. Fixed computation of columns to take into account the startColumn from
     9           <script> tags. Previously, we were only computing the column relative
     10           to the char after the <script> tag. Now, the column number that JSC
     11           computes is always the column number you'll see when viewing the source
     12           in a text editor (assuming the first column position is 1, not 0).
     13
     14        2. Previously, unlinkedExecutables kept the a base-1 startColumn for
     15           ProgramExecutables and EvalExecutables, but uses base-0 columns for
     16           FunctionExecutables. This has been fixed so that they all use base-0
     17           columns. When the executable gets linked, the column is adjusted into
     18           a base-1 value.
     19
     20        3. In the UnlinkedFunctionExecutable, renamed m_functionStartOffset to
     21           m_unlinkedFunctionNameStart because it actually points to the start
     22           column in the name part of the function declaration.
     23
     24           Similarly, renamed m_functionStartColumn to m_unlinkedBodyStartColumn
     25           because it points to the first character in the function body. This is
     26           usually '{' except for functions created from "global code" which
     27           excludes its braces. See FunctionExecutable::fromGlobalCode().
     28
     29               The exclusion of braces for the global code case is needed so that
     30           computed start and end columns will more readily map to what a JS
     31           developer would expect them to be. Otherwise, the first column of the
     32           function source will not be 1 (includes prepended characters added in
     33           constructFunctionSkippingEvalEnabledCheck()).
     34
     35           Also, similarly, a m_unlinkedBodyEndColumn has been added to track the
     36           end column of the UnlinkedFunctionExecutable.
     37
     38        4. For unlinked executables, end column values are either:
     39           a. Relative to the start of the last line if (last line != first line).
     40           b. Relative to the start column position if (last line == first line).
     41
     42           The second case is needed so that we can add an appropriate adjustment
     43           to the end column value (just like we do for the start column) when we
     44           link the executable.
     45
     46        5. This is not new to this patch, but it worth noting that the lineCount
     47           values used through this patch has the following meaning:
     48           - a lineCount of 0 means the source for this code block is on 1 line.
     49           - a lineCount of N means there are N + l lines of source.
     50
     51           This interpretation is janky, but was present before this patch. We can
     52           clean that up later in another patch.
     53
     54
     55        * JavaScriptCore.xcodeproj/project.pbxproj:
     56        - In order to implement WebCore::Internals::parserMetaData(), we need to
     57          move some seemingly unrelated header files from the Project section to
     58          the Private section so that they can be #include'd by the forwarding
     59          CodeBlock.h from WebCore.
     60        * bytecode/CodeBlock.cpp:
     61        (JSC::CodeBlock::sourceCodeForTools):
     62        (JSC::CodeBlock::CodeBlock):
     63        * bytecode/UnlinkedCodeBlock.cpp:
     64        (JSC::generateFunctionCodeBlock):
     65        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
     66        - m_isFromGlobalCode is needed to support the exclusion of the open brace /
     67          prepended code for functions created from "global code".
     68        (JSC::UnlinkedFunctionExecutable::link):
     69        (JSC::UnlinkedFunctionExecutable::fromGlobalCode):
     70        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
     71        * bytecode/UnlinkedCodeBlock.h:
     72        (JSC::UnlinkedFunctionExecutable::create):
     73        (JSC::UnlinkedFunctionExecutable::unlinkedFunctionNameStart):
     74        (JSC::UnlinkedFunctionExecutable::unlinkedBodyStartColumn):
     75        (JSC::UnlinkedFunctionExecutable::unlinkedBodyEndColumn):
     76        (JSC::UnlinkedFunctionExecutable::recordParse):
     77        (JSC::UnlinkedCodeBlock::recordParse):
     78        (JSC::UnlinkedCodeBlock::endColumn):
     79        * bytecompiler/NodesCodegen.cpp:
     80        (JSC::FunctionBodyNode::emitBytecode):
     81        * parser/ASTBuilder.h:
     82        (JSC::ASTBuilder::createFunctionBody):
     83        (JSC::ASTBuilder::setFunctionNameStart):
     84        * parser/Lexer.cpp:
     85        (JSC::::shiftLineTerminator):
     86        - Removed an unused SourceCode Lexer<T>::sourceCode() function.
     87        * parser/Lexer.h:
     88        (JSC::Lexer::positionBeforeLastNewline):
     89        (JSC::Lexer::prevTerminator):
     90        - Added tracking of m_positionBeforeLastNewline in the Lexer to enable us
     91          to exclude the close brace / appended code for functions created from "global
     92          code".
     93        * parser/Nodes.cpp:
     94        (JSC::ProgramNode::ProgramNode):
     95        (JSC::ProgramNode::create):
     96        (JSC::EvalNode::EvalNode):
     97        (JSC::EvalNode::create):
     98        (JSC::FunctionBodyNode::FunctionBodyNode):
     99        (JSC::FunctionBodyNode::create):
     100        (JSC::FunctionBodyNode::setEndPosition):
     101        - setEndPosition() is needed to fixed up the end position so that we can
     102          exclude the close brace / appended code for functions created from "global
     103          code".
     104        * parser/Nodes.h:
     105        (JSC::ProgramNode::startColumn):
     106        (JSC::ProgramNode::endColumn):
     107        (JSC::EvalNode::startColumn):
     108        (JSC::EvalNode::endColumn):
     109        (JSC::FunctionBodyNode::setFunctionNameStart):
     110        (JSC::FunctionBodyNode::functionNameStart):
     111        (JSC::FunctionBodyNode::endColumn):
     112        * parser/Parser.cpp:
     113        (JSC::::parseFunctionBody):
     114        (JSC::::parseFunctionInfo):
     115        * parser/Parser.h:
     116        (JSC::Parser::positionBeforeLastNewline):
     117        (JSC::::parse):
     118        - Subtracted 1 from startColumn here to keep the node column values consistently
     119          base-0. See note 2 above.
     120        (JSC::parse):
     121        * parser/SourceProviderCacheItem.h:
     122        (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
     123        * parser/SyntaxChecker.h:
     124        (JSC::SyntaxChecker::createFunctionBody):
     125        (JSC::SyntaxChecker::setFunctionNameStart):
     126        * runtime/CodeCache.cpp:
     127        (JSC::CodeCache::getGlobalCodeBlock):
     128        (JSC::CodeCache::getProgramCodeBlock):
     129        (JSC::CodeCache::getEvalCodeBlock):
     130        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
     131        * runtime/CodeCache.h:
     132        * runtime/Executable.cpp:
     133        (JSC::ScriptExecutable::newCodeBlockFor):
     134        (JSC::FunctionExecutable::FunctionExecutable):
     135        (JSC::ProgramExecutable::initializeGlobalProperties):
     136        (JSC::FunctionExecutable::fromGlobalCode):
     137        * runtime/Executable.h:
     138        (JSC::ExecutableBase::isEvalExecutable):
     139        (JSC::ExecutableBase::isProgramExecutable):
     140        (JSC::ScriptExecutable::ScriptExecutable):
     141        (JSC::ScriptExecutable::endColumn):
     142        (JSC::ScriptExecutable::recordParse):
     143        (JSC::FunctionExecutable::create):
     144        (JSC::FunctionExecutable::bodyIncludesBraces):
     145        * runtime/FunctionConstructor.cpp:
     146        (JSC::constructFunctionSkippingEvalEnabledCheck):
     147        * runtime/FunctionPrototype.cpp:
     148        (JSC::insertSemicolonIfNeeded):
     149        (JSC::functionProtoFuncToString):
     150        * runtime/JSGlobalObject.cpp:
     151        (JSC::JSGlobalObject::createProgramCodeBlock):
     152        (JSC::JSGlobalObject::createEvalCodeBlock):
     153
    11542013-11-19  Dean Jackson  <dino@apple.com>
    2155
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r159394 r159520  
    118118                0F24E54D17EE274900ABB217 /* JITOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54617EE274900ABB217 /* JITOperations.h */; };
    119119                0F24E54E17EE274900ABB217 /* JITOperationWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54717EE274900ABB217 /* JITOperationWrappers.h */; };
    120                 0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54817EE274900ABB217 /* TempRegisterSet.h */; };
     120                0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54817EE274900ABB217 /* TempRegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
    121121                0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E54917EE274900ABB217 /* Repatch.cpp */; };
    122122                0F24E55117EE274900ABB217 /* Repatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54A17EE274900ABB217 /* Repatch.h */; };
     
    10131013                A7BDAECA17F4EA1400F6140C /* JSArrayIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7BDAEC417F4EA1400F6140C /* JSArrayIterator.cpp */; };
    10141014                A7BDAECB17F4EA1400F6140C /* JSArrayIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BDAEC517F4EA1400F6140C /* JSArrayIterator.h */; };
    1015                 A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BFF3BF179868940002F462 /* DFGFiltrationResult.h */; };
     1015                A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BFF3BF179868940002F462 /* DFGFiltrationResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10161016                A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C0C4AB167C08CD0017011D /* JSScriptRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10171017                A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7C0C4AA167C08CD0017011D /* JSScriptRef.cpp */; };
     
    12231223                C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FC9BD216644DFB00810D33 /* CopiedBlockInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12241224                C2FCAE1017A9C24E0034C735 /* BytecodeBasicBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */; };
    1225                 C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */; };
     1225                C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12261226                C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */; };
    1227                 C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */; };
     1227                C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12281228                C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FE18A316BAEC4000AF3061 /* StructureRareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12291229                DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    41784178                                86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
    41794179                                65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
     4180                                0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
     4181                                A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */,
     4182                                C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
     4183                                C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */,
    41804184                                0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */,
    41814185                                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */,
     
    41854189                                BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
    41864190                                0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */,
    4187                                 C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
    41884191                                A7BDAEC717F4EA1400F6140C /* ArrayIteratorConstructor.h in Headers */,
    41894192                                A7BDAEC917F4EA1400F6140C /* ArrayIteratorPrototype.h in Headers */,
     
    43084311                                0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */,
    43094312                                A78A9775179738B8009DF744 /* DFGFailedFinalizer.h in Headers */,
    4310                                 A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */,
    43114313                                A78A9777179738B8009DF744 /* DFGFinalizer.h in Headers */,
    43124314                                0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */,
     
    47804782                                BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */,
    47814783                                BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */,
    4782                                 C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */,
    47834784                                BC18C46A0E16F5CD00B34460 /* StringPrototype.h in Headers */,
    47844785                                142E313B134FF0A600AFADB5 /* Strong.h in Headers */,
     
    47964797                                BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
    47974798                                A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
    4798                                 0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
    47994799                                0FA2C17C17D7CF84009D015F /* TestRunnerUtils.h in Headers */,
    48004800                                0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */,
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r159462 r159520  
    115115    unsigned linkedStartOffset = executable->source().startOffset();
    116116    int delta = linkedStartOffset - unlinkedStartOffset;
    117     unsigned rangeStart = delta + unlinked->functionStartOffset();
     117    unsigned rangeStart = delta + unlinked->unlinkedFunctionNameStart();
    118118    unsigned rangeEnd = delta + unlinked->startOffset() + unlinked->sourceLength();
    119119    return toCString(
     
    16391639        unsigned lineCount = unlinkedExecutable->lineCount();
    16401640        unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
    1641         unsigned startColumn = unlinkedExecutable->functionStartColumn();
    1642         startColumn += (unlinkedExecutable->firstLineOffset() ? 1 : ownerExecutable->startColumn());
     1641        bool startColumnIsOnOwnerStartLine = !unlinkedExecutable->firstLineOffset();
     1642        unsigned startColumn = unlinkedExecutable->unlinkedBodyStartColumn() + (startColumnIsOnOwnerStartLine ? ownerExecutable->startColumn() : 1);
     1643        bool endColumnIsOnStartLine = !lineCount;
     1644        unsigned endColumn = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? startColumn : 1);
    16431645        unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
    16441646        unsigned sourceLength = unlinkedExecutable->sourceLength();
    16451647        SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
    1646         FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn);
     1648        FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumn);
    16471649        m_functionDecls[i].set(*m_vm, ownerExecutable, executable);
    16481650    }
     
    16531655        unsigned lineCount = unlinkedExecutable->lineCount();
    16541656        unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
    1655         unsigned startColumn = unlinkedExecutable->functionStartColumn();
    1656         startColumn += (unlinkedExecutable->firstLineOffset() ? 1 : ownerExecutable->startColumn());
     1657        bool startColumnIsOnOwnerStartLine = !unlinkedExecutable->firstLineOffset();
     1658        unsigned startColumn = unlinkedExecutable->unlinkedBodyStartColumn() + (startColumnIsOnOwnerStartLine ? ownerExecutable->startColumn() : 1);
     1659        bool endColumnIsOnStartLine = !lineCount;
     1660        unsigned endColumn = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? startColumn : 1);
    16571661        unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
    16581662        unsigned sourceLength = unlinkedExecutable->sourceLength();
    16591663        SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
    1660         FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn);
     1664        FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumn);
    16611665        m_functionExprs[i].set(*m_vm, ownerExecutable, executable);
    16621666    }
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp

    r156785 r159520  
    6060        body->setUsesArguments();
    6161    body->finishParsing(executable->parameters(), executable->name(), executable->functionNameIsInScopeToggle());
    62     executable->recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
     62    executable->recordParse(body->features(), body->hasCapturedVariables());
    6363   
    6464    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct));
     
    8181}
    8282
    83 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node)
     83UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode)
    8484    : Base(*vm, structure)
    8585    , m_numCapturedVariables(node->capturedVariableCount())
     
    8787    , m_isInStrictContext(node->isStrictMode())
    8888    , m_hasCapturedVariables(node->hasCapturedVariables())
     89    , m_isFromGlobalCode(isFromGlobalCode)
    8990    , m_name(node->ident())
    9091    , m_inferredName(node->inferredName())
     
    9293    , m_firstLineOffset(node->firstLine() - source.firstLine())
    9394    , m_lineCount(node->lastLine() - node->firstLine())
    94     , m_functionStartOffset(node->functionStart() - source.startOffset())
    95     , m_functionStartColumn(node->startColumn())
     95    , m_unlinkedFunctionNameStart(node->functionNameStart() - source.startOffset())
     96    , m_unlinkedBodyStartColumn(node->startColumn())
     97    , m_unlinkedBodyEndColumn(m_lineCount ? node->endColumn() : node->endColumn() - node->startColumn())
    9698    , m_startOffset(node->source().startOffset() - source.startOffset())
    9799    , m_sourceLength(node->source().length())
     
    124126    unsigned firstLine = lineOffset + m_firstLineOffset;
    125127    unsigned startOffset = sourceOffset + m_startOffset;
    126     unsigned startColumn = m_functionStartColumn + 1; // startColumn should start from 1, not 0.
     128    bool startColumnIsOnFirstSourceLine = !m_firstLineOffset;
     129    unsigned startColumn = m_unlinkedBodyStartColumn + (startColumnIsOnFirstSourceLine ? source.startColumn() : 1);
     130    bool endColumnIsOnStartLine = !m_lineCount;
     131    unsigned endColumn = m_unlinkedBodyEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
    127132    SourceCode code(source.provider(), startOffset, startOffset + m_sourceLength, firstLine, startColumn);
    128     return FunctionExecutable::create(vm, code, this, firstLine, firstLine + m_lineCount, startColumn);
     133    return FunctionExecutable::create(vm, code, this, firstLine, firstLine + m_lineCount, startColumn, endColumn);
    129134}
    130135
     
    132137{
    133138    ParserError error;
    134     CodeCache* codeCache = exec->vm().codeCache();
    135     UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(exec->vm(), name, source, error);
     139    VM& vm = exec->vm();
     140    CodeCache* codeCache = vm.codeCache();
     141    UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error);
    136142
    137143    if (exec->lexicalGlobalObject()->hasDebugger())
     
    205211    , m_firstLine(0)
    206212    , m_lineCount(0)
     213    , m_endColumn(UINT_MAX)
    207214    , m_features(0)
    208215    , m_codeType(codeType)
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r157653 r159520  
    8484    friend class CodeCache;
    8585    typedef JSCell Base;
    86     static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node)
    87     {
    88         UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node);
     86    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode = false)
     87    {
     88        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, isFromGlobalCode);
    8989        instance->finishCreation(*vm);
    9090        return instance;
     
    104104    unsigned firstLineOffset() const { return m_firstLineOffset; }
    105105    unsigned lineCount() const { return m_lineCount; }
    106     unsigned functionStartOffset() const { return m_functionStartOffset; }
    107     unsigned functionStartColumn() const { return m_functionStartColumn; }
     106    unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
     107    unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; }
     108    unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; }
    108109    unsigned startOffset() const { return m_startOffset; }
    109110    unsigned sourceLength() { return m_sourceLength; }
     
    127128    FunctionParameters* parameters() { return m_parameters.get(); }
    128129
    129     void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
     130    void recordParse(CodeFeatures features, bool hasCapturedVariables)
    130131    {
    131132        m_features = features;
    132133        m_hasCapturedVariables = hasCapturedVariables;
    133         m_lineCount = lastLine - firstLine;
    134134    }
    135135
     
    144144
    145145private:
    146     UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*);
     146    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, bool isFromGlobalCode);
    147147    WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
    148148    WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
     
    152152    bool m_isInStrictContext : 1;
    153153    bool m_hasCapturedVariables : 1;
     154    bool m_isFromGlobalCode : 1;
    154155
    155156    Identifier m_name;
     
    161162    unsigned m_firstLineOffset;
    162163    unsigned m_lineCount;
    163     unsigned m_functionStartOffset;
    164     unsigned m_functionStartColumn;
     164    unsigned m_unlinkedFunctionNameStart;
     165    unsigned m_unlinkedBodyStartColumn;
     166    unsigned m_unlinkedBodyEndColumn;
    165167    unsigned m_startOffset;
    166168    unsigned m_sourceLength;
     
    187189    static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
    188190
    189     DECLARE_INFO;
     191    DECLARE_EXPORT_INFO;
    190192};
    191193
     
    442444        int& startOffset, int& endOffset, unsigned& line, unsigned& column);
    443445
    444     void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount)
     446    void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn)
    445447    {
    446448        m_features = features;
     
    448450        m_firstLine = firstLine;
    449451        m_lineCount = lineCount;
     452        // For the UnlinkedCodeBlock, startColumn is always 0.
     453        m_endColumn = endColumn;
    450454    }
    451455
     
    454458    unsigned firstLine() const { return m_firstLine; }
    455459    unsigned lineCount() const { return m_lineCount; }
     460    ALWAYS_INLINE unsigned startColumn() const { return 0; }
     461    unsigned endColumn() const { return m_endColumn; }
    456462
    457463protected:
     
    493499    unsigned m_firstLine;
    494500    unsigned m_lineCount;
     501    unsigned m_endColumn;
    495502
    496503    CodeFeatures m_features;
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r159139 r159520  
    22552255    if (!returnNode) {
    22562256        RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
    2257         ASSERT((startOffset() -  1) >= lineStartOffset());
    2258         generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset() - 1, lineStartOffset());
     2257        ASSERT(startOffset() >= lineStartOffset());
     2258        generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
    22592259        generator.emitReturn(r0);
    22602260        return;
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r157724 r159520  
    284284    }
    285285
    286     FunctionBodyNode* createFunctionBody(const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext)
    287     {
    288         return FunctionBodyNode::create(m_vm, startLocation, endLocation, startColumn, inStrictContext);
    289     }
    290 
    291     void setFunctionStart(FunctionBodyNode* body, int functionStart)
    292     {
    293         body->setFunctionStart(functionStart);
     286    FunctionBodyNode* createFunctionBody(const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
     287    {
     288        return FunctionBodyNode::create(m_vm, startLocation, endLocation, startColumn, endColumn, inStrictContext);
     289    }
     290
     291    void setFunctionNameStart(FunctionBodyNode* body, int functionNameStart)
     292    {
     293        body->setFunctionNameStart(functionNameStart);
    294294    }
    295295   
  • trunk/Source/JavaScriptCore/parser/Lexer.cpp

    r157836 r159520  
    619619    ASSERT(isLineTerminator(m_current));
    620620
     621    m_positionBeforeLastNewline = currentPosition();
    621622    T prev = m_current;
    622623    shift();
     
    18541855}
    18551856
    1856 template <typename T>
    1857 SourceCode Lexer<T>::sourceCode(int openBrace, int closeBrace, int firstLine, unsigned startColumn)
    1858 {
    1859     ASSERT(m_source->provider()->source()[openBrace] == '{');
    1860     ASSERT(m_source->provider()->source()[closeBrace] == '}');
    1861     return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine, startColumn);
    1862 }
    1863 
    18641857// Instantiate the two flavors of Lexer we need instead of putting most of this file in Lexer.h
    18651858template class Lexer<LChar>;
  • trunk/Source/JavaScriptCore/parser/Lexer.h

    r157836 r159520  
    9696        return JSTextPosition(m_lineNumber, currentOffset(), currentLineStartOffset());
    9797    }
     98    JSTextPosition positionBeforeLastNewline() const { return m_positionBeforeLastNewline; }
    9899    void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
    99100    int lastLineNumber() const { return m_lastLineNumber; }
    100101    bool prevTerminator() const { return m_terminator; }
    101     SourceCode sourceCode(int openBrace, int closeBrace, int firstLine, unsigned startColumn);
    102102    bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0);
    103103    bool skipRegExp();
     
    228228    const T* m_codeStartPlusOffset;
    229229    const T* m_lineStart;
     230    JSTextPosition m_positionBeforeLastNewline;
    230231    bool m_isReparsing;
    231232    bool m_atLineStart;
  • trunk/Source/JavaScriptCore/parser/Nodes.cpp

    r156785 r159520  
    115115// ------------------------------ ProgramNode -----------------------------
    116116
    117 inline ProgramNode::ProgramNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
     117inline ProgramNode::ProgramNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    118118    : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
    119119    , m_startColumn(startColumn)
    120 {
    121 }
    122 
    123 PassRefPtr<ProgramNode> ProgramNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    124 {
    125     RefPtr<ProgramNode> node = new ProgramNode(vm, startLocation, endLocation, startColumn, children, varStack, funcStack,  capturedVariables, source, features, numConstants);
     120    , m_endColumn(endColumn)
     121{
     122}
     123
     124PassRefPtr<ProgramNode> ProgramNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
     125{
     126    RefPtr<ProgramNode> node = new ProgramNode(vm, startLocation, endLocation, startColumn, endColumn, children, varStack, funcStack,  capturedVariables, source, features, numConstants);
    126127
    127128    ASSERT(node->m_arena.last() == node);
     
    134135// ------------------------------ EvalNode -----------------------------
    135136
    136 inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
     137inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    137138    : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
    138 {
    139 }
    140 
    141 PassRefPtr<EvalNode> EvalNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    142 {
    143     RefPtr<EvalNode> node = new EvalNode(vm, startLocation, endLocation, children, varStack, funcStack, capturedVariables, source, features, numConstants);
     139    , m_endColumn(endColumn)
     140{
     141}
     142
     143PassRefPtr<EvalNode> EvalNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
     144{
     145    RefPtr<EvalNode> node = new EvalNode(vm, startLocation, endLocation, endColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants);
    144146
    145147    ASSERT(node->m_arena.last() == node);
     
    180182}
    181183
    182 inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext)
     184inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
    183185    : ScopeNode(vm, startLocation, endLocation, inStrictContext)
    184186    , m_startColumn(startColumn)
    185 {
    186 }
    187 
    188 inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
     187    , m_endColumn(endColumn)
     188{
     189}
     190
     191inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
    189192    : ScopeNode(vm, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
    190193    , m_startColumn(startColumn)
     194    , m_endColumn(endColumn)
    191195{
    192196}
     
    206210}
    207211
    208 FunctionBodyNode* FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext)
    209 {
    210     return new FunctionBodyNode(vm, startLocation, endLocation, startColumn, inStrictContext);
    211 }
    212 
    213 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
    214 {
    215     RefPtr<FunctionBodyNode> node = new FunctionBodyNode(vm, startLocation, endLocation, startColumn, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
     212FunctionBodyNode* FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
     213{
     214    return new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn, inStrictContext);
     215}
     216
     217PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
     218{
     219    RefPtr<FunctionBodyNode> node = new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn , children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
    216220
    217221    ASSERT(node->m_arena.last() == node);
     
    222226}
    223227
     228void FunctionBodyNode::setEndPosition(JSTextPosition position)
     229{
     230    m_lastLine = position.line;
     231    m_endColumn = position.offset - position.lineStartOffset;
     232}
     233
    224234} // namespace JSC
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r158473 r159520  
    193193        virtual bool isBlock() const { return false; }
    194194
    195     private:
     195    protected:
    196196        int m_lastLine;
    197197    };
     
    14691469    public:
    14701470        static const bool isFunctionNode = false;
    1471         static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    1472 
    1473         unsigned startColumn() { return m_startColumn; }
     1471        static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
     1472
     1473        unsigned startColumn() const { return m_startColumn; }
     1474        unsigned endColumn() const { return m_endColumn; }
    14741475
    14751476        static const bool scopeIsFunction = false;
    14761477
    14771478    private:
    1478         ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
     1479        ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    14791480
    14801481        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) OVERRIDE;
    14811482
    14821483        unsigned m_startColumn;
     1484        unsigned m_endColumn;
    14831485    };
    14841486
     
    14861488    public:
    14871489        static const bool isFunctionNode = false;
    1488         static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    1489 
    1490         unsigned startColumn() { return 1; }
     1490        static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
     1491
     1492        ALWAYS_INLINE unsigned startColumn() const { return 0; }
     1493        unsigned endColumn() const { return m_endColumn; }
    14911494
    14921495        static const bool scopeIsFunction = false;
    14931496
    14941497    private:
    1495         EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    1496 
    1497         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) OVERRIDE;
     1498        EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
     1499
     1500        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) OVERRIDE;
     1501
     1502        unsigned m_endColumn;
    14981503    };
    14991504
     
    15201525    public:
    15211526        static const bool isFunctionNode = true;
    1522         static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool isStrictMode);
    1523         static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
     1527        static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isStrictMode);
     1528        static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    15241529
    15251530        FunctionParameters* parameters() const { return m_parameters.get(); }
     
    15381543        FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
    15391544
    1540         void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
    1541         int functionStart() const { return m_functionStart; }
     1545        void setFunctionNameStart(int functionNameStart) { m_functionNameStart = functionNameStart; }
     1546        int functionNameStart() const { return m_functionNameStart; }
    15421547        unsigned startColumn() const { return m_startColumn; }
     1548        unsigned endColumn() const { return m_endColumn; }
     1549
     1550        void setEndPosition(JSTextPosition);
    15431551
    15441552        static const bool scopeIsFunction = true;
    15451553
    15461554    private:
    1547         FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool inStrictContext);
    1548         FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
     1555        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool inStrictContext);
     1556        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    15491557
    15501558        Identifier m_ident;
     
    15521560        FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
    15531561        RefPtr<FunctionParameters> m_parameters;
    1554         int m_functionStart;
     1562        int m_functionNameStart;
    15551563        unsigned m_startColumn;
     1564        unsigned m_endColumn;
    15561565    };
    15571566
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r159225 r159520  
    11631163    next();
    11641164
    1165     if (match(CLOSEBRACE))
    1166         return context.createFunctionBody(startLocation, tokenLocation(), startColumn, strictMode());
     1165    if (match(CLOSEBRACE)) {
     1166        unsigned endColumn = tokenColumn();
     1167        return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode());
     1168    }
    11671169    DepthManager statementDepth(&m_statementDepth);
    11681170    m_statementDepth = 0;
    11691171    typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<VM*>(m_vm), m_lexer.get());
    11701172    failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder), "Cannot parse body of this function");
    1171     return context.createFunctionBody(startLocation, tokenLocation(), startColumn, strictMode());
     1173    unsigned endColumn = tokenColumn();
     1174    return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode());
    11721175}
    11731176
     
    11911194    AutoPopScopeRef functionScope(this, pushScope());
    11921195    functionScope->setIsFunction();
    1193     int functionStart = m_token.m_location.startOffset;
     1196    int functionNameStart = m_token.m_location.startOffset;
    11941197    const Identifier* lastFunctionName = m_lastFunctionName;
    11951198    m_lastFunctionName = nullptr;
     
    12321235        endLocation.startOffset = cachedInfo->closeBraceOffset;
    12331236        endLocation.lineStartOffset = cachedInfo->closeBraceLineStartOffset;
     1237
     1238        bool endColumnIsOnStartLine = (endLocation.line == bodyStartLine);
    12341239        ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
    1235 
    1236         body = context.createFunctionBody(startLocation, endLocation, bodyStartColumn, cachedInfo->strictMode);
     1240        unsigned bodyEndColumn = endColumnIsOnStartLine ?
     1241            endLocation.startOffset - m_token.m_data.lineStartOffset :
     1242            endLocation.startOffset - endLocation.lineStartOffset;
     1243
     1244        body = context.createFunctionBody(startLocation, endLocation, bodyStartColumn, bodyEndColumn, cachedInfo->strictMode);
    12371245       
    12381246        functionScope->restoreFromSourceProviderCache(cachedInfo);
     
    12411249        closeBraceOffset = cachedInfo->closeBraceOffset;
    12421250
    1243         context.setFunctionStart(body, functionStart);
     1251        context.setFunctionNameStart(body, functionNameStart);
    12441252        m_token = cachedInfo->closeBraceToken();
    12451253
     
    12711279    if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
    12721280        SourceProviderCacheItemCreationParameters parameters;
    1273         parameters.functionStart = functionStart;
     1281        parameters.functionNameStart = functionNameStart;
    12741282        parameters.closeBraceLine = closeBraceLine;
    12751283        parameters.closeBraceOffset = closeBraceOffset;
     
    12791287
    12801288    }
    1281     context.setFunctionStart(body, functionStart);
     1289    context.setFunctionNameStart(body, functionNameStart);
    12821290   
    12831291    failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r159210 r159520  
    414414    template <class ParsedNode>
    415415    PassRefPtr<ParsedNode> parse(ParserError&);
     416
     417    JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
    416418
    417419private:
     
    882884
    883885    JSTokenLocation startLocation(tokenLocation());
    884     unsigned startColumn = m_source->startColumn();
     886    ASSERT(m_source->startColumn() > 0);
     887    unsigned startColumn = m_source->startColumn() - 1;
    885888
    886889    String parseError = parseInner();
     
    901904    if (m_sourceElements) {
    902905        JSTokenLocation endLocation;
    903         endLocation.line = m_lexer->lastLineNumber();
     906        endLocation.line = m_lexer->lineNumber();
    904907        endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
    905908        endLocation.startOffset = m_lexer->currentOffset();
     909        unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
    906910        result = ParsedNode::create(m_vm,
    907911                                    startLocation,
    908912                                    endLocation,
    909913                                    startColumn,
     914                                    endColumn,
    910915                                    m_sourceElements,
    911916                                    m_varDeclarations ? &m_varDeclarations->data : 0,
     
    915920                                    m_features,
    916921                                    m_numConstants);
    917         result->setLoc(m_source->firstLine(), m_lastTokenEndPosition.line, m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
     922        result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
    918923    } else {
    919924        // We can never see a syntax error when reparsing a function, since we should have
     
    945950
    946951template <class ParsedNode>
    947 PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
     952PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error, JSTextPosition* positionBeforeLastNewline = 0)
    948953{
    949954    SamplingRegion samplingRegion("Parsing");
     
    952957    if (source.provider()->source().is8Bit()) {
    953958        Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode);
    954         return parser.parse<ParsedNode>(error);
     959        RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error);
     960        if (positionBeforeLastNewline)
     961            *positionBeforeLastNewline = parser.positionBeforeLastNewline();
     962        return result.release();
    955963    }
    956964    Parser<Lexer<UChar>> parser(vm, source, parameters, name, strictness, parserMode);
    957     return parser.parse<ParsedNode>(error);
     965    RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error);
     966    if (positionBeforeLastNewline)
     967        *positionBeforeLastNewline = parser.positionBeforeLastNewline();
     968    return result.release();
    958969}
    959970
  • trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h

    r157653 r159520  
    3535
    3636struct SourceProviderCacheItemCreationParameters {
    37     unsigned functionStart;
     37    unsigned functionNameStart;
    3838    unsigned closeBraceLine;
    3939    unsigned closeBraceOffset;
     
    7171    }
    7272
    73     unsigned functionStart : 31;
     73    unsigned functionNameStart : 31;
    7474    bool needsFullActivation : 1;
    7575   
     
    108108
    109109inline SourceProviderCacheItem::SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters& parameters)
    110     : functionStart(parameters.functionStart)
     110    : functionNameStart(parameters.functionNameStart)
    111111    , needsFullActivation(parameters.needsFullActivation)
    112112    , closeBraceLine(parameters.closeBraceLine)
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r157724 r159520  
    154154    ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
    155155    ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return FunctionExpr; }
    156     int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, bool) { return 1; }
    157     void setFunctionStart(int, int) { }
     156    int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool) { return 1; }
     157    void setFunctionNameStart(int, int) { }
    158158    int createArguments() { return 1; }
    159159    int createArguments(int) { return 1; }
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r153221 r159520  
    7676
    7777template <class UnlinkedCodeBlockType, class ExecutableType>
    78 UnlinkedCodeBlockType* CodeCache::getCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
     78UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
    7979{
    8080    SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, strictness);
     
    8282    bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff;
    8383    if (!addResult.isNewEntry && canCache) {
    84         UnlinkedCodeBlockType* unlinkedCode = jsCast<UnlinkedCodeBlockType*>(addResult.iterator->value.cell.get());
    85         unsigned firstLine = source.firstLine() + unlinkedCode->firstLine();
    86         unsigned startColumn = source.firstLine() ? source.startColumn() : 0;
    87         executable->recordParse(unlinkedCode->codeFeatures(), unlinkedCode->hasCapturedVariables(), firstLine, firstLine + unlinkedCode->lineCount(), startColumn);
    88         return unlinkedCode;
     84        UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast<UnlinkedCodeBlockType*>(addResult.iterator->value.cell.get());
     85        unsigned firstLine = source.firstLine() + unlinkedCodeBlock->firstLine();
     86        unsigned lineCount = unlinkedCodeBlock->lineCount();
     87        unsigned startColumn = unlinkedCodeBlock->startColumn() + source.startColumn();
     88        bool endColumnIsOnStartLine = !lineCount;
     89        unsigned endColumn = unlinkedCodeBlock->endColumn() + (endColumnIsOnStartLine ? startColumn : 1);
     90        executable->recordParse(unlinkedCodeBlock->codeFeatures(), unlinkedCodeBlock->hasCapturedVariables(), firstLine, firstLine + lineCount, startColumn, endColumn);
     91        return unlinkedCodeBlock;
    8992    }
    9093
     
    9598        return 0;
    9699    }
    97     executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo(), rootNode->lastLine(), rootNode->startColumn());
     100    unsigned lineCount = rootNode->lastLine() - rootNode->lineNo();
     101    unsigned startColumn = rootNode->startColumn() + 1;
     102    bool endColumnIsOnStartLine = !lineCount;
     103    unsigned unlinkedEndColumn = rootNode->endColumn();
     104    unsigned endColumn = unlinkedEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
     105    executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo(), rootNode->lastLine(), startColumn, endColumn);
    98106
    99     UnlinkedCodeBlockType* unlinkedCode = UnlinkedCodeBlockType::create(&vm, executable->executableInfo());
    100     unlinkedCode->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo() - source.firstLine(), rootNode->lastLine() - rootNode->lineNo());
    101     OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, rootNode.get(), unlinkedCode, debuggerMode, profilerMode)));
     107    UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo());
     108    unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo() - source.firstLine(), lineCount, unlinkedEndColumn);
     109
     110    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode)));
    102111    error = generator->generate();
    103112    rootNode->destroyData();
     
    109118    if (!canCache) {
    110119        m_sourceCode.remove(addResult.iterator);
    111         return unlinkedCode;
     120        return unlinkedCodeBlock;
    112121    }
    113122
    114     addResult.iterator->value = SourceCodeValue(vm, unlinkedCode, m_sourceCode.age());
    115     return unlinkedCode;
     123    addResult.iterator->value = SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age());
     124    return unlinkedCodeBlock;
    116125}
    117126
    118127UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
    119128{
    120     return getCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, strictness, debuggerMode, profilerMode, error);
     129    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, strictness, debuggerMode, profilerMode, error);
    121130}
    122131
    123132UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
    124133{
    125     return getCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictness, debuggerMode, profilerMode, error);
     134    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictness, debuggerMode, profilerMode, error);
    126135}
    127136
     
    133142        return jsCast<UnlinkedFunctionExecutable*>(addResult.iterator->value.cell.get());
    134143
    135     RefPtr<ProgramNode> program = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
     144    JSTextPosition positionBeforeLastNewline;
     145    RefPtr<ProgramNode> program = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error, &positionBeforeLastNewline);
    136146    if (!program) {
    137147        ASSERT(error.m_type != ParserError::ErrorNone);
     
    148158    RELEASE_ASSERT(funcExpr->isFuncExprNode());
    149159    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
     160    body->setEndPosition(positionBeforeLastNewline);
    150161    ASSERT(body);
    151162    ASSERT(body->ident().isNull());
    152163
    153     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body);
     164    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body, true);
    154165    functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
    155166
  • trunk/Source/JavaScriptCore/runtime/CodeCache.h

    r153221 r159520  
    254254
    255255    template <class UnlinkedCodeBlockType, class ExecutableType>
    256     UnlinkedCodeBlockType* getCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
     256    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
    257257
    258258    CodeCacheMap m_sourceCode;
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r158459 r159520  
    181181
    182182    ASSERT(vm->heap.isDeferred());
    183    
     183    ASSERT(startColumn() != UINT_MAX);
     184    ASSERT(endColumn() != UINT_MAX);
     185
    184186    if (classInfo() == EvalExecutable::info()) {
    185187        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
     
    210212        executable->m_unlinkedExecutable->codeBlockFor(
    211213            *vm, executable->m_source, kind, debuggerMode, profilerMode, error);
    212     recordParse(executable->m_unlinkedExecutable->features(), executable->m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn());
     214    recordParse(executable->m_unlinkedExecutable->features(), executable->m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn(), endColumn());
    213215    if (!unlinkedCodeBlock) {
    214216        exception = vm->throwException(
     
    363365const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
    364366
    365 FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn)
     367FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces)
    366368    : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext())
    367369    , m_unlinkedExecutable(vm, this, unlinkedExecutable)
     370    , m_bodyIncludesBraces(bodyIncludesBraces)
    368371{
    369372    RELEASE_ASSERT(!source.isNull());
     
    371374    m_firstLine = firstLine;
    372375    m_lastLine = lastLine;
     376    ASSERT(startColumn != UINT_MAX);
     377    ASSERT(endColumn != UINT_MAX);
    373378    m_startColumn = startColumn;
     379    m_endColumn = endColumn;
    374380}
    375381
     
    455461
    456462    JSObject* exception = 0;
    457     UnlinkedProgramCodeBlock* unlinkedCode = globalObject->createProgramCodeBlock(callFrame, this, &exception);
     463    UnlinkedProgramCodeBlock* unlinkedCodeBlock = globalObject->createProgramCodeBlock(callFrame, this, &exception);
    458464    if (exception)
    459465        return exception;
    460466
    461     m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCode);
     467    m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock);
    462468
    463469    BatchedTransitionOptimizer optimizer(vm, globalObject);
    464470
    465     const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCode->variableDeclarations();
    466     const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCode->functionDeclarations();
     471    const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
     472    const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCodeBlock->functionDeclarations();
    467473
    468474    for (size_t i = 0; i < functionDeclarations.size(); ++i) {
     
    565571FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
    566572{
    567     UnlinkedFunctionExecutable* unlinkedFunction = UnlinkedFunctionExecutable::fromGlobalCode(name, exec, debugger, source, exception);
    568     if (!unlinkedFunction)
     573    UnlinkedFunctionExecutable* unlinkedExecutable = UnlinkedFunctionExecutable::fromGlobalCode(name, exec, debugger, source, exception);
     574    if (!unlinkedExecutable)
    569575        return 0;
    570     unsigned firstLine = source.firstLine() + unlinkedFunction->firstLineOffset();
    571     unsigned startOffset = source.startOffset() + unlinkedFunction->startOffset();
    572     unsigned startColumn = source.startColumn();
    573     unsigned sourceLength = unlinkedFunction->sourceLength();
    574     SourceCode functionSource(source.provider(), startOffset, startOffset + sourceLength, firstLine, startColumn);
    575     return FunctionExecutable::create(exec->vm(), functionSource, unlinkedFunction, firstLine, unlinkedFunction->lineCount(), startColumn);
     576    unsigned lineCount = unlinkedExecutable->lineCount();
     577    unsigned firstLine = source.firstLine() + unlinkedExecutable->firstLineOffset();
     578    unsigned startOffset = source.startOffset() + unlinkedExecutable->startOffset();
     579
     580    // We don't have any owner executable. The source string is effectively like a global
     581    // string (like in the handling of eval). Hence, the startColumn is always 1.
     582    unsigned startColumn = 1;
     583    unsigned sourceLength = unlinkedExecutable->sourceLength();
     584    bool endColumnIsOnStartLine = !lineCount;
     585    // The unlinkedBodyEndColumn is based-0. Hence, we need to add 1 to it. But if the
     586    // endColumn is on the startLine, then we need to subtract back the adjustment for
     587    // the open brace resulting in an adjustment of 0.
     588    unsigned endColumnExcludingBraces = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? 0 : 1);
     589    unsigned startOffsetExcludingOpenBrace = startOffset + 1;
     590    unsigned endOffsetExcludingCloseBrace = startOffset + sourceLength - 1;
     591    SourceCode bodySource(source.provider(), startOffsetExcludingOpenBrace, endOffsetExcludingCloseBrace, firstLine, startColumn);
     592
     593    return FunctionExecutable::create(exec->vm(), bodySource, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumnExcludingBraces, false);
    576594}
    577595
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r158681 r159520  
    9494    CodeBlockHash hashFor(CodeSpecializationKind) const;
    9595
     96    bool isEvalExecutable()
     97    {
     98        return structure()->typeInfo().type() == EvalExecutableType;
     99    }
    96100    bool isFunctionExecutable()
    97101    {
    98102        return structure()->typeInfo().type() == FunctionExecutableType;
     103    }
     104    bool isProgramExecutable()
     105    {
     106        return structure()->typeInfo().type() == ProgramExecutableType;
    99107    }
    100108
     
    356364        , m_features(isInStrictContext ? StrictModeFeature : 0)
    357365        , m_neverInline(false)
     366        , m_startColumn(UINT_MAX)
     367        , m_endColumn(UINT_MAX)
    358368    {
    359369    }
     
    364374        , m_features(isInStrictContext ? StrictModeFeature : 0)
    365375        , m_neverInline(false)
     376        , m_startColumn(UINT_MAX)
     377        , m_endColumn(UINT_MAX)
    366378    {
    367379    }
     
    379391    int lastLine() const { return m_lastLine; }
    380392    unsigned startColumn() const { return m_startColumn; }
     393    unsigned endColumn() const { return m_endColumn; }
    381394
    382395    bool usesEval() const { return m_features & EvalFeature; }
     
    396409    DECLARE_INFO;
    397410
    398     void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn)
     411    void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn, unsigned endColumn)
    399412    {
    400413        m_features = features;
     
    402415        m_firstLine = firstLine;
    403416        m_lastLine = lastLine;
     417        ASSERT(startColumn != UINT_MAX);
    404418        m_startColumn = startColumn;
     419        ASSERT(endColumn != UINT_MAX);
     420        m_endColumn = endColumn;
    405421    }
    406422
     
    438454    int m_lastLine;
    439455    unsigned m_startColumn;
     456    unsigned m_endColumn;
    440457};
    441458
     
    550567    typedef ScriptExecutable Base;
    551568
    552     static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn)
    553     {
    554         FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn);
     569    static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces = true)
     570    {
     571        FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn, endColumn, bodyIncludesBraces);
    555572        executable->finishCreation(vm);
    556573        return executable;
     
    639656    void clearCode();
    640657
     658    bool bodyIncludesBraces() const { return m_bodyIncludesBraces; }
     659
    641660private:
    642     FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
     661    FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces);
    643662
    644663    bool isCompiling()
     
    659678    RefPtr<FunctionCodeBlock> m_codeBlockForCall;
    660679    RefPtr<FunctionCodeBlock> m_codeBlockForConstruct;
     680    bool m_bodyIncludesBraces;
    661681};
    662682
  • trunk/Source/JavaScriptCore/runtime/FunctionConstructor.cpp

    r156624 r159520  
    9494    String program;
    9595    if (args.isEmpty())
    96         program = ASCIILiteral("(function() { \n})");
     96        program = ASCIILiteral("(function() {\n})");
    9797    else if (args.size() == 1)
    98         program = makeString("(function() { ", args.at(0).toString(exec)->value(exec), "\n})");
     98        program = makeString("(function() {", args.at(0).toString(exec)->value(exec), "\n})");
    9999    else {
    100100        StringBuilder builder;
     
    105105            builder.append(args.at(i).toString(exec)->value(exec));
    106106        }
    107         builder.appendLiteral(") { ");
     107        builder.appendLiteral(") {");
    108108        builder.append(args.at(args.size() - 1).toString(exec)->value(exec));
    109109        builder.appendLiteral("\n})");
  • trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp

    r156624 r159520  
    8686
    8787// Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.)
    88 static inline void insertSemicolonIfNeeded(String& functionBody)
    89 {
     88static inline void insertSemicolonIfNeeded(String& functionBody, bool bodyIncludesBraces)
     89{
     90    if (!bodyIncludesBraces)
     91        functionBody = makeString("{ ", functionBody, "}");
     92
    9093    ASSERT(functionBody[0] == '{');
    9194    ASSERT(functionBody[functionBody.length() - 1] == '}');
     
    110113        FunctionExecutable* executable = function->jsExecutable();
    111114        String sourceString = executable->source().toString();
    112         insertSemicolonIfNeeded(sourceString);
     115        insertSemicolonIfNeeded(sourceString, executable->bodyIncludesBraces());
    113116        return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
    114117    }
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r159395 r159520  
    739739    DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
    740740    ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
    741     UnlinkedProgramCodeBlock* unlinkedCode = vm().codeCache()->getProgramCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
     741    UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getProgramCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
    742742
    743743    if (hasDebugger())
     
    749749    }
    750750   
    751     return unlinkedCode;
     751    return unlinkedCodeBlock;
    752752}
    753753
     
    758758    DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
    759759    ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
    760     UnlinkedEvalCodeBlock* unlinkedCode = vm().codeCache()->getEvalCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
     760    UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
    761761
    762762    if (hasDebugger())
     
    768768    }
    769769
    770     return unlinkedCode;
     770    return unlinkedCodeBlock;
    771771}
    772772
  • trunk/Source/WebCore/ChangeLog

    r159519 r159520  
     12013-11-19  Mark Lam  <mark.lam@apple.com>
     2
     3        Add tracking of endColumn for Executables.
     4        https://bugs.webkit.org/show_bug.cgi?id=124245.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Test: js/dom/script-start-end-locations.html
     9
     10        * ForwardingHeaders/bytecode: Added.
     11        * ForwardingHeaders/bytecode/CodeBlock.h: Added.
     12        * WebCore.exp.in:
     13        * testing/Internals.cpp:
     14        (WebCore::GetCallerCodeBlockFunctor::GetCallerCodeBlockFunctor):
     15        (WebCore::GetCallerCodeBlockFunctor::operator()):
     16        (WebCore::GetCallerCodeBlockFunctor::codeBlock):
     17        (WebCore::Internals::parserMetaData):
     18        * testing/Internals.h:
     19        * testing/Internals.idl:
     20
    1212013-11-15  Jer Noble  <jer.noble@apple.com>
    222
  • trunk/Source/WebCore/WebCore.exp.in

    r159511 r159520  
    825825__ZN7WebCore22RuntimeEnabledFeatures14sharedFeaturesEv
    826826__ZN7WebCore22ScriptExecutionContext26canSuspendActiveDOMObjectsEv
     827__ZN7WebCore22ScriptExecutionContext2vmEv
    827828__ZN7WebCore22StorageEventDispatcher34dispatchLocalStorageEventsToFramesERNS_9PageGroupERKN3WTF6VectorINS3_6RefPtrINS_5FrameEEELm0ENS3_15CrashOnOverflowEEERKNS3_6StringESE_SE_SE_PNS_14SecurityOriginE
    828829__ZN7WebCore22URLWithUserTypedStringEP8NSStringP5NSURL
  • trunk/Source/WebCore/testing/Internals.cpp

    r159188 r159520  
    9696#include "ViewportArguments.h"
    9797#include "WorkerThread.h"
     98#include <bytecode/CodeBlock.h>
     99#include <runtime/JSCJSValue.h>
    98100#include <wtf/text/CString.h>
    99101#include <wtf/text/StringBuffer.h>
     
    158160#include "MockMediaPlayerMediaSource.h"
    159161#endif
     162
     163using JSC::CodeBlock;
     164using JSC::FunctionExecutable;
     165using JSC::JSFunction;
     166using JSC::JSValue;
     167using JSC::ScriptExecutable;
     168using JSC::StackVisitor;
    160169
    161170namespace WebCore {
     
    12511260    inspectorController->didCancelFrame();
    12521261#endif
     1262}
     1263
     1264class GetCallerCodeBlockFunctor {
     1265public:
     1266    GetCallerCodeBlockFunctor()
     1267        : m_iterations(0)
     1268        , m_codeBlock(0)
     1269    {
     1270    }
     1271
     1272    StackVisitor::Status operator()(StackVisitor& visitor)
     1273    {
     1274        ++m_iterations;
     1275        if (m_iterations < 2)
     1276            return StackVisitor::Continue;
     1277
     1278        m_codeBlock = visitor->codeBlock();
     1279        return StackVisitor::Done;
     1280    }
     1281
     1282    CodeBlock* codeBlock() const { return m_codeBlock; }
     1283
     1284private:
     1285    int m_iterations;
     1286    CodeBlock* m_codeBlock;
     1287};
     1288
     1289String Internals::parserMetaData(ScriptValue value)
     1290{
     1291    JSC::VM* vm = contextDocument()->vm();
     1292    JSC::ExecState* exec = vm->topCallFrame;
     1293    JSC::JSValue code = value.jsValue();
     1294    ScriptExecutable* executable;
     1295
     1296    if (!code || code.isNull() || code.isUndefined()) {
     1297        GetCallerCodeBlockFunctor iter;
     1298        exec->iterate(iter);
     1299        CodeBlock* codeBlock = iter.codeBlock();
     1300        executable = codeBlock->ownerExecutable();
     1301    } else if (code.isFunction()) {
     1302        JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
     1303        executable = funcObj->jsExecutable();
     1304    } else
     1305        return String();
     1306
     1307    unsigned startLine = executable->lineNo();
     1308    unsigned startColumn = executable->startColumn();
     1309    unsigned endLine = executable->lastLine();
     1310    unsigned endColumn = executable->endColumn();
     1311
     1312    StringBuilder result;
     1313
     1314    if (executable->isFunctionExecutable()) {
     1315        FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
     1316        String inferredName = funcExecutable->inferredName().string();
     1317        result.append("function \"");
     1318        result.append(inferredName);
     1319        result.append("\"");
     1320    } else if (executable->isEvalExecutable())
     1321        result.append("eval");
     1322    else {
     1323        ASSERT(executable->isProgramExecutable());
     1324        result.append("program");
     1325    }
     1326
     1327    result.append(" { ");
     1328    result.appendNumber(startLine);
     1329    result.append(":");
     1330    result.appendNumber(startColumn);
     1331    result.append(" - ");
     1332    result.appendNumber(endLine);
     1333    result.append(":");
     1334    result.appendNumber(endColumn);
     1335    result.append(" }");
     1336
     1337    return result.toString();
    12531338}
    12541339
  • trunk/Source/WebCore/testing/Internals.h

    r158853 r159520  
    3232#include "ExceptionCodePlaceholder.h"
    3333#include "NodeList.h"
     34#include "ScriptValue.h"
    3435#include <runtime/ArrayBuffer.h>
    3536#include <runtime/Float32Array.h>
     
    181182    void emitInspectorDidCancelFrame();
    182183
     184    String parserMetaData(ScriptValue = ScriptValue());
     185
    183186    bool hasSpellingMarker(int from, int length, ExceptionCode&);
    184187    bool hasGrammarMarker(int from, int length, ExceptionCode&);
  • trunk/Source/WebCore/testing/Internals.idl

    r158853 r159520  
    139139    void emitInspectorDidCancelFrame();
    140140
     141    // Calling parserMetaData() with no arguments gets the metadata for the script of the current scope.
     142    DOMString parserMetaData(optional any func);
     143
    141144    [RaisesException] boolean hasSpellingMarker(long from, long length);
    142145    [RaisesException] boolean hasGrammarMarker(long from, long length);
  • trunk/Source/WebKit/ChangeLog

    r159485 r159520  
     12013-11-19  Mark Lam  <mark.lam@apple.com>
     2
     3        Add tracking of endColumn for Executables.
     4        https://bugs.webkit.org/show_bug.cgi?id=124245.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
     9        - Added an exported symbol to make the Win32 build happy. The Win64 symbol
     10          is currently a copy of the Win32 one. It'll need to be updated if the
     11          mangled symbol is different for Win64.
     12
    1132013-11-18  Mark Rowe  <mrowe@apple.com>
    214
  • trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in

    r159073 r159520  
    463463        symbolWithPointer(?cacheStorage@WebCore@@YAAAVApplicationCacheStorage@1@XZ, ?cacheStorage@WebCore@@YAAEAVApplicationCacheStorage@1@XZ)
    464464        symbolWithPointer(?setDefaultOriginQuota@ApplicationCacheStorage@WebCore@@QAEX_J@Z, ?setDefaultOriginQuota@ApplicationCacheStorage@WebCore@@QEAAX_J@Z)
     465        symbolWithPointer(?vm@ScriptExecutionContext@WebCore@@QAEPAVVM@JSC@@XZ, ?vm@ScriptExecutionContext@WebCore@@QAEPAVVM@JSC@@XZ)
Note: See TracChangeset for help on using the changeset viewer.