Unreviewed, rolling out r192876.
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Dec 2015 14:39:58 +0000 (14:39 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Dec 2015 14:39:58 +0000 (14:39 +0000)
It broke a lot of JSC and layout tests for GTK and EFL

Reverted changeset:

"[ES6] "super" and "this" should be lexically bound inside an
arrow function and should live in a JSLexicalEnvironment"
https://bugs.webkit.org/show_bug.cgi?id=149338
http://trac.webkit.org/changeset/192876

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@192882 268f45cc-cd09-0410-ab3c-d52691b4dbfc

77 files changed:
LayoutTests/ChangeLog
LayoutTests/js/arrowfunction-supercall-expected.txt [deleted file]
LayoutTests/js/arrowfunction-supercall.html [deleted file]
LayoutTests/js/arrowfunction-tdz-expected.txt
LayoutTests/js/script-tests/arrowfunction-supercall.js [deleted file]
LayoutTests/js/script-tests/arrowfunction-tdz.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecode/BytecodeUseDef.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/EvalCodeCache.h
Source/JavaScriptCore/bytecode/ExecutableInfo.h
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGCapabilities.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
Source/JavaScriptCore/ftl/FTLOperations.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/Nodes.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/ParserModes.h
Source/JavaScriptCore/runtime/CodeCache.cpp
Source/JavaScriptCore/runtime/CodeCache.h
Source/JavaScriptCore/runtime/CommonIdentifiers.h
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/Executable.cpp
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
Source/JavaScriptCore/tests/es6.yaml
Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink-osrexit.js
Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js
Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-1.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-3.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-4.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-1.js
Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-7.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-tdz-1.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-tdz-2.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-tdz-3.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-tdz-4.js [deleted file]
Source/JavaScriptCore/tests/stress/arrowfunction-tdz.js [new file with mode: 0644]

index 254ff9a..37816b6 100644 (file)
@@ -1,3 +1,16 @@
+2015-12-01  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        Unreviewed, rolling out r192876.
+
+        It broke a lot of JSC and layout tests for GTK and EFL
+
+        Reverted changeset:
+
+        "[ES6] "super" and "this" should be lexically bound inside an
+        arrow function and should live in a JSLexicalEnvironment"
+        https://bugs.webkit.org/show_bug.cgi?id=149338
+        http://trac.webkit.org/changeset/192876
+
 2015-12-01  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         [Streams API] pull function of tee should call readFromReadableStreamReader directly
diff --git a/LayoutTests/js/arrowfunction-supercall-expected.txt b/LayoutTests/js/arrowfunction-supercall-expected.txt
deleted file mode 100644 (file)
index 8a39c37..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-Tests for ES6 arrow function, calling of the super in arrow function
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS isReferenceError is true
-PASS b.id is value
-PASS isReferenceError is true
-PASS d1.id is "b"
-PASS d2.id is value
-PASS (new D()).id is value
-PASS (new E(false)).id is value
-PASS typeof (new E(true)).id is 'undefined'
-PASS (new F(false)).id is value
-PASS typeof (new F(true)).id is 'undefined'
-PASS indexOfParentClassInStackError < indexOfnestedArrowInStackError is true
-PASS indexOfnestedArrowInStackError < indexOfarrowInChildConstructorInStackError is true
-PASS indexOfarrowInChildConstructorInStackError < indexOfChildClassInStackError is true
-PASS indexOfChildClassInStackError > 0 is true
-PASS indexOfParentClassInStackError > -1 && errorStack.indexOf('ParentClass', indexOfParentClassInStackError + 1) === -1 is true
-PASS indexOfnestedArrowInStackError > -1 && errorStack.indexOf('nestedArrow', indexOfnestedArrowInStackError + 1) === -1 is true
-PASS indexOfarrowInChildConstructorInStackError > -1 && errorStack.indexOf('arrowInChildConstructor', indexOfarrowInChildConstructorInStackError + 1) === -1 is true
-PASS indexOfChildClassInStackError > -1 && errorStack.indexOf('ChildClass', indexOfChildClassInStackError + 1) === -1 is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/LayoutTests/js/arrowfunction-supercall.html b/LayoutTests/js/arrowfunction-supercall.html
deleted file mode 100644 (file)
index 6d98e81..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="script-tests/arrowfunction-supercall.js"></script>
-<script src="../resources/js-test-post.js"></script>
-</body>
-</html>
index fcb6a44..17af6cd 100644 (file)
@@ -4,14 +4,6 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 
 PASS isReferenceError is true
-PASS isReferenceError is true
-PASS d.id is 'a'
-PASS e.id is 'a'
-PASS f.id is 'a'
-PASS isReferenceError is true
-PASS g.id is 'a'
-PASS h.id is 'a'
-PASS i.id is 'a'
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/js/script-tests/arrowfunction-supercall.js b/LayoutTests/js/script-tests/arrowfunction-supercall.js
deleted file mode 100644 (file)
index 2cef609..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-description('Tests for ES6 arrow function, calling of the super in arrow function');
-
-var value = 'abcd-1234';
-
-var A = class A {
-  constructor() {
-    this.id = value;
-  }
-};
-
-var B = class B extends A {
-  constructor(accessThisBeforeSuper) {
-    var f = () =>  { super(); };
-    if (accessThisBeforeSuper) {
-      if (this.id !== value) throw new Error('Should be reference error because of TDZ');
-      f();
-    } else {
-      f();
-      if (this.id !== value) throw new Error('wrong value');
-    }
-  }
-};
-
-var isReferenceError = false;
-try {
-    new B(true);
-} catch (e) {
-    isReferenceError = e instanceof ReferenceError;
-}
-
-shouldBe('isReferenceError', 'true');
-
-var b = new B(false);
-shouldBe('b.id', 'value');
-
-var C = class C extends A {
-  constructor(runSuperInConstructor, forceTDZ) {
-    var f1 = () =>  { if (!forceTDZ) super();  this.id = 'b'; };
-    var f2 = () =>  { if (this.id !== 'b') throw new Error('wrong bound of the this'); };
-    var f3 = () =>  { if (this.id !== value) throw new Error('wrong bound of the this'); };
-
-    if (runSuperInConstructor) {
-      super();
-      f3();
-    } else {
-      f1();
-      f2();
-    }
-  }
-};
-
-isReferenceError = false;
-try {
-    new C(false, true);
-} catch (e) {
-    isReferenceError = e instanceof ReferenceError;
-}
-shouldBe('isReferenceError', 'true');
-var d1 = new C(false, false);
-shouldBe('d1.id', '"b"');
-
-var d2 = new C(true, false);
-shouldBe('d2.id', 'value');
-
-var D = class D extends A {
-  constructor () {
-    var arrow = () => {
-      let __proto__ = 'some-text';
-      var arr = () => {
-          let value = __proto__ + 'text';
-          super();
-      };
-
-      arr();
-    };
-
-    arrow();
-  }
-};
-shouldBe('(new D()).id', 'value');
-
-class E extends A {
-  constructor(doReplaceProto) {
-    var arrow = () => {
-      if (doReplaceProto)
-        E.__proto__ = function () {};
-      super();
-    };
-
-    arrow();
-  }
-};
-shouldBe('(new E(false)).id', "value");
-shouldBe('typeof (new E(true)).id', "'undefined'");
-
-class F extends A {
-  constructor(doReplaceProto) {
-    var arrow = () => super();
-    if (doReplaceProto)
-      F.__proto__ = function () {};
-    arrow();
-  }
-};
-shouldBe('(new F(false)).id', "value");
-shouldBe('typeof (new F(true)).id',  "'undefined'");
-
-var errorStack;
-
-var ParentClass = class ParentClass {
-  constructor() {
-    try {
-      this.idValue = testValue;
-      throw new Error('Error');
-    } catch (e) {
-      errorStack  = e.stack;
-    }
-  }
-};
-
-var ChildClass = class ChildClass extends ParentClass {
-  constructor () {
-    var arrowInChildConstructor = () => {
-      var nestedArrow = () => {
-        super();
-      }
-
-      nestedArrow();
-    };
-
-    arrowInChildConstructor();
-  }
-};
-
-var c = new ChildClass();
-
-var indexOfParentClassInStackError = errorStack.indexOf('ParentClass');
-var indexOfnestedArrowInStackError = errorStack.indexOf('nestedArrow');
-var indexOfarrowInChildConstructorInStackError = errorStack.indexOf('arrowInChildConstructor');
-var indexOfChildClassInStackError = errorStack.indexOf('ChildClass');
-
-shouldBeTrue("indexOfParentClassInStackError < indexOfnestedArrowInStackError");
-shouldBeTrue("indexOfnestedArrowInStackError < indexOfarrowInChildConstructorInStackError");
-shouldBeTrue("indexOfarrowInChildConstructorInStackError < indexOfChildClassInStackError");
-shouldBeTrue("indexOfChildClassInStackError > 0");
-
-shouldBeTrue("indexOfParentClassInStackError > -1 && errorStack.indexOf('ParentClass', indexOfParentClassInStackError + 1) === -1");
-shouldBeTrue("indexOfnestedArrowInStackError > -1 && errorStack.indexOf('nestedArrow', indexOfnestedArrowInStackError + 1) === -1");
-shouldBeTrue("indexOfarrowInChildConstructorInStackError > -1 && errorStack.indexOf('arrowInChildConstructor', indexOfarrowInChildConstructorInStackError + 1) === -1");
-shouldBeTrue("indexOfChildClassInStackError > -1 && errorStack.indexOf('ChildClass', indexOfChildClassInStackError + 1) === -1");
-
-var successfullyParsed = true;
index b41aa67..aaf58fc 100644 (file)
@@ -1,20 +1,13 @@
 description('Tests for ES6 arrow function test tdz');
 
-var A = class A {
-  constructor() {
-    this.id = 'a';
-  }
-};
-
+var A = class A { };
 var B = class B extends A {
   constructor(accessThisBeforeSuper) {
-    var f = () => this;
     if (accessThisBeforeSuper) {
-      f();
+      var f = () => this;
       super();
     } else {
       super();
-      f();
     }
   }
 };
@@ -28,65 +21,6 @@ try {
 
 shouldBe('isReferenceError', 'true');
 
-var a = new B(false);
-
-var D = class D extends A {
-  constructor(accessThisBeforeSuper, returnThis) {
-    var f = () => returnThis ? this : {};
-    if (accessThisBeforeSuper) {
-      let val = f();
-      super();
-    } else {
-      super();
-      let val = f();
-    }
-  }
-};
-
-isReferenceError = false;
-try {
-      new D(true, true);
-} catch (e) {
-      isReferenceError = e instanceof ReferenceError;
-}
-
-shouldBe('isReferenceError', 'true');
-
-var d = new D(false, true);
-shouldBe('d.id', "'a'");
-var e = new D(false, false);
-shouldBe('e.id', "'a'");
-var f = new D(true, false);
-shouldBe('f.id', "'a'");
-
-var G = class G extends A {
-  constructor(accessThisBeforeSuper, returnThis) {
-    var f = () => returnThis ? (() => this ) : (()=>{});
-    let af = f();
-    if (accessThisBeforeSuper) {
-      let result = af();
-      super();
-    } else {
-      super();
-      let result = af();
-    }
-  }
-};
-
-try {
-      new G(true, true);
-} catch (e) {
-    exception = e;
-    isReferenceError = e instanceof ReferenceError;
-}
-
-shouldBe('isReferenceError', 'true');
-
-var g = new G(false, true);
-shouldBe('g.id', "'a'");
-var h = new G(false, false);
-shouldBe('h.id', "'a'");
-var i = new G(true, false);
-shouldBe('i.id', "'a'");
+var e = new B(false);
 
 var successfullyParsed = true;
index 33b4244..ab49f9a 100644 (file)
@@ -1,3 +1,16 @@
+2015-12-01  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        Unreviewed, rolling out r192876.
+
+        It broke a lot of JSC and layout tests for GTK and EFL
+
+        Reverted changeset:
+
+        "[ES6] "super" and "this" should be lexically bound inside an
+        arrow function and should live in a JSLexicalEnvironment"
+        https://bugs.webkit.org/show_bug.cgi?id=149338
+        http://trac.webkit.org/changeset/192876
+
 2015-12-01 Aleksandr Skachkov   <gskachkov@gmail.com>
 
         [ES6] "super" and "this" should be lexically bound inside an arrow function and should live in a JSLexicalEnvironment
index c81e26c..816b4a5 100644 (file)
@@ -115,7 +115,7 @@ UnlinkedFunctionExecutable* createExecutableInternal(VM& vm, const SourceCode& s
     }
     metadata->overrideName(name);
     VariableEnvironment dummyTDZVariables;
-    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, dummyTDZVariables, false, WTF::move(sourceOverride));
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, dummyTDZVariables, WTF::move(sourceOverride));
     functionExecutable->setNameValue(vm, jsString(&vm, name.string()));
     return functionExecutable;
 }
index 61ee4d7..f6c89a9 100644 (file)
@@ -90,7 +90,7 @@
             { "name" : "op_switch_string", "length" : 4 },
             { "name" : "op_new_func", "length" : 4 },
             { "name" : "op_new_func_exp", "length" : 4 },
-            { "name" : "op_new_arrow_func_exp", "length" : 4 },
+            { "name" : "op_new_arrow_func_exp", "length" : 5 },
             { "name" : "op_call", "length" : 9 },
             { "name" : "op_tail_call", "length" : 9 },
             { "name" : "op_call_eval", "length" : 9 },
             { "name" : "op_enumerator_structure_pname", "length" : 4 },
             { "name" : "op_enumerator_generic_pname", "length" : 4 },
             { "name" : "op_to_index_string", "length" : 3 },
+            { "name" : "op_load_arrowfunction_this", "length" : 2 },
             { "name" : "op_assert", "length" : 3 },
             { "name" : "op_copy_rest", "length": 4 },
             { "name" : "op_get_rest_length", "length": 3 }
index 5a20f48..cbb8948 100644 (file)
@@ -57,6 +57,7 @@ void computeUsesForBytecodeOffset(
         return;
     case op_assert:
     case op_get_scope:
+    case op_load_arrowfunction_this:
     case op_to_this:
     case op_check_tdz:
     case op_profile_will_call:
@@ -370,6 +371,7 @@ void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset,
     case op_to_this:
     case op_check_tdz:
     case op_get_scope:
+    case op_load_arrowfunction_this:
     case op_create_direct_arguments:
     case op_create_scoped_arguments:
     case op_create_out_of_band_arguments:
index ce51aef..9e1386e 100644 (file)
@@ -757,6 +757,11 @@ void CodeBlock::dumpBytecode(
             printLocationOpAndRegisterOperand(out, exec, location, it, "get_scope", r0);
             break;
         }
+        case op_load_arrowfunction_this: {
+            int r0 = (++it)->u.operand;
+            printLocationOpAndRegisterOperand(out, exec, location, it, "load_arrowfunction_this", r0);
+            break;
+        }
         case op_create_direct_arguments: {
             int r0 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "create_direct_arguments");
@@ -1302,8 +1307,9 @@ void CodeBlock::dumpBytecode(
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
+            int r2 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "op_new_arrow_func_exp");
-            out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
+            out.printf("%s, %s, f%d, %s", registerName(r0).data(), registerName(r1).data(), f0, registerName(r2).data());
             break;
         }
         case op_new_func_exp: {
index e2d6a41..62521fc 100644 (file)
@@ -50,12 +50,12 @@ namespace JSC {
                 return m_cacheMap.get(evalSource.impl()).get();
             return 0;
         }
-
-        EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const String& evalSource, JSScope* scope)
+        
+        EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const String& evalSource, JSScope* scope)
         {
             VariableEnvironment variablesUnderTDZ;
             JSScope::collectVariablesUnderTDZ(scope, variablesUnderTDZ);
-            EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext, thisTDZMode, isDerivedConstructorContext, isArrowFunctionContext, &variablesUnderTDZ);
+            EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext, thisTDZMode, &variablesUnderTDZ);
             if (!evalExecutable)
                 return 0;
 
index 13246cc..92144f8 100644 (file)
@@ -31,7 +31,7 @@
 namespace JSC {
 
 struct ExecutableInfo {
-    ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, bool isArrowFunction, bool isDerivedConstructorContext, bool isArrowFunctionContext)
+    ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, bool isArrowFunction)
         : m_needsActivation(needsActivation)
         , m_usesEval(usesEval)
         , m_isStrictMode(isStrictMode)
@@ -39,8 +39,6 @@ struct ExecutableInfo {
         , m_isBuiltinFunction(isBuiltinFunction)
         , m_constructorKind(static_cast<unsigned>(constructorKind))
         , m_isArrowFunction(isArrowFunction)
-        , m_isDerivedConstructorContext(isDerivedConstructorContext)
-        , m_isArrowFunctionContext(isArrowFunctionContext)
     {
         ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
     }
@@ -52,8 +50,6 @@ struct ExecutableInfo {
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
     ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
     bool isArrowFunction() const { return m_isArrowFunction; }
-    bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; }
-    bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
 
 private:
     unsigned m_needsActivation : 1;
@@ -63,8 +59,6 @@ private:
     unsigned m_isBuiltinFunction : 1;
     unsigned m_constructorKind : 2;
     unsigned m_isArrowFunction : 1;
-    unsigned m_isDerivedConstructorContext : 1;
-    unsigned m_isArrowFunctionContext : 1;
 };
 
 } // namespace JSC
index 4de594d..c114b9b 100644 (file)
@@ -66,8 +66,6 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType code
     , m_isBuiltinFunction(info.isBuiltinFunction())
     , m_constructorKind(static_cast<unsigned>(info.constructorKind()))
     , m_isArrowFunction(info.isArrowFunction())
-    , m_isDerivedConstructorContext(info.isDerivedConstructorContext())
-    , m_isArrowFunctionContext(info.isArrowFunctionContext())
     , m_firstLine(0)
     , m_lineCount(0)
     , m_endColumn(UINT_MAX)
index 8807bee..fa514c1 100644 (file)
@@ -117,8 +117,6 @@ public:
     bool isStrictMode() const { return m_isStrictMode; }
     bool usesEval() const { return m_usesEval; }
     bool isArrowFunction() const { return m_isArrowFunction; }
-    bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; }
-    bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
 
     bool needsFullScopeChain() const { return m_needsFullScopeChain; }
 
@@ -390,8 +388,6 @@ private:
     unsigned m_isBuiltinFunction : 1;
     unsigned m_constructorKind : 2;
     unsigned m_isArrowFunction : 1;
-    unsigned m_isDerivedConstructorContext : 1;
-    unsigned m_isArrowFunctionContext : 1;
 
     unsigned m_firstLine;
     unsigned m_lineCount;
index 2eab1b5..6da1859 100644 (file)
@@ -67,7 +67,7 @@ static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock(
     executable->recordParse(function->features(), function->hasCapturedVariables());
     
     UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode,
-        ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), isArrowFunction, executable->isDerivedConstructorContext(), false));
+        ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), isArrowFunction));
     auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode, executable->parentScopeTDZVariables()));
     error = generator->generate();
     if (error.isValid())
@@ -75,7 +75,7 @@ static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock(
     return result;
 }
 
-UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, bool isDerivedConstructorContext)
+UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables)
     : Base(*vm, structure)
     , m_name(node->ident())
     , m_inferredName(node->inferredName())
@@ -100,7 +100,6 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* struct
     , m_constructorKind(static_cast<unsigned>(node->constructorKind()))
     , m_functionMode(node->functionMode())
     , m_isArrowFunction(node->isArrowFunction())
-    , m_isDerivedConstructorContext(isDerivedConstructorContext)
 {
     ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind()));
     m_parentScopeTDZVariables.swap(parentScopeTDZVariables);
index 7b2d7b2..d8e8229 100644 (file)
@@ -65,10 +65,10 @@ public:
     typedef JSCell Base;
     static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
-    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, bool isDerivedConstructorContext, RefPtr<SourceProvider>&& sourceOverride = nullptr)
+    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, RefPtr<SourceProvider>&& sourceOverride = nullptr)
     {
         UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
-            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, parentScopeTDZVariables, isDerivedConstructorContext);
+            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, parentScopeTDZVariables);
         instance->finishCreation(*vm);
         return instance;
     }
@@ -126,10 +126,9 @@ public:
     bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; }
     const VariableEnvironment* parentScopeTDZVariables() const { return &m_parentScopeTDZVariables; }
     bool isArrowFunction() const { return m_isArrowFunction; }
-    bool isDerivedConstructorContext() const {return m_isDerivedConstructorContext; }
 
 private:
-    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, VariableEnvironment&, bool isDerivedConstructorContext);
+    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, VariableEnvironment&);
     WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall;
     WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForConstruct;
 
@@ -160,7 +159,6 @@ private:
     unsigned m_constructorKind : 2;
     unsigned m_functionMode : 1; // FunctionMode
     unsigned m_isArrowFunction : 1;
-    unsigned m_isDerivedConstructorContext : 1;
 
 protected:
     void finishCreation(VM& vm)
index d58ff41..1abbba4 100644 (file)
@@ -155,8 +155,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedP
     , m_thisRegister(CallFrame::thisArgumentOffset())
     , m_codeType(GlobalCode)
     , m_vm(&vm)
-    , m_isDerivedConstructorContext(false)
-    , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval())
 {
     ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
 
@@ -187,11 +185,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedP
     // operations we emit we will have ResolveTypes that implictly do TDZ checks. Therefore, we don't need
     // additional TDZ checks on top of those. This is why we can omit pushing programNode->lexicalVariables()
     // to the TDZ stack.
-    
-    if (needsToUpdateArrowFunctionContext()) {
-        initializeArrowFunctionContextScopeIfNeeded();
-        emitPutThisToArrowFunctionContextScope();
-    }
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode, const VariableEnvironment* parentScopeTDZVariables)
@@ -209,8 +202,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
     // compatible with tail calls (we have no way of emitting op_did_call).
     // https://bugs.webkit.org/show_bug.cgi?id=148819
     , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && isStrictMode() && !m_shouldEmitProfileHooks)
-    , m_isDerivedConstructorContext(codeBlock->isDerivedConstructorContext())
-    , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval())
 {
     for (auto& constantRegister : m_linkTimeConstantRegisters)
         constantRegister = nullptr;
@@ -235,9 +226,8 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
             pattern->collectBoundIdentifiers(boundParameterProperties);
         }
     }
-    
-    bool containsArrowOrEvalButNotInArrowBlock = needsToUpdateArrowFunctionContext() && !m_codeBlock->isArrowFunction();
-    bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain() || containsArrowOrEvalButNotInArrowBlock;
+
+    bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain();
     bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
     bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval();
     if (shouldCaptureAllOfTheThings)
@@ -502,21 +492,16 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
             instructions().append(0);
             instructions().append(0);
         }
-    } else if (functionNode->usesThis())
-        emitLoadThisFromArrowFunctionLexicalEnvironment();
+    } else {
+        if (functionNode->usesThis() || codeBlock->usesEval())
+            emitLoadArrowFunctionThis(&m_thisRegister);
+    }
 
     // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called
     // because a function's default parameter ExpressionNodes will use temporary registers.
     m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false));
     initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, functionNode, functionSymbolTable, symbolTableConstantIndex, captures);
 
-    if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) {
-        initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable);
-        emitPutThisToArrowFunctionContextScope();
-        emitPutNewTargetToArrowFunctionContextScope();
-        emitPutDerivedConstructorToArrowFunctionContextScope();
-    }
-
     pushLexicalScope(m_scopeNode, true);
 }
 
@@ -529,8 +514,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
     , m_codeType(EvalCode)
     , m_vm(&vm)
     , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
-    , m_isDerivedConstructorContext(codeBlock->isDerivedConstructorContext())
-    , m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval())
 {
     for (auto& constantRegister : m_linkTimeConstantRegisters)
         constantRegister = nullptr;
@@ -560,14 +543,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
 
     m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false));
 
-    if (codeBlock->isArrowFunctionContext() && evalNode->usesThis())
-        emitLoadThisFromArrowFunctionLexicalEnvironment();
-
-    if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunctionContext()) {
-        initializeArrowFunctionContextScopeIfNeeded();
-        emitPutThisToArrowFunctionContextScope();
-    }
-    
     pushLexicalScope(m_scopeNode, true);
 }
 
@@ -580,8 +555,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNod
     , m_codeType(ModuleCode)
     , m_vm(&vm)
     , m_usesNonStrictEval(false)
-    , m_isDerivedConstructorContext(false)
-    , m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval())
 {
     ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
 
@@ -817,59 +790,6 @@ void BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeSta
     }
 }
 
-void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* symbolTable)
-{
-    if (m_arrowFunctionContextLexicalEnvironmentRegister != nullptr)
-        return;
-    
-    if (m_lexicalEnvironmentRegister != nullptr) {
-        m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalEnvironmentRegister;
-        
-        if (!m_codeBlock->isArrowFunction()) {
-            ScopeOffset offset;
-
-            offset = symbolTable->takeNextScopeOffset();
-            symbolTable->set(propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
-
-            if (m_codeType == FunctionCode) {
-                offset = symbolTable->takeNextScopeOffset();
-                symbolTable->set(propertyNames().newTargetLocalPrivateName.impl(), SymbolTableEntry(VarOffset(offset)));
-            }
-            
-            if (isConstructor() && constructorKind() == ConstructorKind::Derived) {
-                offset = symbolTable->takeNextScopeOffset();
-                symbolTable->set(propertyNames().derivedConstructorPrivateName.impl(), SymbolTableEntry(VarOffset(offset)));
-            }
-        }
-
-        return;
-    }
-
-    VariableEnvironment environment;
-    auto addResult = environment.add(propertyNames().thisIdentifier);
-    addResult.iterator->value.setIsCaptured();
-    addResult.iterator->value.setIsConst();
-    
-    if (m_codeType == FunctionCode)  {
-        auto addTarget = environment.add(propertyNames().newTargetLocalPrivateName);
-        addTarget.iterator->value.setIsCaptured();
-        addTarget.iterator->value.setIsLet();
-    }
-
-    if (isConstructor() && constructorKind() == ConstructorKind::Derived) {
-        auto derivedConstructor = environment.add(propertyNames().derivedConstructorPrivateName);
-        derivedConstructor.iterator->value.setIsCaptured();
-        derivedConstructor.iterator->value.setIsLet();
-    }
-
-    size_t size = m_symbolTableStack.size();
-    pushLexicalScopeInternal(environment, true, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
-
-    ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1);
-
-    m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope;
-}
-
 RegisterID* BytecodeGenerator::initializeNextParameter()
 {
     VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
@@ -1896,9 +1816,9 @@ void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvir
     }
 }
 
-Variable BytecodeGenerator::variable(const Identifier& property, ThisResolutionType thisResolutionType)
+Variable BytecodeGenerator::variable(const Identifier& property)
 {
-    if (property == propertyNames().thisIdentifier && thisResolutionType == ThisResolutionType::Local) {
+    if (property == propertyNames().thisIdentifier) {
         return Variable(property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
             ReadOnly, Variable::SpecialVariable, 0, false);
     }
@@ -2595,6 +2515,9 @@ void BytecodeGenerator::emitNewFunctionCommon(RegisterID* dst, BaseFuncExprNode*
     instructions().append(dst->index());
     instructions().append(scopeRegister()->index());
     instructions().append(index);
+    
+    if (opcodeID == op_new_arrow_func_exp)
+        instructions().append(thisRegister()->index());
 }
 
 RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func)
@@ -2605,6 +2528,10 @@ RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* dst, FuncEx
 
 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func)
 {
+    bool isClassConstructor = m_codeBlock->isConstructor() && constructorKind() != ConstructorKind::None;
+    if (isClassConstructor)
+        emitTDZCheck(thisRegister());
+    
     emitNewFunctionCommon(dst, func, op_new_arrow_func_exp);
     return dst;
 }
@@ -3200,6 +3127,13 @@ void BytecodeGenerator::allocateAndEmitScope()
     m_topMostScope = addVar();
     emitMove(m_topMostScope, scopeRegister());
 }
+
+RegisterID* BytecodeGenerator::emitLoadArrowFunctionThis(RegisterID* arrowFunctionThis)
+{
+    emitOpcode(op_load_arrowfunction_this);
+    instructions().append(arrowFunctionThis->index());
+    return arrowFunctionThis;
+}
     
 void BytecodeGenerator::emitComplexPopScopes(RegisterID* scope, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
 {
@@ -3868,64 +3802,6 @@ void BytecodeGenerator::popIndexedForInScope(RegisterID* localRegister)
     m_forInContextStack.removeLast();
 }
 
-RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment()
-{
-    ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived);
-    
-    m_resolvedArrowFunctionScopeContextRegister = emitResolveScope(nullptr, variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped));
-    return m_resolvedArrowFunctionScopeContextRegister.get();
-}
-
-void BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment()
-{
-    emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound);
-}
-    
-RegisterID* BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment()
-{
-    m_isNewTargetLoadedInArrowFunction = true;
-
-    Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
-    emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), newTargetVar, ThrowIfNotFound));
-    
-    return m_newTargetRegister;
-}
-
-RegisterID* BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment()
-{
-    Variable protoScopeVar = variable(propertyNames().derivedConstructorPrivateName);
-    return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), protoScopeVar, ThrowIfNotFound);
-}
-    
-void BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope()
-{
-    ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
-        
-    Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
-    emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization);
-}
-    
-void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope()
-{
-    if (isConstructor() && constructorKind() == ConstructorKind::Derived) {
-        ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
-            
-        Variable protoScope = variable(propertyNames().derivedConstructorPrivateName);
-        emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, Initialization);
-    }
-}
-    
-void BytecodeGenerator::emitPutThisToArrowFunctionContextScope()
-{
-    ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
-        
-    if (isDerivedConstructorContext())
-        emitLoadArrowFunctionLexicalEnvironment();
-
-    Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped);
-    emitPutToScope(isDerivedConstructorContext() ? m_resolvedArrowFunctionScopeContextRegister.get() : m_arrowFunctionContextLexicalEnvironmentRegister, thisVar, thisRegister(), DoNotThrowIfNotFound, NotInitialization);
-}
-
 void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
 {
     if (!localRegister)
index 2c2ec96..07316b1 100644 (file)
@@ -65,8 +65,6 @@ namespace JSC {
         ExpectArrayConstructor
     };
 
-    enum class ThisResolutionType { Local, Scoped };
-    
     class CallArguments {
     public:
         CallArguments(BytecodeGenerator&, ArgumentsNode*, unsigned additionalArguments = 0);
@@ -281,18 +279,13 @@ namespace JSC {
         const CommonIdentifiers& propertyNames() const { return *m_vm->propertyNames; }
 
         bool isConstructor() const { return m_codeBlock->isConstructor(); }
-        bool isDerivedConstructorContext() const { return m_codeBlock->isDerivedConstructorContext(); }
-        bool usesArrowFunction() const { return m_scopeNode->usesArrowFunction(); }
-        bool needsToUpdateArrowFunctionContext() const { return m_needsToUpdateArrowFunctionContext; }
-        bool usesEval() const { return m_scopeNode->usesEval(); }
-        bool usesThis() const { return m_scopeNode->usesThis(); }
         ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); }
 
         ParserError generate();
 
         bool isArgumentNumber(const Identifier&, int);
 
-        Variable variable(const Identifier&, ThisResolutionType = ThisResolutionType::Local);
+        Variable variable(const Identifier&);
         
         enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
         void createVariable(const Identifier&, VarKind, SymbolTable*, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
@@ -300,11 +293,7 @@ namespace JSC {
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
         RegisterID* argumentsRegister() { return m_argumentsRegister; }
-        RegisterID* newTarget()
-        {
-            return !m_codeBlock->isArrowFunction() || m_isNewTargetLoadedInArrowFunction
-                ? m_newTargetRegister : emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
-        }
+        RegisterID* newTarget() { return m_newTargetRegister; }
 
         RegisterID* scopeRegister() { return m_scopeRegister; }
 
@@ -490,10 +479,6 @@ namespace JSC {
         void emitProfileType(RegisterID* registerToProfile, const JSTextPosition& startDivot, const JSTextPosition& endDivot);
 
         void emitProfileControlFlow(int);
-        
-        RegisterID* emitLoadArrowFunctionLexicalEnvironment();
-        void emitLoadThisFromArrowFunctionLexicalEnvironment();
-        RegisterID* emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
 
         RegisterID* emitLoad(RegisterID* dst, bool);
         RegisterID* emitLoad(RegisterID* dst, const Identifier&);
@@ -638,10 +623,6 @@ namespace JSC {
         void emitGetScope();
         RegisterID* emitPushWithScope(RegisterID* objectScope);
         void emitPopWithScope();
-        void emitPutThisToArrowFunctionContextScope();
-        void emitPutNewTargetToArrowFunctionContextScope();
-        void emitPutDerivedConstructorToArrowFunctionContextScope();
-        RegisterID* emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
 
         void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart);
 
@@ -717,6 +698,7 @@ namespace JSC {
 
         void allocateCalleeSaveSpace();
         void allocateAndEmitScope();
+        RegisterID* emitLoadArrowFunctionThis(RegisterID*);
         void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
 
         typedef HashMap<double, JSValue> NumberMap;
@@ -768,8 +750,6 @@ namespace JSC {
         
         UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata)
         {
-            bool newisDerivedConstructorContext = constructorKind() == ConstructorKind::Derived || (m_isDerivedConstructorContext && metadata->isArrowFunction());
-
             VariableEnvironment variablesUnderTDZ;
             getVariablesUnderTDZ(variablesUnderTDZ);
 
@@ -778,7 +758,7 @@ namespace JSC {
             if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() == ConstructorKind::None))
                 constructAbility = ConstructAbility::CannotConstruct;
 
-            return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, variablesUnderTDZ, newisDerivedConstructorContext);
+            return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, variablesUnderTDZ);
         }
 
         void getVariablesUnderTDZ(VariableEnvironment&);
@@ -788,7 +768,6 @@ namespace JSC {
 
         void initializeVarLexicalEnvironment(int symbolTableConstantIndex);
         void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures);
-        void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* = nullptr);
 
     public:
         JSString* addStringConstant(const Identifier&);
@@ -830,8 +809,6 @@ namespace JSC {
         RegisterID* m_globalObjectRegister { nullptr };
         RegisterID* m_newTargetRegister { nullptr };
         RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount];
-        RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr };
-        RefPtr<RegisterID> m_resolvedArrowFunctionScopeContextRegister;
 
         SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters;
         SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
@@ -886,9 +863,6 @@ namespace JSC {
         bool m_isBuiltinFunction { false };
         bool m_usesNonStrictEval { false };
         bool m_inTailPosition { false };
-        bool m_isDerivedConstructorContext { false };
-        bool m_needsToUpdateArrowFunctionContext;
-        bool m_isNewTargetLoadedInArrowFunction { false };
     };
 
 }
index a2e84f2..242738e 100644 (file)
@@ -145,10 +145,7 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
 
 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext())
-        generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
-    
-    if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.isDerivedConstructorContext())
+    if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived)
         generator.emitTDZCheck(generator.thisRegister());
 
     if (dst == generator.ignoredResult())
@@ -167,17 +164,10 @@ RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
     if (dst == generator.ignoredResult())
         return 0;
 
-    RegisterID* scopeId;
-    if (generator.isDerivedConstructorContext())
-        scopeId = generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
-    else {
-        RegisterID callee;
-        callee.setIndex(JSStack::Callee);
+    RegisterID callee;
+    callee.setIndex(JSStack::Callee);
 
-        scopeId = &callee;
-    }
-    
-    return generator.emitGetById(generator.finalDestination(dst), scopeId, generator.propertyNames().underscoreProto);
+    return generator.emitGetById(generator.finalDestination(dst), &callee, generator.propertyNames().underscoreProto);
 }
 
 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
@@ -701,21 +691,6 @@ CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argume
 
 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    // We need try to load 'this' before call eval in constructor, because 'this' can created by 'super' in some of the arrow function
-    // var A = class A {
-    //   constructor () { this.id = 'A'; }
-    // }
-    //
-    // var B = class B extend A {
-    //    constructor () {
-    //       var arrow = () => super();
-    //       arrow();
-    //       eval("this.id = 'B'");
-    //    }
-    // }
-    if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext())
-        generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
-
     Variable var = generator.variable(generator.propertyNames().eval);
     if (RegisterID* local = var.local()) {
         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
@@ -743,16 +718,11 @@ RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, Re
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
     CallArguments callArguments(generator, m_args);
     if (m_expr->isSuperNode()) {
-        ASSERT(generator.isConstructor() || generator.isDerivedConstructorContext());
-        ASSERT(generator.constructorKind() == ConstructorKind::Derived || generator.isDerivedConstructorContext());
+        ASSERT(generator.isConstructor());
+        ASSERT(generator.constructorKind() == ConstructorKind::Derived);
         generator.emitMove(callArguments.thisRegister(), generator.newTarget());
         RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
         generator.emitMove(generator.thisRegister(), ret);
-        
-        bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Derived;
-        if (generator.isDerivedConstructorContext() || (isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext()))
-            generator.emitPutThisToArrowFunctionContextScope();
-        
         return ret;
     }
     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
@@ -3010,9 +2980,6 @@ void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 
     // If there is no return we must automatically insert one.
     if (!returnNode) {
-        if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext())
-            generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment
-
         RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
         generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code.
         ASSERT(startOffset() >= lineStartOffset());
index d540550..d383c3f 100644 (file)
@@ -196,7 +196,7 @@ JSValue DebuggerCallFrame::evaluate(const String& script, NakedPtr<Exception>& e
     VariableEnvironment variablesUnderTDZ;
     JSScope::collectVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ);
 
-    EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), codeBlock.isStrictMode(), thisTDZMode, codeBlock.unlinkedCodeBlock()->isDerivedConstructorContext(), codeBlock.unlinkedCodeBlock()->isArrowFunction(), &variablesUnderTDZ);
+    EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), codeBlock.isStrictMode(), thisTDZMode, &variablesUnderTDZ);
     if (vm.exception()) {
         exception = vm.exception();
         vm.clearException();
index 35cae39..fbe82e9 100644 (file)
@@ -1805,6 +1805,15 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         forNode(node).setType(m_graph, SpecObjectOther);
         break;
 
+    case LoadArrowFunctionThis:
+        if (JSValue base = forNode(node->child1()).m_value) {
+            JSArrowFunction* function = jsDynamicCast<JSArrowFunction*>(base);
+            setConstant(node, *m_graph.freeze(function->boundThis()));
+            break;
+        }
+        forNode(node).setType(m_graph, SpecFinalObject);
+        break;
+            
     case SkipScope: {
         JSValue child = forNode(node->child1()).value();
         if (child) {
index 268e267..439e620 100644 (file)
@@ -4514,6 +4514,17 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             set(VirtualRegister(currentInstruction[1].u.operand), result);
             NEXT_OPCODE(op_get_scope);
         }
+
+        case op_load_arrowfunction_this: {
+            Node* callee = get(VirtualRegister(JSStack::Callee));
+            Node* result;
+            if (JSArrowFunction* function = callee->dynamicCastConstant<JSArrowFunction*>())
+                result = jsConstant(function->boundThis());
+            else
+                result = addToGraph(LoadArrowFunctionThis, callee);
+            set(VirtualRegister(currentInstruction[1].u.operand), result);
+            NEXT_OPCODE(op_load_arrowfunction_this);
+        }
             
         case op_create_direct_arguments: {
             noticeArgumentsUse();
@@ -4563,20 +4574,24 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             NEXT_OPCODE(op_new_func);
         }
 
-        case op_new_func_exp:
-        case op_new_arrow_func_exp: {
+        case op_new_func_exp: {
             FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand);
             FrozenValue* frozen = m_graph.freezeStrong(expr);
             set(VirtualRegister(currentInstruction[1].u.operand),
                 addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_new_func_exp);
+        }
+
+        case op_new_arrow_func_exp: {
+            FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand);
+            FrozenValue* frozen = m_graph.freezeStrong(expr);
+
+            set(VirtualRegister(currentInstruction[1].u.operand),
+                addToGraph(NewArrowFunction, OpInfo(frozen),
+                    get(VirtualRegister(currentInstruction[2].u.operand)),
+                    get(VirtualRegister(currentInstruction[4].u.operand))));
             
-            if (opcodeID == op_new_func_exp) {
-                // Curly braces are necessary
-                NEXT_OPCODE(op_new_func_exp);
-            } else {
-                // Curly braces are necessary
-                NEXT_OPCODE(op_new_arrow_func_exp);
-            }
+            NEXT_OPCODE(op_new_arrow_func_exp);
         }
 
         case op_typeof: {
index 6164972..7a5ec3f 100644 (file)
@@ -202,6 +202,7 @@ CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruc
     case op_switch_char:
     case op_in:
     case op_get_scope:
+    case op_load_arrowfunction_this:
     case op_get_from_scope:
     case op_get_enumerable_length:
     case op_has_generic_property:
index 2637911..a85586d 100644 (file)
@@ -139,6 +139,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
     case ArithCos:
     case ArithLog:
     case GetScope:
+    case LoadArrowFunctionThis:
     case SkipScope:
     case StringCharCodeAt:
     case StringFromCharCode:
index 16f973d..b26e0a5 100644 (file)
@@ -107,6 +107,7 @@ bool doesGC(Graph& graph, Node* node)
     case GetButterflyReadOnly:
     case CheckArray:
     case GetScope:
+    case LoadArrowFunctionThis:
     case SkipScope:
     case GetClosureVar:
     case PutClosureVar:
index 77bd380..a957d2b 100644 (file)
@@ -1012,6 +1012,11 @@ private:
             break;
         }
 
+        case LoadArrowFunctionThis: {
+            fixEdge<KnownCellUse>(node->child1());
+            break;
+        }
+
         case SkipScope:
         case GetScope:
         case GetGetter:
index 008d8c7..2ed3ce4 100644 (file)
@@ -207,6 +207,7 @@ namespace JSC { namespace DFG {
     macro(MultiPutByOffset, NodeMustGenerate) \
     macro(GetArrayLength, NodeResultInt32) \
     macro(GetTypedArrayByteOffset, NodeResultInt32) \
+    macro(LoadArrowFunctionThis, NodeResultJS) \
     macro(GetScope, NodeResultJS) \
     macro(SkipScope, NodeResultJS) \
     macro(GetClosureVar, NodeResultJS) \
index 12ab163..db8dd6f 100644 (file)
@@ -838,14 +838,17 @@ private:
 
         case NewFunction:
         case NewArrowFunction: {
+            bool isArrowFunction = node->op() == NewArrowFunction;
             if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid()) {
                 m_heap.escape(node->child1().node());
                 break;
             }
             
-            target = &m_heap.newAllocation(node, Allocation::Kind::Function);
+            target = &m_heap.newAllocation(node, isArrowFunction ? Allocation::Kind::NewArrowFunction : Allocation::Kind::Function);
             writes.add(FunctionExecutablePLoc, LazyNode(node->cellOperand()));
             writes.add(FunctionActivationPLoc, LazyNode(node->child1().node()));
+            if (isArrowFunction)
+                writes.add(ArrowFunctionBoundThisPLoc, LazyNode(node->child2().node()));
             break;
         }
 
@@ -1015,6 +1018,14 @@ private:
                 m_heap.escape(node->child1().node());
             break;
 
+        case LoadArrowFunctionThis:
+            target = m_heap.onlyLocalAllocation(node->child1().node());
+            if (target && target->isArrowFunctionAllocation())
+                exactRead = ArrowFunctionBoundThisPLoc;
+            else
+                m_heap.escape(node->child1().node());
+            break;
+        
         case GetScope:
             target = m_heap.onlyLocalAllocation(node->child1().node());
             if (target && target->isFunctionAllocation())
@@ -2034,8 +2045,9 @@ private:
         
         case NewFunction:
         case NewArrowFunction: {
+            bool isArrowFunction = node->op() == NewArrowFunction;
             Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
-            ASSERT(locations.size() == 2);
+            ASSERT(locations.size() == (isArrowFunction ? 3 : 2));
                 
             PromotedHeapLocation executable(FunctionExecutablePLoc, allocation.identifier());
             ASSERT_UNUSED(executable, locations.contains(executable));
@@ -2044,6 +2056,13 @@ private:
             ASSERT(locations.contains(activation));
 
             node->child1() = Edge(resolve(block, activation), KnownCellUse);
+            
+            if (isArrowFunction) {
+                PromotedHeapLocation boundThis(ArrowFunctionBoundThisPLoc, allocation.identifier());
+                ASSERT(locations.contains(boundThis));
+                node->child2() = Edge(resolve(block, boundThis), CellUse);
+            }
+            
             break;
         }
 
index 49d5c74..59ae9f3 100644 (file)
@@ -594,6 +594,10 @@ private:
             changed |= setPrediction(SpecObjectOther);
             break;
 
+        case LoadArrowFunctionThis:
+            changed |= setPrediction(SpecFinalObject);
+            break;
+
         case In:
             changed |= setPrediction(SpecBoolean);
             break;
index 24f6977..8fe1591 100644 (file)
@@ -102,6 +102,10 @@ void printInternal(PrintStream& out, PromotedLocationKind kind)
     case ClosureVarPLoc:
         out.print("ClosureVarPLoc");
         return;
+
+    case ArrowFunctionBoundThisPLoc:
+        out.print("ArrowFunctionBoundThisPLoc");
+        return;
     }
     
     RELEASE_ASSERT_NOT_REACHED();
index b4e3c2b..97293f3 100644 (file)
@@ -46,7 +46,8 @@ enum PromotedLocationKind {
     FunctionExecutablePLoc,
     FunctionActivationPLoc,
     ActivationScopePLoc,
-    ClosureVarPLoc
+    ClosureVarPLoc,
+    ArrowFunctionBoundThisPLoc
 };
 
 class PromotedLocationDescriptor {
index 616c3b0..f5c68db 100644 (file)
@@ -202,6 +202,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case Arrayify:
     case ArrayifyToStructure:
     case GetScope:
+    case LoadArrowFunctionThis:
     case SkipScope:
     case GetClosureVar:
     case PutClosureVar:
index d0781e6..800613c 100755 (executable)
@@ -4739,6 +4739,15 @@ void SpeculativeJIT::compileGetScope(Node* node)
     m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSFunction::offsetOfScopeChain()), result.gpr());
     cellResult(result.gpr(), node);
 }
+
+    
+void SpeculativeJIT::compileLoadArrowFunctionThis(Node* node)
+{
+    SpeculateCellOperand function(this, node->child1());
+    GPRTemporary result(this, Reuse, function);
+    m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSArrowFunction::offsetOfThisValue()), result.gpr());
+    cellResult(result.gpr(), node);
+}
     
 void SpeculativeJIT::compileSkipScope(Node* node)
 {
index c42ba31..8660b04 100755 (executable)
@@ -2200,6 +2200,7 @@ public:
     void compileGetByValOnScopedArguments(Node*);
     
     void compileGetScope(Node*);
+    void compileLoadArrowFunctionThis(Node*);
     void compileSkipScope(Node*);
 
     void compileGetArrayLength(Node*);
index 6e0f146..b0c4e94 100644 (file)
@@ -3799,6 +3799,10 @@ void SpeculativeJIT::compile(Node* node)
     case GetScope:
         compileGetScope(node);
         break;
+
+    case LoadArrowFunctionThis:
+        compileLoadArrowFunctionThis(node);
+        break;
             
     case SkipScope:
         compileSkipScope(node);
index f11822d..570332c 100644 (file)
@@ -3837,6 +3837,10 @@ void SpeculativeJIT::compile(Node* node)
         compileGetScope(node);
         break;
             
+    case LoadArrowFunctionThis:
+        compileLoadArrowFunctionThis(node);
+        break;
+            
     case SkipScope:
         compileSkipScope(node);
         break;
index 8728d9e..64a4822 100644 (file)
@@ -152,6 +152,7 @@ inline CapabilityLevel canCompile(Node* node)
     case CountExecution:
     case GetExecutable:
     case GetScope:
+    case LoadArrowFunctionThis:
     case GetCallee:
     case GetArgumentCount:
     case ToString:
index 072a32a..4adc1aa 100644 (file)
@@ -810,6 +810,9 @@ private:
         case GetScope:
             compileGetScope();
             break;
+        case LoadArrowFunctionThis:
+            compileLoadArrowFunctionThis();
+            break;
         case SkipScope:
             compileSkipScope();
             break;
@@ -4504,6 +4507,11 @@ private:
         setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSFunction_scope));
     }
     
+    void compileLoadArrowFunctionThis()
+    {
+        setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSArrowFunction_this));
+    }
+    
     void compileSkipScope()
     {
         setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSScope_next));
index 37015b6..c3672e8 100644 (file)
@@ -164,17 +164,25 @@ extern "C" JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
         // Figure out what the executable and activation are
         FunctionExecutable* executable = nullptr;
         JSScope* activation = nullptr;
+        JSValue boundThis;
+        bool isArrowFunction = false;
         for (unsigned i = materialization->properties().size(); i--;) {
             const ExitPropertyValue& property = materialization->properties()[i];
             if (property.location() == PromotedLocationDescriptor(FunctionExecutablePLoc))
                 executable = jsCast<FunctionExecutable*>(JSValue::decode(values[i]));
             if (property.location() == PromotedLocationDescriptor(FunctionActivationPLoc))
                 activation = jsCast<JSScope*>(JSValue::decode(values[i]));
+            if (property.location() == PromotedLocationDescriptor(ArrowFunctionBoundThisPLoc)) {
+                isArrowFunction = true;
+                boundThis = JSValue::decode(values[i]);
+            }
         }
         RELEASE_ASSERT(executable && activation);
 
         
-        JSFunction* result = JSFunction::createWithInvalidatedReallocationWatchpoint(vm, executable, activation);
+        JSFunction* result = isArrowFunction
+            ? JSArrowFunction::createWithInvalidatedReallocationWatchpoint(vm, executable, activation, boundThis)
+            : JSFunction::createWithInvalidatedReallocationWatchpoint(vm, executable, activation);
 
         return result;
     }
index ea3db19..c54751c 100644 (file)
@@ -172,7 +172,7 @@ JSValue eval(CallFrame* callFrame)
         ASSERT(!callFrame->vm().exception());
 
         ThisTDZMode thisTDZMode = callerCodeBlock->unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded;
-        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, callerCodeBlock->unlinkedCodeBlock()->isDerivedConstructorContext(), callerCodeBlock->unlinkedCodeBlock()->isArrowFunction(), programSource, callerScopeChain);
+        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, programSource, callerScopeChain);
         if (!eval)
             return jsUndefined();
     }
index cb52c45..2d6f02c 100644 (file)
@@ -221,6 +221,7 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_end)
         DEFINE_OP(op_enter)
         DEFINE_OP(op_get_scope)
+        DEFINE_OP(op_load_arrowfunction_this)
         DEFINE_OP(op_eq)
         DEFINE_OP(op_eq_null)
         case op_get_array_length:
index 515279f..6850f7a 100755 (executable)
@@ -500,6 +500,7 @@ namespace JSC {
         void emit_op_end(Instruction*);
         void emit_op_enter(Instruction*);
         void emit_op_get_scope(Instruction*);
+        void emit_op_load_arrowfunction_this(Instruction*);
         void emit_op_eq(Instruction*);
         void emit_op_eq_null(Instruction*);
         void emit_op_get_by_id(Instruction*);
index cbbcf3f..f60ae57 100755 (executable)
@@ -684,6 +684,14 @@ void JIT::emit_op_get_scope(Instruction* currentInstruction)
     loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT0);
     emitStoreCell(dst, regT0);
 }
+    
+void JIT::emit_op_load_arrowfunction_this(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);
+    loadPtr(Address(regT0, JSArrowFunction::offsetOfThisValue()), regT0);
+    emitStoreCell(dst, regT0);
+}
 
 void JIT::emit_op_to_this(Instruction* currentInstruction)
 {
@@ -980,14 +988,23 @@ void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
     
 void JIT::emitNewFuncExprCommon(Instruction* currentInstruction)
 {
+    OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode);
+    bool isArrowFunction = opcodeID == op_new_arrow_func_exp;
+    
     Jump notUndefinedScope;
     int dst = currentInstruction[1].u.operand;
 #if USE(JSVALUE64)
     emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+    if (isArrowFunction)
+        emitGetVirtualRegister(currentInstruction[4].u.operand, regT1);
     notUndefinedScope = branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsUndefined())));
     store64(TrustedImm64(JSValue::encode(jsUndefined())), Address(callFrameRegister, sizeof(Register) * dst));
 #else
     emitLoadPayload(currentInstruction[2].u.operand, regT0);
+    if (isArrowFunction) {
+        int value = currentInstruction[4].u.operand;
+        emitLoad(value, regT3, regT2);
+    }
     notUndefinedScope = branch32(NotEqual, tagFor(currentInstruction[2].u.operand), TrustedImm32(JSValue::UndefinedTag));
     emitStore(dst, jsUndefined());
 #endif
@@ -995,7 +1012,14 @@ void JIT::emitNewFuncExprCommon(Instruction* currentInstruction)
     notUndefinedScope.link(this);
         
     FunctionExecutable* function = m_codeBlock->functionExpr(currentInstruction[3].u.operand);
-    callOperation(operationNewFunction, dst, regT0, function);
+    if (isArrowFunction)
+#if USE(JSVALUE64)
+        callOperation(operationNewArrowFunction, dst, regT0, function, regT1);
+#else 
+        callOperation(operationNewArrowFunction, dst, regT0, function, regT3, regT2);
+#endif
+    else
+        callOperation(operationNewFunction, dst, regT0, function);
     done.link(this);
 }
     
index 89455ed..4e04365 100644 (file)
@@ -938,6 +938,14 @@ void JIT::emit_op_get_scope(Instruction* currentInstruction)
     emitStoreCell(dst, regT0);
 }
 
+void JIT::emit_op_load_arrowfunction_this(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);
+    loadPtr(Address(regT0, JSArrowFunction::offsetOfThisValue()), regT0);
+    emitStoreCell(dst, regT0);
+}
+
 void JIT::emit_op_create_this(Instruction* currentInstruction)
 {
     int callee = currentInstruction[2].u.operand;
index 1a52aff..765f197 100644 (file)
@@ -1055,12 +1055,13 @@ LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
 LLINT_SLOW_PATH_DECL(slow_path_new_arrow_func_exp)
 {
     LLINT_BEGIN();
-    
+
+    JSValue thisValue = LLINT_OP_C(4).jsValue();
     CodeBlock* codeBlock = exec->codeBlock();
     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
     FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
     
-    LLINT_RETURN(JSFunction::create(vm, executable, scope));
+    LLINT_RETURN(JSArrowFunction::create(vm, executable, scope, thisValue));
 }
 
 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
index 1bf13eb..5ad5b3f 100644 (file)
@@ -1461,7 +1461,7 @@ _llint_op_new_func_exp:
 _llint_op_new_arrow_func_exp:
     traceExecution()
     callSlowPath(_llint_slow_path_new_arrow_func_exp)
-    dispatch(4)
+    dispatch(5)
 
 _llint_op_call:
     traceExecution()
index c5a87e3..e1d122c 100644 (file)
@@ -2422,6 +2422,16 @@ _llint_op_profile_control_flow:
     dispatch(2)
 
 
+_llint_op_load_arrowfunction_this:
+    traceExecution()
+    loadi Callee + PayloadOffset[cfr], t0
+    loadi JSArrowFunction::m_boundThis[t0], t0
+    loadisFromInstruction(1, t1)
+    storei CellTag, TagOffset[cfr, t1, 8]
+    storei t0, PayloadOffset[cfr, t1, 8]
+    dispatch(2)
+
+
 _llint_op_get_rest_length:
     traceExecution()
     loadi PayloadOffset + ArgumentCount[cfr], t0
index e18d81c..49f3cd7 100644 (file)
@@ -2284,14 +2284,22 @@ _llint_op_profile_type:
 .opProfileTypeDone:
     dispatch(6)
 
-
-
 _llint_op_profile_control_flow:
     traceExecution()
     loadpFromInstruction(1, t0)
     addq 1, BasicBlockLocation::m_executionCount[t0]
     dispatch(2)
 
+
+_llint_op_load_arrowfunction_this:
+    traceExecution()
+    loadp Callee[cfr], t0
+    loadp JSArrowFunction::m_boundThis[t0], t0
+    loadisFromInstruction(1, t1)
+    storeq t0, [cfr, t1, 8]
+    dispatch(2)
+
+
 _llint_op_get_rest_length:
     traceExecution()
     loadi PayloadOffset + ArgumentCount[cfr], t0
index b15a813..ce985ca 100644 (file)
@@ -374,7 +374,7 @@ public:
 
     ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
     {
-        usesArrowFunction();
+        usesThis();
         SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn);
         ArrowFuncExprNode* result = new (m_parserArena) ArrowFuncExprNode(location, *functionInfo.name, functionInfo.body, source);
         functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
@@ -912,7 +912,6 @@ private:
 
     void incConstants() { m_scope.m_numConstants++; }
     void usesThis() { m_scope.m_features |= ThisFeature; }
-    void usesArrowFunction() { m_scope.m_features |= ArrowFunctionFeature; }
     void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
     void usesWith() { m_scope.m_features |= WithFeature; }
     void usesEval() 
index d839c12..5ca3466 100644 (file)
@@ -1559,7 +1559,6 @@ namespace JSC {
 
         bool usesEval() const { return m_features & EvalFeature; }
         bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
-        bool usesArrowFunction() const { return m_features & ArrowFunctionFeature; }
         bool modifiesParameter() const { return m_features & ModifiedParameterFeature; }
         bool modifiesArguments() const { return m_features & (EvalFeature | ModifiedArgumentsFeature); }
         bool isStrictMode() const { return m_features & StrictModeFeature; }
index 4f6ade8..0af2c5a 100644 (file)
@@ -1876,11 +1876,11 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
         semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
         semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
     }
-    if (functionScope->hasDirectSuper() && functionBodyType == StandardFunctionBodyBlock) {
+    if (functionScope->hasDirectSuper()) {
         semanticFailIfTrue(!isClassConstructor, "Cannot call super() outside of a class constructor");
         semanticFailIfTrue(constructorKind != ConstructorKind::Derived, "Cannot call super() in a base class constructor");
     }
-    if (functionScope->needsSuperBinding() && functionBodyType == StandardFunctionBodyBlock)
+    if (functionScope->needsSuperBinding())
         semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class");
 
     JSTokenLocation location = JSTokenLocation(m_token.m_location);
index 5268d78..49585cb 100644 (file)
@@ -143,19 +143,17 @@ inline bool functionNameScopeIsDynamic(bool usesEval, bool isStrictMode)
 
 typedef unsigned CodeFeatures;
 
-const CodeFeatures NoFeatures =                       0;
-const CodeFeatures EvalFeature =                 1 << 0;
-const CodeFeatures ArgumentsFeature =            1 << 1;
-const CodeFeatures WithFeature =                 1 << 2;
-const CodeFeatures ThisFeature =                 1 << 3;
-const CodeFeatures StrictModeFeature =           1 << 4;
-const CodeFeatures ShadowsArgumentsFeature =     1 << 5;
-const CodeFeatures ModifiedParameterFeature =    1 << 6;
-const CodeFeatures ModifiedArgumentsFeature =    1 << 7;
-const CodeFeatures ArrowFunctionFeature =        1 << 8;
-const CodeFeatures ArrowFunctionContextFeature = 1 << 9;
-
-const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature | ArrowFunctionFeature | ArrowFunctionContextFeature;
+const CodeFeatures NoFeatures =                    0;
+const CodeFeatures EvalFeature =              1 << 0;
+const CodeFeatures ArgumentsFeature =         1 << 1;
+const CodeFeatures WithFeature =              1 << 2;
+const CodeFeatures ThisFeature =              1 << 3;
+const CodeFeatures StrictModeFeature =        1 << 4;
+const CodeFeatures ShadowsArgumentsFeature =  1 << 5;
+const CodeFeatures ModifiedParameterFeature = 1 << 6;
+const CodeFeatures ModifiedArgumentsFeature = 1 << 7;
+
+const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature;
 
 } // namespace JSC
 
index c3ae1e3..f13b25e 100644 (file)
@@ -83,7 +83,8 @@ template <> struct CacheTypes<UnlinkedModuleProgramCodeBlock> {
 };
 
 template <class UnlinkedCodeBlockType, class ExecutableType>
-UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, bool, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ)
+UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode,
+    JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ)
 {
     SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, thisTDZMode);
     SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
@@ -111,8 +112,7 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe
     bool endColumnIsOnStartLine = !lineCount;
     unsigned unlinkedEndColumn = rootNode->endColumn();
     unsigned endColumn = unlinkedEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
-    unsigned arrowContextFeature = executable->isArrowFunctionContext() ? ArrowFunctionContextFeature : 0;
-    executable->recordParse(rootNode->features() | arrowContextFeature, rootNode->hasCapturedVariables(), rootNode->firstLine(), rootNode->lastLine(), startColumn, endColumn);
+    executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine(), rootNode->lastLine(), startColumn, endColumn);
 
     UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo());
     unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine() - source.firstLine(), lineCount, unlinkedEndColumn);
@@ -132,18 +132,18 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe
 UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
 {
     VariableEnvironment emptyParentTDZVariables;
-    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, false, debuggerMode, profilerMode, error, &emptyParentTDZVariables);
+    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error, &emptyParentTDZVariables);
 }
 
-UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, bool isArrowFunctionContext, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ)
+UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ)
 {
-    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, thisTDZMode, isArrowFunctionContext, debuggerMode, profilerMode, error, variablesUnderTDZ);
+    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ);
 }
 
 UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
 {
     VariableEnvironment emptyParentTDZVariables;
-    return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, ThisTDZMode::CheckIfNeeded, false, debuggerMode, profilerMode, error, &emptyParentTDZVariables);
+    return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error, &emptyParentTDZVariables);
 }
 
 // FIXME: There's no need to add the function's name to the key here. It's already in the source code.
@@ -188,7 +188,7 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v
     metadata->setEndPosition(positionBeforeLastNewline);
     // The Function constructor only has access to global variables, so no variables will be under TDZ.
     VariableEnvironment emptyTDZVariables;
-    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, false);
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables);
     functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
 
     m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
index 6d06de7..48c8cfe 100644 (file)
@@ -258,7 +258,7 @@ public:
     ~CodeCache();
 
     UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ProfilerMode, ParserError&);
-    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, bool, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);
+    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);
     UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ProfilerMode, ParserError&);
     UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);
 
@@ -269,7 +269,7 @@ public:
 
 private:
     template <class UnlinkedCodeBlockType, class ExecutableType> 
-    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, bool, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);
+    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);
 
     CodeCacheMap m_sourceCode;
 };
index bdd76a0..495f235 100644 (file)
     macro(Uint32Array) \
     macro(Float32Array) \
     macro(Float64Array) \
-    macro(newTargetLocal) \
-    macro(derivedConstructor) \
-
 
 
 namespace JSC {
index 0b605fa..490636f 100644 (file)
@@ -225,7 +225,7 @@ SLOW_PATH_DECL(slow_path_create_this)
     
 #if !ASSERT_DISABLED
     ConstructData constructData;
-    ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS || constructor->jsExecutable()->isArrowFunction());
+    ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
 #endif
 
     auto& cacheWriteBarrier = pc[4].u.jsCell;
index 1892ac1..8365292 100644 (file)
@@ -131,15 +131,13 @@ Intrinsic NativeExecutable::intrinsic() const
 
 const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(ScriptExecutable) };
 
-ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext, bool isInDerivedConstructorContext, bool isInArrowFunctionContext)
+ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext)
     : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
     , m_source(source)
     , m_features(isInStrictContext ? StrictModeFeature : 0)
     , m_hasCapturedVariables(false)
     , m_neverInline(false)
     , m_didTryToEnterInLoop(false)
-    , m_isDerivedConstructorContext(isInDerivedConstructorContext)
-    , m_isArrowFunctionContext(isInArrowFunctionContext)
     , m_overrideLineNumber(-1)
     , m_firstLine(-1)
     , m_lastLine(-1)
@@ -414,7 +412,7 @@ JSObject* ScriptExecutable::prepareForExecutionImpl(
 
 const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(EvalExecutable) };
 
-EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, ThisTDZMode thisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ)
+EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, ThisTDZMode thisTDZMode, const VariableEnvironment* variablesUnderTDZ)
 {
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     if (!globalObject->evalEnabled()) {
@@ -422,10 +420,10 @@ EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source
         return 0;
     }
 
-    EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext, isDerivedConstructorContext, isArrowFunctionContext);
+    EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
     executable->finishCreation(exec->vm());
 
-    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode, isArrowFunctionContext, variablesUnderTDZ);
+    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode, variablesUnderTDZ);
     if (!unlinkedEvalCode)
         return 0;
 
@@ -434,8 +432,8 @@ EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source
     return executable;
 }
 
-EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext, bool isDerivedConstructorContext, bool isArrowFunctionContext)
-    : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec->vm(), source, inStrictContext, isDerivedConstructorContext, isArrowFunctionContext)
+EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
+    : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec->vm(), source, inStrictContext)
 {
 }
 
@@ -447,7 +445,7 @@ void EvalExecutable::destroy(JSCell* cell)
 const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(ProgramExecutable) };
 
 ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
-    : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false, false, false)
+    : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false)
 {
     m_typeProfilingStartOffset = 0;
     m_typeProfilingEndOffset = source.length() - 1;
@@ -463,7 +461,7 @@ void ProgramExecutable::destroy(JSCell* cell)
 const ClassInfo ModuleProgramExecutable::s_info = { "ModuleProgramExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(ModuleProgramExecutable) };
 
 ModuleProgramExecutable::ModuleProgramExecutable(ExecState* exec, const SourceCode& source)
-    : ScriptExecutable(exec->vm().moduleProgramExecutableStructure.get(), exec->vm(), source, false, false, false)
+    : ScriptExecutable(exec->vm().moduleProgramExecutableStructure.get(), exec->vm(), source, false)
 {
     m_typeProfilingStartOffset = 0;
     m_typeProfilingEndOffset = source.length() - 1;
@@ -494,8 +492,10 @@ void ModuleProgramExecutable::destroy(JSCell* cell)
 
 const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
 
-FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn)
-    : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext(), unlinkedExecutable->isDerivedConstructorContext(), false)
+FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, 
+    UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, 
+    unsigned lastLine, unsigned startColumn, unsigned endColumn)
+    : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext())
     , m_unlinkedExecutable(vm, this, unlinkedExecutable)
 {
     RELEASE_ASSERT(!source.isNull());
index 25068e9..9fc9be7 100644 (file)
@@ -344,9 +344,7 @@ public:
     bool usesEval() const { return m_features & EvalFeature; }
     bool usesArguments() const { return m_features & ArgumentsFeature; }
     bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature); }
-    bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
     bool isStrictMode() const { return m_features & StrictModeFeature; }
-    bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; }
     ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
         
     void setNeverInline(bool value) { m_neverInline = value; }
@@ -395,7 +393,7 @@ private:
     JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind);
 
 protected:
-    ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, bool isInDerivedConstructorContext, bool isInArrowFunctionContext);
+    ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext);
 
     void finishCreation(VM& vm)
     {
@@ -414,8 +412,6 @@ protected:
     bool m_neverInline;
     bool m_neverOptimize { false };
     bool m_didTryToEnterInLoop;
-    bool m_isDerivedConstructorContext;
-    bool m_isArrowFunctionContext;
     int m_overrideLineNumber;
     int m_firstLine;
     int m_lastLine;
@@ -438,7 +434,7 @@ public:
         return m_evalCodeBlock.get();
     }
 
-    static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, ThisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const VariableEnvironment*);
+    static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, ThisTDZMode, const VariableEnvironment*);
 
     PassRefPtr<JITCode> generatedJITCode()
     {
@@ -452,7 +448,7 @@ public:
         
     DECLARE_INFO;
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false, isDerivedConstructorContext(), isArrowFunctionContext()); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); }
 
     unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
     unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
@@ -460,7 +456,7 @@ public:
 private:
     friend class ExecutableBase;
     friend class ScriptExecutable;
-    EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, bool isDerivedConstructorContext, bool isArrowFunctionContext);
+    EvalExecutable(ExecState*, const SourceCode&, bool);
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
@@ -505,7 +501,7 @@ public:
         
     DECLARE_INFO;
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false, isDerivedConstructorContext(), false); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); }
 
 private:
     friend class ExecutableBase;
@@ -546,8 +542,7 @@ public:
 
     DECLARE_INFO;
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false, isDerivedConstructorContext(), false); }
-
+    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); }
     UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); }
 
     SymbolTable* moduleEnvironmentSymbolTable() { return m_moduleEnvironmentSymbolTable.get(); }
@@ -656,7 +651,6 @@ public:
     bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
     ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); }
     bool isArrowFunction() const { return m_unlinkedExecutable->isArrowFunction(); }
-    bool isDerivedConstructorContext() const { return m_unlinkedExecutable->isDerivedConstructorContext(); }
     bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
     const Identifier& name() { return m_unlinkedExecutable->name(); }
     const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
index 208ce47..bc08f96 100644 (file)
@@ -949,14 +949,14 @@ UnlinkedProgramCodeBlock* JSGlobalObject::createProgramCodeBlock(CallFrame* call
     return unlinkedCodeBlock;
 }
 
-UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, ThisTDZMode thisTDZMode, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ)
+UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, ThisTDZMode thisTDZMode, const VariableEnvironment* variablesUnderTDZ)
 {
     ParserError error;
     JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
     DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
     ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
     UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock(
-        vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, thisTDZMode, isArrowFunctionContext, debuggerMode, profilerMode, error, variablesUnderTDZ);
+        vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ);
 
     if (hasDebugger())
         debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message());
index 37738e2..8e1629c 100644 (file)
@@ -661,7 +661,7 @@ public:
     unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
 
     UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception);
-    UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, bool isArrowFunctionContext, const VariableEnvironment*);
+    UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, const VariableEnvironment*);
     UnlinkedModuleProgramCodeBlock* createModuleProgramCodeBlock(CallFrame*, ModuleProgramExecutable*);
 
 protected:
index ce1e3bb..2bf13bb 100644 (file)
@@ -581,7 +581,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
 
     JSGlobalObject* calleeGlobalObject = exec->callee()->globalObject();
     VariableEnvironment emptyTDZVariables; // Indirect eval does not have access to the lexical scope.
-    EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false, ThisTDZMode::CheckIfNeeded, false, false, &emptyTDZVariables);
+    EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false, ThisTDZMode::CheckIfNeeded, &emptyTDZVariables);
     if (!eval)
         return JSValue::encode(jsUndefined());
 
index 771a3b5..88d4a7c 100644 (file)
 - path: es6/arrow_functions_lexical_arguments_binding.js
   cmd: runES6 :fail
 - path: es6/arrow_functions_lexical_new.target_binding.js
-  cmd: runES6 :normal
+  cmd: runES6 :fail
 - path: es6/arrow_functions_lexical_super_binding.js
   cmd: runES6 :fail
 - path: es6/arrow_functions_no_prototype_property.js
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js
deleted file mode 100644 (file)
index 7a8d27c..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-var testCase = function (actual, expected, message) {
-    if (actual !== expected) {
-        throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-    }
-};
-
-function getTarget(name) {
-    return x => new.target;
-}
-
-noInline(getTarget)
-
-for (var i=0; i < 1000; i++) {
-    var undefinedTarget = getTarget()();
-    testCase(undefinedTarget, undefined, "Error: new.target is not lexically binded inside of the arrow function #1");
-}
-
-for (var i = 0; i < 1000; i++) {
-    var newTarget = new getTarget()();
-    testCase(newTarget, getTarget, "Error: new.target is not lexically binded inside of the arrow function #2");
-}
-
-var passed = false;
-var A = class A {
-    constructor() {
-        this.idValue = 123;
-        passed = passed && new.target === B;
-    }
-};
-
-var B  = class B extends A {
-    constructor() {
-        var f = () => {
-            passed = new.target === B;
-            super();
-        };
-        f();
-    }
-};
-
-for (var i = 0; i < 1000; i++) {
-    passed = false;
-    var b = new B();
-
-    testCase(passed, true, "Error: new.target is not lexically binded inside of the arrow function in constructor #3");
-}
-
-var C = class C extends A {
-    constructor(tryToAccessToVarInArrow) {
-        var f = () => {
-            super();
-            if (tryToAccessToVarInArrow)
-                this.id2 = newTargetLocal;
-        };
-
-        f();
-
-        if (!tryToAccessToVarInArrow)
-            this.id = newTargetLocal;
-    }
-};
-
-var tryToCreateClass = function (val) {
-    var result = false;
-    try {
-        new C(val);
-    }
-    catch (e) {
-        result = e instanceof ReferenceError; 
-    }
-
-    return result;
-};
-
-for (var i = 0; i < 1000; i++) {
-    testCase(tryToCreateClass(true), true, "Error: newTargetLocal should be hided variable");
-    testCase(tryToCreateClass(false), true, "Error: newTargetLocal should be hided variable");
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-1.js b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-1.js
deleted file mode 100644 (file)
index c247147..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-var testCase = function (actual, expected, message) {
-    if (actual !== expected) {
-        throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-    }
-};
-
-var testValue  = 'test-value';
-
-var A = class A {
-    constructor() {
-        this.idValue = testValue;
-    }
-};
-
-var B = class B extends A {
-    constructor (inArrowFuction, inConstructor) {
-        var arrow = () => {
-            if (inArrowFuction) {
-                super();
-                testCase(this.idValue, testValue, "Error: super() should create this and put value into idValue property");
-            }
-        }
-
-        if (inArrowFuction)
-            arrow();
-
-        if (inConstructor)
-            super();
-
-        testCase(this.idValue, testValue, "Error: arrow function should return this to constructor");
-    }
-};
-
-for (var i = 0; i < 1000; i++) {
-    new B(true, false);
-    new B(false, true);
-}
-
-var testException = function (value1, value2, index) {
-    var exception;
-    try {
-        new B(value1, value2);
-    } catch (e) {
-        exception = e;
-        if (!(e instanceof ReferenceError))
-            throw "Exception thrown was not a reference error";
-    }
-
-    if (!exception)
-        throw "Exception not thrown for an unitialized this at iteration " + index;
-}
-
-for (var i=0; i < 1000; i++) {
-    testException(false, false, i);
-}
-
-var C = class C extends A {
-    constructor() {
-        eval("var x = 20");
-        super();
-        let f = () => this;
-        let xf = f();
-        xf.id = 'test-id';
-    }
-};
-
-var c = new C();
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js
deleted file mode 100644 (file)
index 83c8e37..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-var testCase = function (actual, expected, message) {
-    if (actual !== expected) {
-        throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-    }
-};
-
-var testValue  = 'test-value';
-
-var A = class A {
-    constructor() {
-        this.idValue = testValue;
-    }
-};
-
-var B = class B extends A {
-    constructor (inArrowFuction, inConstructor, setProtoToNull) {
-        var arrow = () => () => () => {
-            if (inArrowFuction) {
-              super();
-              testCase(this.idValue, testValue, "Error: super() should create this and put value into idValue property");
-            }
-        };
-
-        if (inArrowFuction)
-            arrow()()();
-
-        if (inConstructor)
-            super();
-
-        testCase(this.idValue, testValue, "Error: arrow function should return this to constructor");
-    }
-};
-
-for (var i=0; i < 1000; i++) {
-    new B(true, false);
-    new B(false, true);
-}
-
-var testException = function (index) {
-    var exception;
-    try {
-        new B(false, false);
-    } catch (e) {
-        exception = e;
-        if (!(e instanceof ReferenceError))
-            throw "Exception thrown was not a correct error. Expected ReferenceError but was " + e.name;
-    }
-
-    if (!exception)
-        throw "Exception not thrown for an unitialized this at iteration #" + index;
-}
-
-for (var i = 0; i < 1000; i++) {
-  testException(i, ReferenceError);
-}
-
-var C = class C extends A {
-    constructor () {
-      var arrow = () => {
-          let __proto__ = 'some-text';
-          var arr = () => {
-              testCase(typeof  __proto__, 'string', "Erorr: __proto__ variable has wrong type");
-              super();
-              testCase(this.idValue, testValue, "Error: super() should create this and put value into idValue property");
-           };
-           arr();
-       };
-
-      arrow();
-
-      testCase(this.idValue, testValue, "Error: arrow function should return this to constructor");
-    }
-};
-
-for (var i = 0; i < 1000; i++) {
-    new C();
-}
-
-class D extends A {
-    constructor(doReplaceProto) {
-        var arrow = () => super();
-        if (doReplaceProto)
-            D.__proto__ = function () {};
-        arrow();
-    }
-}
-
-testCase((new D(false)).idValue, testValue, "Error: arrow function bound wrong super");
-testCase(typeof (new D(true)).idValue, "undefined" , "Error: arrow function bound wrong super");
-
-class E extends A {
-    constructor(doReplaceProto) {
-        var arrow = () => {
-            if (doReplaceProto)
-                E.__proto__ = function () {};
-            super();
-        };
-
-        arrow();
-    }
-}
-
-testCase((new E(false)).idValue, testValue, "Error: arrow function bound wrong super #1");
-testCase(typeof (new E(true)).idValue, "undefined" , "Error: arrow function bound wrong super #1");
-
-
-class F extends A {
-    constructor(doReplaceProto) {
-        var arrow = () => {
-            F.__proto__ = null;
-            super();
-        };
-
-        arrow();
-    }
-}
-
-var testTypeErrorException = function (index) {
-    var exception;
-    try {
-        new F();
-    } catch (e) {
-        exception = e;
-        if (!(e instanceof TypeError))
-            throw "Exception thrown was not a correct error. Expected TypeError but was " + e.name;
-    }
-
-    if (!exception)
-        throw "Exception not thrown for an unitialized this at iteration #" + index;
-}
-
-for (var i = 0; i < 1000; i++) {
-  testTypeErrorException(i);
-}
-
-var errorStack;
-
-var ParentClass = class ParentClass {
-    constructor() {
-        try {
-            this.idValue = testValue;
-            throw new Error('Error');
-        } catch (e) {
-            errorStack  = e.stack;
-        }
-    }
-};
-
-var ChildClass = class ChildClass extends ParentClass {
-    constructor () {
-        var arrowInChildConstructor = () => {
-            var nestedArrow = () => {
-                super();
-            }
-
-            nestedArrow();
-        };
-
-        arrowInChildConstructor();
-    }
-};
-
-for (var i = 0; i < 1000; i++) {
-    errorStack = '';
-    let c = new ChildClass();
-
-    let parentClassIndexOf = errorStack.indexOf('ParentClass');
-    let nestedArrowIndexOf = errorStack.indexOf('nestedArrow');
-    let arrowInChildConstructorIndexOf = errorStack.indexOf('arrowInChildConstructor');
-    let childClassIndexOf = errorStack.indexOf('ChildClass');
-
-    testCase(parentClassIndexOf > -1 && errorStack.indexOf('ParentClass', parentClassIndexOf + 1) === -1, true, "Error: stack of error should contain ParentClass text");
-    testCase(nestedArrowIndexOf > -1 && errorStack.indexOf('nestedArrow', nestedArrowIndexOf + 1) === -1, true, "Error: stack of error should contain nestedArrow text");
-    testCase(arrowInChildConstructorIndexOf > -1 && errorStack.indexOf('arrowInChildConstructor', arrowInChildConstructorIndexOf + 1) === -1, true, "Error: stack of error should contain arrowInChildConstructor text");
-    testCase(childClassIndexOf > -1 && errorStack.indexOf('ChildClass', childClassIndexOf + 1) === -1, true, "Error: stack of error should contains ChildClass text");
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-3.js b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-3.js
deleted file mode 100644 (file)
index 6fbb6d5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-var testCase = function (actual, expected, message) {
-    if (actual !== expected) {
-        throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-    }
-};
-
-var testValue  = 'test-value';
-
-var A = class A {
-    constructor() {
-        this.idValue = testValue;
-    }
-};
-
-var B = class B extends A {
-    constructor (beforeSuper) {
-        var arrow = () => eval('(() => this.idValue)()');
-
-        if (beforeSuper) {
-            var result = arrow();
-            super();
-            testCase(result, testValue, "Error: has to be TDZ error");
-        } else {
-            super();
-            let result= arrow();
-            testCase(result, testValue, "Error: super() should create this and put value into idValue property");
-        }
-    }
-};
-
-for (var i = 0; i < 1000; i++) {
-    var b = new B(false);
-}
-
-var testException = function (value, index) {
-  var exception;
-  try {
-       new B(value);
-  } catch (e) {
-      exception = e;
-      if (!(e instanceof ReferenceError))
-          throw "Exception thrown was not a reference error";
-  }
-
-  if (!exception)
-      throw "Exception not thrown for an unitialized this at iteration #" + index;
-}
-
-
-for (var i = 0; i < 1000; i++) {
-    testException(true, i);
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-4.js b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-4.js
deleted file mode 100644 (file)
index 18a6f70..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-var testCase = function (actual, expected, message) {
-    if (actual !== expected) {
-        throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-    }
-};
-
-var testValue  = 'test-value';
-
-var A = class A {
-    constructor() {
-        this.idValue = testValue;
-    }
-};
-
-var B = class B extends A {
-  constructor (beforeSuper) {
-
-      var arrow = () => eval('(() => super())()');
-
-      if (beforeSuper) {
-          arrow();
-          testCase(this.idValue, testValue, "Error: super() should create this and put value into idValue property");
-      } else {
-          testCase(this.idValue, testValue, "Error: has to be TDZ error");
-          arrow();
-      }
-  }
-};
-
-var C = class C extends A {
-    constructor () {
-        var arrow = () => eval('(() => super())()');
-        arrow();
-        return {};
-    }
-};
-
-var D = class D extends A {
-    constructor () {
-        var arrow = () => eval('(() => super())()');
-        arrow();
-        eval('this.id="new-value"');
-    }
-};
-
-var E = class E extends A {
-    constructor () {
-        var arrow = () => eval("eval('(() => super())()')");
-        arrow();
-        eval('eval("this.id=\'new-value\'")');
-    }
-};
-
-for (var i=0; i < 1000; i++) {
-    new B(true);
-    var c = new C();
-    testCase(typeof c.id, 'undefined', 'Error during set value in eval #1');
-    var d = new D();
-    testCase(d.id, 'new-value', 'Error during set value in eval #2');
-    var e = new E();
-    testCase(e.id, 'new-value', 'Error during set value in eval #3');
-}
-
-var testException = function (value, index) {
-    var exception;
-    try {
-        new B(value);
-    } catch (e) {
-        exception = e;
-        if (!(e instanceof ReferenceError))
-            throw "Exception thrown was not a reference error";
-    }
-
-    if (!exception)
-        throw "Exception not thrown for an unitialized this at iteration #" + index;
-}
-
-for (var i=0; i < 1000; i++) {
-    testException(false, i);
-}
index 69cb8cd..4cfab24 100644 (file)
@@ -8,7 +8,6 @@ function Dog(name) {
   this.name = name;
   this.getName = () => eval("this.name");
   this.getNameHard = () => eval("(() => this.name)()");
-  this.getNameReallyHard = () => eval("eval('(() => this.name)()')");
 }
 
 noInline(Dog)
@@ -17,5 +16,4 @@ for (var i=0;i<10000; i++) {
   var d = new Dog("Max");
   testCase(d.getName(), d.name, "Error: this is not lexically binded inside of the arrow function #1");
   testCase(d.getNameHard(), d.name, "Error: this is not lexically binded inside of the arrow function #2");
-  testCase(d.getNameReallyHard(), d.name, "Error: this is not lexically binded inside of the arrow function #3");
 }
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-7.js b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-7.js
deleted file mode 100644 (file)
index 2f76c9d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-var testCase = function (actual, expected, message) {
-    if (actual !== expected) {
-        throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-    }
-};
-
-var deepScope = function (x, y) {
-    var _x = x, _y = y;
-    return ()=> _x + _y + this.val;
-};
-
-var a = deepScope.call({val:'A'}, 'D', 'E');
-var b = deepScope.call({val:'B'}, 'D', 'F');
-var c = deepScope.call({val:'C'}, 'D', 'G');
-
-var anotherScope = function (_af) {
-    return _af();
-};
-
-for (var i = 0; i < 1000; i++) {
-    testCase(c(), anotherScope.call({val:'I'}, c), "Error: this is not lexically binded inside of the arrow function #1");
-    testCase(b(), anotherScope.call({val:'J'}, b), "Error: this is not lexically binded inside of the arrow function #2");
-    testCase(a(), anotherScope.call({val:'K'}, a), "Error: this is not lexically binded inside of the arrow function #3");
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-1.js b/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-1.js
deleted file mode 100644 (file)
index 8d4d9d4..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-var A = class A { };
-var B = class B extends A {
-    constructor(beforeSuper, returnThis) {
-        var f = () => returnThis ? this : {};
-        if (beforeSuper) {
-            let val = f();
-            super();
-        } else {
-            super();
-            let val = f();
-        }
-    }
-};
-
-var exception = null;
-for (var i=0; i < 10000; i++) {
-    try {
-        new B(true, true);
-    } catch (e) {
-        exception = e;
-        if (!(e instanceof ReferenceError))
-            throw "Exception thrown was not a reference error";
-    }
-
-    if (!exception)
-        throw "Exception not thrown for an unitialized this at iteration";
-
-    var a = new B(false, true);
-    var b = new B(false, false);
-    var c = new B(true, false);
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-2.js b/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-2.js
deleted file mode 100644 (file)
index 7afccaf..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-var A = class A { };
-var B = class B extends A {
-    constructor(beforeSuper, returnThis) {
-        var f = () => returnThis ? (() => this ) : (()=>{});
-        let af = f();
-        if (beforeSuper) {
-            let result = af();
-            super();
-        } else {
-            super();
-            let result = af();
-        }
-    }
-};
-
-var exception = null;
-for (var i = 0; i < 10000; i++) {
-    try {
-        new B(true, true);
-    } catch (e) {
-        exception = e;
-        if (!(e instanceof ReferenceError))
-            throw "Exception thrown was not a reference error";
-    }
-
-    if (!exception)
-        throw "Exception not thrown for an unitialized this at iteration";
-
-    var a = new B(false, true);
-    var b = new B(false, false);
-    var c = new B(true, false);
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-3.js b/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-3.js
deleted file mode 100644 (file)
index ab98309..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-var testCase = function (actual, expected, message) {
-  if (actual !== expected) {
-    throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-  }
-};
-
-var A = class A {
-   constructor() {
-      this.id = 'A'
-   }
-};
-
-var B = class B extends A {
-  constructor(beforeSuper) {
-    var f = () => {
-      if (this.id === 'A') {
-        return 'ok';
-      }
-      return 'ok';
-    };
-    let val;
-    if (beforeSuper) {
-      val = f();
-      super();
-    } else {
-      super();
-      val = f();
-    }
-    this.res = val;
-  }
-};
-
-var C = class C extends A {
-  constructor(beforeSuper) {
-    var f = () => {
-      if (this > 5) {
-        return 'ok';
-      }
-      return 'ok';
-    };
-    let val;
-    if (beforeSuper) {
-      val = f();
-      super();
-    } else {
-      super();
-      val = f();
-    }
-    this.res = val;
-  }
-};
-
-var D = class D extends A {
-  constructor(beforeSuper) {
-    var f = () => {
-      if (this < 5) {
-        return 'ok';
-      }
-      return 'ok';
-    };
-    let val;
-    if (beforeSuper) {
-      val = f();
-      super();
-    } else {
-      super();
-      val = f();
-    }
-    this.res = val;
-  }
-};
-
-var E = class E extends A {
-  constructor(beforeSuper) {
-    var f = () => {
-      if (this !== 5) {
-        return 'ok';
-      }
-      return 'ok';
-    };
-    let val;
-    if (beforeSuper) {
-      val = f();
-      super();
-    } else {
-      super();
-       val = f();
-    }
-    this.res = val;
-  }
-};
-
-var F = class F extends A {
-  constructor(beforeSuper) {
-    var f = () => {
-      if (this <= 5) {
-        return 'ok';
-      }
-      return 'ok';
-    };
-    let val;
-    if (beforeSuper) {
-      val = f();
-      super();
-    } else {
-      super();
-      val = f();
-    }
-    this.res = val;
-  }
-};
-
-var G = class G extends A {
-  constructor(beforeSuper) {
-    var f = () => {
-      if (this >= 5) {
-        return 'ok';
-      }
-      return 'ok';
-    };
-    let val;
-    if (beforeSuper) {
-      val = f();
-      super();
-    } else {
-      super();
-      val = f();
-    }
-    this.res = val;
-  }
-};
-
-var G = class G extends A {
-  constructor(beforeSuper) {
-    var f = () => {
-      if (this === 5) {
-        return 'ok';
-      }
-      return 'ok';
-    };
-    let val;
-    if (beforeSuper) {
-      val = f();
-      super();
-    } else {
-      super();
-      val = f();
-    }
-    this.res = val;
-  }
-};
-
-var tryToCreate = function (classForCreate) {
-  var result = false;
-  try {
-       new classForCreate(true);
-  } catch (e) {
-      result = e instanceof ReferenceError;
-  }
-
-  return result;
-}
-
-var check = function (classForCheck) {
-  testCase(tryToCreate(classForCheck), true, 'Exception wasn\'t thrown or was not a reference error');
-  var result = new classForCheck(false);
-  testCase(result.res, 'ok', 'Error in setting id ');
-}
-
-for (var i = 0; i < 10000; i++) {
-  check(B);
-  check(C);
-  check(D);
-  check(E);
-  check(F);
-  check(G);
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-4.js b/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-4.js
deleted file mode 100644 (file)
index 87c2927..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-var testCase = function (actual, expected, message) {
-    if (actual !== expected) {
-        throw message + ". Expected '" + expected + "', but was '" + actual + "'";
-    }
-};
-
-var testValue  = 'test-value';
-
-var A = class A {
-    constructor() {
-        this.idValue = testValue;
-    }
-};
-
-var B = class B extends A {
-  constructor (doRunSuper) {
-      var arrow = () => {
-          if (doRunSuper) {
-              super();
-              testCase(this.idValue, testValue, "Error: super() should create this and put value into idValue property");
-          }
-      }
-
-      if (doRunSuper) {
-          arrow();
-          testCase(this.idValue, testValue, "Error: arrow function should return this to constructor");
-      } else {
-          var value = this.idValue;//force TDZ error
-          debug(value);
-      }
-  }
-};
-
-for (var i=0; i < 10000; i++) {
-    var exception;
-    try {
-        new B(false);
-    } catch (e) {
-        exception = e;
-        if (!(e instanceof ReferenceError))
-            throw "Exception thrown was not a reference error";
-    }
-
-    if (!exception)
-        throw "Exception not thrown for an unitialized this at iteration #" + i;
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz.js b/Source/JavaScriptCore/tests/stress/arrowfunction-tdz.js
new file mode 100644 (file)
index 0000000..6874923
--- /dev/null
@@ -0,0 +1,27 @@
+var A = class A { };
+var B = class B extends A {
+  constructor(accessThisBeforeSuper) {
+    if (accessThisBeforeSuper) {
+      var f = () => this;
+      super();
+    } else {
+      super();
+    }
+  }
+};
+
+var exception = null;
+for (var i=0; i<10000; i++) {
+  try {
+       new B(true);
+  } catch (e) {
+      exception = e;
+      if (!(e instanceof ReferenceError))
+          throw "Exception thrown was not a reference error";
+  }
+
+  if (!exception)
+      throw "Exception not thrown for an unitialized this at iteration";
+
+  var e = new B(false);
+}