WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
patch
a-backup.diff (text/plain), 32.04 KB, created by
Saam Barati
on 2016-08-02 13:25:30 PDT
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2016-08-02 13:25:30 PDT
Size:
32.04 KB
patch
obsolete
>Index: JSTests/Changelog >=================================================================== >--- JSTests/Changelog (revision 203979) >+++ JSTests/Changelog (working copy) >@@ -1,3 +1,46 @@ >+2016-08-02 Saam Barati <sbarati@apple.com> >+ >+ update a class extending null w.r.t the ES7 spec >+ https://bugs.webkit.org/show_bug.cgi?id=160417 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * Changelog: >+ * stress/class-derived-from-null.js: Added. >+ (assert): >+ (test): >+ (test1.C): >+ (test1): >+ (jsNull): >+ (test2.C): >+ (test2): >+ (test3.C): >+ (test3.D): >+ (test3.E): >+ (test3): >+ (test4.E): >+ (test4): >+ (test5.E): >+ (test5): >+ (test6.Base): >+ (test6.D): >+ (test6.E): >+ (test6.F): >+ (test6.G): >+ (test6): >+ >+2016-08-01 Saam Barati <sbarati@apple.com> >+ >+ update a class extending null w.r.t the ES7 spec >+ https://bugs.webkit.org/show_bug.cgi?id=160417 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/class-derived-from-null.js: Added. >+ (assert): >+ (C): >+ (E): >+ > 2016-08-01 Keith Miller <keith_miller@apple.com> > > We should not keep the JavaScript tests inside the Source/JavaScriptCore/ directory. >Index: JSTests/stress/class-derived-from-null.js >=================================================================== >--- JSTests/stress/class-derived-from-null.js (nonexistent) >+++ JSTests/stress/class-derived-from-null.js (working copy) >@@ -0,0 +1,128 @@ >+function assert(b) { >+ if (!b) >+ throw new Error("Bad!") >+} >+ >+function test(f, count = 1000) { >+ for (let i = 0; i < count; i++) >+ f(); >+} >+ >+function test1() { >+ class C extends null { } >+ assert((new C) instanceof C); >+ assert(!((new C) instanceof Object)); >+ assert(Reflect.getPrototypeOf(C.prototype) === null); >+ >+ let o = {} >+ class D extends null { >+ constructor() { >+ return o; >+ } >+ } >+ assert(new D === o); >+ assert(Reflect.getPrototypeOf(D.prototype) === null); >+ >+ class E extends null { >+ constructor() { >+ return this; >+ } >+ } >+ assert((new E) instanceof E); >+ assert(!((new E) instanceof Object)); >+ assert(Reflect.getPrototypeOf(E.prototype) === null); >+} >+test(test1); >+ >+function jsNull() { return null; } >+function test2() { >+ class C extends jsNull() { } >+ assert((new C) instanceof C); >+ assert(!((new C) instanceof Object)); >+ assert(Reflect.getPrototypeOf(C.prototype) === null); >+ >+ let o = {} >+ class D extends jsNull() { >+ constructor() { >+ return o; >+ } >+ } >+ assert(new D === o); >+ assert(Reflect.getPrototypeOf(D.prototype) === null); >+ >+ class E extends jsNull() { >+ constructor() { >+ return this; >+ } >+ } >+ assert((new E) instanceof E); >+ assert(!((new E) instanceof Object)); >+ assert(Reflect.getPrototypeOf(E.prototype) === null); >+} >+test(test2); >+ >+function test3() { >+ class C extends jsNull() { constructor() { super(); } } >+ let threw = false; >+ try { >+ new C; >+ } catch(e) { >+ threw = e.toString() === "TypeError: function is not a constructor (evaluating 'super()')"; >+ } >+ assert(threw); >+ >+ class D extends jsNull() { constructor() { let arr = ()=>super(); arr(); } } >+ threw = false; >+ try { >+ new D; >+ } catch(e) { >+ threw = e.toString() === "TypeError: function is not a constructor (evaluating 'super()')"; >+ } >+ assert(threw); >+ >+ class E extends jsNull() { constructor() { let arr = ()=>super(); return this; } } >+ assert((new E) instanceof E); >+ assert(!((new E) instanceof Object)); >+ assert(Reflect.getPrototypeOf(E.prototype) === null); >+} >+test(test3); >+ >+function test4() { >+ class E extends jsNull() { constructor() { return 25; } } >+ assert((new E) instanceof E); >+ assert(!((new E) instanceof Object)); >+ assert(Reflect.getPrototypeOf(E.prototype) === null); >+} >+test(test4); >+ >+function test5() { >+ class E extends jsNull() { constructor() { let arr = ()=>this; return arr(); } } >+ assert((new E) instanceof E); >+ assert(!((new E) instanceof Object)); >+ assert(Reflect.getPrototypeOf(E.prototype) === null); >+} >+test(test5); >+ >+function test6() { >+ class Base { } >+ class D extends Base { } >+ class E extends jsNull() { constructor() { let ret = this; return ret; } } >+ class F extends jsNull() { constructor() { return 25; } } >+ class G extends jsNull() { constructor() { super(); } } >+ let result = Reflect.construct(E, [], D); >+ assert(result instanceof D); >+ assert(result instanceof Object); >+ >+ result = Reflect.construct(F, [], D); >+ assert(result instanceof D); >+ assert(result instanceof Object); >+ >+ let threw = false; >+ try { >+ Reflect.construct(G, [], D); >+ } catch(e) { >+ threw = e.toString() === "TypeError: function is not a constructor (evaluating 'super()')"; >+ } >+ assert(threw); >+} >+test(test6); >Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 203979) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,51 @@ >+2016-08-02 Saam Barati <sbarati@apple.com> >+ >+ update a class extending null w.r.t the ES7 spec >+ https://bugs.webkit.org/show_bug.cgi?id=160417 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ When a class extends null, it should not be marked as a derived class. >+ This was changed in the ES2016 spec, and this patch makes the needed >+ changes in JSC to follow the spec. This allows classes to extend >+ null and have their default constructor invoked without throwing an exception. >+ This also prevents |this| from being under TDZ at the start of the constructor. >+ Because ES6 allows arbitrary expressions in the `class <ident> extends <expr>` >+ syntax, we don't know statically if a constructor is extending null or not. >+ Therefore, we don't always know statically if it's a base or derived constructor. >+ I solved this by putting a boolean on the constructor function under a private >+ symbol named isDerivedConstructor when doing class construction. We only need >+ to put this boolean on constructors that may extend null. Constructors that are >+ declared in a class with no extends syntax can tell statically that they are a base constructor. >+ >+ I've also renamed the ConstructorKind::Derived enum value to be >+ ConstructorKind::Extends to better indicate that we can't answer >+ the "am I a derived constructor?" question statically. >+ >+ * builtins/BuiltinExecutables.cpp: >+ (JSC::BuiltinExecutables::createDefaultConstructor): >+ * builtins/BuiltinNames.h: >+ * bytecompiler/BytecodeGenerator.cpp: >+ (JSC::BytecodeGenerator::BytecodeGenerator): >+ (JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded): >+ (JSC::BytecodeGenerator::emitReturn): >+ (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment): >+ (JSC::BytecodeGenerator::ensureThis): >+ (JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope): >+ * bytecompiler/BytecodeGenerator.h: >+ (JSC::BytecodeGenerator::makeFunction): >+ * bytecompiler/NodesCodegen.cpp: >+ (JSC::EvalFunctionCallNode::emitBytecode): >+ (JSC::FunctionCallValueNode::emitBytecode): >+ (JSC::FunctionNode::emitBytecode): >+ (JSC::ClassExprNode::emitBytecode): >+ * parser/Parser.cpp: >+ (JSC::Parser<LexerType>::Parser): >+ (JSC::Parser<LexerType>::parseFunctionInfo): >+ (JSC::Parser<LexerType>::parseClass): >+ (JSC::Parser<LexerType>::parseMemberExpression): >+ * parser/ParserModes.h: >+ > 2016-08-01 Saam Barati <sbarati@apple.com> > > Sub should be a Math IC >Index: Source/JavaScriptCore/builtins/BuiltinExecutables.cpp >=================================================================== >--- Source/JavaScriptCore/builtins/BuiltinExecutables.cpp (revision 203979) >+++ Source/JavaScriptCore/builtins/BuiltinExecutables.cpp (working copy) >@@ -53,7 +53,7 @@ UnlinkedFunctionExecutable* BuiltinExecu > break; > case ConstructorKind::Base: > return createExecutable(m_vm, makeSource(baseConstructorCode), name, constructorKind, ConstructAbility::CanConstruct); >- case ConstructorKind::Derived: >+ case ConstructorKind::Extends: > return createExecutable(m_vm, makeSource(derivedConstructorCode), name, constructorKind, ConstructAbility::CanConstruct); > } > ASSERT_NOT_REACHED(); >Index: Source/JavaScriptCore/builtins/BuiltinNames.h >=================================================================== >--- Source/JavaScriptCore/builtins/BuiltinNames.h (revision 203979) >+++ Source/JavaScriptCore/builtins/BuiltinNames.h (working copy) >@@ -127,6 +127,7 @@ namespace JSC { > macro(isArray) \ > macro(isArrayConstructor) \ > macro(isConstructor) \ >+ macro(isDerivedConstructor) \ > macro(isRegExpObject) \ > macro(concatMemcpy) \ > macro(appendMemcpy) \ >Index: Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >=================================================================== >--- Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (revision 203979) >+++ Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (working copy) >@@ -560,9 +560,18 @@ BytecodeGenerator::BytecodeGenerator(VM& > if (SourceParseMode::ArrowFunctionMode != parseMode) { > if (isConstructor()) { > emitMove(m_newTargetRegister, &m_thisRegister); >- if (constructorKind() == ConstructorKind::Derived) >+ if (constructorKind() == ConstructorKind::Extends) { >+ RefPtr<Label> isDerived = newLabel(); >+ RefPtr<Label> done = newLabel(); >+ m_isDerivedConstuctor = addVar(); >+ emitGetById(m_isDerivedConstuctor, &m_calleeRegister, propertyNames().builtinNames().isDerivedConstructorPrivateName()); >+ emitJumpIfTrue(m_isDerivedConstuctor, isDerived.get()); >+ emitCreateThis(&m_thisRegister); >+ emitJump(done.get()); >+ emitLabel(isDerived.get()); > emitMoveEmptyValue(&m_thisRegister); >- else >+ emitLabel(done.get()); >+ } else > emitCreateThis(&m_thisRegister); > } else if (constructorKind() != ConstructorKind::None) > emitThrowTypeError("Cannot call a class constructor without |new|"); >@@ -948,7 +957,7 @@ void BytecodeGenerator::initializeArrowF > functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().newTargetLocalPrivateName().impl(), SymbolTableEntry(VarOffset(offset))); > } > >- if (isConstructor() && constructorKind() == ConstructorKind::Derived && isSuperUsedInInnerArrowFunction()) { >+ if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction()) { > offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary); > functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().derivedConstructorPrivateName().impl(), SymbolTableEntry(VarOffset(offset))); > } >@@ -970,7 +979,7 @@ void BytecodeGenerator::initializeArrowF > addTarget.iterator->value.setIsLet(); > } > >- if (isConstructor() && constructorKind() == ConstructorKind::Derived && isSuperUsedInInnerArrowFunction()) { >+ if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction()) { > auto derivedConstructor = environment.add(propertyNames().builtinNames().derivedConstructorPrivateName()); > derivedConstructor.iterator->value.setIsCaptured(); > derivedConstructor.iterator->value.setIsLet(); >@@ -3265,24 +3274,28 @@ void BytecodeGenerator::emitCallDefinePr > RegisterID* BytecodeGenerator::emitReturn(RegisterID* src) > { > if (isConstructor()) { >- bool derived = constructorKind() == ConstructorKind::Derived; >+ bool mightBeDerived = constructorKind() == ConstructorKind::Extends; > bool srcIsThis = src->index() == m_thisRegister.index(); > >- if (derived && srcIsThis) >+ if (mightBeDerived && srcIsThis) > emitTDZCheck(src); > > if (!srcIsThis) { > RefPtr<Label> isObjectLabel = newLabel(); > emitJumpIfTrue(emitIsObject(newTemporary(), src), isObjectLabel.get()); > >- if (derived) { >+ if (mightBeDerived) { >+ ASSERT(m_isDerivedConstuctor); >+ RefPtr<Label> returnThis = newLabel(); >+ emitJumpIfFalse(m_isDerivedConstuctor, returnThis.get()); >+ // Else, we're a derived constructor here. > RefPtr<Label> isUndefinedLabel = newLabel(); > emitJumpIfTrue(emitIsUndefined(newTemporary(), src), isUndefinedLabel.get()); > emitThrowTypeError("Cannot return a non-object type in the constructor of a derived class."); > emitLabel(isUndefinedLabel.get()); > emitTDZCheck(&m_thisRegister); >+ emitLabel(returnThis.get()); > } >- > emitUnaryNoDstOp(op_ret, &m_thisRegister); > emitLabel(isObjectLabel.get()); > } >@@ -4285,7 +4298,7 @@ void BytecodeGenerator::popIndexedForInS > > RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment(const Identifier& identifier) > { >- ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived || m_codeType == EvalCode); >+ ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Extends || m_codeType == EvalCode); > > return emitResolveScope(nullptr, variable(identifier, ThisResolutionType::Scoped)); > } >@@ -4311,10 +4324,10 @@ RegisterID* BytecodeGenerator::emitLoadD > > RegisterID* BytecodeGenerator::ensureThis() > { >- if (constructorKind() == ConstructorKind::Derived && needsToUpdateArrowFunctionContext() && isSuperCallUsedInInnerArrowFunction()) >+ if (constructorKind() == ConstructorKind::Extends && needsToUpdateArrowFunctionContext() && isSuperCallUsedInInnerArrowFunction()) > emitLoadThisFromArrowFunctionLexicalEnvironment(); > >- if (constructorKind() == ConstructorKind::Derived || isDerivedConstructorContext()) >+ if (constructorKind() == ConstructorKind::Extends || isDerivedConstructorContext()) > emitTDZCheck(thisRegister()); > > return thisRegister(); >@@ -4357,7 +4370,7 @@ void BytecodeGenerator::emitPutNewTarget > > void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope() > { >- if ((isConstructor() && constructorKind() == ConstructorKind::Derived) || m_codeBlock->isClassContext()) { >+ if ((isConstructor() && constructorKind() == ConstructorKind::Extends) || m_codeBlock->isClassContext()) { > if (isSuperUsedInInnerArrowFunction()) { > ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister); > >Index: Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >=================================================================== >--- Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (revision 203979) >+++ Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (working copy) >@@ -829,7 +829,7 @@ namespace JSC { > DerivedContextType newDerivedContextType = DerivedContextType::None; > > if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode) { >- if (constructorKind() == ConstructorKind::Derived || isDerivedConstructorContext()) >+ if (constructorKind() == ConstructorKind::Extends || isDerivedConstructorContext()) > newDerivedContextType = DerivedContextType::DerivedConstructorContext; > else if (m_codeBlock->isClassContext() || isDerivedClassContext()) > newDerivedContextType = DerivedContextType::DerivedMethodContext; >@@ -910,6 +910,7 @@ namespace JSC { > RegisterID* m_emptyValueRegister { nullptr }; > RegisterID* m_globalObjectRegister { nullptr }; > RegisterID* m_newTargetRegister { nullptr }; >+ RegisterID* m_isDerivedConstuctor { nullptr }; > RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount]; > RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr }; > >Index: Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp >=================================================================== >--- Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (revision 203979) >+++ Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (working copy) >@@ -751,7 +751,7 @@ RegisterID* EvalFunctionCallNode::emitBy > // eval("this.id = 'B'"); > // } > // } >- if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction()) >+ if (generator.constructorKind() == ConstructorKind::Extends && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction()) > generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); > > Variable var = generator.variable(generator.propertyNames().eval); >@@ -785,11 +785,11 @@ RegisterID* FunctionCallValueNode::emitB > CallArguments callArguments(generator, m_args); > > ASSERT(generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext); >- ASSERT(generator.constructorKind() == ConstructorKind::Derived || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext); >+ ASSERT(generator.constructorKind() == ConstructorKind::Extends || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext); > generator.emitMove(callArguments.thisRegister(), generator.newTarget()); > RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); > >- bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Derived; >+ bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Extends; > bool doWeUseArrowFunctionInConstructor = isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext(); > > if (generator.isDerivedConstructorContext() || (doWeUseArrowFunctionInConstructor && generator.isSuperCallUsedInInnerArrowFunction())) >@@ -3364,7 +3364,7 @@ void FunctionNode::emitBytecode(Bytecode > > // If there is no return we must automatically insert one. > if (!returnNode) { >- if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isSuperCallUsedInInnerArrowFunction()) >+ if (generator.constructorKind() == ConstructorKind::Extends && generator.needsToUpdateArrowFunctionContext() && generator.isSuperCallUsedInInnerArrowFunction()) > 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()); >@@ -3460,10 +3460,32 @@ RegisterID* ClassExprNode::emitBytecode( > metadata->setEcmaName(ecmaName()); > metadata->setClassSource(m_classSource); > constructor = generator.emitNode(dst, m_constructorExpression); >+ if (m_classHeritage) { >+ RefPtr<RegisterID> isDerivedConstructor = generator.newTemporary(); >+ generator.emitUnaryOp(op_not, isDerivedConstructor.get(), >+ generator.emitUnaryOp(op_eq_null, isDerivedConstructor.get(), superclass.get())); >+ generator.emitDirectPutById(constructor.get(), generator.propertyNames().builtinNames().isDerivedConstructorPrivateName(), isDerivedConstructor.get(), PropertyNode::Unknown); >+ } > } else { >- constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst), >- m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base, >- m_name, ecmaName(), m_classSource); >+ if (m_classHeritage) { >+ constructor = generator.finalDestination(dst); >+ RefPtr<RegisterID> tempRegister = generator.newTemporary(); >+ RefPtr<Label> superclassIsNullLabel = generator.newLabel(); >+ RefPtr<Label> done = generator.newLabel(); >+ >+ generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get()); >+ generator.emitNewDefaultConstructor(constructor.get(), ConstructorKind::Extends, m_name, ecmaName(), m_classSource); >+ generator.emitLoad(tempRegister.get(), jsBoolean(true)); >+ generator.emitJump(done.get()); >+ generator.emitLabel(superclassIsNullLabel.get()); >+ generator.emitNewDefaultConstructor(constructor.get(), ConstructorKind::Base, m_name, ecmaName(), m_classSource); >+ generator.emitLoad(tempRegister.get(), jsBoolean(false)); >+ generator.emitLabel(done.get()); >+ generator.emitDirectPutById(constructor.get(), generator.propertyNames().builtinNames().isDerivedConstructorPrivateName(), tempRegister.get(), PropertyNode::Unknown); >+ } else { >+ constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst), >+ ConstructorKind::Base, m_name, ecmaName(), m_classSource); >+ } > } > > const auto& propertyNames = generator.propertyNames(); >Index: Source/JavaScriptCore/parser/Parser.cpp >=================================================================== >--- Source/JavaScriptCore/parser/Parser.cpp (revision 203979) >+++ Source/JavaScriptCore/parser/Parser.cpp (working copy) >@@ -224,7 +224,7 @@ Parser<LexerType>::Parser(VM* vm, const > scope->setEvalContextType(evalContextType); > > if (derivedContextType == DerivedContextType::DerivedConstructorContext) { >- scope->setConstructorKind(ConstructorKind::Derived); >+ scope->setConstructorKind(ConstructorKind::Extends); > scope->setExpectedSuperBinding(SuperBinding::Needed); > } > >@@ -2101,7 +2101,7 @@ template <class TreeBuilder> bool Parser > > if (m_defaultConstructorKind != ConstructorKind::None) { > constructorKind = m_defaultConstructorKind; >- expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Derived ? SuperBinding::Needed : SuperBinding::NotNeeded; >+ expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Extends ? SuperBinding::Needed : SuperBinding::NotNeeded; > } > > functionBodyType = StandardFunctionBodyBlock; >@@ -2303,7 +2303,7 @@ template <class TreeBuilder> TreeClassEx > parentClass = parseMemberExpression(context); > failIfFalse(parentClass, "Cannot parse the parent class name"); > } >- const ConstructorKind constructorKind = parentClass ? ConstructorKind::Derived : ConstructorKind::Base; >+ const ConstructorKind constructorKind = parentClass ? ConstructorKind::Extends : ConstructorKind::Base; > > consumeOrFail(OPENBRACE, "Expected opening '{' at the start of a class body"); > >@@ -4017,7 +4017,7 @@ template <class TreeBuilder> TreeExpress > ? functionScope->constructorKind() > : closestOrdinaryFunctionScope->constructorKind(); > semanticFailIfTrue(functionConstructorKind == ConstructorKind::None, "super is not valid in this context"); >- semanticFailIfTrue(functionConstructorKind != ConstructorKind::Derived, "super is not valid in this context"); >+ semanticFailIfTrue(functionConstructorKind != ConstructorKind::Extends, "super is not valid in this context"); > } > } > if (currentScope()->isArrowFunction()) >Index: Source/JavaScriptCore/parser/ParserModes.h >=================================================================== >--- Source/JavaScriptCore/parser/ParserModes.h (revision 203979) >+++ Source/JavaScriptCore/parser/ParserModes.h (working copy) >@@ -35,7 +35,7 @@ enum class JSParserStrictMode { NotStric > enum class JSParserBuiltinMode { NotBuiltin, Builtin }; > enum class JSParserCodeType { Program, Function, Module }; > >-enum class ConstructorKind { None, Base, Derived }; >+enum class ConstructorKind { None, Base, Extends }; > enum class SuperBinding { Needed, NotNeeded }; > > enum DebuggerMode { DebuggerOff, DebuggerOn }; >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 203979) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,15 @@ >+2016-08-02 Saam Barati <sbarati@apple.com> >+ >+ update a class extending null w.r.t the ES7 spec >+ https://bugs.webkit.org/show_bug.cgi?id=160417 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * js/class-syntax-extends-expected.txt: >+ * js/class-syntax-super-expected.txt: >+ * js/script-tests/class-syntax-extends.js: >+ * js/script-tests/class-syntax-super.js: >+ > 2016-08-01 Adrian Perez de Castro <aperez@igalia.com> > > Update Apache configuration for Arch Linux >Index: LayoutTests/js/class-syntax-extends-expected.txt >=================================================================== >--- LayoutTests/js/class-syntax-extends-expected.txt (revision 203979) >+++ LayoutTests/js/class-syntax-extends-expected.txt (working copy) >@@ -57,10 +57,10 @@ PASS Object.getPrototypeOf((class extend > PASS new (class extends undefined { constructor () { this } }):::TypeError: The superclass is not an object. > PASS x = undefined; new (class extends x { constructor () { super(); } }):::TypeError: The superclass is not an object. > PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x >-PASS new (class extends null { constructor () { this; } }):::ReferenceError: Cannot access uninitialized variable. >+PASS new (class extends null { constructor () { this; } }) > PASS new (class extends null { constructor () { super(); } }):::TypeError: function is not a constructor (evaluating 'super()') > PASS x = {}; new (class extends null { constructor () { return x } }):::x >-PASS y = 12; new (class extends null { constructor () { return y; } }):::TypeError: Cannot return a non-object type in the constructor of a derived class. >+PASS y = 12; class C extends null { constructor () { return y; } }; new C instanceof C; > PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x > PASS x = null; Object.getPrototypeOf((class extends x { }).prototype):::null > PASS Object.prototype.isPrototypeOf(class { }) >Index: LayoutTests/js/class-syntax-super-expected.txt >=================================================================== >--- LayoutTests/js/class-syntax-super-expected.txt (revision 203979) >+++ LayoutTests/js/class-syntax-super-expected.txt (working copy) >@@ -30,12 +30,12 @@ PASS x = { }; new (class extends Base { > PASS x instanceof Base > PASS new (class extends Base { constructor() { } }):::ReferenceError: Cannot access uninitialized variable. > PASS new (class extends Base { constructor() { return 1; } }):::TypeError: Cannot return a non-object type in the constructor of a derived class. >-PASS new (class extends null { constructor() { return undefined } }):::ReferenceError: Cannot access uninitialized variable. >+PASS new (class extends null { constructor() { return undefined } }) > PASS new (class extends null { constructor() { super(); return undefined } }):::TypeError: function is not a constructor (evaluating 'super()') > PASS x = { }; new (class extends null { constructor() { return x } });:::x > PASS x instanceof Object >-PASS new (class extends null { constructor() { } }):::ReferenceError: Cannot access uninitialized variable. >-PASS new (class extends null { constructor() { return 1; } }):::TypeError: Cannot return a non-object type in the constructor of a derived class. >+PASS new (class extends null { constructor() { } }) >+PASS new (class extends null { constructor() { return 1; } }) > PASS new (class extends null { constructor() { super() } }):::TypeError: function is not a constructor (evaluating 'super()') > PASS new (class { constructor() { super() } }):::SyntaxError: super is not valid in this context. > PASS function x() { super(); }:::SyntaxError: super is not valid in this context. >Index: LayoutTests/js/script-tests/class-syntax-extends.js >=================================================================== >--- LayoutTests/js/script-tests/class-syntax-extends.js (revision 203979) >+++ LayoutTests/js/script-tests/class-syntax-extends.js (working copy) >@@ -115,10 +115,10 @@ shouldBe('Object.getPrototypeOf((class e > shouldThrow('new (class extends undefined { constructor () { this } })', '"TypeError: The superclass is not an object."'); > shouldThrow('x = undefined; new (class extends x { constructor () { super(); } })', '"TypeError: The superclass is not an object."'); > shouldBeTrue ('class x {}; new (class extends null { constructor () { return new x; } }) instanceof x'); >-shouldThrow('new (class extends null { constructor () { this; } })', '"ReferenceError: Cannot access uninitialized variable."'); >+shouldNotThrow('new (class extends null { constructor () { this; } })'); > shouldThrow('new (class extends null { constructor () { super(); } })', '"TypeError: function is not a constructor (evaluating \'super()\')"'); > shouldBe('x = {}; new (class extends null { constructor () { return x } })', 'x'); >-shouldThrow('y = 12; new (class extends null { constructor () { return y; } })', '"TypeError: Cannot return a non-object type in the constructor of a derived class."'); >+shouldBeTrue('y = 12; class C extends null { constructor () { return y; } }; new C instanceof C;', '"TypeError: Cannot return a non-object type in the constructor of a derived class."'); > shouldBeTrue ('class x {}; new (class extends null { constructor () { return new x; } }) instanceof x'); > shouldBe('x = null; Object.getPrototypeOf((class extends x { }).prototype)', 'null'); > shouldBeTrue('Object.prototype.isPrototypeOf(class { })'); >Index: LayoutTests/js/script-tests/class-syntax-super.js >=================================================================== >--- LayoutTests/js/script-tests/class-syntax-super.js (revision 203979) >+++ LayoutTests/js/script-tests/class-syntax-super.js (working copy) >@@ -113,12 +113,12 @@ shouldBe('x = { }; new (class extends Ba > shouldBeFalse('x instanceof Base'); > shouldThrow('new (class extends Base { constructor() { } })', '"ReferenceError: Cannot access uninitialized variable."'); > shouldThrow('new (class extends Base { constructor() { return 1; } })', '"TypeError: Cannot return a non-object type in the constructor of a derived class."'); >-shouldThrow('new (class extends null { constructor() { return undefined } })'); >+shouldNotThrow('new (class extends null { constructor() { return undefined } })'); > shouldThrow('new (class extends null { constructor() { super(); return undefined } })', '"TypeError: function is not a constructor (evaluating \'super()\')"'); > shouldBe('x = { }; new (class extends null { constructor() { return x } });', 'x'); > shouldBeTrue('x instanceof Object'); >-shouldThrow('new (class extends null { constructor() { } })', '"ReferenceError: Cannot access uninitialized variable."'); >-shouldThrow('new (class extends null { constructor() { return 1; } })', '"TypeError: Cannot return a non-object type in the constructor of a derived class."'); >+shouldNotThrow('new (class extends null { constructor() { } })'); >+shouldNotThrow('new (class extends null { constructor() { return 1; } })'); > shouldThrow('new (class extends null { constructor() { super() } })', '"TypeError: function is not a constructor (evaluating \'super()\')"'); > shouldThrow('new (class { constructor() { super() } })', '"SyntaxError: super is not valid in this context."'); > shouldThrow('function x() { super(); }', '"SyntaxError: super is not valid in this context."');
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 160417
:
285039
|
285130
|
285136
|
285154