<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[198042] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/198042">198042</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2016-03-11 13:08:08 -0800 (Fri, 11 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Implement Function.name and Function#toString for ES6 class.
https://bugs.webkit.org/show_bug.cgi?id=155336

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

The only thing that the ES6 spec says about toString with regards to class
objects is:

&quot;The string representation must have the syntax of a FunctionDeclaration,
FunctionExpression, GeneratorDeclaration, GeneratorExpression, ClassDeclaration,
ClassExpression, ArrowFunction, MethodDefinition, or GeneratorMethod depending
upon the actual characteristics of the object.&quot;

Previously, invoking toString() on a class object will return the function
source string of the class' constructor function.  This does not conform to the
spec in that the toString string for a class does not have the syntax of a
ClassDeclaration or ClassExpression.

This is now fixed by doing the following:

1. Added &quot;m_classSource&quot; to FunctionExecutable (and correspondingly to
   UnlinkedFunctionExecutable, FunctionMetadataNode, and ClassExprNode).
   m_classSource is the SourceCode for the code range &quot;class ... { ... }&quot;.

   Since the class constructor function is the in memory representation of the
   class object, only class constructor functions will have its m_classSource
   set.  m_classSource will be &quot;null&quot; (by default) for all other functions.
   This is how we know if a FunctionExecutable is for a class.

   Note: FunctionExecutable does not have its own m_classSource.  It always gets
   it from its UnlinkedFunctionExecutable.  This is ok to do because our CodeCache
   currently does not cache UnlinkedFunctionExecutables for class constructors.

2. The ClassExprNode now tracks the SourceCode range for the class expression.
   This is used to set m_classSource in the UnlinkedFunctionExecutable at
   bytecode generation time, and the FunctionExecutable later at bytecode
   linking time.

3. Function.prototype.toString() now checks if the function is for a class.
   If so, it returns the string for the class source instead of just the
   function source for the class constructor.

   Note: the class source is static from the time the class was parsed.  This
   can introduces some weirdness at runtime.  Consider the following:

       var v1 = class {}
       v1.toString(); // yields &quot;class {}&quot;.

       class c2 extends v1 {}

       c2.__proto__ === v1; // yields true i.e. c2 extends v1.
       c2.toString(); // yields &quot;class c2 extends v1 {}&quot; which is fine.

       v1 = {}; // point v1 to something else now.

       c2.__proto__ === v1; // now yields false i.e. c2 no longer extends v1.
                            // c2 actually extends the class that v1 used to
                            // point to, but ...
       c2.toString(); // still yields &quot;class c2 extends v1 {}&quot; which is no longer true.

   It is unclear how we can best implement toString() to avoid this issue.
   The above behavior is how Chrome (Version 51.0.2671.0 canary (64-bit))
   currently implements toString() of a class, and we do the same in this patch.
   In Firefox (45.0), toString() of a class will yield the function source of it
   constructor function, which is not better.

In this patch, we also added ES6 compliance for Function.name on class objects:

4. The ClassExprNode now has a m_ecmaName string for tracking the inferred
   name of a class according to the ES6 spec.  The ASTBuilder now mirrors its
   handling of FuncExprNodes to ClassExprNodes in setting the nodes' m_ecmaName
   where relevant.

   The m_ecmaName is later used to set the m_ecmaName of the FunctionExecutable
   of the class constructor, which in turn is used to populate the initial value
   of the Function.name property.

5. Also renamed some variable names (/m_metadata/metadata/) to be consistent with
   webkit naming convention.

* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
(JSC::BytecodeGenerator::emitNewDefaultConstructor):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ClassExprNode::emitBytecode):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createAssignResolve):
(JSC::ASTBuilder::createYield):
(JSC::ASTBuilder::createClassExpr):
(JSC::ASTBuilder::createFunctionExpr):
(JSC::ASTBuilder::createProperty):
(JSC::ASTBuilder::makeAssignNode):
* parser/NodeConstructors.h:
(JSC::FunctionParameters::FunctionParameters):
(JSC::BaseFuncExprNode::BaseFuncExprNode):
(JSC::FuncExprNode::FuncExprNode):
(JSC::FuncDeclNode::FuncDeclNode):
(JSC::ArrowFuncExprNode::ArrowFuncExprNode):
(JSC::ClassDeclNode::ClassDeclNode):
(JSC::ClassExprNode::ClassExprNode):
* parser/Nodes.h:
(JSC::ExpressionNode::isDestructuringNode):
(JSC::ExpressionNode::isFuncExprNode):
(JSC::ExpressionNode::isArrowFuncExprNode):
(JSC::ExpressionNode::isClassExprNode):
(JSC::ExpressionNode::isCommaNode):
(JSC::ExpressionNode::isSimpleArray):
(JSC::ExpressionNode::isAdd):
* parser/Parser.cpp:
(JSC::stringForFunctionMode):
(JSC::Parser&lt;LexerType&gt;::parseFunctionInfo):
(JSC::Parser&lt;LexerType&gt;::parseClass):
* parser/ParserFunctionInfo.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createEmptyLetExpression):
(JSC::SyntaxChecker::createYield):
(JSC::SyntaxChecker::createClassExpr):
(JSC::SyntaxChecker::createFunctionExpr):
(JSC::SyntaxChecker::createFunctionMetadata):
(JSC::SyntaxChecker::createArrowFunctionExpr):
* runtime/Executable.cpp:
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::FunctionExecutable::finishCreation):
* runtime/Executable.h:
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
* tests/es6.yaml:

LayoutTests:

* js/class-syntax-name-expected.txt:
* js/script-tests/class-syntax-name.js:
(shouldBe):
(shouldBeTrue):
- Rebased expected result.

* js/function-toString-vs-name.html:
* js/script-tests/function-toString-vs-name.js:
- Added new tests for class.

* platform/mac/inspector/model/remote-object-expected.txt:
- Rebased expected result.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsclasssyntaxnameexpectedtxt">trunk/LayoutTests/js/class-syntax-name-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsfunctiontoStringvsnamehtml">trunk/LayoutTests/js/function-toString-vs-name.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsclasssyntaxnamejs">trunk/LayoutTests/js/script-tests/class-syntax-name.js</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsfunctiontoStringvsnamejs">trunk/LayoutTests/js/script-tests/function-toString-vs-name.js</a></li>
<li><a href="#trunkLayoutTestsplatformmacinspectormodelremoteobjectexpectedtxt">trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutablecpp">trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutableh">trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserASTBuilderh">trunk/Source/JavaScriptCore/parser/ASTBuilder.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserNodeConstructorsh">trunk/Source/JavaScriptCore/parser/NodeConstructors.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserNodesh">trunk/Source/JavaScriptCore/parser/Nodes.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParsercpp">trunk/Source/JavaScriptCore/parser/Parser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParserFunctionInfoh">trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSyntaxCheckerh">trunk/Source/JavaScriptCore/parser/SyntaxChecker.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutableh">trunk/Source/JavaScriptCore/runtime/Executable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeFunctionPrototypecpp">trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoretestses6yaml">trunk/Source/JavaScriptCore/tests/es6.yaml</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/LayoutTests/ChangeLog        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-03-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Implement Function.name and Function#toString for ES6 class.
+        https://bugs.webkit.org/show_bug.cgi?id=155336
+
+        Reviewed by Geoffrey Garen.
+
+        * js/class-syntax-name-expected.txt:
+        * js/script-tests/class-syntax-name.js:
+        (shouldBe):
+        (shouldBeTrue):
+        - Rebased expected result.
+
+        * js/function-toString-vs-name.html:
+        * js/script-tests/function-toString-vs-name.js:
+        - Added new tests for class.
+
+        * platform/mac/inspector/model/remote-object-expected.txt:
+        - Rebased expected result.
+
</ins><span class="cx"> 2016-03-11  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking imported/blink/fast/multicol/dynamic/multicol-with-abspos-svg-with-foreignobject-with-multicol-crash.html as flaky
</span></span></pre></div>
<a id="trunkLayoutTestsjsclasssyntaxnameexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/class-syntax-name-expected.txt (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/class-syntax-name-expected.txt        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/LayoutTests/js/class-syntax-name-expected.txt        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -12,24 +12,24 @@
</span><span class="cx"> PASS 'use strict'; class { constructor() {} }:::SyntaxError: Class statements must have a name.
</span><span class="cx"> PASS class A { constructor() {} }
</span><span class="cx"> PASS 'use strict'; class A { constructor() {} }
</span><del>-PASS class A { constructor() {} }; A.toString():::'function A() {}'
-PASS 'use strict'; class A { constructor() {} }; A.toString():::'function A() {}'
</del><ins>+PASS class A { constructor() {} }; A.toString():::'class A { constructor() {} }'
+PASS 'use strict'; class A { constructor() {} }; A.toString():::'class A { constructor() {} }'
</ins><span class="cx"> PASS class A { constructor() {} }; (new A) instanceof A
</span><span class="cx"> PASS 'use strict'; class A { constructor() {} }; (new A) instanceof A
</span><del>-PASS class A { constructor() { this.base = A; } }; (new A).base.toString():::'function A() { this.base = A; }'
-PASS 'use strict'; class A { constructor() { this.base = A; } }; (new A).base.toString():::'function A() { this.base = A; }'
</del><ins>+PASS class A { constructor() { this.base = A; } }; (new A).base.toString():::'class A { constructor() { this.base = A; } }'
+PASS 'use strict'; class A { constructor() { this.base = A; } }; (new A).base.toString():::'class A { constructor() { this.base = A; } }'
</ins><span class="cx"> PASS class A { constructor() {} }; class B extends A {};
</span><span class="cx"> PASS 'use strict'; class A { constructor() {} }; class B extends A {};
</span><del>-PASS class A { constructor() {} }; class B extends A { constructor() {} }; B.toString():::'function B() {}'
-PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() {} }; B.toString():::'function B() {}'
</del><ins>+PASS class A { constructor() {} }; class B extends A { constructor() {} }; B.toString():::'class B extends A { constructor() {} }'
+PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() {} }; B.toString():::'class B extends A { constructor() {} }'
</ins><span class="cx"> PASS class A { constructor() {} }; class B extends A {}; (new B) instanceof A
</span><span class="cx"> PASS 'use strict'; class A { constructor() {} }; class B extends A {}; (new B) instanceof A
</span><span class="cx"> PASS class A { constructor() {} }; class B extends A {}; (new B) instanceof B
</span><span class="cx"> PASS 'use strict'; class A { constructor() {} }; class B extends A {}; (new B) instanceof B
</span><del>-PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString():::'function A() {}'
-PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString():::'function A() {}'
-PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
-PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
</del><ins>+PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString():::'class A { constructor() {} }'
+PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString():::'class A { constructor() {} }'
+PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString():::'class B extends A { constructor() { super(); this.base = A; this.derived = B; } }'
+PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString():::'class B extends A { constructor() { super(); this.base = A; this.derived = B; } }'
</ins><span class="cx"> 
</span><span class="cx"> Class expression
</span><span class="cx"> PASS A:::ReferenceError: Can't find variable: A
</span><span class="lines">@@ -52,8 +52,8 @@
</span><span class="cx"> PASS 'use strict'; typeof (new (class A {})):::&quot;object&quot;
</span><span class="cx"> PASS (new (class A { constructor() { this.base = A; } })).base
</span><span class="cx"> PASS 'use strict'; (new (class A { constructor() { this.base = A; } })).base
</span><del>-PASS (new (class A { constructor() { this.base = A; } })).base.toString():::&quot;function A() { this.base = A; }&quot;
-PASS 'use strict'; (new (class A { constructor() { this.base = A; } })).base.toString():::&quot;function A() { this.base = A; }&quot;
</del><ins>+PASS (new (class A { constructor() { this.base = A; } })).base.toString():::&quot;class A { constructor() { this.base = A; } }&quot;
+PASS 'use strict'; (new (class A { constructor() { this.base = A; } })).base.toString():::&quot;class A { constructor() { this.base = A; } }&quot;
</ins><span class="cx"> PASS class A {}; (class B extends A {})
</span><span class="cx"> PASS 'use strict'; class A {}; (class B extends A {})
</span><span class="cx"> PASS class A {}; (class B extends A {}); B:::ReferenceError: Can't find variable: B
</span><span class="lines">@@ -64,36 +64,36 @@
</span><span class="cx"> PASS 'use strict'; class A {}; new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })
</span><span class="cx"> PASS class A {}; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })) instanceof A
</span><span class="cx"> PASS 'use strict'; class A {}; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })) instanceof A
</span><del>-PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString():::'function A() {}'
-PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString():::'function A() {}'
-PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
-PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
</del><ins>+PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString():::'class A { constructor() {} }'
+PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString():::'class A { constructor() {} }'
+PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString():::'class B extends A { constructor() { super(); this.base = A; this.derived = B; } }'
+PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString():::'class B extends A { constructor() { super(); this.base = A; this.derived = B; } }'
</ins><span class="cx"> 
</span><span class="cx"> Class expression assignment to variable
</span><span class="cx"> PASS A:::ReferenceError: Can't find variable: A
</span><span class="cx"> PASS 'use strict'; A:::ReferenceError: Can't find variable: A
</span><span class="cx"> PASS var VarA = class {}
</span><span class="cx"> PASS 'use strict'; var VarA = class {}
</span><del>-PASS var VarA = class { constructor() {} }; VarA.toString():::'function () {}'
-PASS 'use strict'; var VarA = class { constructor() {} }; VarA.toString():::'function () {}'
</del><ins>+PASS var VarA = class { constructor() {} }; VarA.toString():::'class { constructor() {} }'
+PASS 'use strict'; var VarA = class { constructor() {} }; VarA.toString():::'class { constructor() {} }'
</ins><span class="cx"> PASS VarA:::ReferenceError: Can't find variable: VarA
</span><span class="cx"> PASS 'use strict'; VarA:::ReferenceError: Can't find variable: VarA
</span><span class="cx"> PASS var VarA = class A { constructor() {} }
</span><span class="cx"> PASS 'use strict'; var VarA = class A { constructor() {} }
</span><del>-PASS var VarA = class A { constructor() {} }; VarA.toString():::'function A() {}'
-PASS 'use strict'; var VarA = class A { constructor() {} }; VarA.toString():::'function A() {}'
</del><ins>+PASS var VarA = class A { constructor() {} }; VarA.toString():::'class A { constructor() {} }'
+PASS 'use strict'; var VarA = class A { constructor() {} }; VarA.toString():::'class A { constructor() {} }'
</ins><span class="cx"> PASS var VarA = class A { constructor() {} }; A.toString():::ReferenceError: Can't find variable: A
</span><span class="cx"> PASS 'use strict'; var VarA = class A { constructor() {} }; A.toString():::ReferenceError: Can't find variable: A
</span><span class="cx"> PASS var VarA = class A { constructor() {} }; (new VarA) instanceof VarA
</span><span class="cx"> PASS 'use strict'; var VarA = class A { constructor() {} }; (new VarA) instanceof VarA
</span><del>-PASS var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString():::'function A() { this.base = A; }'
-PASS 'use strict'; var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString():::'function A() { this.base = A; }'
</del><ins>+PASS var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString():::'class A { constructor() { this.base = A; } }'
+PASS 'use strict'; var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString():::'class A { constructor() { this.base = A; } }'
</ins><span class="cx"> PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} };
</span><span class="cx"> PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} };
</span><span class="cx"> PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; B:::ReferenceError: Can't find variable: B
</span><span class="cx"> PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; B:::ReferenceError: Can't find variable: B
</span><del>-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString():::'function B() {}'
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString():::'function B() {}'
</del><ins>+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString():::'class B extends VarA { constructor() {} }'
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString():::'class B extends VarA { constructor() {} }'
</ins><span class="cx"> PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarA
</span><span class="cx"> PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarA
</span><span class="cx"> PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarB
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx"> PASS 'use strict'; class A {}; var result = A; result
</span><span class="cx"> PASS eval('var Foo = 10'); Foo:::10
</span><span class="cx"> PASS 'use strict'; eval('var Foo = 10'); Foo:::ReferenceError: Can't find variable: Foo
</span><del>-PASS eval('class Bar { constructor() {} }; Bar.toString()');:::'function Bar() {}'
</del><ins>+PASS eval('class Bar { constructor() {} }; Bar.toString()');:::'class Bar { constructor() {} }'
</ins><span class="cx"> PASS 'use strict'; eval('class Bar { constructor() {} }'); Bar.toString():::ReferenceError: Can't find variable: Bar
</span><span class="cx"> PASS successfullyParsed
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsjsfunctiontoStringvsnamehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/function-toString-vs-name.html (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/function-toString-vs-name.html        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/LayoutTests/js/function-toString-vs-name.html        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -5,6 +5,46 @@
</span><span class="cx"> &lt;/head&gt;
</span><span class="cx"> &lt;body&gt;
</span><span class="cx"> &lt;script src=&quot;script-tests/function-toString-vs-name.js&quot;&gt;&lt;/script&gt;
</span><ins>+
+&lt;script&gt;
+failures = &quot;&quot;;
+
+section = &quot;global class statements with identical class bodies from different scripts&quot;;
+&lt;/script&gt;
+&lt;!-- Case 1: A global class statement: --&gt;
+    &lt;script&gt;class globalClass1 { constructor(x) { return x; } stuff() { return 5; } }&lt;/script&gt;
+
+&lt;!-- Case 2: Same class body as Case 1 but indented. --&gt;
+        &lt;script&gt;class globalClass2 { constructor(x) { return x; } stuff() { return 5; } }&lt;/script&gt;
+
+&lt;!-- Case 3: Same class body indented on the same line. --&gt;
+&lt;script&gt;class globalClass3 { constructor(x) { return x; } stuff() { return 5; } }&lt;/script&gt;
+
+&lt;script&gt;
+section = &quot;global class expressions with identical class bodies from different scripts&quot;;
+&lt;/script&gt;
+&lt;!-- Case 1: A global class expression: --&gt;
+    &lt;script&gt;var globalClassExpr1 = class { constructor(x) { return x; } stuff() { return 5; } }&lt;/script&gt;
+
+&lt;!-- Case 2: Same class body as Case 1 but indented. --&gt;
+        &lt;script&gt;var globalClassExpr2 = class { constructor(x) { return x; } stuff() { return 5; } }&lt;/script&gt;
+
+&lt;!-- Case 3: Same class body indented on the same line. --&gt;
+&lt;script&gt;var globalClassExpr3 = class { constructor(x) { return x; } stuff() { return 5; } }&lt;/script&gt;
+
+&lt;script&gt;
+test(globalClass1, &quot;globalClass1&quot;, &quot;class globalClass1 { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalClass2, &quot;globalClass2&quot;, &quot;class globalClass2 { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalClass3, &quot;globalClass3&quot;, &quot;class globalClass3 { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+
+test(globalClassExpr1, &quot;globalClassExpr1&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalClassExpr2, &quot;globalClassExpr2&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalClassExpr3, &quot;globalClassExpr3&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+
+if (failureCount)
+    throw Error(&quot;Found &quot; + failureCount + &quot; failures:\n&quot; + failures);
+&lt;/script&gt;
+
</ins><span class="cx"> &lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsclasssyntaxnamejs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/class-syntax-name.js (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/class-syntax-name.js        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/LayoutTests/js/script-tests/class-syntax-name.js        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -68,15 +68,15 @@
</span><span class="cx"> runTestShouldThrow(&quot;class {}&quot;);
</span><span class="cx"> runTestShouldThrow(&quot;class { constructor() {} }&quot;);
</span><span class="cx"> runTestShouldNotThrow(&quot;class A { constructor() {} }&quot;);
</span><del>-runTestShouldBe(&quot;class A { constructor() {} }; A.toString()&quot;, &quot;'function A() {}'&quot;);
</del><ins>+runTestShouldBe(&quot;class A { constructor() {} }; A.toString()&quot;, &quot;'class A { constructor() {} }'&quot;);
</ins><span class="cx"> runTestShouldBeTrue(&quot;class A { constructor() {} }; (new A) instanceof A&quot;);
</span><del>-runTestShouldBe(&quot;class A { constructor() { this.base = A; } }; (new A).base.toString()&quot;, &quot;'function A() { this.base = A; }'&quot;);
</del><ins>+runTestShouldBe(&quot;class A { constructor() { this.base = A; } }; (new A).base.toString()&quot;, &quot;'class A { constructor() { this.base = A; } }'&quot;);
</ins><span class="cx"> runTestShouldNotThrow(&quot;class A { constructor() {} }; class B extends A {};&quot;);
</span><del>-runTestShouldBe(&quot;class A { constructor() {} }; class B extends A { constructor() {} }; B.toString()&quot;, &quot;'function B() {}'&quot;);
</del><ins>+runTestShouldBe(&quot;class A { constructor() {} }; class B extends A { constructor() {} }; B.toString()&quot;, &quot;'class B extends A { constructor() {} }'&quot;);
</ins><span class="cx"> runTestShouldBeTrue(&quot;class A { constructor() {} }; class B extends A {}; (new B) instanceof A&quot;);
</span><span class="cx"> runTestShouldBeTrue(&quot;class A { constructor() {} }; class B extends A {}; (new B) instanceof B&quot;);
</span><del>-runTestShouldBe(&quot;class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString()&quot;, &quot;'function A() {}'&quot;);
-runTestShouldBe(&quot;class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString()&quot;, &quot;'function B() { super(); this.base = A; this.derived = B; }'&quot;);
</del><ins>+runTestShouldBe(&quot;class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString()&quot;, &quot;'class A { constructor() {} }'&quot;);
+runTestShouldBe(&quot;class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString()&quot;, &quot;'class B extends A { constructor() { super(); this.base = A; this.derived = B; } }'&quot;);
</ins><span class="cx"> 
</span><span class="cx"> // Class expression. Class name not added to scope. Class name is available inside class scope.
</span><span class="cx"> debug(''); debug('Class expression');
</span><span class="lines">@@ -90,29 +90,29 @@
</span><span class="cx"> runTestShouldNotThrow(&quot;new (class A {})&quot;);
</span><span class="cx"> runTestShouldBe(&quot;typeof (new (class A {}))&quot;, '&quot;object&quot;');
</span><span class="cx"> runTestShouldNotThrow(&quot;(new (class A { constructor() { this.base = A; } })).base&quot;);
</span><del>-runTestShouldBe(&quot;(new (class A { constructor() { this.base = A; } })).base.toString()&quot;, '&quot;function A() { this.base = A; }&quot;');
</del><ins>+runTestShouldBe(&quot;(new (class A { constructor() { this.base = A; } })).base.toString()&quot;, '&quot;class A { constructor() { this.base = A; } }&quot;');
</ins><span class="cx"> runTestShouldNotThrow(&quot;class A {}; (class B extends A {})&quot;);
</span><span class="cx"> runTestShouldThrow(&quot;class A {}; (class B extends A {}); B&quot;);
</span><span class="cx"> runTestShouldNotThrow(&quot;class A {}; new (class B extends A {})&quot;);
</span><span class="cx"> runTestShouldNotThrow(&quot;class A {}; new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })&quot;);
</span><span class="cx"> runTestShouldBeTrue(&quot;class A {}; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })) instanceof A&quot;);
</span><del>-runTestShouldBe(&quot;class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString()&quot;, &quot;'function A() {}'&quot;);
-runTestShouldBe(&quot;class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString()&quot;, &quot;'function B() { super(); this.base = A; this.derived = B; }'&quot;);
</del><ins>+runTestShouldBe(&quot;class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString()&quot;, &quot;'class A { constructor() {} }'&quot;);
+runTestShouldBe(&quot;class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString()&quot;, &quot;'class B extends A { constructor() { super(); this.base = A; this.derived = B; } }'&quot;);
</ins><span class="cx"> 
</span><span class="cx"> // Assignment of a class expression to a variable. Variable name available in scope, class name is not. Class name is available inside class scope.
</span><span class="cx"> debug(''); debug('Class expression assignment to variable');
</span><span class="cx"> runTestShouldThrow(&quot;A&quot;);
</span><span class="cx"> runTestShouldNotThrow(&quot;var VarA = class {}&quot;);
</span><del>-runTestShouldBe(&quot;var VarA = class { constructor() {} }; VarA.toString()&quot;, &quot;'function () {}'&quot;);
</del><ins>+runTestShouldBe(&quot;var VarA = class { constructor() {} }; VarA.toString()&quot;, &quot;'class { constructor() {} }'&quot;);
</ins><span class="cx"> runTestShouldThrow(&quot;VarA&quot;);
</span><span class="cx"> runTestShouldNotThrow(&quot;var VarA = class A { constructor() {} }&quot;);
</span><del>-runTestShouldBe(&quot;var VarA = class A { constructor() {} }; VarA.toString()&quot;, &quot;'function A() {}'&quot;);
</del><ins>+runTestShouldBe(&quot;var VarA = class A { constructor() {} }; VarA.toString()&quot;, &quot;'class A { constructor() {} }'&quot;);
</ins><span class="cx"> runTestShouldThrow(&quot;var VarA = class A { constructor() {} }; A.toString()&quot;);
</span><span class="cx"> runTestShouldBeTrue(&quot;var VarA = class A { constructor() {} }; (new VarA) instanceof VarA&quot;);
</span><del>-runTestShouldBe(&quot;var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString()&quot;, &quot;'function A() { this.base = A; }'&quot;);
</del><ins>+runTestShouldBe(&quot;var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString()&quot;, &quot;'class A { constructor() { this.base = A; } }'&quot;);
</ins><span class="cx"> runTestShouldNotThrow(&quot;var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} };&quot;);
</span><span class="cx"> runTestShouldThrow(&quot;var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; B&quot;);
</span><del>-runTestShouldBe(&quot;var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString()&quot;, &quot;'function B() {}'&quot;);
</del><ins>+runTestShouldBe(&quot;var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString()&quot;, &quot;'class B extends VarA { constructor() {} }'&quot;);
</ins><span class="cx"> runTestShouldBeTrue(&quot;var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarA&quot;);
</span><span class="cx"> runTestShouldBeTrue(&quot;var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarB&quot;);
</span><span class="cx"> runTestShouldBeTrue(&quot;var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).base === VarA&quot;);
</span><span class="lines">@@ -128,5 +128,5 @@
</span><span class="cx"> runTestShouldNotThrow(&quot;class A {}; var result = A; result&quot;);
</span><span class="cx"> shouldBe(&quot;eval('var Foo = 10'); Foo&quot;, &quot;10&quot;);
</span><span class="cx"> shouldThrow(&quot;'use strict'; eval('var Foo = 10'); Foo&quot;);
</span><del>-shouldBe(&quot;eval('class Bar { constructor() {} }; Bar.toString()');&quot;, &quot;'function Bar() {}'&quot;);
</del><ins>+shouldBe(&quot;eval('class Bar { constructor() {} }; Bar.toString()');&quot;, &quot;'class Bar { constructor() {} }'&quot;);
</ins><span class="cx"> shouldThrow(&quot;'use strict'; eval('class Bar { constructor() {} }'); Bar.toString()&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsfunctiontoStringvsnamejs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/function-toString-vs-name.js (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/function-toString-vs-name.js        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/LayoutTests/js/script-tests/function-toString-vs-name.js        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -218,6 +218,306 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+section = &quot;class from statement&quot;;
+(function () {
+    class foo {}
+    class bar {}
+    class bax { static name() {} }
+    let baz = bar;
+    class goo extends foo {}
+
+    test(foo, &quot;foo&quot;, &quot;class foo {}&quot;);
+    test(bar, &quot;bar&quot;, &quot;class bar {}&quot;);
+    shouldBe(&quot;typeof bax.name of &quot;, &quot;bax&quot;, typeof bax.name, &quot;function&quot;);
+    shouldBe(&quot;toString of &quot;, &quot;bax&quot;, bax.toString(), &quot;class bax { static name() {} }&quot;);
+    test(baz, &quot;bar&quot;, &quot;class bar {}&quot;);
+    test(goo, &quot;goo&quot;, &quot;class goo extends foo {}&quot;);
+
+    section = &quot;bound class from statement&quot;;
+    {
+        let bound1 = foo.bind({});
+        test(bound1, &quot;bound foo&quot;, &quot;function foo() { [native code] }&quot;);
+        let bound2 = bar.bind({});
+        test(bound2, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound3 = bax.bind({});
+        test(bound3, &quot;bound &quot;, &quot;function() { [native code] }&quot;); // bax.name is not a string.
+        let bound4 = baz.bind({});
+        test(bound4, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound5 = goo.bind({});
+        test(bound5, &quot;bound goo&quot;, &quot;function goo() { [native code] }&quot;);
+    }
+})();
+
+section = &quot;class with constructor from statement&quot;;
+(function () {
+    class foo { constructor(x) {} }
+    class bar { constructor() {} }
+    class bax { static name() {} constructor() {} }
+    let baz = bar;
+    class goo extends foo { constructor() { super(5); } }
+
+    test(foo, &quot;foo&quot;, &quot;class foo { constructor(x) {} }&quot;);
+    test(bar, &quot;bar&quot;, &quot;class bar { constructor() {} }&quot;);
+    shouldBe(&quot;typeof bax.name of &quot;, &quot;bax&quot;, typeof bax.name, &quot;function&quot;);
+    shouldBe(&quot;toString of &quot;, &quot;bax&quot;, bax.toString(), &quot;class bax { static name() {} constructor() {} }&quot;);
+    test(baz, &quot;bar&quot;, &quot;class bar { constructor() {} }&quot;);
+    test(goo, &quot;goo&quot;, &quot;class goo extends foo { constructor() { super(5); } }&quot;);
+
+    section = &quot;bound class with constructor from statement&quot;;
+    {
+        let bound1 = foo.bind({});
+        test(bound1, &quot;bound foo&quot;, &quot;function foo() { [native code] }&quot;);
+        let bound2 = bar.bind({});
+        test(bound2, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound3 = bax.bind({});
+        test(bound3, &quot;bound &quot;, &quot;function() { [native code] }&quot;); // bax.name is not a string.
+        let bound4 = baz.bind({});
+        test(bound4, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound5 = goo.bind({});
+        test(bound5, &quot;bound goo&quot;, &quot;function goo() { [native code] }&quot;);
+    }
+})();
+
+section = &quot;class from expression&quot;;
+(function () {
+    let foo = class namedFoo {}
+    let bar = class {}
+    let bax = class { static name() {} }
+    let baz = bar;
+    let goo = class extends foo {}
+
+    test(foo, &quot;namedFoo&quot;, &quot;class namedFoo {}&quot;);
+    test(bar, &quot;bar&quot;, &quot;class {}&quot;);
+    shouldBe(&quot;typeof bax.name of &quot;, &quot;bax&quot;, typeof bax.name, &quot;function&quot;);
+    shouldBe(&quot;toString of &quot;, &quot;bax&quot;, bax.toString(), &quot;class { static name() {} }&quot;);
+    test(baz, &quot;bar&quot;, &quot;class {}&quot;);
+    test(goo, &quot;goo&quot;, &quot;class extends foo {}&quot;);
+
+    section = &quot;bound class from expression&quot;;
+    {
+        let bound1 = foo.bind({});
+        test(bound1, &quot;bound namedFoo&quot;, &quot;function namedFoo() { [native code] }&quot;);
+        let bound2 = bar.bind({});
+        test(bound2, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound3 = bax.bind({});
+        test(bound3, &quot;bound &quot;, &quot;function() { [native code] }&quot;); // bax.name is not a string.
+        let bound4 = baz.bind({});
+        test(bound4, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound5 = goo.bind({});
+        test(bound5, &quot;bound goo&quot;, &quot;function goo() { [native code] }&quot;);
+    }
+})();
+
+section = &quot;class with constructor from expression&quot;;
+(function () {
+    let foo = class namedFoo { constructor(x) {} }
+    let bar = class { constructor() {} }
+    let bax = class { static name() {} constructor() {} }
+    let baz = bar;
+    let goo = class extends foo { constructor() { super(x) } }
+
+    test(foo, &quot;namedFoo&quot;, &quot;class namedFoo { constructor(x) {} }&quot;);
+    test(bar, &quot;bar&quot;, &quot;class { constructor() {} }&quot;);
+    shouldBe(&quot;typeof bax.name of &quot;, &quot;bax&quot;, typeof bax.name, &quot;function&quot;);
+    shouldBe(&quot;toString of &quot;, &quot;bax&quot;, bax.toString(), &quot;class { static name() {} constructor() {} }&quot;);
+    test(baz, &quot;bar&quot;, &quot;class { constructor() {} }&quot;);
+    test(goo, &quot;goo&quot;, &quot;class extends foo { constructor() { super(x) } }&quot;);
+
+    section = &quot;bound class with constructor from expression&quot;;
+    {
+        let bound1 = foo.bind({});
+        test(bound1, &quot;bound namedFoo&quot;, &quot;function namedFoo() { [native code] }&quot;);
+        let bound2 = bar.bind({});
+        test(bound2, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound3 = bax.bind({});
+        test(bound3, &quot;bound &quot;, &quot;function() { [native code] }&quot;); // bax.name is not a string.
+        let bound4 = baz.bind({});
+        test(bound4, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound5 = goo.bind({});
+        test(bound5, &quot;bound goo&quot;, &quot;function goo() { [native code] }&quot;);
+    }
+})();
+
+section = &quot;class in object property&quot;;
+(function () {
+    class gooBase {}
+    let o = {
+        foo: class {},
+        bar: class {},
+        bax: class { static name() {} },
+        goo: class extends gooBase {},
+    };
+    o.bay = o.bar;
+    o.baz = class {};
+
+    test(o.foo, &quot;foo&quot;, &quot;class {}&quot;);
+    test(o.bar, &quot;bar&quot;, &quot;class {}&quot;);
+    shouldBe(&quot;typeof o.bax.name of &quot;, &quot;o.bax&quot;, typeof o.bax.name, &quot;function&quot;);
+    shouldBe(&quot;toString of &quot;, &quot;o.bax&quot;, o.bax.toString(), &quot;class { static name() {} }&quot;);
+    test(o.bay, &quot;bar&quot;, &quot;class {}&quot;);
+    test(o.baz, &quot;&quot;, &quot;class {}&quot;);
+    test(o.goo, &quot;goo&quot;, &quot;class extends gooBase {}&quot;);
+
+    section = &quot;bound class in object property&quot;;
+    {
+        let bound1 = o.foo.bind({});
+        test(bound1, &quot;bound foo&quot;, &quot;function foo() { [native code] }&quot;);
+        let bound2 = o.bar.bind({});
+        test(bound2, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound3 = o.bax.bind({});
+        test(bound3, &quot;bound &quot;, &quot;function() { [native code] }&quot;); // bax.name is not a string.
+        let bound4 = o.bay.bind({});
+        test(bound4, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound5 = o.baz.bind({});
+        test(bound5, &quot;bound &quot;, &quot;function() { [native code] }&quot;);
+        let bound6 = o.goo.bind({});
+        test(bound6, &quot;bound goo&quot;, &quot;function goo() { [native code] }&quot;);
+    }
+})();
+
+section = &quot;class with constructor in object property&quot;;
+(function () {
+    class gooBase { constructor(x) {} }
+    let o = {
+        foo: class { constructor(x) {} },
+        bar: class { constructor() {} },
+        bax: class { static name() {} constructor() {} },
+        goo: class extends gooBase { constructor() { super(5); } },
+    };
+    o.bay = o.bar;
+    o.baz = class { constructor() {} };
+
+    test(o.foo, &quot;foo&quot;, &quot;class { constructor(x) {} }&quot;);
+    test(o.bar, &quot;bar&quot;, &quot;class { constructor() {} }&quot;);
+    shouldBe(&quot;typeof o.bax.name of &quot;, &quot;o.bax&quot;, typeof o.bax.name, &quot;function&quot;);
+    shouldBe(&quot;toString of &quot;, &quot;o.bax&quot;, o.bax.toString(), &quot;class { static name() {} constructor() {} }&quot;);
+    test(o.bay, &quot;bar&quot;, &quot;class { constructor() {} }&quot;);
+    test(o.baz, &quot;&quot;, &quot;class { constructor() {} }&quot;);
+    test(o.goo, &quot;goo&quot;, &quot;class extends gooBase { constructor() { super(5); } }&quot;);
+
+    section = &quot;bound class with constructor in object property&quot;;
+    {
+        let bound1 = o.foo.bind({});
+        test(bound1, &quot;bound foo&quot;, &quot;function foo() { [native code] }&quot;);
+        let bound2 = o.bar.bind({});
+        test(bound2, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound3 = o.bax.bind({});
+        test(bound3, &quot;bound &quot;, &quot;function() { [native code] }&quot;); // bax.name is not a string.
+        let bound4 = o.bay.bind({});
+        test(bound4, &quot;bound bar&quot;, &quot;function bar() { [native code] }&quot;);
+        let bound5 = o.baz.bind({});
+        test(bound5, &quot;bound &quot;, &quot;function() { [native code] }&quot;);
+        let bound6 = o.goo.bind({});
+        test(bound6, &quot;bound goo&quot;, &quot;function goo() { [native code] }&quot;);
+    }
+})();
+
+section = &quot;global class statement&quot;;
+// Checking if there are CodeCache badness that can result from global class statements
+// with identical bodies.
+class globalCS1 { constructor(x) { return x; } stuff() { return 5; } }
+// Identical class body as CS1.
+class globalCS2 { constructor(x) { return x; } stuff() { return 5; } }
+// Identical constructor as CS2 &amp; CS1, but different otherwise.
+class globalCS3 { constructor(x) { return x; } stuff3() { return 15; } }
+
+test(globalCS1, &quot;globalCS1&quot;, &quot;class globalCS1 { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalCS2, &quot;globalCS2&quot;, &quot;class globalCS2 { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalCS3, &quot;globalCS3&quot;, &quot;class globalCS3 { constructor(x) { return x; } stuff3() { return 15; } }&quot;);
+
+section = &quot;global class expression&quot;;
+// Checking if there are CodeCache badness that can result from global class expressions
+// with identical bodies.
+var globalCE1 = class { constructor(x) { return x; } stuff() { return 5; } }
+// Identical class body as CSE1.
+var globalCE2 = class { constructor(x) { return x; } stuff() { return 5; } }
+// Identical constructor as CSE2 &amp; CSE1, but different otherwise.
+var globalCE3 = class { constructor(x) { return x; } stuff3() { return 15; } }
+
+test(globalCE1, &quot;globalCE1&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalCE2, &quot;globalCE2&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+test(globalCE3, &quot;globalCE3&quot;, &quot;class { constructor(x) { return x; } stuff3() { return 15; } }&quot;);
+
+section = &quot;class statements in eval&quot;;
+// Checking if there are CodeCache badness that can result from class statements in
+// identical eval statements.
+(function () {
+    let body1 = &quot;class foo { constructor(x) { return x; } stuff() { return 5; } }&quot;;
+    // Identical class body as body1.
+    let body2 = &quot;class foo { constructor(x) { return x; } stuff() { return 5; } }&quot;;
+    // Identical constructor as body1 &amp; body2, but different otherwise.
+    let body3 = &quot;class foo3 { constructor(x) { return x; } stuff3() { return 15; } }&quot;;
+
+    let bar1 = eval(body1);
+    let bar2 = eval(body2);
+    let bar3 = eval(body3);
+    let bar4 = eval(body1);
+
+    test(bar1, &quot;foo&quot;, &quot;class foo { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar2, &quot;foo&quot;, &quot;class foo { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar3, &quot;foo3&quot;, &quot;class foo3 { constructor(x) { return x; } stuff3() { return 15; } }&quot;);
+    test(bar4, &quot;foo&quot;, &quot;class foo { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+})();
+
+section = &quot;class expressions in eval&quot;;
+// Checking if there are CodeCache badness that can result from class expressions in
+// identical eval statements.
+(function () {
+    let body1 = &quot;var foo = class { constructor(x) { return x; } stuff() { return 5; } }; foo&quot;;
+    // Identical class body as body1.
+    let body2 = &quot;var foo = class { constructor(x) { return x; } stuff() { return 5; } }; foo&quot;;
+    // Identical constructor as body1 &amp; body2, but different otherwise.
+    let body3 = &quot;var foo3 = class { constructor(x) { return x; } stuff3() { return 15; } }; foo3&quot;;
+
+    let bar1 = eval(body1);
+    let bar2 = eval(body2);
+    let bar3 = eval(body3);
+    let bar4 = eval(body1);
+
+    test(bar1, &quot;foo&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar2, &quot;foo&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar3, &quot;foo3&quot;, &quot;class { constructor(x) { return x; } stuff3() { return 15; } }&quot;);
+    test(bar4, &quot;foo&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+})();
+
+section = &quot;class statements in dynamically created Functions&quot;;
+// Checking if there are CodeCache badness that can result from dynamically created
+// Function objects with class statements in identical bodies.
+(function () {
+    let body1 = &quot;class foo { constructor(x) { return x; } stuff() { return 5; } } return foo;&quot;;
+    // Identical class body as body1.
+    let body2 = &quot;class foo { constructor(x) { return x; } stuff() { return 5; } } return foo;&quot;;
+    // Identical constructor as body1 &amp; body2, but different otherwise.
+    let body3 = &quot;class foo3 { constructor(x) { return x; } stuff3() { return 15; } } return foo3;&quot;;
+
+    let bar1 = new Function(body1);
+    let bar2 = new Function(body2);
+    let bar3 = new Function(body3);
+
+    test(bar1(), &quot;foo&quot;, &quot;class foo { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar2(), &quot;foo&quot;, &quot;class foo { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar3(), &quot;foo3&quot;, &quot;class foo3 { constructor(x) { return x; } stuff3() { return 15; } }&quot;);
+})();
+
+section = &quot;class expressions in dynamically created Functions&quot;;
+// Checking if there are CodeCache badness that can result from dynamically created
+// Function objects with class expressions in identical bodies.
+(function () {
+    let body1 = &quot;var foo = class { constructor(x) { return x; } stuff() { return 5; } }; return foo;&quot;;
+    // Identical class body as body1.
+    let body2 = &quot;var foo = class { constructor(x) { return x; } stuff() { return 5; } }; return foo;&quot;;
+    // Identical constructor as body1 &amp; body2, but different otherwise.
+    let body3 = &quot;var foo3 = class { constructor(x) { return x; } stuff3() { return 15; } }; return foo3;&quot;;
+
+    let bar1 = new Function(body1);
+    let bar2 = new Function(body2);
+    let bar3 = new Function(body3);
+
+    test(bar1(), &quot;foo&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar2(), &quot;foo&quot;, &quot;class { constructor(x) { return x; } stuff() { return 5; } }&quot;);
+    test(bar3(), &quot;foo3&quot;, &quot;class { constructor(x) { return x; } stuff3() { return 15; } }&quot;);
+})();
+
</ins><span class="cx"> // FIXME: Uncomment these when we've added support for Function.name of computed properties.
</span><span class="cx"> // section = &quot;Object computed string property&quot;;
</span><span class="cx"> // {
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacinspectormodelremoteobjectexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -4748,7 +4748,7 @@
</span><span class="cx">     &quot;_objectId&quot;: &quot;&lt;filtered&gt;&quot;,
</span><span class="cx">     &quot;_description&quot;: &quot;Person&quot;
</span><span class="cx">   },
</span><del>-  &quot;_functionDescription&quot;: &quot;function Person(name){}&quot;
</del><ins>+  &quot;_functionDescription&quot;: &quot;class Person { constructor(name){} get fullName(){} methodName(p1, p2){} }&quot;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> -----------------------------------------------------
</span><span class="lines">@@ -4771,7 +4771,7 @@
</span><span class="cx">     &quot;_objectId&quot;: &quot;&lt;filtered&gt;&quot;,
</span><span class="cx">     &quot;_description&quot;: &quot;B&quot;
</span><span class="cx">   },
</span><del>-  &quot;_functionDescription&quot;: &quot;function B() { super(...arguments); }&quot;
</del><ins>+  &quot;_functionDescription&quot;: &quot;class B extends Alpha { methodB(){} }&quot;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> -----------------------------------------------------
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,3 +1,137 @@
</span><ins>+2016-03-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Implement Function.name and Function#toString for ES6 class.
+        https://bugs.webkit.org/show_bug.cgi?id=155336
+
+        Reviewed by Geoffrey Garen.
+
+        The only thing that the ES6 spec says about toString with regards to class
+        objects is:
+
+        &quot;The string representation must have the syntax of a FunctionDeclaration,
+        FunctionExpression, GeneratorDeclaration, GeneratorExpression, ClassDeclaration,
+        ClassExpression, ArrowFunction, MethodDefinition, or GeneratorMethod depending
+        upon the actual characteristics of the object.&quot;
+
+        Previously, invoking toString() on a class object will return the function
+        source string of the class' constructor function.  This does not conform to the
+        spec in that the toString string for a class does not have the syntax of a
+        ClassDeclaration or ClassExpression.
+
+        This is now fixed by doing the following:
+
+        1. Added &quot;m_classSource&quot; to FunctionExecutable (and correspondingly to
+           UnlinkedFunctionExecutable, FunctionMetadataNode, and ClassExprNode).
+           m_classSource is the SourceCode for the code range &quot;class ... { ... }&quot;.
+
+           Since the class constructor function is the in memory representation of the
+           class object, only class constructor functions will have its m_classSource
+           set.  m_classSource will be &quot;null&quot; (by default) for all other functions.
+           This is how we know if a FunctionExecutable is for a class.
+
+           Note: FunctionExecutable does not have its own m_classSource.  It always gets
+           it from its UnlinkedFunctionExecutable.  This is ok to do because our CodeCache
+           currently does not cache UnlinkedFunctionExecutables for class constructors.
+
+        2. The ClassExprNode now tracks the SourceCode range for the class expression.
+           This is used to set m_classSource in the UnlinkedFunctionExecutable at
+           bytecode generation time, and the FunctionExecutable later at bytecode
+           linking time.
+
+        3. Function.prototype.toString() now checks if the function is for a class.
+           If so, it returns the string for the class source instead of just the
+           function source for the class constructor.
+
+           Note: the class source is static from the time the class was parsed.  This
+           can introduces some weirdness at runtime.  Consider the following:
+
+               var v1 = class {}
+               v1.toString(); // yields &quot;class {}&quot;.
+
+               class c2 extends v1 {}
+
+               c2.__proto__ === v1; // yields true i.e. c2 extends v1.
+               c2.toString(); // yields &quot;class c2 extends v1 {}&quot; which is fine.
+
+               v1 = {}; // point v1 to something else now.
+
+               c2.__proto__ === v1; // now yields false i.e. c2 no longer extends v1.
+                                    // c2 actually extends the class that v1 used to
+                                    // point to, but ...
+               c2.toString(); // still yields &quot;class c2 extends v1 {}&quot; which is no longer true.
+
+           It is unclear how we can best implement toString() to avoid this issue.
+           The above behavior is how Chrome (Version 51.0.2671.0 canary (64-bit))
+           currently implements toString() of a class, and we do the same in this patch.
+           In Firefox (45.0), toString() of a class will yield the function source of it
+           constructor function, which is not better.
+
+        In this patch, we also added ES6 compliance for Function.name on class objects:
+
+        4. The ClassExprNode now has a m_ecmaName string for tracking the inferred
+           name of a class according to the ES6 spec.  The ASTBuilder now mirrors its
+           handling of FuncExprNodes to ClassExprNodes in setting the nodes' m_ecmaName
+           where relevant.
+
+           The m_ecmaName is later used to set the m_ecmaName of the FunctionExecutable
+           of the class constructor, which in turn is used to populate the initial value
+           of the Function.name property.
+
+        5. Also renamed some variable names (/m_metadata/metadata/) to be consistent with
+           webkit naming convention.
+
+        * bytecode/UnlinkedFunctionExecutable.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedFunctionExecutable.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
+        (JSC::BytecodeGenerator::emitNewDefaultConstructor):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ClassExprNode::emitBytecode):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createAssignResolve):
+        (JSC::ASTBuilder::createYield):
+        (JSC::ASTBuilder::createClassExpr):
+        (JSC::ASTBuilder::createFunctionExpr):
+        (JSC::ASTBuilder::createProperty):
+        (JSC::ASTBuilder::makeAssignNode):
+        * parser/NodeConstructors.h:
+        (JSC::FunctionParameters::FunctionParameters):
+        (JSC::BaseFuncExprNode::BaseFuncExprNode):
+        (JSC::FuncExprNode::FuncExprNode):
+        (JSC::FuncDeclNode::FuncDeclNode):
+        (JSC::ArrowFuncExprNode::ArrowFuncExprNode):
+        (JSC::ClassDeclNode::ClassDeclNode):
+        (JSC::ClassExprNode::ClassExprNode):
+        * parser/Nodes.h:
+        (JSC::ExpressionNode::isDestructuringNode):
+        (JSC::ExpressionNode::isFuncExprNode):
+        (JSC::ExpressionNode::isArrowFuncExprNode):
+        (JSC::ExpressionNode::isClassExprNode):
+        (JSC::ExpressionNode::isCommaNode):
+        (JSC::ExpressionNode::isSimpleArray):
+        (JSC::ExpressionNode::isAdd):
+        * parser/Parser.cpp:
+        (JSC::stringForFunctionMode):
+        (JSC::Parser&lt;LexerType&gt;::parseFunctionInfo):
+        (JSC::Parser&lt;LexerType&gt;::parseClass):
+        * parser/ParserFunctionInfo.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createEmptyLetExpression):
+        (JSC::SyntaxChecker::createYield):
+        (JSC::SyntaxChecker::createClassExpr):
+        (JSC::SyntaxChecker::createFunctionExpr):
+        (JSC::SyntaxChecker::createFunctionMetadata):
+        (JSC::SyntaxChecker::createArrowFunctionExpr):
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::FunctionExecutable):
+        (JSC::FunctionExecutable::finishCreation):
+        * runtime/Executable.h:
+        * runtime/FunctionPrototype.cpp:
+        (JSC::functionProtoFuncToString):
+        * tests/es6.yaml:
+
</ins><span class="cx"> 2016-03-11  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r197994.
</span><span class="lines">@@ -579,7 +713,6 @@
</span><span class="cx">         (noAssign): Deleted.
</span><span class="cx">         (catch): Deleted.
</span><span class="cx"> 
</span><del>-&gt;&gt;&gt;&gt;&gt;&gt;&gt; .r197960
</del><span class="cx"> 2016-03-08  Skachkov Oleksandr  &lt;gskachkov@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         How we load new.target in arrow functions is broken
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2015 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2012-2013, 2015-2016 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -105,6 +105,7 @@
</span><span class="cx">     , m_ecmaName(node-&gt;ecmaName())
</span><span class="cx">     , m_inferredName(node-&gt;inferredName())
</span><span class="cx">     , m_sourceOverride(WTFMove(sourceOverride))
</span><ins>+    , m_classSource(node-&gt;classSource())
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_constructorKind == static_cast&lt;unsigned&gt;(node-&gt;constructorKind()));
</span><span class="cx">     m_parentScopeTDZVariables.swap(parentScopeTDZVariables);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2012-2016 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -76,9 +76,14 @@
</span><span class="cx"> 
</span><span class="cx">     const Identifier&amp; name() const { return m_name; }
</span><span class="cx">     const Identifier&amp; ecmaName() const { return m_ecmaName; }
</span><ins>+    void setEcmaName(const Identifier&amp; name) { m_ecmaName = name; }
</ins><span class="cx">     const Identifier&amp; inferredName() const { return m_inferredName; }
</span><span class="cx">     unsigned parameterCount() const { return m_parameterCount; };
</span><span class="cx">     SourceParseMode parseMode() const { return static_cast&lt;SourceParseMode&gt;(m_sourceParseMode); };
</span><ins>+
+    const SourceCode&amp; classSource() const { return m_classSource; };
+    void setClassSource(const SourceCode&amp; source) { m_classSource = source; };
+
</ins><span class="cx">     bool isInStrictContext() const { return m_isInStrictContext; }
</span><span class="cx">     FunctionMode functionMode() const { return static_cast&lt;FunctionMode&gt;(m_functionMode); }
</span><span class="cx">     ConstructorKind constructorKind() const { return static_cast&lt;ConstructorKind&gt;(m_constructorKind); }
</span><span class="lines">@@ -163,6 +168,7 @@
</span><span class="cx">     Identifier m_ecmaName;
</span><span class="cx">     Identifier m_inferredName;
</span><span class="cx">     RefPtr&lt;SourceProvider&gt; m_sourceOverride;
</span><ins>+    SourceCode m_classSource;
</ins><span class="cx"> 
</span><span class="cx">     VariableEnvironment m_parentScopeTDZVariables;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2009, 2012-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2008 Cameron Zwarich &lt;cwzwarich@uwaterloo.ca&gt;
</span><span class="cx">  * Copyright (C) 2012 Igalia, S.L.
</span><span class="cx">  *
</span><span class="lines">@@ -2810,10 +2810,13 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier&amp; name)
</del><ins>+RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier&amp; name,
+    const Identifier&amp; ecmaName, const SourceCode&amp; classSource)
</ins><span class="cx"> {
</span><span class="cx">     UnlinkedFunctionExecutable* executable = m_vm-&gt;builtinExecutables()-&gt;createDefaultConstructor(constructorKind, name);
</span><span class="cx">     executable-&gt;setInvalidTypeProfilingOffsets();
</span><ins>+    executable-&gt;setEcmaName(ecmaName);
+    executable-&gt;setClassSource(classSource);
</ins><span class="cx"> 
</span><span class="cx">     unsigned index = m_codeBlock-&gt;addFunctionExpr(executable);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2009, 2012-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2008 Cameron Zwarich &lt;cwzwarich@uwaterloo.ca&gt;
</span><span class="cx">  * Copyright (C) 2012 Igalia, S.L.
</span><span class="cx">  *
</span><span class="lines">@@ -518,7 +518,7 @@
</span><span class="cx"> 
</span><span class="cx">         RegisterID* emitNewFunction(RegisterID* dst, FunctionMetadataNode*);
</span><span class="cx">         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
</span><del>-        RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier&amp; name);
</del><ins>+        RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier&amp; name, const Identifier&amp; ecmaName, const SourceCode&amp; classSource);
</ins><span class="cx">         RegisterID* emitNewArrowFunctionExpression(RegisterID*, ArrowFuncExprNode*);
</span><span class="cx">         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx"> *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
</span><span class="cx"> *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>-*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+*  Copyright (C) 2003-2009, 2012-2013, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx"> *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
</span><span class="cx"> *  Copyright (C) 2007 Maks Orlovich
</span><span class="cx"> *  Copyright (C) 2007 Eric Seidel &lt;eric@webkit.org&gt;
</span><span class="lines">@@ -3220,11 +3220,16 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; constructor;
</span><span class="cx"> 
</span><span class="cx">     // FIXME: Make the prototype non-configurable &amp; non-writable.
</span><del>-    if (m_constructorExpression)
</del><ins>+    if (m_constructorExpression) {
+        ASSERT(m_constructorExpression-&gt;isFuncExprNode());
+        FunctionMetadataNode* metadata = static_cast&lt;FuncExprNode*&gt;(m_constructorExpression)-&gt;metadata();
+        metadata-&gt;setEcmaName(ecmaName());
+        metadata-&gt;setClassSource(m_classSource);
</ins><span class="cx">         constructor = generator.emitNode(dst, m_constructorExpression);
</span><del>-    else {
</del><ins>+    } else {
</ins><span class="cx">         constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst),
</span><del>-            m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base, m_name);
</del><ins>+            m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base,
+            m_name, ecmaName(), m_classSource);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     const auto&amp; propertyNames = generator.propertyNames();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserASTBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ASTBuilder.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -346,7 +346,8 @@
</span><span class="cx">             auto metadata = static_cast&lt;FuncExprNode*&gt;(rhs)-&gt;metadata();
</span><span class="cx">             metadata-&gt;setEcmaName(ident);
</span><span class="cx">             metadata-&gt;setInferredName(ident);
</span><del>-        }
</del><ins>+        } else if (rhs-&gt;isClassExprNode())
+            static_cast&lt;ClassExprNode*&gt;(rhs)-&gt;setEcmaName(ident);
</ins><span class="cx">         AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, ident, rhs, assignmentContext);
</span><span class="cx">         setExceptionLocation(node, start, divot, end);
</span><span class="cx">         return node;
</span><span class="lines">@@ -364,10 +365,11 @@
</span><span class="cx">         return node;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ClassExprNode* createClassExpr(const JSTokenLocation&amp; location, const Identifier&amp; name, VariableEnvironment&amp; classEnvironment, ExpressionNode* constructor,
</del><ins>+    ClassExprNode* createClassExpr(const JSTokenLocation&amp; location, const ParserClassInfo&lt;ASTBuilder&gt;&amp; classInfo, VariableEnvironment&amp; classEnvironment, ExpressionNode* constructor,
</ins><span class="cx">         ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
</span><span class="cx">     {
</span><del>-        return new (m_parserArena) ClassExprNode(location, name, classEnvironment, constructor, parentClass, instanceMethods, staticMethods);
</del><ins>+        SourceCode source = m_sourceCode-&gt;subExpression(classInfo.startOffset, classInfo.endOffset, classInfo.startLine, classInfo.startColumn);
+        return new (m_parserArena) ClassExprNode(location, *classInfo.className, source, classEnvironment, constructor, parentClass, instanceMethods, staticMethods);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ExpressionNode* createFunctionExpr(const JSTokenLocation&amp; location, const ParserFunctionInfo&lt;ASTBuilder&gt;&amp; functionInfo)
</span><span class="lines">@@ -442,7 +444,8 @@
</span><span class="cx">             auto metadata = static_cast&lt;FuncExprNode*&gt;(node)-&gt;metadata();
</span><span class="cx">             metadata-&gt;setEcmaName(*propertyName);
</span><span class="cx">             metadata-&gt;setInferredName(*propertyName);
</span><del>-        }
</del><ins>+        } else if (node-&gt;isClassExprNode())
+            static_cast&lt;ClassExprNode*&gt;(node)-&gt;setEcmaName(*propertyName);
</ins><span class="cx">         return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding);
</span><span class="cx">     }
</span><span class="cx">     PropertyNode* createProperty(VM* vm, ParserArena&amp; parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool)
</span><span class="lines">@@ -1301,7 +1304,8 @@
</span><span class="cx">                 auto metadata = static_cast&lt;FuncExprNode*&gt;(expr)-&gt;metadata();
</span><span class="cx">                 metadata-&gt;setEcmaName(resolve-&gt;identifier());
</span><span class="cx">                 metadata-&gt;setInferredName(resolve-&gt;identifier());
</span><del>-            }
</del><ins>+            } else if (expr-&gt;isClassExprNode())
+                static_cast&lt;ClassExprNode*&gt;(expr)-&gt;setEcmaName(resolve-&gt;identifier());
</ins><span class="cx">             AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, resolve-&gt;identifier(), expr, AssignmentContext::AssignmentExpression);
</span><span class="cx">             setExceptionLocation(node, start, divot, end);
</span><span class="cx">             return node;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodeConstructorsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/NodeConstructors.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/NodeConstructors.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/parser/NodeConstructors.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2009, 2013, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -890,27 +890,27 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     
</span><del>-    inline BaseFuncExprNode::BaseFuncExprNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* m_metadata, const SourceCode&amp; source)
</del><ins>+    inline BaseFuncExprNode::BaseFuncExprNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* metadata, const SourceCode&amp; source)
</ins><span class="cx">         : ExpressionNode(location)
</span><del>-        , m_metadata(m_metadata)
</del><ins>+        , m_metadata(metadata)
</ins><span class="cx">     {
</span><span class="cx">         m_metadata-&gt;finishParsing(source, ident, FunctionExpression);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline FuncExprNode::FuncExprNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* m_metadata, const SourceCode&amp; source)
-        : BaseFuncExprNode(location, ident, m_metadata, source)
</del><ins>+    inline FuncExprNode::FuncExprNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* metadata, const SourceCode&amp; source)
+        : BaseFuncExprNode(location, ident, metadata, source)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline FuncDeclNode::FuncDeclNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* m_metadata, const SourceCode&amp; source)
</del><ins>+    inline FuncDeclNode::FuncDeclNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* metadata, const SourceCode&amp; source)
</ins><span class="cx">         : StatementNode(location)
</span><del>-        , m_metadata(m_metadata)
</del><ins>+        , m_metadata(metadata)
</ins><span class="cx">     {
</span><span class="cx">         m_metadata-&gt;finishParsing(source, ident, FunctionDeclaration);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline ArrowFuncExprNode::ArrowFuncExprNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* m_metadata, const SourceCode&amp; source)
-        : BaseFuncExprNode(location, ident, m_metadata, source)
</del><ins>+    inline ArrowFuncExprNode::ArrowFuncExprNode(const JSTokenLocation&amp; location, const Identifier&amp; ident, FunctionMetadataNode* metadata, const SourceCode&amp; source)
+        : BaseFuncExprNode(location, ident, metadata, source)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -927,10 +927,12 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline ClassExprNode::ClassExprNode(const JSTokenLocation&amp; location, const Identifier&amp; name, VariableEnvironment&amp; classEnvironment, ExpressionNode* constructorExpression, ExpressionNode* classHeritage, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
</del><ins>+    inline ClassExprNode::ClassExprNode(const JSTokenLocation&amp; location, const Identifier&amp; name, const SourceCode&amp; classSource, VariableEnvironment&amp; classEnvironment, ExpressionNode* constructorExpression, ExpressionNode* classHeritage, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
</ins><span class="cx">         : ExpressionNode(location)
</span><span class="cx">         , VariableEnvironmentNode(classEnvironment)
</span><ins>+        , m_classSource(classSource)
</ins><span class="cx">         , m_name(name)
</span><ins>+        , m_ecmaName(&amp;name)
</ins><span class="cx">         , m_constructorExpression(constructorExpression)
</span><span class="cx">         , m_classHeritage(classHeritage)
</span><span class="cx">         , m_instanceMethods(instanceMethods)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Nodes.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Nodes.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/parser/Nodes.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2009, 2013, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
</span><span class="cx">  *  Copyright (C) 2007 Maks Orlovich
</span><span class="cx">  *  Copyright (C) 2007 Eric Seidel &lt;eric@webkit.org&gt;
</span><span class="lines">@@ -166,6 +166,7 @@
</span><span class="cx">         virtual bool isDestructuringNode() const { return false; }
</span><span class="cx">         virtual bool isFuncExprNode() const { return false; }
</span><span class="cx">         virtual bool isArrowFuncExprNode() const { return false; }
</span><ins>+        virtual bool isClassExprNode() const { return false; }
</ins><span class="cx">         virtual bool isCommaNode() const { return false; }
</span><span class="cx">         virtual bool isSimpleArray() const { return false; }
</span><span class="cx">         virtual bool isAdd() const { return false; }
</span><span class="lines">@@ -1844,7 +1845,7 @@
</span><span class="cx">         
</span><span class="cx">         void overrideName(const Identifier&amp; ident) { m_ident = ident; }
</span><span class="cx">         const Identifier&amp; ident() { return m_ident; }
</span><del>-        void setEcmaName(const Identifier&amp; ecmaName) { ASSERT(!ecmaName.isNull()); m_ecmaName = ecmaName; }
</del><ins>+        void setEcmaName(const Identifier&amp; ecmaName) { m_ecmaName = ecmaName; }
</ins><span class="cx">         const Identifier&amp; ecmaName() { return m_ident.isEmpty() ? m_ecmaName : m_ident; }
</span><span class="cx">         void setInferredName(const Identifier&amp; inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
</span><span class="cx">         const Identifier&amp; inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
</span><span class="lines">@@ -1862,6 +1863,8 @@
</span><span class="cx">         void setEndPosition(JSTextPosition);
</span><span class="cx"> 
</span><span class="cx">         const SourceCode&amp; source() const { return m_source; }
</span><ins>+        const SourceCode&amp; classSource() const { return m_classSource; }
+        void setClassSource(const SourceCode&amp; source) { m_classSource = source; }
</ins><span class="cx"> 
</span><span class="cx">         int startStartOffset() const { return m_startStartOffset; }
</span><span class="cx">         bool isInStrictContext() const { return m_isInStrictContext; }
</span><span class="lines">@@ -1888,6 +1891,7 @@
</span><span class="cx">         int m_functionNameStart;
</span><span class="cx">         int m_parametersStart;
</span><span class="cx">         SourceCode m_source;
</span><ins>+        SourceCode m_classSource;
</ins><span class="cx">         int m_startStartOffset;
</span><span class="cx">         unsigned m_parameterCount;
</span><span class="cx">         int m_lastLine;
</span><span class="lines">@@ -1974,15 +1978,22 @@
</span><span class="cx">     public:
</span><span class="cx">         using ParserArenaDeletable::operator new;
</span><span class="cx"> 
</span><del>-        ClassExprNode(const JSTokenLocation&amp;, const Identifier&amp;, VariableEnvironment&amp; classEnvironment, ExpressionNode* constructorExpresssion,
</del><ins>+        ClassExprNode(const JSTokenLocation&amp;, const Identifier&amp;, const SourceCode&amp; classSource,
+            VariableEnvironment&amp; classEnvironment, ExpressionNode* constructorExpresssion,
</ins><span class="cx">             ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods);
</span><span class="cx"> 
</span><span class="cx">         const Identifier&amp; name() { return m_name; }
</span><ins>+        const Identifier&amp; ecmaName() { return m_ecmaName ? *m_ecmaName : m_name; }
+        void setEcmaName(const Identifier&amp; name) { m_ecmaName = m_name.isNull() ? &amp;name : &amp;m_name; }
</ins><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</span><span class="cx"> 
</span><ins>+        bool isClassExprNode() const override { return true; }
+
+        SourceCode m_classSource;
</ins><span class="cx">         const Identifier&amp; m_name;
</span><ins>+        const Identifier* m_ecmaName;
</ins><span class="cx">         ExpressionNode* m_constructorExpression;
</span><span class="cx">         ExpressionNode* m_classHeritage;
</span><span class="cx">         PropertyListNode* m_instanceMethods;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2006-2010, 2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -2193,6 +2193,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(match(CLASSTOKEN));
</span><span class="cx">     JSTokenLocation location(tokenLocation());
</span><ins>+    info.startLine = location.line;
+    info.startColumn = tokenColumn();
+    info.startOffset = location.startOffset;
</ins><span class="cx">     next();
</span><span class="cx"> 
</span><span class="cx">     AutoPopScopeRef classScope(this, pushScope());
</span><span class="lines">@@ -2203,7 +2206,6 @@
</span><span class="cx">     const Identifier* className = nullptr;
</span><span class="cx">     if (match(IDENT)) {
</span><span class="cx">         className = m_token.m_data.ident;
</span><del>-        info.className = className;
</del><span class="cx">         next();
</span><span class="cx">         failIfTrue(classScope-&gt;declareLexicalVariable(className, true) &amp; DeclarationResult::InvalidStrictMode, &quot;'&quot;, className-&gt;impl(), &quot;' is not a valid class name&quot;);
</span><span class="cx">     } else if (requirements == FunctionNeedsName) {
</span><span class="lines">@@ -2214,6 +2216,7 @@
</span><span class="cx">     } else
</span><span class="cx">         className = &amp;m_vm-&gt;propertyNames-&gt;nullIdentifier;
</span><span class="cx">     ASSERT(className);
</span><ins>+    info.className = className;
</ins><span class="cx"> 
</span><span class="cx">     TreeExpression parentClass = 0;
</span><span class="cx">     if (consume(EXTENDS)) {
</span><span class="lines">@@ -2343,9 +2346,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    info.endOffset = tokenLocation().endOffset - 1;
</ins><span class="cx">     consumeOrFail(CLOSEBRACE, &quot;Expected a closing '}' after a class body&quot;);
</span><span class="cx"> 
</span><del>-    auto classExpression = context.createClassExpr(location, *className, classScope-&gt;finalizeLexicalEnvironment(), constructor, parentClass, instanceMethods, staticMethods);
</del><ins>+    auto classExpression = context.createClassExpr(location, info, classScope-&gt;finalizeLexicalEnvironment(), constructor, parentClass, instanceMethods, staticMethods);
</ins><span class="cx">     popScope(classScope, TreeBuilder::NeedsFreeVariableInfo);
</span><span class="cx">     return classExpression;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserFunctionInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -43,7 +43,11 @@
</span><span class="cx"> 
</span><span class="cx"> template &lt;class TreeBuilder&gt;
</span><span class="cx"> struct ParserClassInfo {
</span><del>-    const Identifier* className = 0;
</del><ins>+    const Identifier* className { nullptr };
+    unsigned startOffset { 0 };
+    unsigned endOffset { 0 };
+    int startLine { 0 };
+    unsigned startColumn { 0 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSyntaxCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SyntaxChecker.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -182,7 +182,7 @@
</span><span class="cx">     ExpressionType createEmptyLetExpression(const JSTokenLocation&amp;, const Identifier&amp;) { return AssignmentExpr; }
</span><span class="cx">     ExpressionType createYield(const JSTokenLocation&amp;) { return YieldExpr; }
</span><span class="cx">     ExpressionType createYield(const JSTokenLocation&amp;, ExpressionType, bool, int, int, int) { return YieldExpr; }
</span><del>-    ClassExpression createClassExpr(const JSTokenLocation&amp;, const Identifier&amp;, VariableEnvironment&amp;, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
</del><ins>+    ClassExpression createClassExpr(const JSTokenLocation&amp;, const ParserClassInfo&lt;SyntaxChecker&gt;&amp;, VariableEnvironment&amp;, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
</ins><span class="cx">     ExpressionType createFunctionExpr(const JSTokenLocation&amp;, const ParserFunctionInfo&lt;SyntaxChecker&gt;&amp;) { return FunctionExpr; }
</span><span class="cx">     int createFunctionMetadata(const JSTokenLocation&amp;, const JSTokenLocation&amp;, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool, InnerArrowFunctionCodeFeatures = NoInnerArrowFunctionFeatures) { return FunctionBodyResult; }
</span><span class="cx">     ExpressionType createArrowFunctionExpr(const JSTokenLocation&amp;, const ParserFunctionInfo&lt;SyntaxChecker&gt;&amp;) { return FunctionExpr; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.h (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.h        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/runtime/Executable.h        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009, 2010, 2013-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009, 2010, 2013-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -662,6 +662,7 @@
</span><span class="cx">     FunctionMode functionMode() { return m_unlinkedExecutable-&gt;functionMode(); }
</span><span class="cx">     bool isBuiltinFunction() const { return m_unlinkedExecutable-&gt;isBuiltinFunction(); }
</span><span class="cx">     ConstructAbility constructAbility() const { return m_unlinkedExecutable-&gt;constructAbility(); }
</span><ins>+    bool isClass() const { return !classSource().isNull(); }
</ins><span class="cx">     bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
</span><span class="cx">     bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; }
</span><span class="cx">     bool isSetter() const { return parseMode() == SourceParseMode::SetterMode; }
</span><span class="lines">@@ -672,6 +673,7 @@
</span><span class="cx">     const Identifier&amp; inferredName() { return m_unlinkedExecutable-&gt;inferredName(); }
</span><span class="cx">     size_t parameterCount() const { return m_unlinkedExecutable-&gt;parameterCount(); } // Excluding 'this'!
</span><span class="cx">     SourceParseMode parseMode() const { return m_unlinkedExecutable-&gt;parseMode(); }
</span><ins>+    const SourceCode&amp; classSource() const { return m_unlinkedExecutable-&gt;classSource(); }
</ins><span class="cx"> 
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue proto)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeFunctionPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2009, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -89,7 +89,11 @@
</span><span class="cx">             return JSValue::encode(jsMakeNontrivialString(exec, &quot;function &quot;, function-&gt;name(), &quot;() {\n    [native code]\n}&quot;));
</span><span class="cx"> 
</span><span class="cx">         FunctionExecutable* executable = function-&gt;jsExecutable();
</span><del>-        
</del><ins>+        if (executable-&gt;isClass()) {
+            StringView classSource = executable-&gt;classSource().view();
+            return JSValue::encode(jsString(exec, classSource.toStringWithoutCopying()));
+        }
+
</ins><span class="cx">         String functionHeader = executable-&gt;isArrowFunction() ? &quot;&quot; : &quot;function &quot;;
</span><span class="cx">         
</span><span class="cx">         StringView source = executable-&gt;source().provider()-&gt;getRange(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestses6yaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/es6.yaml (198041 => 198042)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/es6.yaml        2016-03-11 20:59:27 UTC (rev 198041)
+++ trunk/Source/JavaScriptCore/tests/es6.yaml        2016-03-11 21:08:08 UTC (rev 198042)
</span><span class="lines">@@ -801,7 +801,7 @@
</span><span class="cx"> - path: es6/function_name_property_isnt_writable_is_configurable.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/function_name_property_object_methods_class.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/function_name_property_object_methods_function.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/function_name_property_shorthand_methods_no_lexical_binding.js
</span><span class="lines">@@ -809,7 +809,7 @@
</span><span class="cx"> - path: es6/function_name_property_symbol-keyed_methods.js
</span><span class="cx">   cmd: runES6 :fail
</span><span class="cx"> - path: es6/function_name_property_variables_class.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/function_name_property_variables_function.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/generators_%GeneratorPrototype%.constructor.js
</span></span></pre>
</div>
</div>

</body>
</html>