[JSC] throw TypeError when constructing dynamically created JSGeneratorFunction
authorcaitp@igalia.com <caitp@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Oct 2016 15:00:43 +0000 (15:00 +0000)
committercaitp@igalia.com <caitp@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Oct 2016 15:00:43 +0000 (15:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163714

Reviewed by Mark Lam.

JSTests:

Add missing test coverage that dynamically created
JSGeneratorFunctions can not be constructed.

* stress/generator-function-constructor.js:
(shouldThrow):

Source/JavaScriptCore:

According to CreateDynamicFunction() (https://tc39.github.io/ecma262/#sec-createdynamicfunction),
non-normal functions are not constructors. Previously, dynamically created functions would always
be constructible, and so it was possible to evaluate `new  (function*() {}.constructor())`,
and have it return an Iterator object.

This change selects a dynamically created function's ConstructAbility based on its parse mode instead.

* runtime/CodeCache.cpp:
(JSC::CodeCache::getFunctionExecutableFromGlobalCode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207618 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/generator-function-constructor.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/CodeCache.cpp

index 03d8303..95bdbf0 100644 (file)
@@ -1,3 +1,16 @@
+2016-10-20  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] throw TypeError when constructing dynamically created JSGeneratorFunction
+        https://bugs.webkit.org/show_bug.cgi?id=163714
+
+        Reviewed by Mark Lam.
+
+        Add missing test coverage that dynamically created
+        JSGeneratorFunctions can not be constructed.
+
+        * stress/generator-function-constructor.js:
+        (shouldThrow):
+
 2016-10-19  JF Bastien  <jfbastien@apple.com>
 
         JavaScript WebAssembly API: baby steps
index 4a6c6a4..fb9aaff 100644 (file)
@@ -2,6 +2,22 @@ function shouldBe(actual, expected) {
     if (actual !== expected)
         throw new Error('bad value: ' + actual);
 }
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
 var global = (new Function("return this"))();
 shouldBe(typeof global.GeneratorFunction, 'undefined');
 var generatorFunctionConstructor = (function *() { }).constructor;
@@ -10,3 +26,6 @@ shouldBe(generatorFunctionConstructor.prototype.constructor, generatorFunctionCo
 shouldBe(generatorFunctionConstructor() instanceof generatorFunctionConstructor, true);
 shouldBe(generatorFunctionConstructor("a") instanceof generatorFunctionConstructor, true);
 shouldBe(generatorFunctionConstructor("a", "b") instanceof generatorFunctionConstructor, true);
+
+// Generator functions created by the GeneratorFunction constructor are not themselves constructors.
+shouldThrow(() => new (generatorFunctionConstructor()), "TypeError: function is not a constructor (evaluating 'new (generatorFunctionConstructor())')");
\ No newline at end of file
index b4c50e6..a413bce 100644 (file)
@@ -1,3 +1,20 @@
+2016-10-20  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] throw TypeError when constructing dynamically created JSGeneratorFunction
+        https://bugs.webkit.org/show_bug.cgi?id=163714
+
+        Reviewed by Mark Lam.
+
+        According to CreateDynamicFunction() (https://tc39.github.io/ecma262/#sec-createdynamicfunction),
+        non-normal functions are not constructors. Previously, dynamically created functions would always
+        be constructible, and so it was possible to evaluate `new  (function*() {}.constructor())`,
+        and have it return an Iterator object.
+
+        This change selects a dynamically created function's ConstructAbility based on its parse mode instead.
+
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+
 2016-10-19  JF Bastien  <jfbastien@apple.com>
 
         create_hash_table: allow empty tables
index fc19bb8..73efab1 100644 (file)
@@ -202,7 +202,8 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v
     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, JSParserScriptMode::Classic, emptyTDZVariables, DerivedContextType::None);
+    ConstructAbility constructAbility = constructAbilityForParseMode(metadata->parseMode());
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, constructAbility, JSParserScriptMode::Classic, emptyTDZVariables, DerivedContextType::None);
 
     functionExecutable->setSourceURLDirective(source.provider()->sourceURL());
     functionExecutable->setSourceMappingURLDirective(source.provider()->sourceMappingURL());