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
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@192882 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 254ff9a..37816b6 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -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
index 8a39c37..0000000
--- a/LayoutTests/js/arrowfunction-supercall-expected.txt
+++ /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
index 6d98e81..0000000
--- a/LayoutTests/js/arrowfunction-supercall.html
+++ /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>
diff --git a/LayoutTests/js/arrowfunction-tdz-expected.txt b/LayoutTests/js/arrowfunction-tdz-expected.txt
index fcb6a44..17af6cd 100644
--- a/LayoutTests/js/arrowfunction-tdz-expected.txt
+++ b/LayoutTests/js/arrowfunction-tdz-expected.txt
@@ -4,14 +4,6 @@
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
index 2cef609..0000000
--- a/LayoutTests/js/script-tests/arrowfunction-supercall.js
+++ /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;
diff --git a/LayoutTests/js/script-tests/arrowfunction-tdz.js b/LayoutTests/js/script-tests/arrowfunction-tdz.js
index b41aa67..aaf58fc 100644
--- a/LayoutTests/js/script-tests/arrowfunction-tdz.js
+++ b/LayoutTests/js/script-tests/arrowfunction-tdz.js
@@ -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 @@
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;
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 33b4244..ab49f9a 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -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
diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp b/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
index c81e26c..816b4a5 100644
--- a/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
+++ b/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
@@ -115,7 +115,7 @@
}
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;
}
diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.json b/Source/JavaScriptCore/bytecode/BytecodeList.json
index 61ee4d7..f6c89a9 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeList.json
+++ b/Source/JavaScriptCore/bytecode/BytecodeList.json
@@ -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 },
@@ -127,6 +127,7 @@
{ "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 }
diff --git a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
index 5a20f48..cbb8948 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
+++ b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
@@ -57,6 +57,7 @@
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 @@
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:
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index ce51aef..9e1386e 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -757,6 +757,11 @@
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 @@
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: {
diff --git a/Source/JavaScriptCore/bytecode/EvalCodeCache.h b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
index e2d6a41..62521fc 100644
--- a/Source/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -50,12 +50,12 @@
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;
diff --git a/Source/JavaScriptCore/bytecode/ExecutableInfo.h b/Source/JavaScriptCore/bytecode/ExecutableInfo.h
index 13246cc..92144f8 100644
--- a/Source/JavaScriptCore/bytecode/ExecutableInfo.h
+++ b/Source/JavaScriptCore/bytecode/ExecutableInfo.h
@@ -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 @@
, 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 @@
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 @@
unsigned m_isBuiltinFunction : 1;
unsigned m_constructorKind : 2;
unsigned m_isArrowFunction : 1;
- unsigned m_isDerivedConstructorContext : 1;
- unsigned m_isArrowFunctionContext : 1;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
index 4de594d..c114b9b 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
@@ -66,8 +66,6 @@
, 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)
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
index 8807bee..fa514c1 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
@@ -117,8 +117,6 @@
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 @@
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;
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
index 2eab1b5..6da1859 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
+++ b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
@@ -67,7 +67,7 @@
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 @@
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 @@
, 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);
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
index 7b2d7b2..d8e8229 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
+++ b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
@@ -65,10 +65,10 @@
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 @@
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 @@
unsigned m_constructorKind : 2;
unsigned m_functionMode : 1; // FunctionMode
unsigned m_isArrowFunction : 1;
- unsigned m_isDerivedConstructorContext : 1;
protected:
void finishCreation(VM& vm)
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index d58ff41..1abbba4 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -155,8 +155,6 @@
, 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
, 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 @@
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 @@
, 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::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 @@
}
}
-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 @@
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::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 @@
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 @@
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)
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 2c2ec96..07316b1 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -65,8 +65,6 @@
ExpectArrayConstructor
};
- enum class ThisResolutionType { Local, Scoped };
-
class CallArguments {
public:
CallArguments(BytecodeGenerator&, ArgumentsNode*, unsigned additionalArguments = 0);
@@ -281,18 +279,13 @@
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 @@
// 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 @@
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 @@
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 @@
void allocateCalleeSaveSpace();
void allocateAndEmitScope();
+ RegisterID* emitLoadArrowFunctionThis(RegisterID*);
void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
typedef HashMap<double, JSValue> NumberMap;
@@ -768,8 +750,6 @@
UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata)
{
- bool newisDerivedConstructorContext = constructorKind() == ConstructorKind::Derived || (m_isDerivedConstructorContext && metadata->isArrowFunction());
-
VariableEnvironment variablesUnderTDZ;
getVariablesUnderTDZ(variablesUnderTDZ);
@@ -778,7 +758,7 @@
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 @@
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 @@
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 @@
bool m_isBuiltinFunction { false };
bool m_usesNonStrictEval { false };
bool m_inTailPosition { false };
- bool m_isDerivedConstructorContext { false };
- bool m_needsToUpdateArrowFunctionContext;
- bool m_isNewTargetLoadedInArrowFunction { false };
};
}
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index a2e84f2..242738e 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -145,10 +145,7 @@
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 @@
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 @@
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 @@
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 @@
// 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());
diff --git a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index d540550..d383c3f 100644
--- a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -196,7 +196,7 @@
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();
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
index 35cae39..fbe82e9 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
@@ -1805,6 +1805,15 @@
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) {
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 268e267..439e620 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -4514,6 +4514,17 @@
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 @@
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: {
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
index 6164972..7a5ec3f 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
@@ -202,6 +202,7 @@
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:
diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h
index 2637911..a85586d 100644
--- a/Source/JavaScriptCore/dfg/DFGClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h
@@ -139,6 +139,7 @@
case ArithCos:
case ArithLog:
case GetScope:
+ case LoadArrowFunctionThis:
case SkipScope:
case StringCharCodeAt:
case StringFromCharCode:
diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
index 16f973d..b26e0a5 100644
--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
@@ -107,6 +107,7 @@
case GetButterflyReadOnly:
case CheckArray:
case GetScope:
+ case LoadArrowFunctionThis:
case SkipScope:
case GetClosureVar:
case PutClosureVar:
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 77bd380..a957d2b 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -1012,6 +1012,11 @@
break;
}
+ case LoadArrowFunctionThis: {
+ fixEdge<KnownCellUse>(node->child1());
+ break;
+ }
+
case SkipScope:
case GetScope:
case GetGetter:
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 008d8c7..2ed3ce4 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -207,6 +207,7 @@
macro(MultiPutByOffset, NodeMustGenerate) \
macro(GetArrayLength, NodeResultInt32) \
macro(GetTypedArrayByteOffset, NodeResultInt32) \
+ macro(LoadArrowFunctionThis, NodeResultJS) \
macro(GetScope, NodeResultJS) \
macro(SkipScope, NodeResultJS) \
macro(GetClosureVar, NodeResultJS) \
diff --git a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp b/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
index 12ab163..db8dd6f 100644
--- a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
@@ -838,14 +838,17 @@
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 @@
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 @@
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 @@
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;
}
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 49d5c74..59ae9f3 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -594,6 +594,10 @@
changed |= setPrediction(SpecObjectOther);
break;
+ case LoadArrowFunctionThis:
+ changed |= setPrediction(SpecFinalObject);
+ break;
+
case In:
changed |= setPrediction(SpecBoolean);
break;
diff --git a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
index 24f6977..8fe1591 100644
--- a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
@@ -102,6 +102,10 @@
case ClosureVarPLoc:
out.print("ClosureVarPLoc");
return;
+
+ case ArrowFunctionBoundThisPLoc:
+ out.print("ArrowFunctionBoundThisPLoc");
+ return;
}
RELEASE_ASSERT_NOT_REACHED();
diff --git a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
index b4e3c2b..97293f3 100644
--- a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
+++ b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
@@ -46,7 +46,8 @@
FunctionExecutablePLoc,
FunctionActivationPLoc,
ActivationScopePLoc,
- ClosureVarPLoc
+ ClosureVarPLoc,
+ ArrowFunctionBoundThisPLoc
};
class PromotedLocationDescriptor {
diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
index 616c3b0..f5c68db 100644
--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
@@ -202,6 +202,7 @@
case Arrayify:
case ArrayifyToStructure:
case GetScope:
+ case LoadArrowFunctionThis:
case SkipScope:
case GetClosureVar:
case PutClosureVar:
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index d0781e6..800613c 100755
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -4739,6 +4739,15 @@
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)
{
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index c42ba31..8660b04 100755
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -2200,6 +2200,7 @@
void compileGetByValOnScopedArguments(Node*);
void compileGetScope(Node*);
+ void compileLoadArrowFunctionThis(Node*);
void compileSkipScope(Node*);
void compileGetArrayLength(Node*);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 6e0f146..b0c4e94 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -3799,6 +3799,10 @@
case GetScope:
compileGetScope(node);
break;
+
+ case LoadArrowFunctionThis:
+ compileLoadArrowFunctionThis(node);
+ break;
case SkipScope:
compileSkipScope(node);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index f11822d7..570332c 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -3837,6 +3837,10 @@
compileGetScope(node);
break;
+ case LoadArrowFunctionThis:
+ compileLoadArrowFunctionThis(node);
+ break;
+
case SkipScope:
compileSkipScope(node);
break;
diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
index 8728d9e..64a4822 100644
--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
@@ -152,6 +152,7 @@
case CountExecution:
case GetExecutable:
case GetScope:
+ case LoadArrowFunctionThis:
case GetCallee:
case GetArgumentCount:
case ToString:
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
index 072a32a..4adc1aa 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
@@ -810,6 +810,9 @@
case GetScope:
compileGetScope();
break;
+ case LoadArrowFunctionThis:
+ compileLoadArrowFunctionThis();
+ break;
case SkipScope:
compileSkipScope();
break;
@@ -4504,6 +4507,11 @@
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));
diff --git a/Source/JavaScriptCore/ftl/FTLOperations.cpp b/Source/JavaScriptCore/ftl/FTLOperations.cpp
index 37015b6..c3672e8 100644
--- a/Source/JavaScriptCore/ftl/FTLOperations.cpp
+++ b/Source/JavaScriptCore/ftl/FTLOperations.cpp
@@ -164,17 +164,25 @@
// 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;
}
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index ea3db19..c54751c 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -172,7 +172,7 @@
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();
}
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index cb52c45..2d6f02c 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -221,6 +221,7 @@
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:
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index 515279f..6850f7a 100755
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -500,6 +500,7 @@
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*);
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index cbbcf3f..f60ae57 100755
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -684,6 +684,14 @@
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::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 @@
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);
}
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 89455ed..4e04365 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -938,6 +938,14 @@
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;
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 1a52aff..765f197 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -1055,12 +1055,13 @@
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)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 1bf13eb..5ad5b3f 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -1461,7 +1461,7 @@
_llint_op_new_arrow_func_exp:
traceExecution()
callSlowPath(_llint_slow_path_new_arrow_func_exp)
- dispatch(4)
+ dispatch(5)
_llint_op_call:
traceExecution()
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index c5a87e3..e1d122c 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -2422,6 +2422,16 @@
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
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index e18d81c..49f3cd7 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -2284,14 +2284,22 @@
.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
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h
index b15a813..ce985ca 100644
--- a/Source/JavaScriptCore/parser/ASTBuilder.h
+++ b/Source/JavaScriptCore/parser/ASTBuilder.h
@@ -374,7 +374,7 @@
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 @@
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()
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index d839c12..5ca3466 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -1559,7 +1559,6 @@
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; }
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp
index 4f6ade8..0af2c5a 100644
--- a/Source/JavaScriptCore/parser/Parser.cpp
+++ b/Source/JavaScriptCore/parser/Parser.cpp
@@ -1876,11 +1876,11 @@
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);
diff --git a/Source/JavaScriptCore/parser/ParserModes.h b/Source/JavaScriptCore/parser/ParserModes.h
index 5268d78..49585cb 100644
--- a/Source/JavaScriptCore/parser/ParserModes.h
+++ b/Source/JavaScriptCore/parser/ParserModes.h
@@ -143,19 +143,17 @@
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 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 | ArrowFunctionFeature | ArrowFunctionContextFeature;
+const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature;
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp
index c3ae1e3..f13b25e 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.cpp
+++ b/Source/JavaScriptCore/runtime/CodeCache.cpp
@@ -83,7 +83,8 @@
};
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 @@
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 @@
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 @@
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()));
diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h
index 6d06de7..48c8cfe 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.h
+++ b/Source/JavaScriptCore/runtime/CodeCache.h
@@ -258,7 +258,7 @@
~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 @@
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;
};
diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
index bdd76a0..495f235 100644
--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -330,9 +330,6 @@
macro(Uint32Array) \
macro(Float32Array) \
macro(Float64Array) \
- macro(newTargetLocal) \
- macro(derivedConstructor) \
-
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
index 0b605fa..490636f 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
@@ -225,7 +225,7 @@
#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;
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 1892ac1..8365292 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -131,15 +131,13 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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());
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 25068e9..9fc9be7 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -344,9 +344,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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(); }
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 208ce47..bc08f96 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -949,14 +949,14 @@
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());
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 37738e2..8e1629c 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -661,7 +661,7 @@
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:
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index ce1e3bb..2bf13bb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -581,7 +581,7 @@
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());
diff --git a/Source/JavaScriptCore/tests/es6.yaml b/Source/JavaScriptCore/tests/es6.yaml
index 771a3b5..88d4a7c 100644
--- a/Source/JavaScriptCore/tests/es6.yaml
+++ b/Source/JavaScriptCore/tests/es6.yaml
@@ -743,7 +743,7 @@
- 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-activation-sink-osrexit.js b/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink-osrexit.js
index 73ec6e2..2e437af 100644
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink-osrexit.js
+++ b/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink-osrexit.js
@@ -1,4 +1,4 @@
-var n = 100000;
+var n = 1000000;
function bar() { }
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js b/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js
index 69d9752..76a79ec 100644
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js
+++ b/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js
@@ -1,4 +1,4 @@
-var n = 1000000;
+var n = 10000000;
function bar(f) { f(10); }
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
index 7a8d27c..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js
+++ /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
index c247147..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-1.js
+++ /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
index 83c8e37..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js
+++ /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
index 6fbb6d5..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-3.js
+++ /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
index 18a6f70..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-4.js
+++ /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);
-}
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-1.js b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-1.js
index 69cb8cd..4cfab24 100644
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-1.js
+++ b/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-1.js
@@ -8,7 +8,6 @@
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 @@
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
index 2f76c9d..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-7.js
+++ /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
index 8d4d9d4..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-1.js
+++ /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
index 7afccaf..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-2.js
+++ /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
index ab98309..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-3.js
+++ /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
index 87c2927..0000000
--- a/Source/JavaScriptCore/tests/stress/arrowfunction-tdz-4.js
+++ /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
index 0000000..6874923
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arrowfunction-tdz.js
@@ -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);
+}