Diff
Modified: trunk/LayoutTests/ChangeLog (202845 => 202846)
--- trunk/LayoutTests/ChangeLog 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/LayoutTests/ChangeLog 2016-07-06 05:04:05 UTC (rev 202846)
@@ -1,3 +1,16 @@
+2016-07-05 Joseph Pecoraro <[email protected]>
+
+ RELEASE_ASSERT(!thisObject) in ObjCCallbackFunctionImpl::call when calling JSExport ObjC Constructor without operator new
+ https://bugs.webkit.org/show_bug.cgi?id=159446
+
+ Reviewed by Mark Lam.
+
+ * js/class-syntax-call-expected.txt:
+ * js/class-syntax-default-constructor-expected.txt:
+ * js/script-tests/class-syntax-call.js:
+ * js/script-tests/class-syntax-default-constructor.js:
+ Improve error message when calling a class constructor without 'new'.
+
2016-07-05 David Kilzer <[email protected]>
Throw exceptions for invalid number of channels for ConvolverNode
Modified: trunk/LayoutTests/js/class-syntax-call-expected.txt (202845 => 202846)
--- trunk/LayoutTests/js/class-syntax-call-expected.txt 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/LayoutTests/js/class-syntax-call-expected.txt 2016-07-06 05:04:05 UTC (rev 202846)
@@ -4,13 +4,13 @@
PASS new A
-PASS A():::"TypeError: Cannot call a class constructor"
+PASS A():::"TypeError: Cannot call a class constructor without |new|"
PASS new B
-PASS B():::"TypeError: Cannot call a class constructor"
+PASS B():::"TypeError: Cannot call a class constructor without |new|"
PASS new (class { constructor() {} })()
-PASS (class { constructor() {} })():::"TypeError: Cannot call a class constructor"
+PASS (class { constructor() {} })():::"TypeError: Cannot call a class constructor without |new|"
PASS new (class extends null { constructor() { super() } })():::"TypeError: function is not a constructor (evaluating 'super()')"
-PASS (class extends null { constructor() { super() } })():::"TypeError: Cannot call a class constructor"
+PASS (class extends null { constructor() { super() } })():::"TypeError: Cannot call a class constructor without |new|"
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/js/class-syntax-default-constructor-expected.txt (202845 => 202846)
--- trunk/LayoutTests/js/class-syntax-default-constructor-expected.txt 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/LayoutTests/js/class-syntax-default-constructor-expected.txt 2016-07-06 05:04:05 UTC (rev 202846)
@@ -4,11 +4,11 @@
PASS new A instanceof A
-PASS A():::TypeError: Cannot call a class constructor
+PASS A():::TypeError: Cannot call a class constructor without |new|
PASS A.prototype.constructor instanceof Function
PASS A.prototype.constructor.name:::"A"
PASS new B instanceof A; new B instanceof A
-PASS B():::TypeError: Cannot call a class constructor
+PASS B():::TypeError: Cannot call a class constructor without |new|
PASS B.prototype.constructor.name:::"B"
PASS A !== B
PASS A.prototype.constructor !== B.prototype.constructor
Modified: trunk/LayoutTests/js/script-tests/class-syntax-call.js (202845 => 202846)
--- trunk/LayoutTests/js/script-tests/class-syntax-call.js 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/LayoutTests/js/script-tests/class-syntax-call.js 2016-07-06 05:04:05 UTC (rev 202846)
@@ -32,12 +32,12 @@
}
shouldNotThrow('new A');
-shouldThrow('A()', '"TypeError: Cannot call a class constructor"');
+shouldThrow('A()', '"TypeError: Cannot call a class constructor without |new|"');
shouldNotThrow('new B');
-shouldThrow('B()', '"TypeError: Cannot call a class constructor"');
+shouldThrow('B()', '"TypeError: Cannot call a class constructor without |new|"');
shouldNotThrow('new (class { constructor() {} })()');
-shouldThrow('(class { constructor() {} })()', '"TypeError: Cannot call a class constructor"');
+shouldThrow('(class { constructor() {} })()', '"TypeError: Cannot call a class constructor without |new|"');
shouldThrow('new (class extends null { constructor() { super() } })()', '"TypeError: function is not a constructor (evaluating \'super()\')"');
-shouldThrow('(class extends null { constructor() { super() } })()', '"TypeError: Cannot call a class constructor"');
+shouldThrow('(class extends null { constructor() { super() } })()', '"TypeError: Cannot call a class constructor without |new|"');
var successfullyParsed = true;
Modified: trunk/LayoutTests/js/script-tests/class-syntax-default-constructor.js (202845 => 202846)
--- trunk/LayoutTests/js/script-tests/class-syntax-default-constructor.js 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/LayoutTests/js/script-tests/class-syntax-default-constructor.js 2016-07-06 05:04:05 UTC (rev 202846)
@@ -43,11 +43,11 @@
class B extends A { };
shouldBeTrue('new A instanceof A');
-shouldThrow('A()', '"TypeError: Cannot call a class constructor"');
+shouldThrow('A()', '"TypeError: Cannot call a class constructor without |new|"');
shouldBeTrue('A.prototype.constructor instanceof Function');
shouldBe('A.prototype.constructor.name', '"A"');
shouldBeTrue('new B instanceof A; new B instanceof A');
-shouldThrow('B()', '"TypeError: Cannot call a class constructor"');
+shouldThrow('B()', '"TypeError: Cannot call a class constructor without |new|"');
shouldBe('B.prototype.constructor.name', '"B"');
shouldBeTrue('A !== B');
shouldBeTrue('A.prototype.constructor !== B.prototype.constructor');
Modified: trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm (202845 => 202846)
--- trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm 2016-07-06 05:04:05 UTC (rev 202846)
@@ -428,6 +428,8 @@
}
}
+ CallbackType type() const { return m_type; }
+
bool isConstructible()
{
return !!wrappedBlock() || m_type == CallbackInitMethod;
@@ -455,6 +457,12 @@
ObjCCallbackFunctionImpl* impl = callback->impl();
JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(callback->globalObject()->globalExec())];
+ if (impl->type() == CallbackInitMethod) {
+ JSGlobalContextRef contextRef = [context JSGlobalContextRef];
+ *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("Cannot call a class constructor without |new|")));
+ return JSValueMakeUndefined(contextRef);
+ }
+
CallbackData callbackData;
JSValueRef result;
@autoreleasepool {
Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (202845 => 202846)
--- trunk/Source/_javascript_Core/API/tests/testapi.mm 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm 2016-07-06 05:04:05 UTC (rev 202846)
@@ -1334,6 +1334,7 @@
} \
})()"];
checkResult(@"shouldn't be able to construct ClassC", ![canConstructClassC toBool]);
+
JSValue *canConstructClassCPrime = [context evaluateScript:@"(function() { \
try { \
(new ClassCPrime(1)); \
@@ -1347,6 +1348,19 @@
@autoreleasepool {
JSContext *context = [[JSContext alloc] init];
+ context[@"ClassA"] = [ClassA class];
+ context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
+ NSLog(@"%@", [exception toString]);
+ context.exception = exception;
+ };
+
+ checkResult(@"ObjC Constructor without 'new' pre", !context.exception);
+ [context evaluateScript:@"ClassA(42)"];
+ checkResult(@"ObjC Constructor without 'new' post", context.exception);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
context[@"ClassD"] = [ClassD class];
context[@"ClassE"] = [ClassE class];
Modified: trunk/Source/_javascript_Core/ChangeLog (202845 => 202846)
--- trunk/Source/_javascript_Core/ChangeLog 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-07-06 05:04:05 UTC (rev 202846)
@@ -1,3 +1,27 @@
+2016-07-05 Joseph Pecoraro <[email protected]>
+
+ RELEASE_ASSERT(!thisObject) in ObjCCallbackFunctionImpl::call when calling JSExport ObjC Constructor without operator new
+ https://bugs.webkit.org/show_bug.cgi?id=159446
+
+ Reviewed by Mark Lam.
+
+ Treat ObjC JSExport init constructors like ES6 Class Constructors
+ and throw a TypeError when called without 'new'.
+
+ * API/ObjCCallbackFunction.mm:
+ (JSC::ObjCCallbackFunctionImpl::type):
+ (JSC::objCCallbackFunctionCallAsFunction):
+ When calling an init method as a function instead of construction
+ throw a TypeError.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ Improve error message.
+
+ * API/tests/testapi.mm:
+ (testObjectiveCAPIMain):
+ Test we get an exception when calling an ObjC constructor without 'new'.
+
2016-07-05 Mark Lam <[email protected]>
Remove some unneeded #include "CachedCall.h".
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (202845 => 202846)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-07-06 04:11:44 UTC (rev 202845)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-07-06 05:04:05 UTC (rev 202846)
@@ -564,7 +564,7 @@
else
emitCreateThis(&m_thisRegister);
} else if (constructorKind() != ConstructorKind::None)
- emitThrowTypeError("Cannot call a class constructor");
+ emitThrowTypeError("Cannot call a class constructor without |new|");
else {
bool shouldEmitToThis = false;
if (functionNode->usesThis() || codeBlock->usesEval() || m_scopeNode->doAnyInnerArrowFunctionsUseThis() || m_scopeNode->doAnyInnerArrowFunctionsUseEval())