Diff
Modified: trunk/LayoutTests/ChangeLog (194448 => 194449)
--- trunk/LayoutTests/ChangeLog 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/LayoutTests/ChangeLog 2015-12-30 21:08:16 UTC (rev 194449)
@@ -1,3 +1,14 @@
+2015-12-30 Skachkov Oleksandr <[email protected]>
+
+ [ES6] Arrow function syntax. Arrow function specific features. Lexical bind "super"
+ https://bugs.webkit.org/show_bug.cgi?id=149615
+
+ Reviewed by Saam Barati.
+
+ * js/arrowfunction-superproperty-expected.txt: Added.
+ * js/arrowfunction-superproperty.html: Added.
+ * js/script-tests/arrowfunction-superproperty.js: Added.
+
2015-12-29 Andy VanWagoner <[email protected]>
Remove tests for sometimes unsupported calendars, numbering systems, and time zone backward links
Added: trunk/LayoutTests/js/arrowfunction-superproperty-expected.txt (0 => 194449)
--- trunk/LayoutTests/js/arrowfunction-superproperty-expected.txt (rev 0)
+++ trunk/LayoutTests/js/arrowfunction-superproperty-expected.txt 2015-12-30 21:08:16 UTC (rev 194449)
@@ -0,0 +1,16 @@
+Tests for ES6 arrow function, access to the super property in arrow function
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS (new B()).getValueParentFunction() is expectedValue
+PASS (new C(false)).value is expectedValue
+PASS E.getParentStaticValue() is expectedValue
+PASS f.prop is expectedValue + "-" + expectedValue
+PASS f.prop is expectedValue + "-" + "new-value"
+PASS (new F()).getParentValue() is expectedValue
+PASS (new F()).getParentValueWithError()() threw exception TypeError: undefined is not an object (evaluating 'super.getValue').
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/arrowfunction-superproperty.html (0 => 194449)
--- trunk/LayoutTests/js/arrowfunction-superproperty.html (rev 0)
+++ trunk/LayoutTests/js/arrowfunction-superproperty.html 2015-12-30 21:08:16 UTC (rev 194449)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/script-tests/arrowfunction-superproperty.js (0 => 194449)
--- trunk/LayoutTests/js/script-tests/arrowfunction-superproperty.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/arrowfunction-superproperty.js 2015-12-30 21:08:16 UTC (rev 194449)
@@ -0,0 +1,95 @@
+description('Tests for ES6 arrow function, access to the super property in arrow function');
+
+var expectedValue = 'test-value';
+
+class A {
+ getValue () {
+ return expectedValue;
+ }
+};
+
+class B extends A {
+ getValueParentFunction() {
+ var arrow = () => super.getValue();
+ return arrow();
+ }
+};
+
+class C extends B {
+ constructor(beforeSuper) {
+ let _value;
+ let arrow = () => super.getValue();
+ if (beforeSuper) {
+ _value = arrow();
+ super();
+ } else {
+ super();
+ _value = arrow();
+ }
+ this.value = _value;
+ }
+};
+
+class D {
+ constructor() {
+ this.value = expectedValue;
+ }
+ static getStaticValue() {
+ return expectedValue;
+ }
+};
+
+class E extends D {
+ static getParentStaticValue() {
+ var arrow = () => super.getStaticValue();
+ return arrow();
+ }
+};
+
+class F extends A {
+ constructor() {
+ super();
+ this.value = expectedValue;
+ }
+ get prop() {
+ var arrow = () => super.getValue()+ '-' + this.value;
+ return arrow();
+ }
+ set prop(value) {
+ var arrow = (newVal) => this.value = newVal;
+ arrow(value);
+ }
+ getParentValue() {
+ let arrow = () => () => super.getValue();
+ return arrow()();
+ }
+ getParentValueWithError() {
+ var f = function () {
+ return () => super.getValue();
+ };
+ return f();
+ }
+ };
+
+shouldBe('(new B()).getValueParentFunction()', 'expectedValue');
+
+shouldBe('(new C(false)).value', 'expectedValue');
+
+// FIXME: Problem with access to the super before super() in constructor
+// https://bugs.webkit.org/show_bug.cgi?id=152108
+//shouldThrow('(new C(true))', 'ReferenceError');
+
+shouldBe('E.getParentStaticValue()', 'expectedValue');
+
+var f = new F();
+
+shouldBe('f.prop', 'expectedValue + "-" + expectedValue');
+
+f.prop = 'new-value';
+shouldBe('f.prop', 'expectedValue + "-" + "new-value"');
+
+shouldBe('(new F()).getParentValue()', 'expectedValue');
+
+shouldThrow('(new F()).getParentValueWithError()()');
+
+var successfullyParsed = true;
Modified: trunk/Source/_javascript_Core/ChangeLog (194448 => 194449)
--- trunk/Source/_javascript_Core/ChangeLog 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-12-30 21:08:16 UTC (rev 194449)
@@ -1,3 +1,65 @@
+2015-12-30 Aleksandr Skachkov <[email protected]>
+
+ [ES6] Arrow function syntax. Arrow function specific features. Lexical bind "super"
+ https://bugs.webkit.org/show_bug.cgi?id=149615
+
+ Reviewed by Saam Barati.
+
+ Implemented lexical bind "super" property for arrow function. 'super' property can be accessed
+ inside of the arrow function in case if arrow function is nested in constructor, method,
+ getter or setter of class. In current patch using 'super' in arrow function, that declared out of the
+ class, lead to wrong type of error, should be SyntaxError(https://bugs.webkit.org/show_bug.cgi?id=150893)
+ and this will be fixed in separete patch.
+
+ * builtins/BuiltinExecutables.cpp:
+ (JSC::createExecutableInternal):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::getSlow):
+ * bytecode/ExecutableInfo.h:
+ (JSC::ExecutableInfo::ExecutableInfo):
+ (JSC::ExecutableInfo::derivedContextType):
+ (JSC::ExecutableInfo::isClassContext):
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedCodeBlock::derivedContextType):
+ (JSC::UnlinkedCodeBlock::isClassContext):
+ * bytecode/UnlinkedFunctionExecutable.cpp:
+ (JSC::generateUnlinkedFunctionCodeBlock):
+ (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+ * bytecode/UnlinkedFunctionExecutable.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::derivedContextType):
+ (JSC::BytecodeGenerator::isDerivedConstructorContext):
+ (JSC::BytecodeGenerator::isDerivedClassContext):
+ (JSC::BytecodeGenerator::isArrowFunction):
+ (JSC::BytecodeGenerator::makeFunction):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::emitHomeObjectForCallee):
+ (JSC::FunctionCallValueNode::emitBytecode):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * interpreter/Interpreter.cpp:
+ (JSC::eval):
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ * runtime/Executable.cpp:
+ (JSC::ScriptExecutable::ScriptExecutable):
+ (JSC::EvalExecutable::create):
+ (JSC::EvalExecutable::EvalExecutable):
+ (JSC::ProgramExecutable::ProgramExecutable):
+ (JSC::ModuleProgramExecutable::ModuleProgramExecutable):
+ (JSC::FunctionExecutable::FunctionExecutable):
+ * runtime/Executable.h:
+ (JSC::ScriptExecutable::derivedContextType):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval):
+ * tests/es6.yaml:
+ * tests/stress/arrowfunction-lexical-bind-superproperty.js: Added.
+
2015-12-29 Yusuke Suzuki <[email protected]>
Unreviewed, relax limitation in operationCreateThis
Modified: trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -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, DerivedContextType::None, WTF::move(sourceOverride));
functionExecutable->setNameValue(vm, jsString(&vm, name.string()));
return functionExecutable;
}
Modified: trunk/Source/_javascript_Core/bytecode/EvalCodeCache.h (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecode/EvalCodeCache.h 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecode/EvalCodeCache.h 2015-12-30 21:08:16 UTC (rev 194449)
@@ -55,11 +55,11 @@
return nullptr;
}
- EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const SourceCode& evalSource, JSScope* scope)
+ EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, const SourceCode& evalSource, JSScope* scope)
{
VariableEnvironment variablesUnderTDZ;
JSScope::collectVariablesUnderTDZ(scope, variablesUnderTDZ);
- EvalExecutable* evalExecutable = EvalExecutable::create(exec, evalSource, inStrictContext, thisTDZMode, isDerivedConstructorContext, isArrowFunctionContext, &variablesUnderTDZ);
+ EvalExecutable* evalExecutable = EvalExecutable::create(exec, evalSource, inStrictContext, thisTDZMode, derivedContextType, isArrowFunctionContext, &variablesUnderTDZ);
if (!evalExecutable)
return nullptr;
Modified: trunk/Source/_javascript_Core/bytecode/ExecutableInfo.h (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecode/ExecutableInfo.h 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecode/ExecutableInfo.h 2015-12-30 21:08:16 UTC (rev 194449)
@@ -29,11 +29,13 @@
#include "ParserModes.h"
namespace JSC {
+
+enum class DerivedContextType { None, DerivedConstructorContext, DerivedMethodContext };
// FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized.
// https://bugs.webkit.org/show_bug.cgi?id=151547
struct ExecutableInfo {
- ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, SuperBinding superBinding, SourceParseMode parseMode, bool isDerivedConstructorContext, bool isArrowFunctionContext)
+ ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isClassContext)
: m_needsActivation(needsActivation)
, m_usesEval(usesEval)
, m_isStrictMode(isStrictMode)
@@ -42,8 +44,9 @@
, m_constructorKind(static_cast<unsigned>(constructorKind))
, m_superBinding(static_cast<unsigned>(superBinding))
, m_parseMode(parseMode)
- , m_isDerivedConstructorContext(isDerivedConstructorContext)
+ , m_derivedContextType(static_cast<unsigned>(derivedContextType))
, m_isArrowFunctionContext(isArrowFunctionContext)
+ , m_isClassContext(isClassContext)
{
ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
@@ -57,8 +60,9 @@
ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); }
SourceParseMode parseMode() const { return m_parseMode; }
- bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; }
+ DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); }
bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
+ bool isClassContext() const { return m_isClassContext; }
private:
unsigned m_needsActivation : 1;
@@ -69,8 +73,9 @@
unsigned m_constructorKind : 2;
unsigned m_superBinding : 1;
SourceParseMode m_parseMode;
- unsigned m_isDerivedConstructorContext : 1;
+ unsigned m_derivedContextType : 2;
unsigned m_isArrowFunctionContext : 1;
+ unsigned m_isClassContext : 1;
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -66,8 +66,9 @@
, m_isBuiltinFunction(info.isBuiltinFunction())
, m_constructorKind(static_cast<unsigned>(info.constructorKind()))
, m_superBinding(static_cast<unsigned>(info.superBinding()))
- , m_isDerivedConstructorContext(info.isDerivedConstructorContext())
+ , m_derivedContextType(static_cast<unsigned>(info.derivedContextType()))
, m_isArrowFunctionContext(info.isArrowFunctionContext())
+ , m_isClassContext(info.isClassContext())
, m_firstLine(0)
, m_lineCount(0)
, m_endColumn(UINT_MAX)
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2015-12-30 21:08:16 UTC (rev 194449)
@@ -119,8 +119,9 @@
bool usesEval() const { return m_usesEval; }
SourceParseMode parseMode() const { return m_parseMode; }
bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; }
- bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; }
+ DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); }
bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
+ bool isClassContext() const { return m_isClassContext; }
bool needsFullScopeChain() const { return m_needsFullScopeChain; }
@@ -393,9 +394,9 @@
unsigned m_isBuiltinFunction : 1;
unsigned m_constructorKind : 2;
unsigned m_superBinding : 1;
- unsigned m_isDerivedConstructorContext : 1;
+ unsigned m_derivedContextType : 2;
unsigned m_isArrowFunctionContext : 1;
-
+ unsigned m_isClassContext : 1;
unsigned m_firstLine;
unsigned m_lineCount;
unsigned m_endColumn;
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -65,9 +65,11 @@
function->finishParsing(executable->name(), executable->functionMode());
executable->recordParse(function->features(), function->hasCapturedVariables());
-
+
+ bool isClassContext = executable->superBinding() == SuperBinding::Needed;
+
UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode,
- ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), executable->superBinding(), parseMode, executable->isDerivedConstructorContext(), false));
+ ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext));
auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode, executable->parentScopeTDZVariables()));
error = generator->generate();
@@ -76,7 +78,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, DerivedContextType derivedContextType)
: Base(*vm, structure)
, m_name(node->ident())
, m_inferredName(node->inferredName())
@@ -101,7 +103,7 @@
, m_constructorKind(static_cast<unsigned>(node->constructorKind()))
, m_functionMode(node->functionMode())
, m_superBinding(static_cast<unsigned>(node->superBinding()))
- , m_isDerivedConstructorContext(isDerivedConstructorContext)
+ , m_derivedContextType(static_cast<unsigned>(derivedContextType))
{
ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind()));
m_parentScopeTDZVariables.swap(parentScopeTDZVariables);
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h 2015-12-30 21:08:16 UTC (rev 194449)
@@ -30,6 +30,7 @@
#include "CodeSpecializationKind.h"
#include "CodeType.h"
#include "ConstructAbility.h"
+#include "ExecutableInfo.h"
#include "ExpressionRangeInfo.h"
#include "HandlerInfo.h"
#include "Identifier.h"
@@ -65,10 +66,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, DerivedContextType derivedContextType, 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, derivedContextType);
instance->finishCreation(*vm);
return instance;
}
@@ -128,11 +129,12 @@
const VariableEnvironment* parentScopeTDZVariables() const { return &m_parentScopeTDZVariables; }
bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; }
- bool isDerivedConstructorContext() const {return m_isDerivedConstructorContext; }
+ JSC::DerivedContextType derivedContextType() const {return static_cast<JSC::DerivedContextType>(m_derivedContextType); }
+
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&, JSC::DerivedContextType);
+
WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall;
WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForConstruct;
@@ -163,7 +165,7 @@
unsigned m_constructorKind : 2;
unsigned m_functionMode : 1; // FunctionMode
unsigned m_superBinding : 1;
- unsigned m_isDerivedConstructorContext : 1;
+ unsigned m_derivedContextType: 2;
protected:
void finishCreation(VM& vm)
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -157,7 +157,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());
@@ -211,8 +210,8 @@
// 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())
+ , m_derivedContextType(codeBlock->derivedContextType())
{
for (auto& constantRegister : m_linkTimeConstantRegisters)
constantRegister = nullptr;
@@ -571,9 +570,9 @@
// Loading |this| inside an arrow function must be done after initializeDefaultParameterValuesAndSetupFunctionScopeStack()
// because that function sets up the SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment()
// consults the SymbolTable stack
- if (parseMode == SourceParseMode::ArrowFunctionMode && functionNode->usesThis())
+ if (SourceParseMode::ArrowFunctionMode == parseMode && (functionNode->usesThis() || isDerivedClassContext() || isDerivedConstructorContext()))
emitLoadThisFromArrowFunctionLexicalEnvironment();
-
+
if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) {
initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable);
emitPutThisToArrowFunctionContextScope();
@@ -593,8 +592,8 @@
, m_codeType(EvalCode)
, m_vm(&vm)
, m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
- , m_isDerivedConstructorContext(codeBlock->isDerivedConstructorContext())
, m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval())
+ , m_derivedContextType(codeBlock->derivedContextType())
{
for (auto& constantRegister : m_linkTimeConstantRegisters)
constantRegister = nullptr;
@@ -644,7 +643,6 @@
, m_codeType(ModuleCode)
, m_vm(&vm)
, m_usesNonStrictEval(false)
- , m_isDerivedConstructorContext(false)
, m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval())
{
ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
@@ -4047,14 +4045,14 @@
void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope()
{
- if (isConstructor() && constructorKind() == ConstructorKind::Derived) {
+ if ((isConstructor() && constructorKind() == ConstructorKind::Derived) || m_codeBlock->isClassContext()) {
ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
Variable protoScope = variable(propertyNames().derivedConstructorPrivateName);
emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, Initialization);
}
}
-
+
void BytecodeGenerator::emitPutThisToArrowFunctionContextScope()
{
ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2015-12-30 21:08:16 UTC (rev 194449)
@@ -281,7 +281,7 @@
const CommonIdentifiers& propertyNames() const { return *m_vm->propertyNames; }
bool isConstructor() const { return m_codeBlock->isConstructor(); }
- bool isDerivedConstructorContext() const { return m_codeBlock->isDerivedConstructorContext(); }
+ DerivedContextType derivedContextType() const { return m_derivedContextType; }
bool usesArrowFunction() const { return m_scopeNode->usesArrowFunction(); }
bool needsToUpdateArrowFunctionContext() const { return m_needsToUpdateArrowFunctionContext; }
bool usesEval() const { return m_scopeNode->usesEval(); }
@@ -697,6 +697,10 @@
bool isBuiltinFunction() const { return m_isBuiltinFunction; }
OpcodeID lastOpcodeID() const { return m_lastOpcodeID; }
+
+ bool isDerivedConstructorContext() { return m_derivedContextType == DerivedContextType::DerivedConstructorContext; }
+ bool isDerivedClassContext() { return m_derivedContextType == DerivedContextType::DerivedMethodContext; }
+ bool isArrowFunction() { return m_codeBlock->isArrowFunction(); }
enum class TDZCheckOptimization { Optimize, DoNotOptimize };
enum class NestedScopeType { IsNested, IsNotNested };
@@ -794,8 +798,15 @@
UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata)
{
- bool newisDerivedConstructorContext = constructorKind() == ConstructorKind::Derived || (m_isDerivedConstructorContext && metadata->parseMode() == SourceParseMode::ArrowFunctionMode);
+ DerivedContextType newDerivedContextType = DerivedContextType::None;
+ if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode) {
+ if (constructorKind() == ConstructorKind::Derived || isDerivedConstructorContext())
+ newDerivedContextType = DerivedContextType::DerivedConstructorContext;
+ else if (m_codeBlock->isClassContext() || isDerivedClassContext())
+ newDerivedContextType = DerivedContextType::DerivedMethodContext;
+ }
+
VariableEnvironment variablesUnderTDZ;
getVariablesUnderTDZ(variablesUnderTDZ);
@@ -808,7 +819,7 @@
else if (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, newDerivedContextType);
}
void getVariablesUnderTDZ(VariableEnvironment&);
@@ -918,9 +929,9 @@
bool m_isBuiltinFunction { false };
bool m_usesNonStrictEval { false };
bool m_inTailPosition { false };
- bool m_isDerivedConstructorContext { false };
bool m_needsToUpdateArrowFunctionContext;
bool m_isNewTargetLoadedInArrowFunction { false };
+ DerivedContextType m_derivedContextType { DerivedContextType::None };
};
}
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -173,12 +173,16 @@
RegisterID callee;
callee.setIndex(JSStack::Callee);
-
return generator.emitGetById(generator.finalDestination(dst), &callee, generator.propertyNames().underscoreProto);
}
static RegisterID* emitHomeObjectForCallee(BytecodeGenerator& generator)
{
+ if (generator.isDerivedClassContext() || generator.isDerivedConstructorContext()) {
+ RegisterID* derivedConstructor = generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
+ return generator.emitGetById(generator.newTemporary(), derivedConstructor, generator.propertyNames().homeObjectPrivateName);
+ }
+
RegisterID callee;
callee.setIndex(JSStack::Callee);
return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
@@ -749,8 +753,8 @@
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() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
+ ASSERT(generator.constructorKind() == ConstructorKind::Derived || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
generator.emitMove(callArguments.thisRegister(), generator.newTarget());
RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
generator.emitMove(generator.thisRegister(), ret);
Modified: trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -192,7 +192,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, codeBlock.unlinkedCodeBlock()->derivedContextType(), codeBlock.unlinkedCodeBlock()->isArrowFunction(), &variablesUnderTDZ);
if (vm.exception()) {
exception = vm.exception();
vm.clearException();
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -183,7 +183,7 @@
// If the literal parser bailed, it should not have thrown exceptions.
ASSERT(!callFrame->vm().exception());
- eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, callerCodeBlock->unlinkedCodeBlock()->isDerivedConstructorContext(), callerCodeBlock->unlinkedCodeBlock()->isArrowFunction(), sourceCode, callerScopeChain);
+ eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, callerCodeBlock->unlinkedCodeBlock()->derivedContextType(), callerCodeBlock->unlinkedCodeBlock()->isArrowFunction(), sourceCode, callerScopeChain);
if (!eval)
return jsUndefined();
Modified: trunk/Source/_javascript_Core/runtime/CodeCache.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/runtime/CodeCache.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -188,7 +188,8 @@
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, DerivedContextType::None);
+
functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/runtime/Executable.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -131,14 +131,14 @@
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, DerivedContextType derivedContextType, bool isInArrowFunctionContext)
: 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_derivedContextType(derivedContextType)
, m_isArrowFunctionContext(isInArrowFunctionContext)
, m_overrideLineNumber(-1)
, m_firstLine(-1)
@@ -414,7 +414,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, DerivedContextType derivedContextType, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ)
{
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
if (!globalObject->evalEnabled()) {
@@ -422,7 +422,7 @@
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, derivedContextType, isArrowFunctionContext);
executable->finishCreation(exec->vm());
UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode, isArrowFunctionContext, variablesUnderTDZ);
@@ -434,8 +434,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, DerivedContextType derivedContextType, bool isArrowFunctionContext)
+ : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec->vm(), source, inStrictContext, derivedContextType, isArrowFunctionContext)
{
}
@@ -447,7 +447,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, DerivedContextType::None, false)
{
m_typeProfilingStartOffset = 0;
m_typeProfilingEndOffset = source.length() - 1;
@@ -463,7 +463,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, DerivedContextType::None, false)
{
m_typeProfilingStartOffset = 0;
m_typeProfilingEndOffset = source.length() - 1;
@@ -495,7 +495,7 @@
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)
+ : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext(), unlinkedExecutable->derivedContextType(), false)
, m_unlinkedExecutable(vm, this, unlinkedExecutable)
{
RELEASE_ASSERT(!source.isNull());
Modified: trunk/Source/_javascript_Core/runtime/Executable.h (194448 => 194449)
--- trunk/Source/_javascript_Core/runtime/Executable.h 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/runtime/Executable.h 2015-12-30 21:08:16 UTC (rev 194449)
@@ -346,7 +346,8 @@
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; }
+ DerivedContextType derivedContextType() const { return m_derivedContextType; }
+
ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
void setNeverInline(bool value) { m_neverInline = value; }
@@ -395,7 +396,7 @@
JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind);
protected:
- ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, bool isInDerivedConstructorContext, bool isInArrowFunctionContext);
+ ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isInArrowFunctionContext);
void finishCreation(VM& vm)
{
@@ -414,7 +415,7 @@
bool m_neverInline;
bool m_neverOptimize { false };
bool m_didTryToEnterInLoop;
- bool m_isDerivedConstructorContext;
+ DerivedContextType m_derivedContextType;
bool m_isArrowFunctionContext;
int m_overrideLineNumber;
int m_firstLine;
@@ -438,7 +439,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, DerivedContextType, bool isArrowFunctionContext, const VariableEnvironment*);
PassRefPtr<JITCode> generatedJITCode()
{
@@ -452,17 +453,17 @@
DECLARE_INFO;
+ ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext() , false); }
- ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, isDerivedConstructorContext(), isArrowFunctionContext()); }
-
unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
private:
friend class ExecutableBase;
friend class ScriptExecutable;
- EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, bool isDerivedConstructorContext, bool isArrowFunctionContext);
+ EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, DerivedContextType, bool isArrowFunctionContext);
+
static void visitChildren(JSCell*, SlotVisitor&);
WriteBarrier<EvalCodeBlock> m_evalCodeBlock;
@@ -506,7 +507,7 @@
DECLARE_INFO;
- ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, isDerivedConstructorContext(), false); }
+ ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false); }
private:
friend class ExecutableBase;
@@ -547,7 +548,7 @@
DECLARE_INFO;
- ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, isDerivedConstructorContext(), false); }
+ ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, derivedContextType(), isArrowFunctionContext(), false); }
UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); }
@@ -657,7 +658,7 @@
bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); }
bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
- bool isDerivedConstructorContext() const { return m_unlinkedExecutable->isDerivedConstructorContext(); }
+ DerivedContextType derivedContextType() const { return m_unlinkedExecutable->derivedContextType(); }
bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
const Identifier& name() { return m_unlinkedExecutable->name(); }
const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (194448 => 194449)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2015-12-30 21:08:16 UTC (rev 194449)
@@ -587,7 +587,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, DerivedContextType::None, false, &emptyTDZVariables);
if (!eval)
return JSValue::encode(jsUndefined());
Modified: trunk/Source/_javascript_Core/tests/es6.yaml (194448 => 194449)
--- trunk/Source/_javascript_Core/tests/es6.yaml 2015-12-30 20:15:27 UTC (rev 194448)
+++ trunk/Source/_javascript_Core/tests/es6.yaml 2015-12-30 21:08:16 UTC (rev 194449)
@@ -747,7 +747,7 @@
- path: es6/arrow_functions_lexical_new.target_binding.js
cmd: runES6 :normal
- path: es6/arrow_functions_lexical_super_binding.js
- cmd: runES6 :fail
+ cmd: runES6 :normal
- path: es6/arrow_functions_no_prototype_property.js
cmd: runES6 :normal
- path: es6/block-level_function_declaration.js
Added: trunk/Source/_javascript_Core/tests/stress/arrowfunction-lexical-bind-superproperty.js (0 => 194449)
--- trunk/Source/_javascript_Core/tests/stress/arrowfunction-lexical-bind-superproperty.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/arrowfunction-lexical-bind-superproperty.js 2015-12-30 21:08:16 UTC (rev 194449)
@@ -0,0 +1,224 @@
+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.value = testValue;
+ }
+ getConstValue () {
+ return testValue;
+ }
+ getValue () {
+ return this.value;
+ }
+ setValue (value) {
+ this.value = value;
+ }
+};
+
+var B = class B extends A {
+ getParentValue() {
+ var arrow = () => super.getValue();
+ return arrow();
+ }
+};
+
+var C = class C {
+ constructor() {
+ this.value = testValue;
+ }
+ static getStaticValue() {
+ return testValue;
+ }
+};
+
+var D = class D extends C {
+ static getParentStaticValue() {
+ var arrow = () => super.getStaticValue();
+ return arrow();
+ }
+};
+
+var E = class E extends A {
+ constructor() {
+ super();
+ }
+ get prop() {
+ var arrow = () => super.getConstValue() + '-' + this.value;
+ return arrow();
+ }
+ set prop(value) {
+ var arrow = (newVal) => super.setValue(newVal);
+ arrow(value);
+ }
+ setInitValue() {
+ this.value = testValue;
+ }
+ };
+
+var b = new B();
+for (var i = 0; i < 10000; i++) {
+ testCase(b.getParentValue(), testValue, i);
+}
+
+for (var i = 0; i < 10000; i++) {
+ testCase(D.getParentStaticValue(), testValue, i);
+}
+
+var e = new E();
+for (var i = 0; i < 10000; i++) {
+ e.setInitValue();
+ testCase(e.prop, testValue+'-'+testValue, i);
+ e.prop = 'new-test-value';
+ testCase(e.prop, testValue+'-new-test-value', i);
+}
+
+var F = class F extends A {
+ newMethod() {
+ var arrow = () => eval('super.getValue()');
+ var r = arrow();
+ return r;
+ }
+};
+
+var f = new F();
+for (var i=0; i < 10000; i++) {
+ try {
+ var result = f.newMethod();
+ testCase(result, testValue, i);
+ } catch(e) {
+ if (!(e instanceof SyntaxError))
+ throw e;
+ }
+}
+
+var G = class G extends A {
+ constructor() {
+ super();
+ }
+ get prop() {
+ var arrow = () => () => super.getConstValue() + '-' + this.value;
+ return arrow()();
+ }
+ set prop(value) {
+ var arrow = () => (newVal) => this.value = newVal;
+ arrow()(value);
+ }
+ setInitValue() {
+ this.value = testValue;
+ }
+ getValueCB() {
+ var arrow = () => super.getValue();
+ return arrow;
+ }
+ setValueCB() {
+ var arrow = (newVal) => this.value = newVal;
+ return arrow;
+ }
+ getParentValue() {
+ return super.getValue();
+ }
+ getParentValueWithError() {
+ var f = function () {
+ return () => super.getValue();
+ };
+ return f();
+ }
+ };
+
+ var g = new G();
+ for (var i = 0; i < 10000; i++) {
+ g.setInitValue();
+ testCase(g.prop, testValue + '-' + testValue, 'Error: Some problem with using arrow and "super" inside of the method');
+ g.prop = 'new-test-value';
+ testCase(g.prop, testValue + '-new-test-value', 'Error: Some problem with using arrow and "super" inside of the getter and setter');
+ }
+
+var g1 = new G();
+for (var i = 0; i < 10000; i++) {
+ g1.setInitValue();
+ let getValue = g1.getValueCB();
+ testCase(getValue(), testValue, 'Error: Some problem with using arrow and "super" inside of the method that retun arrow function');
+ let setValue = g1.setValueCB();
+ setValue('new-value');
+ testCase(getValue(), 'new-value', 'Error: Some problem with using arrow and "super" inside of the method that retun arrow function');
+}
+
+var g2 = new G();
+for (var i = 0; i < 10000; i++) {
+ let error = false;
+ try {
+ g2.getParentValueWithError()();
+ } catch(e) {
+ // FIXME: should by check if e instanceof SyntaxError
+ // https://bugs.webkit.org/show_bug.cgi?id=150893
+ error = true;
+ }
+ testCase(error, true, 'Error: using "super" should lead to error');
+}
+
+
+var H = class H extends A {
+ constructor() {
+ var arrow = () => () => super.getValue();
+ super();
+ this.newValue = arrow()();
+ }
+};
+
+for (var i = 0; i < 10000; i++) {
+ let h = new H();
+ testCase(h.newValue, testValue, 'Error: Some problem with using "super" inside of the constructor');
+}
+
+var I = class I extends A {
+ constructor (beforeSuper) {
+ var arrow = () => super.getValue();
+ if (beforeSuper) {
+ this._value = arrow();
+ super();
+ } else {
+ super();
+ this._value = arrow();
+ }
+ }
+}
+
+var J = class J extends A {
+ constructor (beforeSuper) {
+ var _value;
+ var arrow = () => super.getConstValue();
+ if (beforeSuper) {
+ _value = arrow();
+ super();
+ } else {
+ super();
+ _value = arrow();
+ }
+ this._value = _value;
+ }
+}
+
+for (var i = 0; i < 10000; i++) {
+ let i = new I(false);
+ testCase(i._value, testValue, 'Error: Some problem with using "super" inside of the constructor');
+ let j = new J(false);
+ testCase(j._value, testValue, 'Error: Some problem with using "super" inside of the constructor');
+
+ // FIXME: Problem with access to the super before super() in constructor
+ // https://bugs.webkit.org/show_bug.cgi?id=152108
+ //let j2 = new J(true);
+ //testCase(j2._value, testValue, 'Error: Some problem with using "super" inside of the constructor');
+ error = false;
+ try {
+ new I(true);
+ } catch (e) {
+ error = e instanceof ReferenceError;
+ }
+ testCase(error, true, 'Error: using "super" property before super() should lead to error');
+}