summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Balter <leonardo.balter@gmail.com>2016-04-15 17:56:36 -0400
committerLeo Balter <leonardo.balter@gmail.com>2016-04-15 17:56:36 -0400
commit3723e7caebecf3c4701d70b0445bf1f0c795a6a5 (patch)
treef41e52813610fb92aff388677bc73cada8bbd7db
parente7f6cd7f867ad02de59181d37267b9bb40bb3c5e (diff)
parent74bff6b3d51421cc9d69efffdc059cb3adcc81d9 (diff)
downloadqtdeclarative-testsuites-3723e7caebecf3c4701d70b0445bf1f0c795a6a5.tar.gz
Merge pull request #545 from bocoup/generation
Introduce test generation tool
-rw-r--r--CONTRIBUTING.md34
-rwxr-xr-xmake.py57
-rw-r--r--src/dstr-binding/ary-name-iter-val.case35
-rw-r--r--src/dstr-binding/default/arrow-function.template46
-rw-r--r--src/dstr-binding/default/cls-decl-gen-meth-static.template69
-rw-r--r--src/dstr-binding/default/cls-decl-gen-meth.template69
-rw-r--r--src/dstr-binding/default/cls-decl-meth-static.template67
-rw-r--r--src/dstr-binding/default/cls-decl-meth.template67
-rw-r--r--src/dstr-binding/default/cls-expr-gen-meth-static.template71
-rw-r--r--src/dstr-binding/default/cls-expr-gen-meth.template71
-rw-r--r--src/dstr-binding/default/cls-expr-meth-static.template68
-rw-r--r--src/dstr-binding/default/cls-expr-meth.template68
-rw-r--r--src/dstr-binding/default/const-stmt.template21
-rw-r--r--src/dstr-binding/default/func-decl.template46
-rw-r--r--src/dstr-binding/default/func-expr.template47
-rw-r--r--src/dstr-binding/default/gen-func-decl.template45
-rw-r--r--src/dstr-binding/default/gen-func-expr.template47
-rw-r--r--src/dstr-binding/default/gen-meth.template53
-rw-r--r--src/dstr-binding/default/let-stmt.template21
-rw-r--r--src/dstr-binding/default/meth.template50
-rw-r--r--src/dstr-binding/default/var-stmt.template20
-rw-r--r--src/spread/default/call-expr.template28
-rw-r--r--src/spread/default/member-expr.template28
-rw-r--r--src/spread/default/super-call.template34
-rw-r--r--src/spread/error/call-expr.template23
-rw-r--r--src/spread/error/member-expr.template23
-rw-r--r--src/spread/error/super-call.template30
-rw-r--r--src/spread/sngl-err-expr-throws.case22
-rw-r--r--src/spread/sngl-iter.case42
-rw-r--r--test/language/expressions/arrow-function/dstr-ary-name-iter-val.js69
-rw-r--r--test/language/expressions/call/spread-err-sngl-err-expr-throws.js36
-rw-r--r--test/language/expressions/call/spread-sngl-iter.js60
-rw-r--r--test/language/expressions/class/dstr-gen-meth-ary-name-iter-val.js94
-rw-r--r--test/language/expressions/class/dstr-gen-meth-static-ary-name-iter-val.js94
-rw-r--r--test/language/expressions/class/dstr-meth-ary-name-iter-val.js91
-rw-r--r--test/language/expressions/class/dstr-meth-static-ary-name-iter-val.js91
-rw-r--r--test/language/expressions/function/dstr-ary-name-iter-val.js70
-rw-r--r--test/language/expressions/generators/dstr-ary-name-iter-val.js70
-rw-r--r--test/language/expressions/new/spread-err-sngl-err-expr-throws.js35
-rw-r--r--test/language/expressions/new/spread-sngl-iter.js59
-rw-r--r--test/language/expressions/object/dstr-gen-meth-ary-name-iter-val.js76
-rw-r--r--test/language/expressions/object/dstr-meth-ary-name-iter-val.js73
-rw-r--r--test/language/expressions/super/spread-err-sngl-err-expr-throws.js43
-rw-r--r--test/language/expressions/super/spread-sngl-iter.js66
-rw-r--r--test/language/statements/class/dstr-gen-meth-ary-name-iter-val.js92
-rw-r--r--test/language/statements/class/dstr-gen-meth-static-ary-name-iter-val.js92
-rw-r--r--test/language/statements/class/dstr-meth-ary-name-iter-val.js90
-rw-r--r--test/language/statements/class/dstr-meth-static-ary-name-iter-val.js90
-rw-r--r--test/language/statements/const/dstr-ary-name-iter-val.js43
-rw-r--r--test/language/statements/function/dstr-ary-name-iter-val.js69
-rw-r--r--test/language/statements/generators/dstr-ary-name-iter-val.js68
-rw-r--r--test/language/statements/let/dstr-ary-name-iter-val.js43
-rw-r--r--test/language/statements/variable/dstr-ary-name-iter-val.js42
-rwxr-xr-xtools/generation/generator.py88
-rw-r--r--tools/generation/lib/__init__.py1
-rw-r--r--tools/generation/lib/case.py44
-rw-r--r--tools/generation/lib/expander.py58
-rw-r--r--tools/generation/lib/template.py160
-rw-r--r--tools/generation/lib/test.py63
-rw-r--r--tools/generation/lib/util/__init__.py1
-rw-r--r--tools/generation/lib/util/find_comments.py68
-rw-r--r--tools/generation/lib/util/parse_yaml.py17
-rw-r--r--tools/generation/requirements.txt1
-rw-r--r--tools/generation/test/expected/normal/nested/path2-normal.js19
-rw-r--r--tools/generation/test/expected/normal/no-info-normal.js15
-rw-r--r--tools/generation/test/expected/normal/path1-normal.js33
-rw-r--r--tools/generation/test/fixtures/normal.case27
-rw-r--r--tools/generation/test/fixtures/normal/no-info.template9
-rw-r--r--tools/generation/test/fixtures/normal/normal.template27
-rw-r--r--tools/generation/test/fixtures/normal/normal2.template13
-rwxr-xr-xtools/generation/test/run.py58
71 files changed, 3660 insertions, 0 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c368f65b4..6e5d41b15 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -246,3 +246,37 @@ p.then(function () {
```
As above, exceptions that are thrown from a `then` clause are passed to a later `$DONE` function and reported asynchronously.
+
+## Procedurally-generated tests
+
+Some language features are expressed through a number of distinct syntactic forms. Test262 maintains these tests as a set of "test cases" and "test templates" in order to ensure equivalent coverage across all forms. The sub-directories within the `src/` directory describe the various language features that benefit from this approach.
+
+Test cases and test templates specify meta-data using the same YAML frontmatter pattern as so-called "static" (i.e. non-generated) tests. The expected attributes differ between test cases and test templates:
+
+- test cases (`*.case`)
+ - `template` - name of the sub-directory to locate templates for this test
+ - `description` (see above)
+ - `info` (see above)
+ - `features` (see above; merged with value defined by test template)
+- test templates (`*.template`)
+ - `path` - location within the published test hierarchy to output files created from this template
+ - `name` - human-readable name of the syntactic form described by this template (used to generate the test file's `description` field)
+ - `esid` (see above)
+ - `es5id` (see above)
+ - `es6id` (see above)
+ - `info` (see above)
+ - `features` (see above; merged with value defined by test case)
+
+Generated files are managed using the `make.py` Python script located in the root of this repository.
+
+To create files:
+
+ make.py
+
+To remove all generated files:
+
+ make.py clean
+
+The executable located at `tools/generation/generator.py` offers additional control over the generation procedure.
+
+ ./tools/generation/generator.py --help
diff --git a/make.py b/make.py
new file mode 100755
index 000000000..2d440b972
--- /dev/null
+++ b/make.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+import os, shutil, subprocess, sys
+
+OUT_DIR = os.environ.get('OUT_DIR') or 'test'
+SRC_DIR = os.environ.get('SRC_DIR') or 'src'
+
+def shell(*args):
+ sp = subprocess.Popen(list(args), stdout=subprocess.PIPE)
+ cmd_str = ' '.join(args)
+
+ print '> ' + cmd_str
+
+ for line in iter(sp.stdout.readline, ''):
+ sys.stdout.write(line)
+
+ sp.communicate()
+
+ if sp.returncode == 1:
+ raise Exception('Command failed: ' + cmd_str)
+
+targets = dict()
+def target(*deps):
+ def other(orig):
+ def wrapped():
+ print 'Running target: ' + orig.__name__
+
+ for dep in deps:
+ targets[dep]()
+ return orig()
+ wrapped.__name__ = orig.__name__
+ targets[orig.__name__] = wrapped
+ return wrapped
+ return other
+
+@target()
+def build():
+ shell(sys.executable, 'tools/generation/generator.py',
+ 'create',
+ '--out', OUT_DIR,
+ SRC_DIR)
+
+@target()
+def clean():
+ shell(sys.executable, 'tools/generation/generator.py', 'clean', OUT_DIR)
+
+if len(sys.argv) == 1:
+ targets['build']()
+
+for target in sys.argv[1:]:
+ if not target in targets:
+ sys.stderr.write('No target named: "' + target + '".\n' +
+ 'Available targets: ' + ', '.join(list(targets)) + '\n')
+ sys.exit(1)
+ targets[target]()
diff --git a/src/dstr-binding/ary-name-iter-val.case b/src/dstr-binding/ary-name-iter-val.case
new file mode 100644
index 000000000..8c65a0868
--- /dev/null
+++ b/src/dstr-binding/ary-name-iter-val.case
@@ -0,0 +1,35 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: SingleNameBinding with normal value iteration
+template: default
+info: |
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+//- elems
+[x, y, z]
+//- vals
+[1, 2, 3]
+//- body
+assert.sameValue(x, 1);
+assert.sameValue(y, 2);
+assert.sameValue(z, 3);
diff --git a/src/dstr-binding/default/arrow-function.template b/src/dstr-binding/default/arrow-function.template
new file mode 100644
index 000000000..7e87227e9
--- /dev/null
+++ b/src/dstr-binding/default/arrow-function.template
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/arrow-function/dstr-
+name: arrow function expression
+es6id: 14.2.16
+info: |
+ ArrowFunction : ArrowParameters => ConciseBody
+
+ [...]
+ 4. Let closure be FunctionCreate(Arrow, parameters, ConciseBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var f;
+f = (/*{ elems }*/) => {
+ /*{ body }*/
+ callCount = callCount + 1;
+};
+
+f(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-decl-gen-meth-static.template b/src/dstr-binding/default/cls-decl-gen-meth-static.template
new file mode 100644
index 000000000..3f6b55e17
--- /dev/null
+++ b/src/dstr-binding/default/cls-decl-gen-meth-static.template
@@ -0,0 +1,69 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/class/dstr-gen-meth-static-
+name: static class expression generator method
+es6id: 14.5.15
+info: |
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation for
+ m with arguments F and false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod : * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+class C {
+ static *method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+C.method(/*{ vals }*/).next();
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-decl-gen-meth.template b/src/dstr-binding/default/cls-decl-gen-meth.template
new file mode 100644
index 000000000..0579b3ca6
--- /dev/null
+++ b/src/dstr-binding/default/cls-decl-gen-meth.template
@@ -0,0 +1,69 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/class/dstr-gen-meth-
+name: class expression method
+es6id: 14.5.16
+info: |
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod : * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+class C {
+ *method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+new C().method(/*{ vals }*/).next();
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-decl-meth-static.template b/src/dstr-binding/default/cls-decl-meth-static.template
new file mode 100644
index 000000000..0f1fff2b7
--- /dev/null
+++ b/src/dstr-binding/default/cls-decl-meth-static.template
@@ -0,0 +1,67 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/class/dstr-meth-static-
+name: static class expression method
+es6id: 14.5.15
+info: |
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation for
+ m with arguments F and false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+class C {
+ static method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+C.method(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-decl-meth.template b/src/dstr-binding/default/cls-decl-meth.template
new file mode 100644
index 000000000..1a7ba2fc2
--- /dev/null
+++ b/src/dstr-binding/default/cls-decl-meth.template
@@ -0,0 +1,67 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/class/dstr-meth-
+name: class expression method
+es6id: 14.5.15
+info: |
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+class C {
+ method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+new C().method(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-expr-gen-meth-static.template b/src/dstr-binding/default/cls-expr-gen-meth-static.template
new file mode 100644
index 000000000..340945db7
--- /dev/null
+++ b/src/dstr-binding/default/cls-expr-gen-meth-static.template
@@ -0,0 +1,71 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/class/dstr-gen-meth-static-
+name: static class expression generator method
+es6id: 14.5.16
+info: |
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation
+ for m with arguments F and false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod :
+ * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var C = class {
+ static *method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+C.method(/*{ vals }*/).next();
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-expr-gen-meth.template b/src/dstr-binding/default/cls-expr-gen-meth.template
new file mode 100644
index 000000000..c4c0d4c8f
--- /dev/null
+++ b/src/dstr-binding/default/cls-expr-gen-meth.template
@@ -0,0 +1,71 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/class/dstr-gen-meth-
+name: class expression method
+es6id: 14.5.16
+info: |
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod :
+ * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var C = class {
+ *method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+new C().method(/*{ vals }*/).next();
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-expr-meth-static.template b/src/dstr-binding/default/cls-expr-meth-static.template
new file mode 100644
index 000000000..aff8b8a63
--- /dev/null
+++ b/src/dstr-binding/default/cls-expr-meth-static.template
@@ -0,0 +1,68 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/class/dstr-meth-static-
+name: static class expression method
+es6id: 14.5.16
+info: |
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation for
+ m with arguments F and false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var C = class {
+ static method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+C.method(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/cls-expr-meth.template b/src/dstr-binding/default/cls-expr-meth.template
new file mode 100644
index 000000000..a97f94827
--- /dev/null
+++ b/src/dstr-binding/default/cls-expr-meth.template
@@ -0,0 +1,68 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/class/dstr-meth-
+name: class expression method
+es6id: 14.5.16
+info: |
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var C = class {
+ method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+new C().method(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/const-stmt.template b/src/dstr-binding/default/const-stmt.template
new file mode 100644
index 000000000..aeddb7a8f
--- /dev/null
+++ b/src/dstr-binding/default/const-stmt.template
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/const/dstr-
+name: >
+ `const` statement
+es6id: 13.3.1.4
+info: |
+ LexicalBinding : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let value be GetValue(rhs).
+ 3. ReturnIfAbrupt(value).
+ 4. Let env be the running execution context's LexicalEnvironment.
+ 5. Return the result of performing BindingInitialization for BindingPattern
+ using value and env as the arguments.
+---*/
+
+const /*{ elems }*/ = /*{ vals }*/;
+
+/*{ body }*/
diff --git a/src/dstr-binding/default/func-decl.template b/src/dstr-binding/default/func-decl.template
new file mode 100644
index 000000000..7dd6b58f2
--- /dev/null
+++ b/src/dstr-binding/default/func-decl.template
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/function/dstr-
+name: function declaration
+es6id: 14.1.19
+info: |
+ FunctionDeclaration :
+ function BindingIdentifier ( FormalParameters ) { FunctionBody }
+
+ [...]
+ 3. Let F be FunctionCreate(Normal, FormalParameters, FunctionBody,
+ scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+function f(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+};
+f(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/func-expr.template b/src/dstr-binding/default/func-expr.template
new file mode 100644
index 000000000..58d7cd99a
--- /dev/null
+++ b/src/dstr-binding/default/func-expr.template
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/function/dstr-
+name: function expression
+es6id: 14.1.20
+info: |
+ FunctionExpression : function ( FormalParameters ) { FunctionBody }
+
+ [...]
+ 3. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody,
+ scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var f;
+f = function(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+};
+
+f(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/gen-func-decl.template b/src/dstr-binding/default/gen-func-decl.template
new file mode 100644
index 000000000..4e0403562
--- /dev/null
+++ b/src/dstr-binding/default/gen-func-decl.template
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/generators/dstr-
+name: generator function declaration
+es6id: 14.4.12
+info: |
+ GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
+
+ [...]
+ 2. Let F be GeneratorFunctionCreate(Normal, FormalParameters,
+ GeneratorBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+function* f(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+};
+f(/*{ vals }*/).next();
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/gen-func-expr.template b/src/dstr-binding/default/gen-func-expr.template
new file mode 100644
index 000000000..b930bc59e
--- /dev/null
+++ b/src/dstr-binding/default/gen-func-expr.template
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/generators/dstr-
+name: generator function expression
+es6id: 14.4.14
+info: |
+ GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
+
+ [...]
+ 3. Let closure be GeneratorFunctionCreate(Normal, FormalParameters,
+ GeneratorBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var f;
+f = function*(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+};
+
+f(/*{ vals }*/).next();
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/gen-meth.template b/src/dstr-binding/default/gen-meth.template
new file mode 100644
index 000000000..511917820
--- /dev/null
+++ b/src/dstr-binding/default/gen-meth.template
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/object/dstr-gen-meth-
+name: generator method
+es6id: 14.4.13
+info: |
+ GeneratorMethod :
+ * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var obj = {
+ *method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+obj.method(/*{ vals }*/).next();
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/let-stmt.template b/src/dstr-binding/default/let-stmt.template
new file mode 100644
index 000000000..33ffd8612
--- /dev/null
+++ b/src/dstr-binding/default/let-stmt.template
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/let/dstr-
+name: >
+ `let` statement
+es6id: 13.3.1.4
+info: |
+ LexicalBinding : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let value be GetValue(rhs).
+ 3. ReturnIfAbrupt(value).
+ 4. Let env be the running execution context's LexicalEnvironment.
+ 5. Return the result of performing BindingInitialization for BindingPattern
+ using value and env as the arguments.
+---*/
+
+let /*{ elems }*/ = /*{ vals }*/;
+
+/*{ body }*/
diff --git a/src/dstr-binding/default/meth.template b/src/dstr-binding/default/meth.template
new file mode 100644
index 000000000..363cc1684
--- /dev/null
+++ b/src/dstr-binding/default/meth.template
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/object/dstr-meth-
+name: method
+es6id: 14.3.8
+info: |
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters,
+ FunctionBody, scope, strict). If functionPrototype was passed as a
+ parameter then pass its value as the functionPrototype optional argument
+ of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+---*/
+
+var callCount = 0;
+var obj = {
+ method(/*{ elems }*/) {
+ /*{ body }*/
+ callCount = callCount + 1;
+ }
+};
+
+obj.method(/*{ vals }*/);
+assert.sameValue(callCount, 1);
diff --git a/src/dstr-binding/default/var-stmt.template b/src/dstr-binding/default/var-stmt.template
new file mode 100644
index 000000000..a4511eb3b
--- /dev/null
+++ b/src/dstr-binding/default/var-stmt.template
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/variable/dstr-
+name: >
+ `var` statement
+es6id: 13.3.2.4
+info: |
+ VariableDeclaration : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let rval be GetValue(rhs).
+ 3. ReturnIfAbrupt(rval).
+ 4. Return the result of performing BindingInitialization for
+ BindingPattern passing rval and undefined as arguments.
+---*/
+
+var /*{ elems }*/ = /*{ vals }*/;
+
+/*{ body }*/
diff --git a/src/spread/default/call-expr.template b/src/spread/default/call-expr.template
new file mode 100644
index 000000000..4f1017889
--- /dev/null
+++ b/src/spread/default/call-expr.template
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/call/spread-
+name: CallExpression
+es6id: 12.3.4.1
+info: |
+ CallExpression : MemberExpression Arguments
+
+ [...]
+ 9. Return EvaluateDirectCall(func, thisValue, Arguments, tailCall).
+
+ 12.3.4.3 Runtime Semantics: EvaluateDirectCall
+
+ 1. Let argList be ArgumentListEvaluation(arguments).
+ [...]
+ 6. Let result be Call(func, thisValue, argList).
+ [...]
+---*/
+
+var callCount = 0;
+
+(function(/*{ params }*/) {
+ /*{ body }*/
+ callCount += 1;
+}(/*{ args }*/));
+
+assert.sameValue(callCount, 1);
diff --git a/src/spread/default/member-expr.template b/src/spread/default/member-expr.template
new file mode 100644
index 000000000..6069bff04
--- /dev/null
+++ b/src/spread/default/member-expr.template
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/new/spread-
+name: >
+ `new` operator
+es6id: 12.3.3.1
+info: |
+ MemberExpression : new MemberExpression Arguments
+
+ 1. Return EvaluateNew(MemberExpression, Arguments).
+
+ 12.3.3.1.1 Runtime Semantics: EvaluateNew
+
+ 6. If arguments is empty, let argList be an empty List.
+ 7. Else,
+ a. Let argList be ArgumentListEvaluation of arguments.
+ [...]
+---*/
+
+var callCount = 0;
+
+new function(/*{ params }*/) {
+ /*{ body }*/
+ callCount += 1;
+}(/*{ args }*/);
+
+assert.sameValue(callCount, 1);
diff --git a/src/spread/default/super-call.template b/src/spread/default/super-call.template
new file mode 100644
index 000000000..7a91e9d3c
--- /dev/null
+++ b/src/spread/default/super-call.template
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/super/spread-
+name: SuperCall
+es6id: 12.3.5.1
+info: |
+ SuperCall : super Arguments
+
+ 1. Let newTarget be GetNewTarget().
+ 2. If newTarget is undefined, throw a ReferenceError exception.
+ 3. Let func be GetSuperConstructor().
+ 4. ReturnIfAbrupt(func).
+ 5. Let argList be ArgumentListEvaluation of Arguments.
+ [...]
+---*/
+
+var callCount = 0;
+
+class Test262ParentClass {
+ constructor(/*{ params }*/) {
+ /*{ body }*/
+ callCount += 1;
+ }
+}
+
+class Test262ChildClass extends Test262ParentClass {
+ constructor() {
+ super(/*{ args }*/);
+ }
+}
+
+new Test262ChildClass();
+assert.sameValue(callCount, 1);
diff --git a/src/spread/error/call-expr.template b/src/spread/error/call-expr.template
new file mode 100644
index 000000000..69d6e380e
--- /dev/null
+++ b/src/spread/error/call-expr.template
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/call/spread-err-
+name: CallExpression
+es6id: 12.3.4.1
+info: |
+ CallExpression : MemberExpression Arguments
+
+ [...]
+ 9. Return EvaluateDirectCall(func, thisValue, Arguments, tailCall).
+
+ 12.3.4.3 Runtime Semantics: EvaluateDirectCall
+
+ 1. Let argList be ArgumentListEvaluation(arguments).
+ [...]
+ 6. Let result be Call(func, thisValue, argList).
+ [...]
+---*/
+
+assert.throws(/*{ error }*/, function() {
+ (function(/*{ params }*/) {}(/*{ args }*/));
+});
diff --git a/src/spread/error/member-expr.template b/src/spread/error/member-expr.template
new file mode 100644
index 000000000..b70627f3c
--- /dev/null
+++ b/src/spread/error/member-expr.template
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/new/spread-err-
+name: >
+ `new` operator
+es6id: 12.3.3.1
+info: |
+ MemberExpression : new MemberExpression Arguments
+
+ 1. Return EvaluateNew(MemberExpression, Arguments).
+
+ 12.3.3.1.1 Runtime Semantics: EvaluateNew
+
+ 6. If arguments is empty, let argList be an empty List.
+ 7. Else,
+ a. Let argList be ArgumentListEvaluation of arguments.
+ [...]
+---*/
+
+assert.throws(/*{ error }*/, function() {
+ new function(/*{ params }*/) {}(/*{ args }*/);
+});
diff --git a/src/spread/error/super-call.template b/src/spread/error/super-call.template
new file mode 100644
index 000000000..eb3ec0466
--- /dev/null
+++ b/src/spread/error/super-call.template
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/super/spread-err-
+name: SuperCall
+es6id: 12.3.5.1
+info: |
+ SuperCall : super Arguments
+
+ 1. Let newTarget be GetNewTarget().
+ 2. If newTarget is undefined, throw a ReferenceError exception.
+ 3. Let func be GetSuperConstructor().
+ 4. ReturnIfAbrupt(func).
+ 5. Let argList be ArgumentListEvaluation of Arguments.
+ [...]
+---*/
+
+class Test262ParentClass {
+ constructor(/*{ params }*/) {}
+}
+
+class Test262ChildClass extends Test262ParentClass {
+ constructor() {
+ super(/*{ args }*/);
+ }
+}
+
+assert.throws(/*{ error }*/, function() {
+ new Test262ChildClass();
+});
diff --git a/src/spread/sngl-err-expr-throws.case b/src/spread/sngl-err-expr-throws.case
new file mode 100644
index 000000000..389a9366e
--- /dev/null
+++ b/src/spread/sngl-err-expr-throws.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Spread operator applied to the only argument when evaluation throws
+template: error
+features: [generators]
+info: |
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+---*/
+
+//- error
+Test262Error
+//- args
+...function*() { throw new Test262Error(); }()
diff --git a/src/spread/sngl-iter.case b/src/spread/sngl-iter.case
new file mode 100644
index 000000000..594b07237
--- /dev/null
+++ b/src/spread/sngl-iter.case
@@ -0,0 +1,42 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Spread operator applied to the only argument with a valid iterator
+template: default
+features: [Symbol.iterator]
+info: |
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+ 6. Repeat
+ a. Let next be IteratorStep(iterator).
+ b. ReturnIfAbrupt(next).
+ c. If next is false, return list.
+ d. Let nextArg be IteratorValue(next).
+ e. ReturnIfAbrupt(nextArg).
+ f. Append nextArg as the last element of list.
+---*/
+
+//- setup
+var iter = {};
+iter[Symbol.iterator] = function() {
+ var callCount = 0;
+ return {
+ next: function() {
+ callCount += 1;
+ return { done: callCount === 3, value: callCount };
+ }
+ };
+};
+//- args
+...iter
+//- body
+assert.sameValue(arguments.length, 2);
+assert.sameValue(arguments[0], 1);
+assert.sameValue(arguments[1], 2);
diff --git a/test/language/expressions/arrow-function/dstr-ary-name-iter-val.js b/test/language/expressions/arrow-function/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..fe684355e
--- /dev/null
+++ b/test/language/expressions/arrow-function/dstr-ary-name-iter-val.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/arrow-function.template
+/*---
+description: SingleNameBinding with normal value iteration (arrow function expression)
+es6id: 14.2.16
+flags: [generated]
+info: >
+ ArrowFunction : ArrowParameters => ConciseBody
+
+ [...]
+ 4. Let closure be FunctionCreate(Arrow, parameters, ConciseBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var f;
+f = ([x, y, z]) => {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+};
+
+f([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/call/spread-err-sngl-err-expr-throws.js b/test/language/expressions/call/spread-err-sngl-err-expr-throws.js
new file mode 100644
index 000000000..2d70fa3d7
--- /dev/null
+++ b/test/language/expressions/call/spread-err-sngl-err-expr-throws.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/spread/sngl-err-expr-throws.case
+// - src/spread/error/call-expr.template
+/*---
+description: Spread operator applied to the only argument when evaluation throws (CallExpression)
+es6id: 12.3.4.1
+features: [generators]
+
+flags: [generated]
+info: >
+ CallExpression : MemberExpression Arguments
+
+ [...]
+ 9. Return EvaluateDirectCall(func, thisValue, Arguments, tailCall).
+
+ 12.3.4.3 Runtime Semantics: EvaluateDirectCall
+
+ 1. Let argList be ArgumentListEvaluation(arguments).
+ [...]
+ 6. Let result be Call(func, thisValue, argList).
+ [...]
+
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+---*/
+
+assert.throws(Test262Error, function() {
+ (function() {}(...function*() { throw new Test262Error(); }()));
+});
diff --git a/test/language/expressions/call/spread-sngl-iter.js b/test/language/expressions/call/spread-sngl-iter.js
new file mode 100644
index 000000000..d6d86102b
--- /dev/null
+++ b/test/language/expressions/call/spread-sngl-iter.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/spread/sngl-iter.case
+// - src/spread/default/call-expr.template
+/*---
+description: Spread operator applied to the only argument with a valid iterator (CallExpression)
+es6id: 12.3.4.1
+features: [Symbol.iterator]
+
+flags: [generated]
+info: >
+ CallExpression : MemberExpression Arguments
+
+ [...]
+ 9. Return EvaluateDirectCall(func, thisValue, Arguments, tailCall).
+
+ 12.3.4.3 Runtime Semantics: EvaluateDirectCall
+
+ 1. Let argList be ArgumentListEvaluation(arguments).
+ [...]
+ 6. Let result be Call(func, thisValue, argList).
+ [...]
+
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+ 6. Repeat
+ a. Let next be IteratorStep(iterator).
+ b. ReturnIfAbrupt(next).
+ c. If next is false, return list.
+ d. Let nextArg be IteratorValue(next).
+ e. ReturnIfAbrupt(nextArg).
+ f. Append nextArg as the last element of list.
+---*/
+var iter = {};
+iter[Symbol.iterator] = function() {
+ var callCount = 0;
+ return {
+ next: function() {
+ callCount += 1;
+ return { done: callCount === 3, value: callCount };
+ }
+ };
+};
+
+var callCount = 0;
+
+(function() {
+ assert.sameValue(arguments.length, 2);
+ assert.sameValue(arguments[0], 1);
+ assert.sameValue(arguments[1], 2);
+ callCount += 1;
+}(...iter));
+
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/class/dstr-gen-meth-ary-name-iter-val.js b/test/language/expressions/class/dstr-gen-meth-ary-name-iter-val.js
new file mode 100644
index 000000000..10b822b6f
--- /dev/null
+++ b/test/language/expressions/class/dstr-gen-meth-ary-name-iter-val.js
@@ -0,0 +1,94 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-expr-gen-meth.template
+/*---
+description: SingleNameBinding with normal value iteration (class expression method)
+es6id: 14.5.16
+flags: [generated]
+info: >
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod :
+ * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var C = class {
+ *method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+new C().method([1, 2, 3]).next();
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/class/dstr-gen-meth-static-ary-name-iter-val.js b/test/language/expressions/class/dstr-gen-meth-static-ary-name-iter-val.js
new file mode 100644
index 000000000..dab262ab3
--- /dev/null
+++ b/test/language/expressions/class/dstr-gen-meth-static-ary-name-iter-val.js
@@ -0,0 +1,94 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-expr-gen-meth-static.template
+/*---
+description: SingleNameBinding with normal value iteration (static class expression generator method)
+es6id: 14.5.16
+flags: [generated]
+info: >
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation
+ for m with arguments F and false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod :
+ * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var C = class {
+ static *method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+C.method([1, 2, 3]).next();
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/class/dstr-meth-ary-name-iter-val.js b/test/language/expressions/class/dstr-meth-ary-name-iter-val.js
new file mode 100644
index 000000000..4bbf52373
--- /dev/null
+++ b/test/language/expressions/class/dstr-meth-ary-name-iter-val.js
@@ -0,0 +1,91 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-expr-meth.template
+/*---
+description: SingleNameBinding with normal value iteration (class expression method)
+es6id: 14.5.16
+flags: [generated]
+info: >
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var C = class {
+ method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+new C().method([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/class/dstr-meth-static-ary-name-iter-val.js b/test/language/expressions/class/dstr-meth-static-ary-name-iter-val.js
new file mode 100644
index 000000000..bcf43ba71
--- /dev/null
+++ b/test/language/expressions/class/dstr-meth-static-ary-name-iter-val.js
@@ -0,0 +1,91 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-expr-meth-static.template
+/*---
+description: SingleNameBinding with normal value iteration (static class expression method)
+es6id: 14.5.16
+flags: [generated]
+info: >
+ ClassExpression : class BindingIdentifieropt ClassTail
+
+ 1. If BindingIdentifieropt is not present, let className be undefined.
+ 2. Else, let className be StringValue of BindingIdentifier.
+ 3. Let value be the result of ClassDefinitionEvaluation of ClassTail
+ with argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation for
+ m with arguments F and false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var C = class {
+ static method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+C.method([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/function/dstr-ary-name-iter-val.js b/test/language/expressions/function/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..b6861fbd0
--- /dev/null
+++ b/test/language/expressions/function/dstr-ary-name-iter-val.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/func-expr.template
+/*---
+description: SingleNameBinding with normal value iteration (function expression)
+es6id: 14.1.20
+flags: [generated]
+info: >
+ FunctionExpression : function ( FormalParameters ) { FunctionBody }
+
+ [...]
+ 3. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody,
+ scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var f;
+f = function([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+};
+
+f([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/generators/dstr-ary-name-iter-val.js b/test/language/expressions/generators/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..afa950384
--- /dev/null
+++ b/test/language/expressions/generators/dstr-ary-name-iter-val.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/gen-func-expr.template
+/*---
+description: SingleNameBinding with normal value iteration (generator function expression)
+es6id: 14.4.14
+flags: [generated]
+info: >
+ GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
+
+ [...]
+ 3. Let closure be GeneratorFunctionCreate(Normal, FormalParameters,
+ GeneratorBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var f;
+f = function*([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+};
+
+f([1, 2, 3]).next();
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/new/spread-err-sngl-err-expr-throws.js b/test/language/expressions/new/spread-err-sngl-err-expr-throws.js
new file mode 100644
index 000000000..a2b21ad2a
--- /dev/null
+++ b/test/language/expressions/new/spread-err-sngl-err-expr-throws.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/spread/sngl-err-expr-throws.case
+// - src/spread/error/member-expr.template
+/*---
+description: Spread operator applied to the only argument when evaluation throws (`new` operator)
+es6id: 12.3.3.1
+features: [generators]
+
+flags: [generated]
+info: >
+ MemberExpression : new MemberExpression Arguments
+
+ 1. Return EvaluateNew(MemberExpression, Arguments).
+
+ 12.3.3.1.1 Runtime Semantics: EvaluateNew
+
+ 6. If arguments is empty, let argList be an empty List.
+ 7. Else,
+ a. Let argList be ArgumentListEvaluation of arguments.
+ [...]
+
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+---*/
+
+assert.throws(Test262Error, function() {
+ new function() {}(...function*() { throw new Test262Error(); }());
+});
diff --git a/test/language/expressions/new/spread-sngl-iter.js b/test/language/expressions/new/spread-sngl-iter.js
new file mode 100644
index 000000000..af9cfe233
--- /dev/null
+++ b/test/language/expressions/new/spread-sngl-iter.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/spread/sngl-iter.case
+// - src/spread/default/member-expr.template
+/*---
+description: Spread operator applied to the only argument with a valid iterator (`new` operator)
+es6id: 12.3.3.1
+features: [Symbol.iterator]
+
+flags: [generated]
+info: >
+ MemberExpression : new MemberExpression Arguments
+
+ 1. Return EvaluateNew(MemberExpression, Arguments).
+
+ 12.3.3.1.1 Runtime Semantics: EvaluateNew
+
+ 6. If arguments is empty, let argList be an empty List.
+ 7. Else,
+ a. Let argList be ArgumentListEvaluation of arguments.
+ [...]
+
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+ 6. Repeat
+ a. Let next be IteratorStep(iterator).
+ b. ReturnIfAbrupt(next).
+ c. If next is false, return list.
+ d. Let nextArg be IteratorValue(next).
+ e. ReturnIfAbrupt(nextArg).
+ f. Append nextArg as the last element of list.
+---*/
+var iter = {};
+iter[Symbol.iterator] = function() {
+ var callCount = 0;
+ return {
+ next: function() {
+ callCount += 1;
+ return { done: callCount === 3, value: callCount };
+ }
+ };
+};
+
+var callCount = 0;
+
+new function() {
+ assert.sameValue(arguments.length, 2);
+ assert.sameValue(arguments[0], 1);
+ assert.sameValue(arguments[1], 2);
+ callCount += 1;
+}(...iter);
+
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/object/dstr-gen-meth-ary-name-iter-val.js b/test/language/expressions/object/dstr-gen-meth-ary-name-iter-val.js
new file mode 100644
index 000000000..6533c3c74
--- /dev/null
+++ b/test/language/expressions/object/dstr-gen-meth-ary-name-iter-val.js
@@ -0,0 +1,76 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/gen-meth.template
+/*---
+description: SingleNameBinding with normal value iteration (generator method)
+es6id: 14.4.13
+flags: [generated]
+info: >
+ GeneratorMethod :
+ * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var obj = {
+ *method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+obj.method([1, 2, 3]).next();
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/object/dstr-meth-ary-name-iter-val.js b/test/language/expressions/object/dstr-meth-ary-name-iter-val.js
new file mode 100644
index 000000000..d9bfb6f4d
--- /dev/null
+++ b/test/language/expressions/object/dstr-meth-ary-name-iter-val.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/meth.template
+/*---
+description: SingleNameBinding with normal value iteration (method)
+es6id: 14.3.8
+flags: [generated]
+info: >
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters,
+ FunctionBody, scope, strict). If functionPrototype was passed as a
+ parameter then pass its value as the functionPrototype optional argument
+ of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+var obj = {
+ method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+obj.method([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/expressions/super/spread-err-sngl-err-expr-throws.js b/test/language/expressions/super/spread-err-sngl-err-expr-throws.js
new file mode 100644
index 000000000..33809221e
--- /dev/null
+++ b/test/language/expressions/super/spread-err-sngl-err-expr-throws.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/spread/sngl-err-expr-throws.case
+// - src/spread/error/super-call.template
+/*---
+description: Spread operator applied to the only argument when evaluation throws (SuperCall)
+es6id: 12.3.5.1
+features: [generators]
+
+flags: [generated]
+info: >
+ SuperCall : super Arguments
+
+ 1. Let newTarget be GetNewTarget().
+ 2. If newTarget is undefined, throw a ReferenceError exception.
+ 3. Let func be GetSuperConstructor().
+ 4. ReturnIfAbrupt(func).
+ 5. Let argList be ArgumentListEvaluation of Arguments.
+ [...]
+
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+---*/
+
+class Test262ParentClass {
+ constructor() {}
+}
+
+class Test262ChildClass extends Test262ParentClass {
+ constructor() {
+ super(...function*() { throw new Test262Error(); }());
+ }
+}
+
+assert.throws(Test262Error, function() {
+ new Test262ChildClass();
+});
diff --git a/test/language/expressions/super/spread-sngl-iter.js b/test/language/expressions/super/spread-sngl-iter.js
new file mode 100644
index 000000000..b4ae03e8b
--- /dev/null
+++ b/test/language/expressions/super/spread-sngl-iter.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/spread/sngl-iter.case
+// - src/spread/default/super-call.template
+/*---
+description: Spread operator applied to the only argument with a valid iterator (SuperCall)
+es6id: 12.3.5.1
+features: [Symbol.iterator]
+
+flags: [generated]
+info: >
+ SuperCall : super Arguments
+
+ 1. Let newTarget be GetNewTarget().
+ 2. If newTarget is undefined, throw a ReferenceError exception.
+ 3. Let func be GetSuperConstructor().
+ 4. ReturnIfAbrupt(func).
+ 5. Let argList be ArgumentListEvaluation of Arguments.
+ [...]
+
+ 12.3.6.1 Runtime Semantics: ArgumentListEvaluation
+
+ ArgumentList : ... AssignmentExpression
+
+ 1. Let list be an empty List.
+ 2. Let spreadRef be the result of evaluating AssignmentExpression.
+ 3. Let spreadObj be GetValue(spreadRef).
+ 4. Let iterator be GetIterator(spreadObj).
+ 5. ReturnIfAbrupt(iterator).
+ 6. Repeat
+ a. Let next be IteratorStep(iterator).
+ b. ReturnIfAbrupt(next).
+ c. If next is false, return list.
+ d. Let nextArg be IteratorValue(next).
+ e. ReturnIfAbrupt(nextArg).
+ f. Append nextArg as the last element of list.
+---*/
+var iter = {};
+iter[Symbol.iterator] = function() {
+ var callCount = 0;
+ return {
+ next: function() {
+ callCount += 1;
+ return { done: callCount === 3, value: callCount };
+ }
+ };
+};
+
+var callCount = 0;
+
+class Test262ParentClass {
+ constructor() {
+ assert.sameValue(arguments.length, 2);
+ assert.sameValue(arguments[0], 1);
+ assert.sameValue(arguments[1], 2);
+ callCount += 1;
+ }
+}
+
+class Test262ChildClass extends Test262ParentClass {
+ constructor() {
+ super(...iter);
+ }
+}
+
+new Test262ChildClass();
+assert.sameValue(callCount, 1);
diff --git a/test/language/statements/class/dstr-gen-meth-ary-name-iter-val.js b/test/language/statements/class/dstr-gen-meth-ary-name-iter-val.js
new file mode 100644
index 000000000..5420f0f2a
--- /dev/null
+++ b/test/language/statements/class/dstr-gen-meth-ary-name-iter-val.js
@@ -0,0 +1,92 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-decl-gen-meth.template
+/*---
+description: SingleNameBinding with normal value iteration (class expression method)
+es6id: 14.5.16
+flags: [generated]
+info: >
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod : * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+class C {
+ *method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+new C().method([1, 2, 3]).next();
+assert.sameValue(callCount, 1);
diff --git a/test/language/statements/class/dstr-gen-meth-static-ary-name-iter-val.js b/test/language/statements/class/dstr-gen-meth-static-ary-name-iter-val.js
new file mode 100644
index 000000000..33490cd0c
--- /dev/null
+++ b/test/language/statements/class/dstr-gen-meth-static-ary-name-iter-val.js
@@ -0,0 +1,92 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-decl-gen-meth-static.template
+/*---
+description: SingleNameBinding with normal value iteration (static class expression generator method)
+es6id: 14.5.15
+flags: [generated]
+info: >
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation for
+ m with arguments F and false.
+ [...]
+
+ 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation
+
+ GeneratorMethod : * PropertyName ( StrictFormalParameters ) { GeneratorBody }
+
+ 1. Let propKey be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(propKey).
+ 3. If the function code for this GeneratorMethod is strict mode code,
+ let strict be true. Otherwise let strict be false.
+ 4. Let scope be the running execution context's LexicalEnvironment.
+ 5. Let closure be GeneratorFunctionCreate(Method,
+ StrictFormalParameters, GeneratorBody, scope, strict).
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+class C {
+ static *method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+C.method([1, 2, 3]).next();
+assert.sameValue(callCount, 1);
diff --git a/test/language/statements/class/dstr-meth-ary-name-iter-val.js b/test/language/statements/class/dstr-meth-ary-name-iter-val.js
new file mode 100644
index 000000000..d811ee11f
--- /dev/null
+++ b/test/language/statements/class/dstr-meth-ary-name-iter-val.js
@@ -0,0 +1,90 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-decl-meth.template
+/*---
+description: SingleNameBinding with normal value iteration (class expression method)
+es6id: 14.5.15
+flags: [generated]
+info: >
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ i. Let status be the result of performing
+ PropertyDefinitionEvaluation for m with arguments proto and
+ false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+class C {
+ method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+new C().method([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/statements/class/dstr-meth-static-ary-name-iter-val.js b/test/language/statements/class/dstr-meth-static-ary-name-iter-val.js
new file mode 100644
index 000000000..f760fc0e9
--- /dev/null
+++ b/test/language/statements/class/dstr-meth-static-ary-name-iter-val.js
@@ -0,0 +1,90 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/cls-decl-meth-static.template
+/*---
+description: SingleNameBinding with normal value iteration (static class expression method)
+es6id: 14.5.15
+flags: [generated]
+info: >
+ ClassDeclaration : class BindingIdentifier ClassTail
+
+ 1. Let className be StringValue of BindingIdentifier.
+ 2. Let value be the result of ClassDefinitionEvaluation of ClassTail with
+ argument className.
+ [...]
+
+ 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
+
+ 21. For each ClassElement m in order from methods
+ a. If IsStatic of m is false, then
+ b. Else,
+ Let status be the result of performing PropertyDefinitionEvaluation for
+ m with arguments F and false.
+ [...]
+
+ 14.3.8 Runtime Semantics: DefineMethod
+
+ MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
+
+ [...]
+ 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody,
+ scope, strict). If functionPrototype was passed as a parameter then pass its
+ value as the functionPrototype optional argument of FunctionCreate.
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+class C {
+ static method([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+ }
+};
+
+C.method([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/statements/const/dstr-ary-name-iter-val.js b/test/language/statements/const/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..9c0dfe7d9
--- /dev/null
+++ b/test/language/statements/const/dstr-ary-name-iter-val.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/const-stmt.template
+/*---
+description: SingleNameBinding with normal value iteration (`const` statement)
+es6id: 13.3.1.4
+flags: [generated]
+info: >
+ LexicalBinding : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let value be GetValue(rhs).
+ 3. ReturnIfAbrupt(value).
+ 4. Let env be the running execution context's LexicalEnvironment.
+ 5. Return the result of performing BindingInitialization for BindingPattern
+ using value and env as the arguments.
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+const [x, y, z] = [1, 2, 3];
+
+assert.sameValue(x, 1);
+assert.sameValue(y, 2);
+assert.sameValue(z, 3);
diff --git a/test/language/statements/function/dstr-ary-name-iter-val.js b/test/language/statements/function/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..a1d408404
--- /dev/null
+++ b/test/language/statements/function/dstr-ary-name-iter-val.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/func-decl.template
+/*---
+description: SingleNameBinding with normal value iteration (function declaration)
+es6id: 14.1.19
+flags: [generated]
+info: >
+ FunctionDeclaration :
+ function BindingIdentifier ( FormalParameters ) { FunctionBody }
+
+ [...]
+ 3. Let F be FunctionCreate(Normal, FormalParameters, FunctionBody,
+ scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+function f([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+};
+f([1, 2, 3]);
+assert.sameValue(callCount, 1);
diff --git a/test/language/statements/generators/dstr-ary-name-iter-val.js b/test/language/statements/generators/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..74098d854
--- /dev/null
+++ b/test/language/statements/generators/dstr-ary-name-iter-val.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/gen-func-decl.template
+/*---
+description: SingleNameBinding with normal value iteration (generator function declaration)
+es6id: 14.4.12
+flags: [generated]
+info: >
+ GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
+
+ [...]
+ 2. Let F be GeneratorFunctionCreate(Normal, FormalParameters,
+ GeneratorBody, scope, strict).
+ [...]
+
+ 9.2.1 [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ 9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ 9.2.12 FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var callCount = 0;
+function* f([x, y, z]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ callCount = callCount + 1;
+};
+f([1, 2, 3]).next();
+assert.sameValue(callCount, 1);
diff --git a/test/language/statements/let/dstr-ary-name-iter-val.js b/test/language/statements/let/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..0fa4fcd8e
--- /dev/null
+++ b/test/language/statements/let/dstr-ary-name-iter-val.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/let-stmt.template
+/*---
+description: SingleNameBinding with normal value iteration (`let` statement)
+es6id: 13.3.1.4
+flags: [generated]
+info: >
+ LexicalBinding : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let value be GetValue(rhs).
+ 3. ReturnIfAbrupt(value).
+ 4. Let env be the running execution context's LexicalEnvironment.
+ 5. Return the result of performing BindingInitialization for BindingPattern
+ using value and env as the arguments.
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+let [x, y, z] = [1, 2, 3];
+
+assert.sameValue(x, 1);
+assert.sameValue(y, 2);
+assert.sameValue(z, 3);
diff --git a/test/language/statements/variable/dstr-ary-name-iter-val.js b/test/language/statements/variable/dstr-ary-name-iter-val.js
new file mode 100644
index 000000000..a0a70ce74
--- /dev/null
+++ b/test/language/statements/variable/dstr-ary-name-iter-val.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/var-stmt.template
+/*---
+description: SingleNameBinding with normal value iteration (`var` statement)
+es6id: 13.3.2.4
+flags: [generated]
+info: >
+ VariableDeclaration : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let rval be GetValue(rhs).
+ 3. ReturnIfAbrupt(rval).
+ 4. Return the result of performing BindingInitialization for
+ BindingPattern passing rval and undefined as arguments.
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var [x, y, z] = [1, 2, 3];
+
+assert.sameValue(x, 1);
+assert.sameValue(y, 2);
+assert.sameValue(z, 3);
diff --git a/tools/generation/generator.py b/tools/generation/generator.py
new file mode 100755
index 000000000..754f00fcf
--- /dev/null
+++ b/tools/generation/generator.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+from __future__ import print_function
+import argparse
+import os, sys
+
+from lib.expander import Expander
+from lib.test import Test
+
+def print_error(*values):
+ print('ERROR:', *values, file=sys.stderr)
+
+def find_cases(location):
+ # When a file is specified, return the file name and its containing
+ # directory
+ if os.path.isfile(location):
+ return location, [os.path.dirname(location)]
+
+ # When a directory is specified, if that directory contains a sub-directory
+ # names "default" interpret it as a "case directory"
+ if (os.path.isdir(os.path.join(location, 'default'))):
+ return None, [location]
+ else:
+ return None, map(
+ lambda x: os.path.join(args.cases, x), os.listdir(args.cases))
+
+def clean(args):
+ for (subdir, _, fileNames) in os.walk(args.directory):
+ for fileName in map(lambda x: os.path.join(subdir, x), fileNames):
+ test = Test(fileName)
+ test.load()
+ if test.is_generated():
+ print('Deleting file "' + fileName + '"...')
+ os.remove(fileName)
+
+def create(args):
+ caseFile, caseDirs = find_cases(args.cases)
+
+ for caseDir in caseDirs:
+ exp = Expander(caseDir)
+ for test in exp.expand('utf-8', caseFile):
+ if args.out:
+ try:
+ test.load(args.out)
+
+ if args.no_clobber:
+ print_error(
+ 'Refusing to overwrite file: ' + test.file_name)
+ exit(1)
+
+ if not test.is_generated():
+ print_error(
+ 'Refusing to overwrite non-generated file: ' +
+ test.file_name)
+ exit(1)
+ except IOError:
+ pass
+
+ test.write(args.out, parents=args.parents)
+ else:
+ print(test.to_string())
+
+parser = argparse.ArgumentParser(description='Test262 test generator tool')
+subparsers = parser.add_subparsers()
+
+create_parser = subparsers.add_parser('create',
+ help='''Generate test material''')
+create_parser.add_argument('-o', '--out', help='''The directory to write the
+ compiled tests. If unspecified, tests will be written to standard out.''')
+create_parser.add_argument('-p', '--parents', action='store_true',
+ help='''Create non-existent directories as necessary.''')
+create_parser.add_argument('-n', '--no-clobber', action='store_true',
+ help='''Do not produce test if a corresponding file exists within this
+ directory.''')
+create_parser.add_argument('cases',
+ help='''Test cases to generate. May be a file or a directory.''')
+create_parser.set_defaults(func=create)
+
+clean_parser = subparsers.add_parser('clean',
+ help='''Remove previously-generated files''')
+clean_parser.add_argument('directory',
+ help='''Remove any generated tests from this directory''')
+clean_parser.set_defaults(func=clean)
+
+args = parser.parse_args()
+args.func(args)
diff --git a/tools/generation/lib/__init__.py b/tools/generation/lib/__init__.py
new file mode 100644
index 000000000..2ae28399f
--- /dev/null
+++ b/tools/generation/lib/__init__.py
@@ -0,0 +1 @@
+pass
diff --git a/tools/generation/lib/case.py b/tools/generation/lib/case.py
new file mode 100644
index 000000000..f43d4f664
--- /dev/null
+++ b/tools/generation/lib/case.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+import re
+
+from util.find_comments import find_comments
+from util.parse_yaml import parse_yaml
+
+regionStartPattern = re.compile(r'-\s+(\S+)')
+
+class Case:
+ def __init__(self, file_name):
+ self.attribs = dict(meta=None, regions=dict())
+
+ with open(file_name) as handle:
+ self.attribs = self._parse(handle.read())
+
+ def _parse(self, source):
+ case = dict(meta=None, regions=dict())
+ region_name = None
+ region_start = 0
+ lines = source.split('\n')
+
+ for comment in find_comments(source):
+ meta = parse_yaml(comment['source'])
+ if meta:
+ case['meta'] = meta
+ continue
+
+ match = regionStartPattern.match(comment['source'])
+ if match:
+ if region_name:
+ case['regions'][region_name] = \
+ '\n'.join(lines[region_start:comment['lineno'] - 1])
+
+ region_name = match.group(1)
+ region_start = comment['lineno']
+ continue
+
+ if region_name:
+ case['regions'][region_name] = \
+ '\n'.join(lines[region_start:-1])
+
+ return case
diff --git a/tools/generation/lib/expander.py b/tools/generation/lib/expander.py
new file mode 100644
index 000000000..5703a698b
--- /dev/null
+++ b/tools/generation/lib/expander.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+import re, os
+
+from case import Case
+from template import Template
+
+caseFilenamePattern = re.compile(r'^[^\.].*\.case$')
+templateFilenamePattern = re.compile(r'^[^\.].*\.template$')
+
+class Expander:
+ def __init__(self, case_dir):
+ self.templates = dict()
+ self.case_dir = case_dir
+
+ def _load_templates(self, template_class):
+ directory = os.path.join(self.case_dir, template_class)
+ file_names = map(
+ lambda x: os.path.join(directory, x),
+ filter(self.is_template_file, os.listdir(directory))
+ )
+
+ self.templates[template_class] = [Template(x) for x in file_names]
+
+ def _get_templates(self, template_class):
+ if not template_class in self.templates:
+ self._load_templates(template_class)
+
+ return self.templates[template_class]
+
+ def is_template_file(self, filename):
+ return re.match(templateFilenamePattern, filename)
+
+ def list_cases(self):
+ for name in os.listdir(self.case_dir):
+ full = os.path.join(self.case_dir, name)
+ if os.path.isfile(full) and caseFilenamePattern.match(name):
+ yield full
+
+ def expand(self, encoding, case_file = None):
+ if case_file:
+ case_files = [case_file]
+ else:
+ case_files = self.list_cases()
+
+ for case_file in case_files:
+ for test in self.expand_case(case_file, encoding):
+ yield test
+
+ def expand_case(self, file_name, encoding):
+ case = Case(file_name)
+
+ template_class = case.attribs['meta']['template']
+ templates = self.templates.get(template_class)
+
+ for template in self._get_templates(template_class):
+ yield template.expand(file_name, os.path.basename(file_name[:-5]), case.attribs, encoding)
diff --git a/tools/generation/lib/template.py b/tools/generation/lib/template.py
new file mode 100644
index 000000000..fa891f00b
--- /dev/null
+++ b/tools/generation/lib/template.py
@@ -0,0 +1,160 @@
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+import os, re
+import codecs, yaml
+
+from util.find_comments import find_comments
+from util.parse_yaml import parse_yaml
+from test import Test
+
+indentPattern = re.compile(r'^(\s*)')
+interpolatePattern = re.compile(r'\{\s*(\S+)\s*\}')
+
+def indent(text, prefix = ' '):
+ '''Prefix a block of text (as defined by the "line break" control
+ character) with some character sequence.'''
+
+ if isinstance(text, list):
+ lines = text
+ else:
+ lines = text.split('\n')
+
+ return prefix + ('\n' + prefix).join(lines)
+
+class Template:
+ def __init__(self, filename):
+ self.filename = filename
+
+ with open(filename) as template_file:
+ self.source = template_file.read()
+
+ self.attribs = dict()
+ self.regions = []
+
+ self._parse()
+
+ def _remove_comment(self, comment):
+ '''Create a region that is not intended to be referenced by any case,
+ ensuring that the comment is not emitted in the rendered file.'''
+ name = '__remove_comment_' + str(comment['firstchar']) + '__'
+
+ # When a removed comment ends the line, the following newline character
+ # should also be removed from the generated file.
+ lastchar = comment['lastchar']
+ if self.source[lastchar] == '\n':
+ comment['lastchar'] = comment['lastchar'] + 1
+
+ self.regions.insert(0, dict(name=name, **comment))
+
+ def _parse(self):
+ for comment in find_comments(self.source):
+ meta = parse_yaml(comment['source'])
+
+ # Do not emit the template's frontmatter in generated files
+ # (file-specific frontmatter is generated as part of the rendering
+ # process)
+ if meta:
+ self.attribs['meta'] = meta
+ self._remove_comment(comment)
+ continue
+
+ # Do not emit license information in generated files (recognized as
+ # comments preceeding the YAML frontmatter)
+ if not self.attribs.get('meta'):
+ self._remove_comment(comment)
+ continue
+
+ match = interpolatePattern.match(comment['source'])
+
+ if match == None:
+ continue
+
+ self.regions.insert(0, dict(name=match.group(1), **comment))
+
+ def expand_regions(self, source, context):
+ lines = source.split('\n')
+
+ for region in self.regions:
+ whitespace = indentPattern.match(lines[region['lineno']]).group(1)
+ value = context['regions'].get(region['name'], '')
+ source = source[:region['firstchar']] + \
+ indent(value, whitespace).lstrip() + \
+ source[region['lastchar']:]
+
+ setup = context['regions'].get('setup')
+
+ if setup:
+ source = setup + '\n' + source
+
+ teardown = context['regions'].get('teardown')
+
+ if teardown:
+ source += '\n' + teardown + '\n'
+
+ return source
+
+ def _frontmatter(self, case_filename, case_values):
+ description = case_values['meta']['desc'].strip() + \
+ ' (' + self.attribs['meta']['name'].strip() + ')'
+ lines = []
+
+ lines += [
+ '// This file was procedurally generated from the following sources:',
+ '// - ' + case_filename,
+ '// - ' + self.filename,
+ '/*---',
+ 'description: ' + description,
+ ]
+
+ esid = self.attribs['meta'].get('esid')
+ if esid:
+ lines.append('esid: ' + esid)
+
+ es6id = self.attribs['meta'].get('es6id')
+ if es6id:
+ lines.append('es6id: ' + es6id)
+
+ features = []
+ features += case_values['meta'].get('features', [])
+ features += self.attribs['meta'].get('features', [])
+ if len(features):
+ lines += ['features: ' + yaml.dump(features)]
+
+ flags = ['generated']
+ flags += case_values['meta'].get('flags', [])
+ flags += self.attribs['meta'].get('flags', [])
+ lines += ['flags: ' + yaml.dump(flags).strip()]
+
+ includes = []
+ includes += case_values['meta'].get('includes', [])
+ includes += self.attribs['meta'].get('includes', [])
+ if len(includes):
+ lines += ['includes: ' + yaml.dump(includes).strip()]
+
+ if case_values['meta'].get('negative'):
+ lines += ['negative: ' + case_values['meta'].get('negative')]
+
+ info = []
+
+ if 'info' in self.attribs['meta']:
+ info.append(indent(self.attribs['meta']['info']))
+ if 'info' in case_values['meta']:
+ if len(info):
+ info.append('')
+ info.append(indent(case_values['meta']['info']))
+
+ if len(info):
+ lines.append('info: >')
+ lines += info
+
+ lines.append('---*/')
+
+ return '\n'.join(lines)
+
+ def expand(self, case_filename, case_name, case_values, encoding):
+ frontmatter = self._frontmatter(case_filename, case_values)
+ body = self.expand_regions(self.source, case_values)
+
+ return Test(self.attribs['meta']['path'] + case_name + '.js',
+ source=codecs.encode(frontmatter + '\n' + body, encoding))
diff --git a/tools/generation/lib/test.py b/tools/generation/lib/test.py
new file mode 100644
index 000000000..1dd6d45f7
--- /dev/null
+++ b/tools/generation/lib/test.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+import os, re
+
+from util.find_comments import find_comments
+from util.parse_yaml import parse_yaml
+
+class Test:
+ """Representation of a generated test. Specifies a file location which may
+ or may not exist."""
+ def __init__(self, file_name, source=None):
+ self.file_name = file_name
+ self.source = source
+ self.attribs = dict(meta=None)
+
+ if self.source:
+ self._parse()
+
+ def load(self, prefix = None):
+ location = os.path.join(prefix or '', self.file_name)
+ with open(location) as handle:
+ self.source = handle.read()
+ self._parse()
+
+ def _parse(self):
+ for comment in find_comments(self.source):
+ meta = parse_yaml(comment['source'])
+ if meta:
+ self.attribs['meta'] = meta
+ break
+
+ def is_generated(self):
+ if not self.attribs['meta']:
+ return False
+ flags = self.attribs['meta'].get('flags')
+
+ if not flags:
+ return False
+
+ return 'generated' in flags
+
+ def to_string(self):
+ return '\n'.join([
+ '/**',
+ ' * ----------------------------------------------------------------',
+ ' * ' + self.file_name,
+ ' * ----------------------------------------------------------------',
+ ' */',
+ self.source,
+ '\n'])
+
+ def write(self, prefix, parents=False):
+ location = os.path.join(prefix, self.file_name)
+ path = os.path.dirname(location)
+ if not os.path.exists(path):
+ if parents:
+ os.makedirs(path)
+ else:
+ raise Exception('Directory does not exist: ' + path)
+
+ with open(location, 'w') as handle:
+ handle.write(self.source)
diff --git a/tools/generation/lib/util/__init__.py b/tools/generation/lib/util/__init__.py
new file mode 100644
index 000000000..2ae28399f
--- /dev/null
+++ b/tools/generation/lib/util/__init__.py
@@ -0,0 +1 @@
+pass
diff --git a/tools/generation/lib/util/find_comments.py b/tools/generation/lib/util/find_comments.py
new file mode 100644
index 000000000..81ad0ab55
--- /dev/null
+++ b/tools/generation/lib/util/find_comments.py
@@ -0,0 +1,68 @@
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+def find_comments(source):
+ '''Parse input string describing JavaScript source and yield dictionaries
+ describing the JavaScript comments in the order they appear in the source.
+
+ Each dictionary defines the following attributes:
+
+ - source: the source text of the comment
+ - firstchar: the zero-indexed position of the token that begins the comment
+ - lastchar: the zero-indexed position of the token that closes the comment
+ - lineno: the zero-indexed offset of the line on which the comment appears
+ '''
+ in_string = False
+ in_s_comment = False
+ in_m_comment = False
+ follows_escape = False
+ comment = ''
+ lineno = 0
+
+ for idx in xrange(len(source)):
+ if source[idx] == '\n':
+ lineno += 1
+
+ # Within comments and strings, any odd number of back-slashes begins an
+ # escape sequence.
+ if source[idx - 1] == '\\':
+ follows_escape = not follows_escape
+ else:
+ follows_escape = False
+
+ if in_s_comment:
+ if source[idx] == '\n':
+ in_s_comment = False
+ yield dict(
+ source=comment[1:],
+ firstchar=idx - len(comment) - 1,
+ lastchar=idx,
+ lineno=lineno)
+ continue
+ elif in_m_comment:
+ if source[idx - 1] == '*' and source[idx] == '/':
+ in_m_comment = False
+ yield dict(
+ source=comment[1:-1],
+ firstchar=idx - len(comment) - 1,
+ lastchar=idx + 1,
+ lineno=lineno)
+ continue
+ elif in_string:
+ if source[idx] == in_string and not follows_escape:
+ in_string = False
+ elif source[idx] == '\n' and in_string != '`' and not follows_escape:
+ in_string = False
+ continue
+
+ if in_m_comment or in_s_comment:
+ comment += source[idx]
+ continue
+
+ in_m_comment = source[idx] == '/' and source[idx + 1] == '*'
+ in_s_comment = source[idx] == '/' and source[idx + 1] == '/'
+
+ if in_m_comment or in_s_comment:
+ comment = ''
+ elif source[idx] == '\'' or source[idx] == '"' or source[idx] == '`':
+ in_string = source[idx]
diff --git a/tools/generation/lib/util/parse_yaml.py b/tools/generation/lib/util/parse_yaml.py
new file mode 100644
index 000000000..3ad356db8
--- /dev/null
+++ b/tools/generation/lib/util/parse_yaml.py
@@ -0,0 +1,17 @@
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+import yaml, re
+
+yamlPattern = re.compile(r'\---\n([\s]*)((?:\s|\S)*)[\n\s*]---',
+ flags=re.DOTALL|re.MULTILINE)
+
+def parse_yaml(string):
+ match = yamlPattern.match(string)
+ if not match:
+ return False
+
+ unindented = re.sub('^' + match.group(1), '',
+ match.group(2), flags=re.MULTILINE)
+
+ return yaml.safe_load(unindented)
diff --git a/tools/generation/requirements.txt b/tools/generation/requirements.txt
new file mode 100644
index 000000000..efb082d8d
--- /dev/null
+++ b/tools/generation/requirements.txt
@@ -0,0 +1 @@
+PyYAML==3.11
diff --git a/tools/generation/test/expected/normal/nested/path2-normal.js b/tools/generation/test/expected/normal/nested/path2-normal.js
new file mode 100644
index 000000000..d9da70500
--- /dev/null
+++ b/tools/generation/test/expected/normal/nested/path2-normal.js
@@ -0,0 +1,19 @@
+// This file was procedurally generated from the following sources:
+// - tools/generation/test/fixtures/normal.case
+// - tools/generation/test/fixtures/normal/normal2.template
+/*---
+description: foobar (Second template name)
+esid: sec-a-generic-id
+flags: [generated, a, b]
+includes: [foo.js, bar.js]
+info: >
+ template info
+
+ case info
+---*/
+
+before-Third valueSecond value-after
+
+/* Improperly-terminated comments should not break the tokenizer *
+
+'This is "teardown" code.';
diff --git a/tools/generation/test/expected/normal/no-info-normal.js b/tools/generation/test/expected/normal/no-info-normal.js
new file mode 100644
index 000000000..903028036
--- /dev/null
+++ b/tools/generation/test/expected/normal/no-info-normal.js
@@ -0,0 +1,15 @@
+// This file was procedurally generated from the following sources:
+// - tools/generation/test/fixtures/normal.case
+// - tools/generation/test/fixtures/normal/no-info.template
+/*---
+description: foobar (First template name)
+es6id: 1.2.3
+flags: [generated, a, b]
+includes: [foo.js]
+info: >
+ case info
+---*/
+
+First value
+
+'This is "teardown" code.';
diff --git a/tools/generation/test/expected/normal/path1-normal.js b/tools/generation/test/expected/normal/path1-normal.js
new file mode 100644
index 000000000..3bc10d0e9
--- /dev/null
+++ b/tools/generation/test/expected/normal/path1-normal.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - tools/generation/test/fixtures/normal.case
+// - tools/generation/test/fixtures/normal/normal.template
+/*---
+description: foobar (First template name)
+es6id: 1.2.3
+flags: [generated, a, b, c, d]
+includes: [foo.js]
+info: >
+ template info
+
+ case info
+---*/
+
+before-First value-between-Third value-after
+
+before*Second value*between*First value*after
+
+before/* " */Third valueafter
+
+The following should not be expanded:
+
+/* */*{ first }*/
+/*
+*/*{ first }*/
+//*{ first }*/
+// /*{ first }*/
+"/*{ first }*/"
+'/*{ first }*/'
+`
+/*{ first }*/`
+
+'This is "teardown" code.';
diff --git a/tools/generation/test/fixtures/normal.case b/tools/generation/test/fixtures/normal.case
new file mode 100644
index 000000000..276b58ccd
--- /dev/null
+++ b/tools/generation/test/fixtures/normal.case
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+template: normal
+desc: foobar
+info: case info
+flags: [a, b]
+includes: [foo.js]
+---*/
+
+Because this test appears before any "region" delimiters, it should not appear
+in the generated files.
+
+// - first
+this is not a valid region delimiter
+
+/* *//- first
+this is also not a valid region delimiter
+
+//- first
+First value
+//- second
+Second value
+//- third
+Third value
+//- teardown
+'This is "teardown" code.';
diff --git a/tools/generation/test/fixtures/normal/no-info.template b/tools/generation/test/fixtures/normal/no-info.template
new file mode 100644
index 000000000..0f1b340ea
--- /dev/null
+++ b/tools/generation/test/fixtures/normal/no-info.template
@@ -0,0 +1,9 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+name: First template name
+path: normal/no-info-
+es6id: 1.2.3
+---*/
+
+/*{ first }*/
diff --git a/tools/generation/test/fixtures/normal/normal.template b/tools/generation/test/fixtures/normal/normal.template
new file mode 100644
index 000000000..ac0bea1e1
--- /dev/null
+++ b/tools/generation/test/fixtures/normal/normal.template
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+name: First template name
+path: normal/path1-
+es6id: 1.2.3
+info: template info
+flags: [c, d]
+---*/
+
+before-/*{ first }*/-between-/*{ third }*/-after
+
+before*/*{ second }*/*between*/*{ first }*/*after
+
+before/* " *//*{ third }*/after
+
+The following should not be expanded:
+
+/* */*{ first }*/
+/*
+*/*{ first }*/
+//*{ first }*/
+// /*{ first }*/
+"/*{ first }*/"
+'/*{ first }*/'
+`
+/*{ first }*/`
diff --git a/tools/generation/test/fixtures/normal/normal2.template b/tools/generation/test/fixtures/normal/normal2.template
new file mode 100644
index 000000000..f7ae0b683
--- /dev/null
+++ b/tools/generation/test/fixtures/normal/normal2.template
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+name: Second template name
+path: normal/nested/path2-
+esid: sec-a-generic-id
+includes: [bar.js]
+info: template info
+---*/
+
+before-/*{ third }*//*{ second }*/-after
+
+/* Improperly-terminated comments should not break the tokenizer *
diff --git a/tools/generation/test/run.py b/tools/generation/test/run.py
new file mode 100755
index 000000000..297815d67
--- /dev/null
+++ b/tools/generation/test/run.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# Copyright (C) 2016 the V8 project authors. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+import shutil, subprocess, sys, os, unittest
+
+testDir = os.path.dirname(os.path.relpath(__file__))
+OUT_DIR = os.path.join(testDir, 'out')
+EXPECTED_DIR = os.path.join(testDir, 'expected')
+ex = os.path.join(testDir, '..', 'generator.py')
+
+class TestGeneration(unittest.TestCase):
+ maxDiff = None
+
+ def fixture(self, name):
+ relpath = os.path.relpath(os.path.join(testDir, 'fixtures', name))
+ sp = subprocess.Popen(
+ [ex, 'create', '-o', OUT_DIR, '-p', relpath],
+ stdout=subprocess.PIPE)
+ stdout, stderr = sp.communicate()
+ return dict(stdout=stdout, stderr=stderr, returncode=sp.returncode)
+
+ def getFiles(self, path):
+ names = []
+ for root, _, fileNames in os.walk(path):
+ for fileName in filter(lambda x: x[0] != '.', fileNames):
+ names.append(os.path.join(root, fileName))
+ names.sort()
+ return names
+
+ def compareTrees(self, targetName):
+ expectedPath = os.path.join(EXPECTED_DIR, targetName)
+ actualPath = os.path.join(OUT_DIR, targetName)
+
+ expectedFiles = self.getFiles(expectedPath)
+ actualFiles = self.getFiles(actualPath)
+
+ self.assertListEqual(
+ map(lambda x: os.path.relpath(x, expectedPath), expectedFiles),
+ map(lambda x: os.path.relpath(x, actualPath), actualFiles))
+
+ for expectedFile, actualFile in zip(expectedFiles, actualFiles):
+ with open(expectedFile) as expectedHandle:
+ with open(actualFile) as actualHandle:
+ self.assertMultiLineEqual(
+ expectedHandle.read(),
+ actualHandle.read())
+
+ def tearDown(self):
+ shutil.rmtree(OUT_DIR, ignore_errors=True)
+
+ def test_normal(self):
+ result = self.fixture('normal.case')
+ self.assertEqual(result['returncode'], 0)
+ self.compareTrees('normal')
+
+if __name__ == '__main__':
+ unittest.main()