Diff
Modified: trunk/LayoutTests/ChangeLog (182170 => 182171)
--- trunk/LayoutTests/ChangeLog 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/LayoutTests/ChangeLog 2015-03-31 01:59:31 UTC (rev 182171)
@@ -1,3 +1,21 @@
+2015-03-30 Ryosuke Niwa <[email protected]>
+
+ Extending null should set __proto__ to null
+ https://bugs.webkit.org/show_bug.cgi?id=142882
+
+ Reviewed by Geoffrey Garen and Benjamin Poulain.
+
+ Added more test cases for extending from null, and added checks for prototypes.
+
+ Also rebaselined existing tests.
+
+ * js/class-syntax-call-expected.txt:
+ * js/class-syntax-extends-expected.txt:
+ * js/class-syntax-super-expected.txt:
+ * js/script-tests/class-syntax-call.js:
+ * js/script-tests/class-syntax-extends.js:
+ * js/script-tests/class-syntax-super.js:
+
2015-03-30 Alex Christensen <[email protected]>
[Content Extensions] Correctly handle regular expressions matching everything
Modified: trunk/LayoutTests/js/class-syntax-call-expected.txt (182170 => 182171)
--- trunk/LayoutTests/js/class-syntax-call-expected.txt 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/LayoutTests/js/class-syntax-call-expected.txt 2015-03-31 01:59:31 UTC (rev 182171)
@@ -9,7 +9,7 @@
PASS B() threw exception TypeError: Cannot call a class constructor.
PASS new (class { constructor() {} })() did not throw exception.
PASS (class { constructor() {} })() threw exception TypeError: Cannot call a class constructor.
-PASS new (class extends null { constructor() { super() } })() did not throw exception.
+PASS new (class extends null { constructor() { super() } })() threw exception TypeError: undefined is not an object (evaluating 'super()').
PASS (class extends null { constructor() { super() } })() threw exception TypeError: Cannot call a class constructor.
PASS successfullyParsed is true
Modified: trunk/LayoutTests/js/class-syntax-extends-expected.txt (182170 => 182171)
--- trunk/LayoutTests/js/class-syntax-extends-expected.txt 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/LayoutTests/js/class-syntax-extends-expected.txt 2015-03-31 01:59:31 UTC (rev 182171)
@@ -4,7 +4,10 @@
PASS (new Base) instanceof Base is true
+PASS Object.getPrototypeOf(new Base) is Base.prototype
PASS (new Derived) instanceof Derived is true
+PASS Object.getPrototypeOf(new Derived) is Derived.prototype
+PASS Object.getPrototypeOf(Derived.prototype) is Base.prototype
PASS (new Derived).baseMethod() is "base"
PASS (new Derived).overridenMethod() is "derived"
PASS Derived.staticBaseMethod() is "base"
@@ -15,7 +18,9 @@
PASS x = class extends Base { } did not throw exception.
PASS x = class extends Base { constructor() { } } did not throw exception.
PASS x.__proto__ is Base
+PASS Object.getPrototypeOf(x) is Base
PASS x.prototype.__proto__ is Base.prototype
+PASS Object.getPrototypeOf(x.prototype) is Base.prototype
PASS x = class extends null { constructor() { } }; x.__proto__ is Function.prototype
PASS x.__proto__ is Function.prototype
PASS x = class extends 3 { constructor() { } }; x.__proto__ threw exception TypeError: The superclass is not an object..
@@ -47,6 +52,21 @@
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A() { constructor() { } } threw exception TypeError: The superclass's prototype is not an object..
PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (x++, namespace.A) { constructor() { } } } catch (e) { } x is 2
PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (namespace.A, x++) { constructor() { } } } catch (e) { } x is 2
+PASS Object.getPrototypeOf((class { constructor () { } }).prototype) is Object.prototype
+PASS Object.getPrototypeOf((class extends null { constructor () { super(); } }).prototype) is null
+PASS new (class extends undefined { constructor () { this } }) threw exception ReferenceError: Cannot access uninitialized variable..
+PASS new (class extends undefined { constructor () { super(); } }) threw exception TypeError: undefined is not an object (evaluating 'super()').
+PASS x = {}; new (class extends undefined { constructor () { return x; } }) is x
+PASS y = 12; new (class extends undefined { constructor () { return y; } }) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
+PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
+PASS new (class extends null { constructor () { this; } }) threw exception ReferenceError: Cannot access uninitialized variable..
+PASS new (class extends null { constructor () { super(); } }) threw exception TypeError: undefined is not an object (evaluating 'super()').
+PASS x = {}; new (class extends null { constructor () { return x } }) is x
+PASS y = 12; new (class extends null { constructor () { return y; } }) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
+PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
+PASS x = null; Object.getPrototypeOf((class extends x { }).prototype) is null
+PASS Object.prototype.isPrototypeOf(class { }) is true
+PASS Function.prototype.isPrototypeOf(class { }) is true
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/js/class-syntax-super-expected.txt (182170 => 182171)
--- trunk/LayoutTests/js/class-syntax-super-expected.txt 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/LayoutTests/js/class-syntax-super-expected.txt 2015-03-31 01:59:31 UTC (rev 182171)
@@ -31,12 +31,12 @@
PASS new (class extends Base { constructor() { } }) threw exception ReferenceError: Cannot access uninitialized variable..
PASS new (class extends Base { constructor() { return 1; } }) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
PASS new (class extends null { constructor() { return undefined } }) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS new (class extends null { constructor() { super(); return undefined } }) instanceof Object is true
+PASS new (class extends null { constructor() { super(); return undefined } }) threw exception TypeError: undefined is not an object (evaluating 'super()').
PASS x = { }; new (class extends null { constructor() { return x } }); is x
PASS x instanceof Object is true
PASS new (class extends null { constructor() { } }) threw exception ReferenceError: Cannot access uninitialized variable..
PASS new (class extends null { constructor() { return 1; } }) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS new (class extends null { constructor() { super() } }) did not throw exception.
+PASS new (class extends null { constructor() { super() } }) threw exception TypeError: undefined is not an object (evaluating 'super()').
PASS new (class { constructor() { super() } }) threw exception SyntaxError: Cannot call super() in a base class constructor..
PASS function x() { super(); } threw exception SyntaxError: Cannot call super() outside of a class constructor..
PASS new (class extends Object { constructor() { function x() { super() } } }) threw exception SyntaxError: Cannot call super() outside of a class constructor..
Modified: trunk/LayoutTests/js/script-tests/class-syntax-call.js (182170 => 182171)
--- trunk/LayoutTests/js/script-tests/class-syntax-call.js 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/LayoutTests/js/script-tests/class-syntax-call.js 2015-03-31 01:59:31 UTC (rev 182171)
@@ -9,7 +9,7 @@
shouldThrow('B()', '"TypeError: Cannot call a class constructor"');
shouldNotThrow('new (class { constructor() {} })()');
shouldThrow('(class { constructor() {} })()', '"TypeError: Cannot call a class constructor"');
-shouldNotThrow('new (class extends null { constructor() { super() } })()');
+shouldThrow('new (class extends null { constructor() { super() } })()', '"TypeError: undefined is not an object (evaluating \'super()\')"');
shouldThrow('(class extends null { constructor() { super() } })()', '"TypeError: Cannot call a class constructor"');
var successfullyParsed = true;
Modified: trunk/LayoutTests/js/script-tests/class-syntax-extends.js (182170 => 182171)
--- trunk/LayoutTests/js/script-tests/class-syntax-extends.js 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/LayoutTests/js/script-tests/class-syntax-extends.js 2015-03-31 01:59:31 UTC (rev 182171)
@@ -16,7 +16,10 @@
}
shouldBeTrue('(new Base) instanceof Base');
+shouldBe('Object.getPrototypeOf(new Base)', 'Base.prototype');
shouldBeTrue('(new Derived) instanceof Derived');
+shouldBe('Object.getPrototypeOf(new Derived)', 'Derived.prototype');
+shouldBe('Object.getPrototypeOf(Derived.prototype)', 'Base.prototype');
shouldBe('(new Derived).baseMethod()', '"base"');
shouldBe('(new Derived).overridenMethod()', '"derived"');
shouldBe('Derived.staticBaseMethod()', '"base"');
@@ -28,7 +31,9 @@
shouldNotThrow('x = class extends Base { }');
shouldNotThrow('x = class extends Base { constructor() { } }');
shouldBe('x.__proto__', 'Base');
+shouldBe('Object.getPrototypeOf(x)', 'Base');
shouldBe('x.prototype.__proto__', 'Base.prototype');
+shouldBe('Object.getPrototypeOf(x.prototype)', 'Base.prototype');
shouldBe('x = class extends null { constructor() { } }; x.__proto__', 'Function.prototype');
shouldBe('x.__proto__', 'Function.prototype');
shouldThrow('x = class extends 3 { constructor() { } }; x.__proto__', '"TypeError: The superclass is not an object."');
@@ -63,4 +68,20 @@
shouldBe('x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (x++, namespace.A) { constructor() { } } } catch (e) { } x', '2');
shouldBe('x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (namespace.A, x++) { constructor() { } } } catch (e) { } x', '2');
+shouldBe('Object.getPrototypeOf((class { constructor () { } }).prototype)', 'Object.prototype');
+shouldBe('Object.getPrototypeOf((class extends null { constructor () { super(); } }).prototype)', 'null');
+shouldThrow('new (class extends undefined { constructor () { this } })', '"ReferenceError: Cannot access uninitialized variable."');
+shouldThrow('new (class extends undefined { constructor () { super(); } })', '"TypeError: undefined is not an object (evaluating \'super()\')"');
+shouldBe('x = {}; new (class extends undefined { constructor () { return x; } })', 'x');
+shouldThrow('y = 12; new (class extends undefined { constructor () { return y; } })', '"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');
+shouldThrow('new (class extends null { constructor () { this; } })', '"ReferenceError: Cannot access uninitialized variable."');
+shouldThrow('new (class extends null { constructor () { super(); } })', '"TypeError: undefined is not an object (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 ('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 { })');
+shouldBeTrue('Function.prototype.isPrototypeOf(class { })');
+
var successfullyParsed = true;
Modified: trunk/LayoutTests/js/script-tests/class-syntax-super.js (182170 => 182171)
--- trunk/LayoutTests/js/script-tests/class-syntax-super.js 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/LayoutTests/js/script-tests/class-syntax-super.js 2015-03-31 01:59:31 UTC (rev 182171)
@@ -56,12 +56,12 @@
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 } })');
-shouldBeTrue('new (class extends null { constructor() { super(); return undefined } }) instanceof Object');
+shouldThrow('new (class extends null { constructor() { super(); return undefined } })', '"TypeError: undefined is not an object (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() { super() } })');
+shouldThrow('new (class extends null { constructor() { super() } })', '"TypeError: undefined is not an object (evaluating \'super()\')"');
shouldThrow('new (class { constructor() { super() } })', '"SyntaxError: Cannot call super() in a base class constructor."');
shouldThrow('function x() { super(); }', '"SyntaxError: Cannot call super() outside of a class constructor."');
shouldThrow('new (class extends Object { constructor() { function x() { super() } } })', '"SyntaxError: Cannot call super() outside of a class constructor."');
Modified: trunk/Source/_javascript_Core/ChangeLog (182170 => 182171)
--- trunk/Source/_javascript_Core/ChangeLog 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-03-31 01:59:31 UTC (rev 182171)
@@ -1,3 +1,15 @@
+2015-03-30 Ryosuke Niwa <[email protected]>
+
+ Extending null should set __proto__ to null
+ https://bugs.webkit.org/show_bug.cgi?id=142882
+
+ Reviewed by Geoffrey Garen and Benjamin Poulain.
+
+ Set Derived.prototype.__proto__ to null when extending null.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ClassExprNode::emitBytecode):
+
2015-03-30 Mark Lam <[email protected]>
REGRESSION (r181993): inspector-protocol/debugger/setBreakpoint-dfg-and-modify-local.html crashes.
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (182170 => 182171)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2015-03-31 01:21:21 UTC (rev 182170)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2015-03-31 01:59:31 UTC (rev 182171)
@@ -2865,6 +2865,9 @@
prototype = generator.emitGetById(generator.newTemporary(), constructor.get(), generator.propertyNames().prototype);
if (superclass) {
+ RefPtr<RegisterID> protoParent = generator.newTemporary();
+ generator.emitLoad(protoParent.get(), jsNull());
+
RefPtr<RegisterID> tempRegister = generator.newTemporary();
RefPtr<Label> superclassIsNullLabel = generator.newLabel();
generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get());
@@ -2874,8 +2877,6 @@
generator.emitJumpIfTrue(generator.emitIsObject(tempRegister.get(), superclass.get()), superclassIsObjectLabel.get());
generator.emitThrowTypeError(ASCIILiteral("The superclass is not an object."));
generator.emitLabel(superclassIsObjectLabel.get());
-
- RefPtr<RegisterID> protoParent = generator.newTemporary();
generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype);
RefPtr<Label> protoParentIsObjectOrNullLabel = generator.newLabel();
@@ -2884,9 +2885,9 @@
generator.emitLabel(protoParentIsObjectOrNullLabel.get());
generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown);
+ generator.emitLabel(superclassIsNullLabel.get());
generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown);
- generator.emitLabel(superclassIsNullLabel.get());
emitPutHomeObject(generator, constructor.get(), prototype.get());
}