From 89a75a90f6df2bde0a7bee61b66a16f5cd248bee Mon Sep 17 00:00:00 2001
From: Daniel Ehrenberg <littledan@chromium.org>
Date: Wed, 12 Apr 2017 13:52:18 +0200
Subject: [PATCH] Add templated tests for new proposed Annex B semantics

These tests are againt a proposed fix for
https://github.com/tc39/ecma262/issues/753

They seem to pass in V8, JSC and SpiderMonkey, though ChakraCore
hews slightly closer to the previous specification.
---
 .../eval-global-existing-global-init.case     | 22 ++++----
 ...l-existing-non-enumerable-global-init.case | 42 ++++++++++++++++
 .../global-existing-global-init.case          | 49 ++++++++++++++++++
 ...l-existing-non-enumerable-global-init.case | 50 +++++++++++++++++++
 4 files changed, 151 insertions(+), 12 deletions(-)
 create mode 100644 src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
 create mode 100644 src/annex-b-fns/global-existing-global-init.case
 create mode 100644 src/annex-b-fns/global-existing-non-enumerable-global-init.case

diff --git a/src/annex-b-fns/eval-global-existing-global-init.case b/src/annex-b-fns/eval-global-existing-global-init.case
index 02d9aa7789..0ac273e8e5 100644
--- a/src/annex-b-fns/eval-global-existing-global-init.case
+++ b/src/annex-b-fns/eval-global-existing-global-init.case
@@ -1,25 +1,16 @@
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-desc: Variable binding is set to `undefined`
+desc: Variable binding is left in place by legacy function hoisting
 template: eval-global
 info: |
     B.3.3.3 Changes to EvalDeclarationInstantiation
 
     [...]
     i. If varEnvRec is a global Environment Record, then
-       i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+       i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
     [...]
 
-    8.1.1.4.18 CreateGlobalFunctionBinding
-
-    [...]
-    5. If existingProp is undefined or existingProp.[[Configurable]] is true,
-       then
-       [...]
-    6. Else,
-       a. Let desc be the PropertyDescriptor{[[Value]]: V }.
-    [...]
 includes: [fnGlobalObject.js, propertyHelper.js]
 ---*/
 
@@ -32,8 +23,15 @@ Object.defineProperty(fnGlobalObject(), 'f', {
 });
 //- before
 var global = fnGlobalObject();
-assert.sameValue(f, undefined, "binding is initialized to `undefined`");
+assert.sameValue(f, 'x', "binding is not reinitialized");
 
+verifyProperty(global, "f", {
+  enumerable: true,
+  writable: true,
+  configurable: false
+}, { restore: true });
+//- teardown
+assert.sameValue(typeof f, "function");
 verifyProperty(global, "f", {
   enumerable: true,
   writable: true,
diff --git a/src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case b/src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
new file mode 100644
index 0000000000..4e8484aee4
--- /dev/null
+++ b/src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
@@ -0,0 +1,42 @@
+// Copyright (C) 2017 Igalia, S. L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+  Variable binding is left in place by legacy function hoisting.
+  CreateGlobalVariableBinding leaves the binding as non-enumerable even
+  if it has the chance to change it to be enumerable.
+template: eval-global
+info: |
+    B.3.3.3 Changes to EvalDeclarationInstantiation
+
+    [...]
+    i. If varEnvRec is a global Environment Record, then
+       i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+    [...]
+
+includes: [fnGlobalObject.js, propertyHelper.js]
+---*/
+
+//- setup
+Object.defineProperty(fnGlobalObject(), 'f', {
+  value: 'x',
+  enumerable: false,
+  writable: true,
+  configurable: true
+});
+//- before
+var global = fnGlobalObject();
+assert.sameValue(f, 'x', "binding is not reinitialized");
+
+verifyProperty(global, 'f', {
+  enumerable: false,
+  writable: true,
+  configurable: true
+}, { restore: true });
+//- teardown
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+  enumerable: false,
+  writable: true,
+  configurable: true
+});
diff --git a/src/annex-b-fns/global-existing-global-init.case b/src/annex-b-fns/global-existing-global-init.case
new file mode 100644
index 0000000000..b0d7d1eadc
--- /dev/null
+++ b/src/annex-b-fns/global-existing-global-init.case
@@ -0,0 +1,49 @@
+// Copyright (C) 2017 Igalia, S. L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+  Variable binding is left in place by legacy function hoisting.
+  CreateGlobalVariableBinding leaves the binding as non-enumerable even
+  if it has the chance to change it to be enumerable.
+template: global
+info: |
+    B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+    [...]
+    Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+    [...]
+
+includes: [fnGlobalObject.js, propertyHelper.js]
+---*/
+
+//- setup
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+  value: 'x',
+  enumerable: true,
+  writable: true,
+  configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+  enumerable: true,
+  writable: true,
+  configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+//- body
+return 'inner declaration';
+//- teardown
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+  enumerable: true,
+  writable: true,
+  configurable: false
+});
+`);
diff --git a/src/annex-b-fns/global-existing-non-enumerable-global-init.case b/src/annex-b-fns/global-existing-non-enumerable-global-init.case
new file mode 100644
index 0000000000..c9e97cf9d1
--- /dev/null
+++ b/src/annex-b-fns/global-existing-non-enumerable-global-init.case
@@ -0,0 +1,50 @@
+// Copyright (C) 2017 Igalia, S. L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+  Variable binding is left in place by legacy function hoisting.
+  CreateGlobalVariableBinding leaves the binding as non-enumerable even
+  if it has the chance to change it to be enumerable.
+template: global
+info: |
+    B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+    [...]
+    Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+    [...]
+
+includes: [fnGlobalObject.js, propertyHelper.js]
+---*/
+
+//- setup
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+  value: 'x',
+  enumerable: false,
+  writable: true,
+  configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+  enumerable: false,
+  writable: true,
+  configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+//- body
+return 'inner declaration';
+//- teardown
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+  enumerable: false,
+  writable: true,
+  configurable: true
+});
+`);
-- 
GitLab