Revision: 23272
Author: [email protected]
Date: Thu Aug 21 12:06:25 2014 UTC
Log: Stage ES6 generators
[email protected]
BUG=
Review URL: https://codereview.chromium.org/479543003
http://code.google.com/p/v8/source/detail?r=23272
Added:
/branches/bleeding_edge/test/mjsunit/es6/generators-debug-liveedit.js
/branches/bleeding_edge/test/mjsunit/es6/generators-debug-scopes.js
/branches/bleeding_edge/test/mjsunit/es6/generators-iteration.js
/branches/bleeding_edge/test/mjsunit/es6/generators-objects.js
/branches/bleeding_edge/test/mjsunit/es6/generators-parsing.js
/branches/bleeding_edge/test/mjsunit/es6/generators-poisoned-properties.js
/branches/bleeding_edge/test/mjsunit/es6/generators-relocation.js
/branches/bleeding_edge/test/mjsunit/es6/generators-runtime.js
/branches/bleeding_edge/test/mjsunit/es6/regress/regress-2681.js
/branches/bleeding_edge/test/mjsunit/es6/regress/regress-2691.js
/branches/bleeding_edge/test/mjsunit/es6/regress/regress-3280.js
Deleted:
/branches/bleeding_edge/test/mjsunit/harmony/generators-debug-liveedit.js
/branches/bleeding_edge/test/mjsunit/harmony/generators-debug-scopes.js
/branches/bleeding_edge/test/mjsunit/harmony/generators-iteration.js
/branches/bleeding_edge/test/mjsunit/harmony/generators-objects.js
/branches/bleeding_edge/test/mjsunit/harmony/generators-parsing.js
/branches/bleeding_edge/test/mjsunit/harmony/generators-poisoned-properties.js
/branches/bleeding_edge/test/mjsunit/harmony/generators-relocation.js
/branches/bleeding_edge/test/mjsunit/harmony/generators-runtime.js
/branches/bleeding_edge/test/mjsunit/harmony/regress/regress-2681.js
/branches/bleeding_edge/test/mjsunit/harmony/regress/regress-2691.js
/branches/bleeding_edge/test/mjsunit/harmony/regress/regress-3280.js
Modified:
/branches/bleeding_edge/src/flag-definitions.h
/branches/bleeding_edge/test/mjsunit/mjsunit.status
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/generators-debug-liveedit.js
Thu Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,119 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-generators
+
+var Debug = debug.Debug;
+var LiveEdit = Debug.LiveEdit;
+
+unique_id = 0;
+
+var Generator = (function*(){}).constructor;
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({value: value, done: done}, result);
+}
+
+function MakeGenerator() {
+ // Prevents eval script caching.
+ unique_id++;
+ return Generator('callback',
+ "/* " + unique_id + "*/\n" +
+ "yield callback();\n" +
+ "return 'Cat';\n");
+}
+
+function MakeFunction() {
+ // Prevents eval script caching.
+ unique_id++;
+ return Function('callback',
+ "/* " + unique_id + "*/\n" +
+ "callback();\n" +
+ "return 'Cat';\n");
+}
+
+// First, try MakeGenerator with no perturbations.
+(function(){
+ var generator = MakeGenerator();
+ function callback() {};
+ var iter = generator(callback);
+ assertIteratorResult(undefined, false, iter.next());
+ assertIteratorResult("Cat", true, iter.next());
+})();
+
+function patch(fun, from, to) {
+ function debug() {
+ var log = new Array();
+ var script = Debug.findScript(fun);
+ var pos = script.source.indexOf(from);
+ try {
+ LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
+ log);
+ } finally {
+ print("Change log: " + JSON.stringify(log) + "\n");
+ }
+ }
+ Debug.ExecuteInDebugContext(debug, false);
+}
+
+// Try to edit a MakeGenerator while it's running, then again while it's
+// stopped.
+(function(){
+ var generator = MakeGenerator();
+
+ var gen_patch_attempted = false;
+ function attempt_gen_patch() {
+ assertFalse(gen_patch_attempted);
+ gen_patch_attempted = true;
+ assertThrows(function() { patch(generator, "'Cat'", "'Capybara'") },
+ LiveEdit.Failure);
+ };
+ var iter = generator(attempt_gen_patch);
+ assertIteratorResult(undefined, false, iter.next());
+ // Patch should not succeed because there is a live generator activation
on
+ // the stack.
+ assertIteratorResult("Cat", true, iter.next());
+ assertTrue(gen_patch_attempted);
+
+ // At this point one iterator is live, but closed, so the patch will
succeed.
+ patch(generator, "'Cat'", "'Capybara'");
+ iter = generator(function(){});
+ assertIteratorResult(undefined, false, iter.next());
+ // Patch successful.
+ assertIteratorResult("Capybara", true, iter.next());
+
+ // Patching will fail however when a live iterator is suspended.
+ iter = generator(function(){});
+ assertIteratorResult(undefined, false, iter.next());
+ assertThrows(function() { patch(generator, "'Capybara'", "'Tapir'") },
+ LiveEdit.Failure);
+ assertIteratorResult("Capybara", true, iter.next());
+
+ // Try to patch functions with activations inside and outside generator
+ // function activations. We should succeed in the former case, but not
in the
+ // latter.
+ var fun_outside = MakeFunction();
+ var fun_inside = MakeFunction();
+ var fun_patch_attempted = false;
+ var fun_patch_restarted = false;
+ function attempt_fun_patches() {
+ if (fun_patch_attempted) {
+ assertFalse(fun_patch_restarted);
+ fun_patch_restarted = true;
+ return;
+ }
+ fun_patch_attempted = true;
+ // Patching outside a generator activation must fail.
+ assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
+ LiveEdit.Failure);
+ // Patching inside a generator activation may succeed.
+ patch(fun_inside, "'Cat'", "'Koala'");
+ }
+ iter = generator(function() { return fun_inside(attempt_fun_patches) });
+ assertEquals('Cat',
+ fun_outside(function () {
+ assertIteratorResult('Koala', false, iter.next());
+ assertTrue(fun_patch_restarted);
+ }));
+})();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/generators-debug-scopes.js Thu
Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,326 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-generators
+
+var Debug = debug.Debug;
+
+function RunTest(name, formals_and_body, args, handler, continuation) {
+ var handler_called = false;
+ var exception = null;
+
+ function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ handler_called = true;
+ handler(exec_state);
+ }
+ } catch (e) {
+ exception = e;
+ }
+ }
+
+ function run(thunk) {
+ handler_called = false;
+ exception = null;
+
+ var res = thunk();
+ if (continuation)
+ continuation(res);
+
+ assertTrue(handler_called, "listener not called for " + name);
+ assertNull(exception, name + " / " + exception);
+ }
+
+ var fun = Function.apply(null, formals_and_body);
+ var gen = (function*(){}).constructor.apply(null, formals_and_body);
+
+ Debug.setListener(listener);
+
+ run(function () { return fun.apply(null, args) });
+ run(function () { return gen.apply(null, args).next().value });
+
+ // TODO(wingo): Uncomment after bug 2838 is fixed.
+ // Debug.setListener(null);
+}
+
+// Check that two scope are the same.
+function assertScopeMirrorEquals(scope1, scope2) {
+ assertEquals(scope1.scopeType(), scope2.scopeType());
+ assertEquals(scope1.frameIndex(), scope2.frameIndex());
+ assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
+ assertPropertiesEqual(scope1.scopeObject().value(),
scope2.scopeObject().value());
+}
+
+function CheckFastAllScopes(scopes, exec_state) {
+ var fast_all_scopes = exec_state.frame().allScopes(true);
+ var length = fast_all_scopes.length;
+ assertTrue(scopes.length >= length);
+ for (var i = 0; i < scopes.length && i < length; i++) {
+ var scope = fast_all_scopes[length - i - 1];
+ assertTrue(scope.isScope());
+ assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
+ }
+}
+
+// Check that the scope chain contains the expected types of scopes.
+function CheckScopeChain(scopes, exec_state) {
+ var all_scopes = exec_state.frame().allScopes();
+ assertEquals(scopes.length, exec_state.frame().scopeCount());
+ assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes
length");
+ for (var i = 0; i < scopes.length; i++) {
+ var scope = exec_state.frame().scope(i);
+ assertTrue(scope.isScope());
+ assertEquals(scopes[i], scope.scopeType());
+ assertScopeMirrorEquals(all_scopes[i], scope);
+
+ // Check the global object when hitting the global scope.
+ if (scopes[i] == debug.ScopeType.Global) {
+ // Objects don't have same class (one is "global", other is "Object",
+ // so just check the properties directly.
+ assertPropertiesEqual(this, scope.scopeObject().value());
+ }
+ }
+ CheckFastAllScopes(scopes, exec_state);
+
+ // Get the debug command processor.
+ var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
+ // Send a scopes request and check the result.
+ var json;
+ var request_json = '{"seq":0,"type":"request","command":"scopes"}';
+ var response_json = dcp.processDebugJSONRequest(request_json);
+ var response = JSON.parse(response_json);
+ assertEquals(scopes.length, response.body.scopes.length);
+ for (var i = 0; i < scopes.length; i++) {
+ assertEquals(i, response.body.scopes[i].index);
+ assertEquals(scopes[i], response.body.scopes[i].type);
+ if (scopes[i] == debug.ScopeType.Local ||
+ scopes[i] == debug.ScopeType.Closure) {
+ assertTrue(response.body.scopes[i].object.ref < 0);
+ } else {
+ assertTrue(response.body.scopes[i].object.ref >= 0);
+ }
+ var found = false;
+ for (var j = 0; j < response.refs.length && !found; j++) {
+ found = response.refs[j].handle ==
response.body.scopes[i].object.ref;
+ }
+ assertTrue(found, "Scope object " + response.body.scopes[i].object.ref
+ " not found");
+ }
+}
+
+// Check that the content of the scope is as expected. For functions just
check
+// that there is a function.
+function CheckScopeContent(content, number, exec_state) {
+ var scope = exec_state.frame().scope(number);
+ var count = 0;
+ for (var p in content) {
+ var property_mirror = scope.scopeObject().property(p);
+ assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not
found in scope');
+ if (typeof(content[p]) === 'function') {
+ assertTrue(property_mirror.value().isFunction());
+ } else {
+ assertEquals(content[p],
property_mirror.value().value(), 'property ' + p + ' has unexpected value');
+ }
+ count++;
+ }
+
+ // 'arguments' and might be exposed in the local and closure scope. Just
+ // ignore this.
+ var scope_size = scope.scopeObject().properties().length;
+ if (!scope.scopeObject().property('arguments').isUndefined()) {
+ scope_size--;
+ }
+ // Skip property with empty name.
+ if (!scope.scopeObject().property('').isUndefined()) {
+ scope_size--;
+ }
+
+ if (count != scope_size) {
+ print('Names found in scope:');
+ var names = scope.scopeObject().propertyNames();
+ for (var i = 0; i < names.length; i++) {
+ print(names[i]);
+ }
+ }
+ assertEquals(count, scope_size);
+
+ // Get the debug command processor.
+ var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
+ // Send a scope request for information on a single scope and check the
+ // result.
+ var request_json
= '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
+ request_json += scope.scopeIndex();
+ request_json += '}}';
+ var response_json = dcp.processDebugJSONRequest(request_json);
+ var response = JSON.parse(response_json);
+ assertEquals(scope.scopeType(), response.body.type);
+ assertEquals(number, response.body.index);
+ if (scope.scopeType() == debug.ScopeType.Local ||
+ scope.scopeType() == debug.ScopeType.Closure) {
+ assertTrue(response.body.object.ref < 0);
+ } else {
+ assertTrue(response.body.object.ref >= 0);
+ }
+ var found = false;
+ for (var i = 0; i < response.refs.length && !found; i++) {
+ found = response.refs[i].handle == response.body.object.ref;
+ }
+ assertTrue(found, "Scope object " + response.body.object.ref + " not
found");
+}
+
+
+// Simple empty local scope.
+RunTest("Local 1",
+ ['debugger;'],
+ [],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ });
+
+// Local scope with a parameter.
+RunTest("Local 2",
+ ['a', 'debugger;'],
+ [1],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1}, 0, exec_state);
+ });
+
+// Local scope with a parameter and a local variable.
+RunTest("Local 3",
+ ['a', 'var x = 3; debugger;'],
+ [1],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,x:3}, 0, exec_state);
+ });
+
+// Local scope with parameters and local variables.
+RunTest("Local 4",
+ ['a', 'b', 'var x = 3; var y = 4; debugger;'],
+ [1, 2],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
+ });
+
+// Empty local scope with use of eval.
+RunTest("Local 5",
+ ['eval(""); debugger;'],
+ [],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ });
+
+// Local introducing local variable using eval.
+RunTest("Local 6",
+ ['eval("var i = 5"); debugger;'],
+ [],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({i:5}, 0, exec_state);
+ });
+
+// Local scope with parameters, local variables and local variable
introduced
+// using eval.
+RunTest("Local 7",
+ ['a', 'b',
+ "var x = 3; var y = 4;\n"
+ + "eval('var i = 5'); eval ('var j = 6');\n"
+ + "debugger;"],
+ [1, 2],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
+ });
+
+// Nested empty with blocks.
+RunTest("With",
+ ["with ({}) { with ({}) { debugger; } }"],
+ [],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ CheckScopeContent({}, 1, exec_state);
+ });
+
+// Simple closure formed by returning an inner function referering the
outer
+// functions arguments.
+RunTest("Closure 1",
+ ['a', 'return function() { debugger; return a; }'],
+ [1],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1}, 1, exec_state);
+ },
+ function (result) { result() });
+
+RunTest("The full monty",
+ ['a', 'b',
+ "var x = 3;\n" +
+ "var y = 4;\n" +
+ "eval('var i = 5');\n" +
+ "eval('var j = 6');\n" +
+ "function f(a, b) {\n" +
+ " var x = 9;\n" +
+ " var y = 10;\n" +
+ " eval('var i = 11');\n" +
+ " eval('var j = 12');\n" +
+ " with ({j:13}){\n" +
+ " return function() {\n" +
+ " var x = 14;\n" +
+ " with ({a:15}) {\n" +
+ " with ({b:16}) {\n" +
+ " debugger;\n" +
+ " some_global = a;\n" +
+ " return f;\n" +
+ " }\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "}\n" +
+ "return f(a, b);"],
+ [1, 2],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.With,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({b:16}, 0, exec_state);
+ CheckScopeContent({a:15}, 1, exec_state);
+ CheckScopeContent({x:14}, 2, exec_state);
+ CheckScopeContent({j:13}, 3, exec_state);
+ CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5,
exec_state);
+ },
+ function (result) { result() });
+
+RunTest("Catch block 1",
+ ["try { throw 'Exception'; } catch (e) { debugger; }"],
+ [],
+ function (exec_state) {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e:'Exception'}, 0, exec_state);
+ });
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/generators-iteration.js Thu
Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,698 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-generators --expose-gc
+
+// Test generator iteration.
+
+var GeneratorFunction = (function*(){yield 1;}).__proto__.constructor;
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({ value: value, done: done}, result);
+}
+
+function assertIteratorIsClosed(iter) {
+ assertIteratorResult(undefined, true, iter.next());
+ assertDoesNotThrow(function() { iter.next(); });
+}
+
+function assertThrownIteratorIsClosed(iter) {
+ // TODO(yusukesuzuki): Since status of a thrown generator is "executing",
+ // following tests are failed.
+ // https://code.google.com/p/v8/issues/detail?id=3096
+ // assertIteratorIsClosed(iter);
+}
+
+function TestGeneratorResultPrototype() {
+ function* g() { yield 1; }
+ var iter = g();
+ var result = iter.next();
+
+ assertSame(Object.prototype, Object.getPrototypeOf(result));
+ property_names = Object.getOwnPropertyNames(result);
+ property_names.sort();
+ assertEquals(["done", "value"], property_names);
+ assertIteratorResult(1, false, result);
+}
+TestGeneratorResultPrototype()
+
+function TestGenerator(g, expected_values_for_next,
+ send_val, expected_values_for_send) {
+ function testNext(thunk) {
+ var iter = thunk();
+ for (var i = 0; i < expected_values_for_next.length; i++) {
+ var v1 = expected_values_for_next[i];
+ var v2 = i == expected_values_for_next.length - 1;
+ // var v3 = iter.next();
+ assertIteratorResult(v1, v2, iter.next());
+ }
+ assertIteratorIsClosed(iter);
+ }
+ function testSend(thunk) {
+ var iter = thunk();
+ for (var i = 0; i < expected_values_for_send.length; i++) {
+ assertIteratorResult(expected_values_for_send[i],
+ i == expected_values_for_send.length - 1,
+ iter.next(send_val));
+ }
+ assertIteratorIsClosed(iter);
+ }
+ function testThrow(thunk) {
+ for (var i = 0; i < expected_values_for_next.length; i++) {
+ var iter = thunk();
+ for (var j = 0; j < i; j++) {
+ assertIteratorResult(expected_values_for_next[j],
+ j == expected_values_for_next.length - 1,
+ iter.next());
+ }
+ function Sentinel() {}
+ assertThrows(function () { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ }
+
+ testNext(g);
+ testSend(g);
+ testThrow(g);
+
+ testNext(function*() { return yield* g(); });
+ testSend(function*() { return yield* g(); });
+ testThrow(function*() { return yield* g(); });
+
+ if (g instanceof GeneratorFunction) {
+ testNext(function() { return new g(); });
+ testSend(function() { return new g(); });
+ testThrow(function() { return new g(); });
+ }
+}
+
+TestGenerator(function* g1() { },
+ [undefined],
+ "foo",
+ [undefined]);
+
+TestGenerator(function* g2() { yield 1; },
+ [1, undefined],
+ "foo",
+ [1, undefined]);
+
+TestGenerator(function* g3() { yield 1; yield 2; },
+ [1, 2, undefined],
+ "foo",
+ [1, 2, undefined]);
+
+TestGenerator(function* g4() { yield 1; yield 2; return 3; },
+ [1, 2, 3],
+ "foo",
+ [1, 2, 3]);
+
+TestGenerator(function* g5() { return 1; },
+ [1],
+ "foo",
+ [1]);
+
+TestGenerator(function* g6() { var x = yield 1; return x; },
+ [1, undefined],
+ "foo",
+ [1, "foo"]);
+
+TestGenerator(function* g7() { var x = yield 1; yield 2; return x; },
+ [1, 2, undefined],
+ "foo",
+ [1, 2, "foo"]);
+
+TestGenerator(function* g8() { for (var x = 0; x < 4; x++) { yield x; } },
+ [0, 1, 2, 3, undefined],
+ "foo",
+ [0, 1, 2, 3, undefined]);
+
+// Generator with arguments.
+TestGenerator(
+ function g9() {
+ return (function*(a, b, c, d) {
+ yield a; yield b; yield c; yield d;
+ })("fee", "fi", "fo", "fum");
+ },
+ ["fee", "fi", "fo", "fum", undefined],
+ "foo",
+ ["fee", "fi", "fo", "fum", undefined]);
+
+// Too few arguments.
+TestGenerator(
+ function g10() {
+ return (function*(a, b, c, d) {
+ yield a; yield b; yield c; yield d;
+ })("fee", "fi");
+ },
+ ["fee", "fi", undefined, undefined, undefined],
+ "foo",
+ ["fee", "fi", undefined, undefined, undefined]);
+
+// Too many arguments.
+TestGenerator(
+ function g11() {
+ return (function*(a, b, c, d) {
+ yield a; yield b; yield c; yield d;
+ })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman");
+ },
+ ["fee", "fi", "fo", "fum", undefined],
+ "foo",
+ ["fee", "fi", "fo", "fum", undefined]);
+
+// The arguments object.
+TestGenerator(
+ function g12() {
+ return (function*(a, b, c, d) {
+ for (var i = 0; i < arguments.length; i++) {
+ yield arguments[i];
+ }
+ })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman");
+ },
+ ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman",
+ undefined],
+ "foo",
+ ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman",
+ undefined]);
+
+// Access to captured free variables.
+TestGenerator(
+ function g13() {
+ return (function(a, b, c, d) {
+ return (function*() {
+ yield a; yield b; yield c; yield d;
+ })();
+ })("fee", "fi", "fo", "fum");
+ },
+ ["fee", "fi", "fo", "fum", undefined],
+ "foo",
+ ["fee", "fi", "fo", "fum", undefined]);
+
+// Abusing the arguments object.
+TestGenerator(
+ function g14() {
+ return (function*(a, b, c, d) {
+ arguments[0] = "Be he live";
+ arguments[1] = "or be he dead";
+ arguments[2] = "I'll grind his bones";
+ arguments[3] = "to make my bread";
+ yield a; yield b; yield c; yield d;
+ })("fee", "fi", "fo", "fum");
+ },
+ ["Be he live", "or be he dead", "I'll grind his bones", "to make my
bread",
+ undefined],
+ "foo",
+ ["Be he live", "or be he dead", "I'll grind his bones", "to make my
bread",
+ undefined]);
+
+// Abusing the arguments object: strict mode.
+TestGenerator(
+ function g15() {
+ return (function*(a, b, c, d) {
+ "use strict";
+ arguments[0] = "Be he live";
+ arguments[1] = "or be he dead";
+ arguments[2] = "I'll grind his bones";
+ arguments[3] = "to make my bread";
+ yield a; yield b; yield c; yield d;
+ })("fee", "fi", "fo", "fum");
+ },
+ ["fee", "fi", "fo", "fum", undefined],
+ "foo",
+ ["fee", "fi", "fo", "fum", undefined]);
+
+// GC.
+TestGenerator(function* g16() { yield "baz"; gc(); yield "qux"; },
+ ["baz", "qux", undefined],
+ "foo",
+ ["baz", "qux", undefined]);
+
+// Receivers.
+TestGenerator(
+ function g17() {
+ function* g() { yield this.x; yield this.y; }
+ var o = { start: g, x: 1, y: 2 };
+ return o.start();
+ },
+ [1, 2, undefined],
+ "foo",
+ [1, 2, undefined]);
+
+TestGenerator(
+ function g18() {
+ function* g() { yield this.x; yield this.y; }
+ var iter = new g;
+ iter.x = 1;
+ iter.y = 2;
+ return iter;
+ },
+ [1, 2, undefined],
+ "foo",
+ [1, 2, undefined]);
+
+TestGenerator(
+ function* g19() {
+ var x = 1;
+ yield x;
+ with({x:2}) { yield x; }
+ yield x;
+ },
+ [1, 2, 1, undefined],
+ "foo",
+ [1, 2, 1, undefined]);
+
+TestGenerator(
+ function* g20() { yield (1 + (yield 2) + 3); },
+ [2, NaN, undefined],
+ "foo",
+ [2, "1foo3", undefined]);
+
+TestGenerator(
+ function* g21() { return (1 + (yield 2) + 3); },
+ [2, NaN],
+ "foo",
+ [2, "1foo3"]);
+
+TestGenerator(
+ function* g22() { yield (1 + (yield 2) + 3); yield (4 + (yield 5) +
6); },
+ [2, NaN, 5, NaN, undefined],
+ "foo",
+ [2, "1foo3", 5, "4foo6", undefined]);
+
+TestGenerator(
+ function* g23() {
+ return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6));
+ },
+ [2, NaN, 5, NaN, NaN],
+ "foo",
+ [2, "1foo3", 5, "4foo6", "foofoo"]);
+
+// Rewind a try context with and without operands on the stack.
+TestGenerator(
+ function* g24() {
+ try {
+ return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6));
+ } catch (e) {
+ throw e;
+ }
+ },
+ [2, NaN, 5, NaN, NaN],
+ "foo",
+ [2, "1foo3", 5, "4foo6", "foofoo"]);
+
+// Yielding in a catch context, with and without operands on the stack.
+TestGenerator(
+ function* g25() {
+ try {
+ throw (yield (1 + (yield 2) + 3))
+ } catch (e) {
+ if (typeof e == 'object') throw e;
+ return e + (yield (4 + (yield 5) + 6));
+ }
+ },
+ [2, NaN, 5, NaN, NaN],
+ "foo",
+ [2, "1foo3", 5, "4foo6", "foofoo"]);
+
+// Yield with no arguments yields undefined.
+TestGenerator(
+ function* g26() { return yield yield },
+ [undefined, undefined, undefined],
+ "foo",
+ [undefined, "foo", "foo"]);
+
+// A newline causes the parser to stop looking for an argument to yield.
+TestGenerator(
+ function* g27() {
+ yield
+ 3
+ return
+ },
+ [undefined, undefined],
+ "foo",
+ [undefined, undefined]);
+
+// TODO(wingo): We should use TestGenerator for these, except that
+// currently yield* will unconditionally propagate a throw() to the
+// delegate iterator, which fails for these iterators that don't have
+// throw(). See http://code.google.com/p/v8/issues/detail?id=3484.
+(function() {
+ function* g28() {
+ yield* [1, 2, 3];
+ }
+ var iter = g28();
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(undefined, true, iter.next());
+})();
+
+(function() {
+ function* g29() {
+ yield* "abc";
+ }
+ var iter = g29();
+ assertIteratorResult("a", false, iter.next());
+ assertIteratorResult("b", false, iter.next());
+ assertIteratorResult("c", false, iter.next());
+ assertIteratorResult(undefined, true, iter.next());
+})();
+
+// Generator function instances.
+TestGenerator(GeneratorFunction(),
+ [undefined],
+ "foo",
+ [undefined]);
+
+TestGenerator(new GeneratorFunction(),
+ [undefined],
+ "foo",
+ [undefined]);
+
+TestGenerator(GeneratorFunction('yield 1;'),
+ [1, undefined],
+ "foo",
+ [1, undefined]);
+
+TestGenerator(
+ function() { return GeneratorFunction('x', 'y', 'yield x + y;')(1, 2)
},
+ [3, undefined],
+ "foo",
+ [3, undefined]);
+
+// Access to this with formal arguments.
+TestGenerator(
+ function () {
+ return ({ x: 42, g: function* (a) { yield this.x } }).g(0);
+ },
+ [42, undefined],
+ "foo",
+ [42, undefined]);
+
+// Test that yield* re-yields received results without re-boxing.
+function TestDelegatingYield() {
+ function results(results) {
+ var i = 0;
+ function next() {
+ return results[i++];
+ }
+ var iter = { next: next };
+ var ret = {};
+ ret[Symbol.iterator] = function() { return iter; };
+ return ret;
+ }
+ function* yield_results(expected) {
+ return yield* results(expected);
+ }
+ function collect_results(iterable) {
+ var iter = iterable[Symbol.iterator]();
+ var ret = [];
+ var result;
+ do {
+ result = iter.next();
+ ret.push(result);
+ } while (!result.done);
+ return ret;
+ }
+ // We have to put a full result for the end, because the return will
re-box.
+ var expected = [{value: 1}, 13, "foo", {value: 34, done: true}];
+
+ // Sanity check.
+ assertEquals(expected, collect_results(results(expected)));
+ assertEquals(expected, collect_results(yield_results(expected)));
+}
+TestDelegatingYield();
+
+function TestTryCatch(instantiate) {
+ function* g() { yield 1; try { yield 2; } catch (e) { yield e; } yield
3; }
+ function Sentinel() {}
+
+ function Test1(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorIsClosed(iter);
+ }
+ Test1(instantiate(g));
+
+ function Test2(iter) {
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test2(instantiate(g));
+
+ function Test3(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test3(instantiate(g));
+
+ function Test4(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ var exn = new Sentinel;
+ assertIteratorResult(exn, false, iter.throw(exn));
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorIsClosed(iter);
+ }
+ Test4(instantiate(g));
+
+ function Test5(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ var exn = new Sentinel;
+ assertIteratorResult(exn, false, iter.throw(exn));
+ assertIteratorResult(3, false, iter.next());
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test5(instantiate(g));
+
+ function Test6(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ var exn = new Sentinel;
+ assertIteratorResult(exn, false, iter.throw(exn));
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test6(instantiate(g));
+
+ function Test7(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorIsClosed(iter);
+ }
+ Test7(instantiate(g));
+}
+TestTryCatch(function (g) { return g(); });
+TestTryCatch(function* (g) { return yield* g(); });
+
+function TestTryFinally(instantiate) {
+ function* g() { yield 1; try { yield 2; } finally { yield 3; } yield 4; }
+ function Sentinel() {}
+ function Sentinel2() {}
+
+ function Test1(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(4, false, iter.next());
+ assertIteratorIsClosed(iter);
+ }
+ Test1(instantiate(g));
+
+ function Test2(iter) {
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test2(instantiate(g));
+
+ function Test3(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test3(instantiate(g));
+
+ function Test4(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.throw(new Sentinel));
+ assertThrows(function() { iter.next(); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test4(instantiate(g));
+
+ function Test5(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.throw(new Sentinel));
+ assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test5(instantiate(g));
+
+ function Test6(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test6(instantiate(g));
+
+ function Test7(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(4, false, iter.next());
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test7(instantiate(g));
+
+ function Test8(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(4, false, iter.next());
+ assertIteratorIsClosed(iter);
+ }
+ Test8(instantiate(g));
+}
+TestTryFinally(function (g) { return g(); });
+TestTryFinally(function* (g) { return yield* g(); });
+
+function TestNestedTry(instantiate) {
+ function* g() {
+ try {
+ yield 1;
+ try { yield 2; } catch (e) { yield e; }
+ yield 3;
+ } finally {
+ yield 4;
+ }
+ yield 5;
+ }
+ function Sentinel() {}
+ function Sentinel2() {}
+
+ function Test1(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(4, false, iter.next());
+ assertIteratorResult(5, false, iter.next());
+ assertIteratorIsClosed(iter);
+ }
+ Test1(instantiate(g));
+
+ function Test2(iter) {
+ assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test2(instantiate(g));
+
+ function Test3(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(4, false, iter.throw(new Sentinel));
+ assertThrows(function() { iter.next(); }, Sentinel);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test3(instantiate(g));
+
+ function Test4(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(4, false, iter.throw(new Sentinel));
+ assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test4(instantiate(g));
+
+ function Test5(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ var exn = new Sentinel;
+ assertIteratorResult(exn, false, iter.throw(exn));
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(4, false, iter.next());
+ assertIteratorResult(5, false, iter.next());
+ assertIteratorIsClosed(iter);
+ }
+ Test5(instantiate(g));
+
+ function Test6(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ var exn = new Sentinel;
+ assertIteratorResult(exn, false, iter.throw(exn));
+ assertIteratorResult(4, false, iter.throw(new Sentinel2));
+ assertThrows(function() { iter.next(); }, Sentinel2);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test6(instantiate(g));
+
+ function Test7(iter) {
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ var exn = new Sentinel;
+ assertIteratorResult(exn, false, iter.throw(exn));
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(4, false, iter.throw(new Sentinel2));
+ assertThrows(function() { iter.next(); }, Sentinel2);
+ assertThrownIteratorIsClosed(iter);
+ }
+ Test7(instantiate(g));
+
+ // That's probably enough.
+}
+TestNestedTry(function (g) { return g(); });
+TestNestedTry(function* (g) { return yield* g(); });
+
+function TestRecursion() {
+ function TestNextRecursion() {
+ function* g() { yield iter.next(); }
+ var iter = g();
+ return iter.next();
+ }
+ function TestSendRecursion() {
+ function* g() { yield iter.next(42); }
+ var iter = g();
+ return iter.next();
+ }
+ function TestThrowRecursion() {
+ function* g() { yield iter.throw(1); }
+ var iter = g();
+ return iter.next();
+ }
+ assertThrows(TestNextRecursion, Error);
+ assertThrows(TestSendRecursion, Error);
+ assertThrows(TestThrowRecursion, Error);
+}
+TestRecursion();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/generators-objects.js Thu Aug
21 12:06:25 2014 UTC
@@ -0,0 +1,93 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-generators --harmony-scoping --allow-natives-syntax
+
+// Test instantations of generators.
+
+// Generators shouldn't allocate stack slots. This test will abort in
debug
+// mode if generators have stack slots.
+function TestContextAllocation() {
+ function* g1(a, b, c) { yield 1; return [a, b, c]; }
+ function* g2() { yield 1; return arguments; }
+ function* g3() { yield 1; return this; }
+ function* g4() { var x = 10; yield 1; return x; }
+ // Temporary variable context allocation
+ function* g5(l) { "use strict"; yield 1; for (let x in l) { yield x; } }
+
+ g1();
+ g2();
+ g3();
+ g4();
+ g5(["foo"]);
+}
+TestContextAllocation();
+
+
+// Test the properties and prototype of a generator object.
+function TestGeneratorObject() {
+ function* g() { yield 1; }
+
+ var iter = g();
+ assertSame(g.prototype, Object.getPrototypeOf(iter));
+ assertTrue(iter instanceof g);
+ assertEquals("Generator", %_ClassOf(iter));
+ assertEquals("[object Generator]", String(iter));
+ assertEquals([], Object.getOwnPropertyNames(iter));
+ assertTrue(iter !== g());
+
+ // g() is the same as new g().
+ iter = new g();
+ assertSame(g.prototype, Object.getPrototypeOf(iter));
+ assertTrue(iter instanceof g);
+ assertEquals("Generator", %_ClassOf(iter));
+ assertEquals("[object Generator]", String(iter));
+ assertEquals([], Object.getOwnPropertyNames(iter));
+ assertTrue(iter !== new g());
+}
+TestGeneratorObject();
+
+
+// Test the methods of generator objects.
+function TestGeneratorObjectMethods() {
+ function* g() { yield 1; }
+ var iter = g();
+
+ function TestNonGenerator(non_generator) {
+ assertThrows(function() { iter.next.call(non_generator); }, TypeError);
+ assertThrows(function() { iter.next.call(non_generator, 1); },
TypeError);
+ assertThrows(function() { iter.throw.call(non_generator, 1); },
TypeError);
+ assertThrows(function() { iter.close.call(non_generator); },
TypeError);
+ }
+
+ TestNonGenerator(1);
+ TestNonGenerator({});
+ TestNonGenerator(function(){});
+ TestNonGenerator(g);
+ TestNonGenerator(g.prototype);
+}
+TestGeneratorObjectMethods();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/generators-parsing.js Thu Aug
21 12:06:25 2014 UTC
@@ -0,0 +1,133 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-generators
+
+// Test basic generator syntax.
+
+// Yield statements.
+function* g() { yield 3; yield 4; }
+
+// Yield expressions.
+function* g() { (yield 3) + (yield 4); }
+
+// Yield without a RHS.
+function* g() { yield; }
+function* g() { yield }
+function* g() {
+ yield
+}
+function* g() { (yield) }
+function* g() { [yield] }
+function* g() { {yield} }
+function* g() { yield, yield }
+function* g() { yield; yield }
+function* g() { (yield) ? yield : yield }
+function* g() {
+ (yield)
+ ? yield
+ : yield
+}
+
+// If yield has a RHS, it needs to start on the same line. The * in a
+// yield* counts as starting the RHS.
+function* g() {
+ yield *
+ foo
+}
+assertThrows("function* g() { yield\n* foo }", SyntaxError);
+assertEquals(undefined,
+ (function*(){
+ yield
+ 3
+ })().next().value);
+
+// A YieldExpression is not a LogicalORExpression.
+assertThrows("function* g() { yield ? yield : yield }", SyntaxError);
+
+// You can have a generator in strict mode.
+function* g() { "use strict"; yield 3; yield 4; }
+
+// Generators can have return statements also, which internally parse to a
kind
+// of yield expression.
+function* g() { yield 1; return; }
+function* g() { yield 1; return 2; }
+function* g() { yield 1; return 2; yield "dead"; }
+
+// Generator expression.
+(function* () { yield 3; });
+
+// Named generator expression.
+(function* g() { yield 3; });
+
+// You can have a generator without a yield.
+function* g() { }
+
+// A YieldExpression is valid as the RHS of a YieldExpression.
+function* g() { yield yield 1; }
+function* g() { yield 3 + (yield 4); }
+
+// Generator definitions with a name of "yield" are not specifically ruled
out
+// by the spec, as the `yield' name is outside the generator itself.
However,
+// in strict-mode, "yield" is an invalid identifier.
+function* yield() { (yield 3) + (yield 4); }
+assertThrows("function* yield() { \"use strict\"; (yield 3) + (yield 4);
}",
+ SyntaxError);
+
+// In sloppy mode, yield is a normal identifier, outside of generators.
+function yield(yield) { yield: yield (yield + yield (0)); }
+
+// Yield is always valid as a key in an object literal.
+({ yield: 1 });
+function* g() { yield ({ yield: 1 }) }
+function* g() { yield ({ get yield() { return 1; }}) }
+
+// Checks that yield is a valid label in sloppy mode, but not valid in a
strict
+// mode or in generators.
+function f() { yield: 1 }
+assertThrows("function f() { \"use strict\"; yield: 1 }", SyntaxError)
+assertThrows("function* g() { yield: 1 }", SyntaxError)
+
+// Yield is only a keyword in the body of the generator, not in nested
+// functions.
+function* g() { function f() { yield (yield + yield (0)); } }
+
+// Yield in a generator is not an identifier.
+assertThrows("function* g() { yield = 10; }", SyntaxError);
+
+// Yield binds very loosely, so this parses as "yield (3 + yield 4)",
which is
+// invalid.
+assertThrows("function* g() { yield 3 + yield 4; }", SyntaxError);
+
+// Yield is still a future-reserved-word in strict mode
+assertThrows("function f() { \"use strict\"; var yield = 13; }",
SyntaxError);
+
+// The name of the NFE is let-bound in G, so is invalid.
+assertThrows("function* g() { yield (function yield() {}); }",
SyntaxError);
+
+// In generators, yield is invalid as a formal argument name.
+assertThrows("function* g(yield) { yield (10); }", SyntaxError);
=======================================
--- /dev/null
+++
/branches/bleeding_edge/test/mjsunit/es6/generators-poisoned-properties.js
Thu Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-generators
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({value: value, done: done}, result);
+}
+
+function test(f) {
+ var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
+ var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
+
+ assertFalse(cdesc.enumerable);
+ assertFalse(cdesc.configurable);
+
+ assertFalse(adesc.enumerable);
+ assertFalse(adesc.configurable);
+
+ assertSame(cdesc.get, cdesc.set);
+ assertSame(cdesc.get, adesc.get);
+ assertSame(cdesc.get, adesc.set);
+
+ assertTrue(cdesc.get instanceof Function);
+ assertEquals(0, cdesc.get.length);
+ assertThrows(cdesc.get, TypeError);
+
+ assertThrows(function() { return f.caller; }, TypeError);
+ assertThrows(function() { f.caller = 42; }, TypeError);
+ assertThrows(function() { return f.arguments; }, TypeError);
+ assertThrows(function() { f.arguments = 42; }, TypeError);
+}
+
+function *sloppy() { test(sloppy); }
+function *strict() { "use strict"; test(strict); }
+
+test(sloppy);
+test(strict);
+
+assertIteratorResult(undefined, true, sloppy().next());
+assertIteratorResult(undefined, true, strict().next());
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/generators-relocation.js Thu
Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,61 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-generators
+
+var Debug = debug.Debug;
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({value: value, done: done}, result);
+}
+
+function RunTest(formals_and_body, args, value1, value2) {
+ // A null listener. It isn't important what the listener does.
+ function listener(event, exec_state, event_data, data) {
+ }
+
+ // Create the generator function outside a debugging context. It will
probably
+ // be lazily compiled.
+ var gen = (function*(){}).constructor.apply(null, formals_and_body);
+
+ // Instantiate the generator object.
+ var obj = gen.apply(null, args);
+
+ // Advance to the first yield.
+ assertIteratorResult(value1, false, obj.next());
+
+ // Add a breakpoint on line 3 (the second yield).
+ var bp = Debug.setBreakPoint(gen, 3);
+
+ // Enable the debugger, which should force recompilation of the generator
+ // function and relocation of the suspended generator activation.
+ Debug.setListener(listener);
+
+ // Check that the generator resumes and suspends properly.
+ assertIteratorResult(value2, false, obj.next());
+
+ // Disable debugger -- should not force recompilation.
+ Debug.clearBreakPoint(bp);
+ Debug.setListener(null);
+
+ // Run to completion.
+ assertIteratorResult(undefined, true, obj.next());
+}
+
+function prog(a, b, c) {
+ return a + ';\n' + 'yield ' + b + ';\n' + 'yield ' + c;
+}
+
+// Simple empty local scope.
+RunTest([prog('', '1', '2')], [], 1, 2);
+
+RunTest([prog('for (;;) break', '1', '2')], [], 1, 2);
+
+RunTest([prog('while (0) foo()', '1', '2')], [], 1, 2);
+
+RunTest(['a', prog('var x = 3', 'a', 'x')], [1], 1, 3);
+
+RunTest(['a', prog('', '1', '2')], [42], 1, 2);
+
+RunTest(['a', prog('for (;;) break', '1', '2')], [42], 1, 2);
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/generators-runtime.js Thu Aug
21 12:06:25 2014 UTC
@@ -0,0 +1,148 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-generators
+
+// Test aspects of the generator runtime.
+
+// See:
+//
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunction-objects
+
+function f() { }
+function* g() { yield 1; }
+var GeneratorFunctionPrototype = Object.getPrototypeOf(g);
+var GeneratorFunction = GeneratorFunctionPrototype.constructor;
+var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
+
+// A generator function should have the same set of properties as any
+// other function.
+function TestGeneratorFunctionInstance() {
+ var f_own_property_names = Object.getOwnPropertyNames(f);
+ var g_own_property_names = Object.getOwnPropertyNames(g);
+
+ f_own_property_names.sort();
+ g_own_property_names.sort();
+
+ assertArrayEquals(f_own_property_names, g_own_property_names);
+ var i;
+ for (i = 0; i < f_own_property_names.length; i++) {
+ var prop = f_own_property_names[i];
+ var f_desc = Object.getOwnPropertyDescriptor(f, prop);
+ var g_desc = Object.getOwnPropertyDescriptor(g, prop);
+ assertEquals(f_desc.configurable, g_desc.configurable, prop);
+ if (prop === 'arguments' || prop === 'caller') {
+ // Unlike sloppy functions, which have read-only data arguments and
caller
+ // properties, sloppy generators have a poison pill implemented via
+ // accessors
+ assertFalse('writable' in g_desc, prop);
+ assertTrue(g_desc.get instanceof Function, prop);
+ assertEquals(g_desc.get, g_desc.set, prop);
+ } else {
+ assertEquals(f_desc.writable, g_desc.writable, prop);
+ }
+ assertEquals(f_desc.enumerable, g_desc.enumerable, prop);
+ }
+}
+TestGeneratorFunctionInstance();
+
+
+// Generators have an additional object interposed in the chain between
+// themselves and Function.prototype.
+function TestGeneratorFunctionPrototype() {
+ // Sanity check.
+ assertSame(Object.getPrototypeOf(f), Function.prototype);
+ assertFalse(GeneratorFunctionPrototype === Function.prototype);
+ assertSame(Function.prototype,
+ Object.getPrototypeOf(GeneratorFunctionPrototype));
+ assertSame(GeneratorFunctionPrototype,
+ Object.getPrototypeOf(function* () {}));
+}
+TestGeneratorFunctionPrototype();
+
+
+// Functions that we associate with generator objects are actually defined
by
+// a common prototype.
+function TestGeneratorObjectPrototype() {
+ assertSame(Object.prototype,
+ Object.getPrototypeOf(GeneratorObjectPrototype));
+ assertSame(GeneratorObjectPrototype,
+ Object.getPrototypeOf((function*(){yield 1}).prototype));
+
+ var expected_property_names = ["next", "throw", "constructor"];
+ var found_property_names =
+ Object.getOwnPropertyNames(GeneratorObjectPrototype);
+
+ expected_property_names.sort();
+ found_property_names.sort();
+
+ assertArrayEquals(expected_property_names, found_property_names);
+
+ iterator_desc = Object.getOwnPropertyDescriptor(GeneratorObjectPrototype,
+ Symbol.iterator);
+ assertTrue(iterator_desc !== undefined);
+ assertFalse(iterator_desc.writable);
+ assertFalse(iterator_desc.enumerable);
+ assertFalse(iterator_desc.configurable);
+
+ // The generator object's "iterator" function is just the identity.
+ assertSame(iterator_desc.value.call(42), 42);
+}
+TestGeneratorObjectPrototype();
+
+
+// This tests the object that would be called "GeneratorFunction", if it
were
+// like "Function".
+function TestGeneratorFunction() {
+ assertSame(GeneratorFunctionPrototype, GeneratorFunction.prototype);
+ assertTrue(g instanceof GeneratorFunction);
+
+ assertSame(Function, Object.getPrototypeOf(GeneratorFunction));
+ assertTrue(g instanceof Function);
+
+ assertEquals("function* g() { yield 1; }", g.toString());
+
+ // Not all functions are generators.
+ assertTrue(f instanceof Function); // Sanity check.
+ assertTrue(!(f instanceof GeneratorFunction));
+
+ assertTrue((new GeneratorFunction()) instanceof GeneratorFunction);
+ assertTrue(GeneratorFunction() instanceof GeneratorFunction);
+}
+TestGeneratorFunction();
+
+
+function TestPerGeneratorPrototype() {
+ assertTrue((function*(){}).prototype !== (function*(){}).prototype);
+ assertTrue((function*(){}).prototype !== g.prototype);
+ assertTrue(g.prototype instanceof GeneratorFunctionPrototype);
+ assertSame(GeneratorObjectPrototype, Object.getPrototypeOf(g.prototype));
+ assertTrue(!(g.prototype instanceof Function));
+ assertSame(typeof (g.prototype), "object");
+
+ assertArrayEquals([], Object.getOwnPropertyNames(g.prototype));
+}
+TestPerGeneratorPrototype();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/regress/regress-2681.js Thu
Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,48 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-gc --noincremental-marking --harmony-generators
+
+// Check that we are not flushing code for generators.
+
+function flush_all_code() {
+ // Each GC ages code, and currently 6 gcs will flush all code.
+ for (var i = 0; i < 10; i++) gc();
+}
+
+function* g() {
+ yield 1;
+ yield 2;
+}
+
+var o = g();
+assertEquals({ value: 1, done: false }, o.next());
+
+flush_all_code();
+
+assertEquals({ value: 2, done: false }, o.next());
+assertEquals({ value: undefined, done: true }, o.next());
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/regress/regress-2691.js Thu
Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,34 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-generators
+
+// Check that yield* on non-objects raises a TypeError.
+
+assertThrows('(function*() { yield* 10 })().next()', TypeError);
+assertThrows('(function*() { yield* {} })().next()', TypeError);
+assertThrows('(function*() { yield* undefined })().next()', TypeError);
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/es6/regress/regress-3280.js Thu
Aug 21 12:06:25 2014 UTC
@@ -0,0 +1,25 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-generators --expose-debug-as debug
+
+var Debug = debug.Debug;
+
+var listener_called;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ listener_called = true;
+ exec_state.frame().allScopes();
+ }
+}
+
+Debug.setListener(listener);
+
+function *generator_local_2(a) {
+ debugger;
+}
+generator_local_2(1).next();
+
+assertTrue(listener_called, "listener not called");
=======================================
---
/branches/bleeding_edge/test/mjsunit/harmony/generators-debug-liveedit.js
Thu May 22 07:32:59 2014 UTC
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --expose-debug-as debug --harmony-generators
-
-var Debug = debug.Debug;
-var LiveEdit = Debug.LiveEdit;
-
-unique_id = 0;
-
-var Generator = (function*(){}).constructor;
-
-function assertIteratorResult(value, done, result) {
- assertEquals({value: value, done: done}, result);
-}
-
-function MakeGenerator() {
- // Prevents eval script caching.
- unique_id++;
- return Generator('callback',
- "/* " + unique_id + "*/\n" +
- "yield callback();\n" +
- "return 'Cat';\n");
-}
-
-function MakeFunction() {
- // Prevents eval script caching.
- unique_id++;
- return Function('callback',
- "/* " + unique_id + "*/\n" +
- "callback();\n" +
- "return 'Cat';\n");
-}
-
-// First, try MakeGenerator with no perturbations.
-(function(){
- var generator = MakeGenerator();
- function callback() {};
- var iter = generator(callback);
- assertIteratorResult(undefined, false, iter.next());
- assertIteratorResult("Cat", true, iter.next());
-})();
-
-function patch(fun, from, to) {
- function debug() {
- var log = new Array();
- var script = Debug.findScript(fun);
- var pos = script.source.indexOf(from);
- try {
- LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
- log);
- } finally {
- print("Change log: " + JSON.stringify(log) + "\n");
- }
- }
- Debug.ExecuteInDebugContext(debug, false);
-}
-
-// Try to edit a MakeGenerator while it's running, then again while it's
-// stopped.
-(function(){
- var generator = MakeGenerator();
-
- var gen_patch_attempted = false;
- function attempt_gen_patch() {
- assertFalse(gen_patch_attempted);
- gen_patch_attempted = true;
- assertThrows(function() { patch(generator, "'Cat'", "'Capybara'") },
- LiveEdit.Failure);
- };
- var iter = generator(attempt_gen_patch);
- assertIteratorResult(undefined, false, iter.next());
- // Patch should not succeed because there is a live generator activation
on
- // the stack.
- assertIteratorResult("Cat", true, iter.next());
- assertTrue(gen_patch_attempted);
-
- // At this point one iterator is live, but closed, so the patch will
succeed.
- patch(generator, "'Cat'", "'Capybara'");
- iter = generator(function(){});
- assertIteratorResult(undefined, false, iter.next());
- // Patch successful.
- assertIteratorResult("Capybara", true, iter.next());
-
- // Patching will fail however when a live iterator is suspended.
- iter = generator(function(){});
- assertIteratorResult(undefined, false, iter.next());
- assertThrows(function() { patch(generator, "'Capybara'", "'Tapir'") },
- LiveEdit.Failure);
- assertIteratorResult("Capybara", true, iter.next());
-
- // Try to patch functions with activations inside and outside generator
- // function activations. We should succeed in the former case, but not
in the
- // latter.
- var fun_outside = MakeFunction();
- var fun_inside = MakeFunction();
- var fun_patch_attempted = false;
- var fun_patch_restarted = false;
- function attempt_fun_patches() {
- if (fun_patch_attempted) {
- assertFalse(fun_patch_restarted);
- fun_patch_restarted = true;
- return;
- }
- fun_patch_attempted = true;
- // Patching outside a generator activation must fail.
- assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
- LiveEdit.Failure);
- // Patching inside a generator activation may succeed.
- patch(fun_inside, "'Cat'", "'Koala'");
- }
- iter = generator(function() { return fun_inside(attempt_fun_patches) });
- assertEquals('Cat',
- fun_outside(function () {
- assertIteratorResult('Koala', false, iter.next());
- assertTrue(fun_patch_restarted);
- }));
-})();
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-debug-scopes.js
Fri Apr 25 09:35:41 2014 UTC
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --expose-debug-as debug --harmony-generators
-
-var Debug = debug.Debug;
-
-function RunTest(name, formals_and_body, args, handler, continuation) {
- var handler_called = false;
- var exception = null;
-
- function listener(event, exec_state, event_data, data) {
- try {
- if (event == Debug.DebugEvent.Break) {
- handler_called = true;
- handler(exec_state);
- }
- } catch (e) {
- exception = e;
- }
- }
-
- function run(thunk) {
- handler_called = false;
- exception = null;
-
- var res = thunk();
- if (continuation)
- continuation(res);
-
- assertTrue(handler_called, "listener not called for " + name);
- assertNull(exception, name + " / " + exception);
- }
-
- var fun = Function.apply(null, formals_and_body);
- var gen = (function*(){}).constructor.apply(null, formals_and_body);
-
- Debug.setListener(listener);
-
- run(function () { return fun.apply(null, args) });
- run(function () { return gen.apply(null, args).next().value });
-
- // TODO(wingo): Uncomment after bug 2838 is fixed.
- // Debug.setListener(null);
-}
-
-// Check that two scope are the same.
-function assertScopeMirrorEquals(scope1, scope2) {
- assertEquals(scope1.scopeType(), scope2.scopeType());
- assertEquals(scope1.frameIndex(), scope2.frameIndex());
- assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
- assertPropertiesEqual(scope1.scopeObject().value(),
scope2.scopeObject().value());
-}
-
-function CheckFastAllScopes(scopes, exec_state) {
- var fast_all_scopes = exec_state.frame().allScopes(true);
- var length = fast_all_scopes.length;
- assertTrue(scopes.length >= length);
- for (var i = 0; i < scopes.length && i < length; i++) {
- var scope = fast_all_scopes[length - i - 1];
- assertTrue(scope.isScope());
- assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
- }
-}
-
-// Check that the scope chain contains the expected types of scopes.
-function CheckScopeChain(scopes, exec_state) {
- var all_scopes = exec_state.frame().allScopes();
- assertEquals(scopes.length, exec_state.frame().scopeCount());
- assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes
length");
- for (var i = 0; i < scopes.length; i++) {
- var scope = exec_state.frame().scope(i);
- assertTrue(scope.isScope());
- assertEquals(scopes[i], scope.scopeType());
- assertScopeMirrorEquals(all_scopes[i], scope);
-
- // Check the global object when hitting the global scope.
- if (scopes[i] == debug.ScopeType.Global) {
- // Objects don't have same class (one is "global", other is "Object",
- // so just check the properties directly.
- assertPropertiesEqual(this, scope.scopeObject().value());
- }
- }
- CheckFastAllScopes(scopes, exec_state);
-
- // Get the debug command processor.
- var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
-
- // Send a scopes request and check the result.
- var json;
- var request_json = '{"seq":0,"type":"request","command":"scopes"}';
- var response_json = dcp.processDebugJSONRequest(request_json);
- var response = JSON.parse(response_json);
- assertEquals(scopes.length, response.body.scopes.length);
- for (var i = 0; i < scopes.length; i++) {
- assertEquals(i, response.body.scopes[i].index);
- assertEquals(scopes[i], response.body.scopes[i].type);
- if (scopes[i] == debug.ScopeType.Local ||
- scopes[i] == debug.ScopeType.Closure) {
- assertTrue(response.body.scopes[i].object.ref < 0);
- } else {
- assertTrue(response.body.scopes[i].object.ref >= 0);
- }
- var found = false;
- for (var j = 0; j < response.refs.length && !found; j++) {
- found = response.refs[j].handle ==
response.body.scopes[i].object.ref;
- }
- assertTrue(found, "Scope object " + response.body.scopes[i].object.ref
+ " not found");
- }
-}
-
-// Check that the content of the scope is as expected. For functions just
check
-// that there is a function.
-function CheckScopeContent(content, number, exec_state) {
- var scope = exec_state.frame().scope(number);
- var count = 0;
- for (var p in content) {
- var property_mirror = scope.scopeObject().property(p);
- assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not
found in scope');
- if (typeof(content[p]) === 'function') {
- assertTrue(property_mirror.value().isFunction());
- } else {
- assertEquals(content[p],
property_mirror.value().value(), 'property ' + p + ' has unexpected value');
- }
- count++;
- }
-
- // 'arguments' and might be exposed in the local and closure scope. Just
- // ignore this.
- var scope_size = scope.scopeObject().properties().length;
- if (!scope.scopeObject().property('arguments').isUndefined()) {
- scope_size--;
- }
- // Skip property with empty name.
- if (!scope.scopeObject().property('').isUndefined()) {
- scope_size--;
- }
-
- if (count != scope_size) {
- print('Names found in scope:');
- var names = scope.scopeObject().propertyNames();
- for (var i = 0; i < names.length; i++) {
- print(names[i]);
- }
- }
- assertEquals(count, scope_size);
-
- // Get the debug command processor.
- var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
-
- // Send a scope request for information on a single scope and check the
- // result.
- var request_json
= '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
- request_json += scope.scopeIndex();
- request_json += '}}';
- var response_json = dcp.processDebugJSONRequest(request_json);
- var response = JSON.parse(response_json);
- assertEquals(scope.scopeType(), response.body.type);
- assertEquals(number, response.body.index);
- if (scope.scopeType() == debug.ScopeType.Local ||
- scope.scopeType() == debug.ScopeType.Closure) {
- assertTrue(response.body.object.ref < 0);
- } else {
- assertTrue(response.body.object.ref >= 0);
- }
- var found = false;
- for (var i = 0; i < response.refs.length && !found; i++) {
- found = response.refs[i].handle == response.body.object.ref;
- }
- assertTrue(found, "Scope object " + response.body.object.ref + " not
found");
-}
-
-
-// Simple empty local scope.
-RunTest("Local 1",
- ['debugger;'],
- [],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({}, 0, exec_state);
- });
-
-// Local scope with a parameter.
-RunTest("Local 2",
- ['a', 'debugger;'],
- [1],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:1}, 0, exec_state);
- });
-
-// Local scope with a parameter and a local variable.
-RunTest("Local 3",
- ['a', 'var x = 3; debugger;'],
- [1],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:1,x:3}, 0, exec_state);
- });
-
-// Local scope with parameters and local variables.
-RunTest("Local 4",
- ['a', 'b', 'var x = 3; var y = 4; debugger;'],
- [1, 2],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
- });
-
-// Empty local scope with use of eval.
-RunTest("Local 5",
- ['eval(""); debugger;'],
- [],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({}, 0, exec_state);
- });
-
-// Local introducing local variable using eval.
-RunTest("Local 6",
- ['eval("var i = 5"); debugger;'],
- [],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({i:5}, 0, exec_state);
- });
-
-// Local scope with parameters, local variables and local variable
introduced
-// using eval.
-RunTest("Local 7",
- ['a', 'b',
- "var x = 3; var y = 4;\n"
- + "eval('var i = 5'); eval ('var j = 6');\n"
- + "debugger;"],
- [1, 2],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
- });
-
-// Nested empty with blocks.
-RunTest("With",
- ["with ({}) { with ({}) { debugger; } }"],
- [],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.With,
- debug.ScopeType.With,
- debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({}, 0, exec_state);
- CheckScopeContent({}, 1, exec_state);
- });
-
-// Simple closure formed by returning an inner function referering the
outer
-// functions arguments.
-RunTest("Closure 1",
- ['a', 'return function() { debugger; return a; }'],
- [1],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Closure,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:1}, 1, exec_state);
- },
- function (result) { result() });
-
-RunTest("The full monty",
- ['a', 'b',
- "var x = 3;\n" +
- "var y = 4;\n" +
- "eval('var i = 5');\n" +
- "eval('var j = 6');\n" +
- "function f(a, b) {\n" +
- " var x = 9;\n" +
- " var y = 10;\n" +
- " eval('var i = 11');\n" +
- " eval('var j = 12');\n" +
- " with ({j:13}){\n" +
- " return function() {\n" +
- " var x = 14;\n" +
- " with ({a:15}) {\n" +
- " with ({b:16}) {\n" +
- " debugger;\n" +
- " some_global = a;\n" +
- " return f;\n" +
- " }\n" +
- " }\n" +
- " };\n" +
- " }\n" +
- "}\n" +
- "return f(a, b);"],
- [1, 2],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.With,
- debug.ScopeType.With,
- debug.ScopeType.Local,
- debug.ScopeType.With,
- debug.ScopeType.Closure,
- debug.ScopeType.Closure,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({b:16}, 0, exec_state);
- CheckScopeContent({a:15}, 1, exec_state);
- CheckScopeContent({x:14}, 2, exec_state);
- CheckScopeContent({j:13}, 3, exec_state);
- CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
- CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5,
exec_state);
- },
- function (result) { result() });
-
-RunTest("Catch block 1",
- ["try { throw 'Exception'; } catch (e) { debugger; }"],
- [],
- function (exec_state) {
- CheckScopeChain([debug.ScopeType.Catch,
- debug.ScopeType.Local,
- debug.ScopeType.Global], exec_state);
- CheckScopeContent({e:'Exception'}, 0, exec_state);
- });
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-iteration.js
Thu Aug 7 16:42:14 2014 UTC
+++ /dev/null
@@ -1,698 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-generators --expose-gc
-
-// Test generator iteration.
-
-var GeneratorFunction = (function*(){yield 1;}).__proto__.constructor;
-
-function assertIteratorResult(value, done, result) {
- assertEquals({ value: value, done: done}, result);
-}
-
-function assertIteratorIsClosed(iter) {
- assertIteratorResult(undefined, true, iter.next());
- assertDoesNotThrow(function() { iter.next(); });
-}
-
-function assertThrownIteratorIsClosed(iter) {
- // TODO(yusukesuzuki): Since status of a thrown generator is "executing",
- // following tests are failed.
- // https://code.google.com/p/v8/issues/detail?id=3096
- // assertIteratorIsClosed(iter);
-}
-
-function TestGeneratorResultPrototype() {
- function* g() { yield 1; }
- var iter = g();
- var result = iter.next();
-
- assertSame(Object.prototype, Object.getPrototypeOf(result));
- property_names = Object.getOwnPropertyNames(result);
- property_names.sort();
- assertEquals(["done", "value"], property_names);
- assertIteratorResult(1, false, result);
-}
-TestGeneratorResultPrototype()
-
-function TestGenerator(g, expected_values_for_next,
- send_val, expected_values_for_send) {
- function testNext(thunk) {
- var iter = thunk();
- for (var i = 0; i < expected_values_for_next.length; i++) {
- var v1 = expected_values_for_next[i];
- var v2 = i == expected_values_for_next.length - 1;
- // var v3 = iter.next();
- assertIteratorResult(v1, v2, iter.next());
- }
- assertIteratorIsClosed(iter);
- }
- function testSend(thunk) {
- var iter = thunk();
- for (var i = 0; i < expected_values_for_send.length; i++) {
- assertIteratorResult(expected_values_for_send[i],
- i == expected_values_for_send.length - 1,
- iter.next(send_val));
- }
- assertIteratorIsClosed(iter);
- }
- function testThrow(thunk) {
- for (var i = 0; i < expected_values_for_next.length; i++) {
- var iter = thunk();
- for (var j = 0; j < i; j++) {
- assertIteratorResult(expected_values_for_next[j],
- j == expected_values_for_next.length - 1,
- iter.next());
- }
- function Sentinel() {}
- assertThrows(function () { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- }
-
- testNext(g);
- testSend(g);
- testThrow(g);
-
- testNext(function*() { return yield* g(); });
- testSend(function*() { return yield* g(); });
- testThrow(function*() { return yield* g(); });
-
- if (g instanceof GeneratorFunction) {
- testNext(function() { return new g(); });
- testSend(function() { return new g(); });
- testThrow(function() { return new g(); });
- }
-}
-
-TestGenerator(function* g1() { },
- [undefined],
- "foo",
- [undefined]);
-
-TestGenerator(function* g2() { yield 1; },
- [1, undefined],
- "foo",
- [1, undefined]);
-
-TestGenerator(function* g3() { yield 1; yield 2; },
- [1, 2, undefined],
- "foo",
- [1, 2, undefined]);
-
-TestGenerator(function* g4() { yield 1; yield 2; return 3; },
- [1, 2, 3],
- "foo",
- [1, 2, 3]);
-
-TestGenerator(function* g5() { return 1; },
- [1],
- "foo",
- [1]);
-
-TestGenerator(function* g6() { var x = yield 1; return x; },
- [1, undefined],
- "foo",
- [1, "foo"]);
-
-TestGenerator(function* g7() { var x = yield 1; yield 2; return x; },
- [1, 2, undefined],
- "foo",
- [1, 2, "foo"]);
-
-TestGenerator(function* g8() { for (var x = 0; x < 4; x++) { yield x; } },
- [0, 1, 2, 3, undefined],
- "foo",
- [0, 1, 2, 3, undefined]);
-
-// Generator with arguments.
-TestGenerator(
- function g9() {
- return (function*(a, b, c, d) {
- yield a; yield b; yield c; yield d;
- })("fee", "fi", "fo", "fum");
- },
- ["fee", "fi", "fo", "fum", undefined],
- "foo",
- ["fee", "fi", "fo", "fum", undefined]);
-
-// Too few arguments.
-TestGenerator(
- function g10() {
- return (function*(a, b, c, d) {
- yield a; yield b; yield c; yield d;
- })("fee", "fi");
- },
- ["fee", "fi", undefined, undefined, undefined],
- "foo",
- ["fee", "fi", undefined, undefined, undefined]);
-
-// Too many arguments.
-TestGenerator(
- function g11() {
- return (function*(a, b, c, d) {
- yield a; yield b; yield c; yield d;
- })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman");
- },
- ["fee", "fi", "fo", "fum", undefined],
- "foo",
- ["fee", "fi", "fo", "fum", undefined]);
-
-// The arguments object.
-TestGenerator(
- function g12() {
- return (function*(a, b, c, d) {
- for (var i = 0; i < arguments.length; i++) {
- yield arguments[i];
- }
- })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman");
- },
- ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman",
- undefined],
- "foo",
- ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman",
- undefined]);
-
-// Access to captured free variables.
-TestGenerator(
- function g13() {
- return (function(a, b, c, d) {
- return (function*() {
- yield a; yield b; yield c; yield d;
- })();
- })("fee", "fi", "fo", "fum");
- },
- ["fee", "fi", "fo", "fum", undefined],
- "foo",
- ["fee", "fi", "fo", "fum", undefined]);
-
-// Abusing the arguments object.
-TestGenerator(
- function g14() {
- return (function*(a, b, c, d) {
- arguments[0] = "Be he live";
- arguments[1] = "or be he dead";
- arguments[2] = "I'll grind his bones";
- arguments[3] = "to make my bread";
- yield a; yield b; yield c; yield d;
- })("fee", "fi", "fo", "fum");
- },
- ["Be he live", "or be he dead", "I'll grind his bones", "to make my
bread",
- undefined],
- "foo",
- ["Be he live", "or be he dead", "I'll grind his bones", "to make my
bread",
- undefined]);
-
-// Abusing the arguments object: strict mode.
-TestGenerator(
- function g15() {
- return (function*(a, b, c, d) {
- "use strict";
- arguments[0] = "Be he live";
- arguments[1] = "or be he dead";
- arguments[2] = "I'll grind his bones";
- arguments[3] = "to make my bread";
- yield a; yield b; yield c; yield d;
- })("fee", "fi", "fo", "fum");
- },
- ["fee", "fi", "fo", "fum", undefined],
- "foo",
- ["fee", "fi", "fo", "fum", undefined]);
-
-// GC.
-TestGenerator(function* g16() { yield "baz"; gc(); yield "qux"; },
- ["baz", "qux", undefined],
- "foo",
- ["baz", "qux", undefined]);
-
-// Receivers.
-TestGenerator(
- function g17() {
- function* g() { yield this.x; yield this.y; }
- var o = { start: g, x: 1, y: 2 };
- return o.start();
- },
- [1, 2, undefined],
- "foo",
- [1, 2, undefined]);
-
-TestGenerator(
- function g18() {
- function* g() { yield this.x; yield this.y; }
- var iter = new g;
- iter.x = 1;
- iter.y = 2;
- return iter;
- },
- [1, 2, undefined],
- "foo",
- [1, 2, undefined]);
-
-TestGenerator(
- function* g19() {
- var x = 1;
- yield x;
- with({x:2}) { yield x; }
- yield x;
- },
- [1, 2, 1, undefined],
- "foo",
- [1, 2, 1, undefined]);
-
-TestGenerator(
- function* g20() { yield (1 + (yield 2) + 3); },
- [2, NaN, undefined],
- "foo",
- [2, "1foo3", undefined]);
-
-TestGenerator(
- function* g21() { return (1 + (yield 2) + 3); },
- [2, NaN],
- "foo",
- [2, "1foo3"]);
-
-TestGenerator(
- function* g22() { yield (1 + (yield 2) + 3); yield (4 + (yield 5) +
6); },
- [2, NaN, 5, NaN, undefined],
- "foo",
- [2, "1foo3", 5, "4foo6", undefined]);
-
-TestGenerator(
- function* g23() {
- return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6));
- },
- [2, NaN, 5, NaN, NaN],
- "foo",
- [2, "1foo3", 5, "4foo6", "foofoo"]);
-
-// Rewind a try context with and without operands on the stack.
-TestGenerator(
- function* g24() {
- try {
- return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6));
- } catch (e) {
- throw e;
- }
- },
- [2, NaN, 5, NaN, NaN],
- "foo",
- [2, "1foo3", 5, "4foo6", "foofoo"]);
-
-// Yielding in a catch context, with and without operands on the stack.
-TestGenerator(
- function* g25() {
- try {
- throw (yield (1 + (yield 2) + 3))
- } catch (e) {
- if (typeof e == 'object') throw e;
- return e + (yield (4 + (yield 5) + 6));
- }
- },
- [2, NaN, 5, NaN, NaN],
- "foo",
- [2, "1foo3", 5, "4foo6", "foofoo"]);
-
-// Yield with no arguments yields undefined.
-TestGenerator(
- function* g26() { return yield yield },
- [undefined, undefined, undefined],
- "foo",
- [undefined, "foo", "foo"]);
-
-// A newline causes the parser to stop looking for an argument to yield.
-TestGenerator(
- function* g27() {
- yield
- 3
- return
- },
- [undefined, undefined],
- "foo",
- [undefined, undefined]);
-
-// TODO(wingo): We should use TestGenerator for these, except that
-// currently yield* will unconditionally propagate a throw() to the
-// delegate iterator, which fails for these iterators that don't have
-// throw(). See http://code.google.com/p/v8/issues/detail?id=3484.
-(function() {
- function* g28() {
- yield* [1, 2, 3];
- }
- var iter = g28();
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertIteratorResult(undefined, true, iter.next());
-})();
-
-(function() {
- function* g29() {
- yield* "abc";
- }
- var iter = g29();
- assertIteratorResult("a", false, iter.next());
- assertIteratorResult("b", false, iter.next());
- assertIteratorResult("c", false, iter.next());
- assertIteratorResult(undefined, true, iter.next());
-})();
-
-// Generator function instances.
-TestGenerator(GeneratorFunction(),
- [undefined],
- "foo",
- [undefined]);
-
-TestGenerator(new GeneratorFunction(),
- [undefined],
- "foo",
- [undefined]);
-
-TestGenerator(GeneratorFunction('yield 1;'),
- [1, undefined],
- "foo",
- [1, undefined]);
-
-TestGenerator(
- function() { return GeneratorFunction('x', 'y', 'yield x + y;')(1, 2)
},
- [3, undefined],
- "foo",
- [3, undefined]);
-
-// Access to this with formal arguments.
-TestGenerator(
- function () {
- return ({ x: 42, g: function* (a) { yield this.x } }).g(0);
- },
- [42, undefined],
- "foo",
- [42, undefined]);
-
-// Test that yield* re-yields received results without re-boxing.
-function TestDelegatingYield() {
- function results(results) {
- var i = 0;
- function next() {
- return results[i++];
- }
- var iter = { next: next };
- var ret = {};
- ret[Symbol.iterator] = function() { return iter; };
- return ret;
- }
- function* yield_results(expected) {
- return yield* results(expected);
- }
- function collect_results(iterable) {
- var iter = iterable[Symbol.iterator]();
- var ret = [];
- var result;
- do {
- result = iter.next();
- ret.push(result);
- } while (!result.done);
- return ret;
- }
- // We have to put a full result for the end, because the return will
re-box.
- var expected = [{value: 1}, 13, "foo", {value: 34, done: true}];
-
- // Sanity check.
- assertEquals(expected, collect_results(results(expected)));
- assertEquals(expected, collect_results(yield_results(expected)));
-}
-TestDelegatingYield();
-
-function TestTryCatch(instantiate) {
- function* g() { yield 1; try { yield 2; } catch (e) { yield e; } yield
3; }
- function Sentinel() {}
-
- function Test1(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertIteratorIsClosed(iter);
- }
- Test1(instantiate(g));
-
- function Test2(iter) {
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test2(instantiate(g));
-
- function Test3(iter) {
- assertIteratorResult(1, false, iter.next());
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test3(instantiate(g));
-
- function Test4(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- var exn = new Sentinel;
- assertIteratorResult(exn, false, iter.throw(exn));
- assertIteratorResult(3, false, iter.next());
- assertIteratorIsClosed(iter);
- }
- Test4(instantiate(g));
-
- function Test5(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- var exn = new Sentinel;
- assertIteratorResult(exn, false, iter.throw(exn));
- assertIteratorResult(3, false, iter.next());
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test5(instantiate(g));
-
- function Test6(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- var exn = new Sentinel;
- assertIteratorResult(exn, false, iter.throw(exn));
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test6(instantiate(g));
-
- function Test7(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertIteratorIsClosed(iter);
- }
- Test7(instantiate(g));
-}
-TestTryCatch(function (g) { return g(); });
-TestTryCatch(function* (g) { return yield* g(); });
-
-function TestTryFinally(instantiate) {
- function* g() { yield 1; try { yield 2; } finally { yield 3; } yield 4; }
- function Sentinel() {}
- function Sentinel2() {}
-
- function Test1(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertIteratorResult(4, false, iter.next());
- assertIteratorIsClosed(iter);
- }
- Test1(instantiate(g));
-
- function Test2(iter) {
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test2(instantiate(g));
-
- function Test3(iter) {
- assertIteratorResult(1, false, iter.next());
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test3(instantiate(g));
-
- function Test4(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.throw(new Sentinel));
- assertThrows(function() { iter.next(); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test4(instantiate(g));
-
- function Test5(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.throw(new Sentinel));
- assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2);
- assertThrownIteratorIsClosed(iter);
- }
- Test5(instantiate(g));
-
- function Test6(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test6(instantiate(g));
-
- function Test7(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertIteratorResult(4, false, iter.next());
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test7(instantiate(g));
-
- function Test8(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertIteratorResult(4, false, iter.next());
- assertIteratorIsClosed(iter);
- }
- Test8(instantiate(g));
-}
-TestTryFinally(function (g) { return g(); });
-TestTryFinally(function* (g) { return yield* g(); });
-
-function TestNestedTry(instantiate) {
- function* g() {
- try {
- yield 1;
- try { yield 2; } catch (e) { yield e; }
- yield 3;
- } finally {
- yield 4;
- }
- yield 5;
- }
- function Sentinel() {}
- function Sentinel2() {}
-
- function Test1(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(3, false, iter.next());
- assertIteratorResult(4, false, iter.next());
- assertIteratorResult(5, false, iter.next());
- assertIteratorIsClosed(iter);
- }
- Test1(instantiate(g));
-
- function Test2(iter) {
- assertThrows(function() { iter.throw(new Sentinel); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test2(instantiate(g));
-
- function Test3(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(4, false, iter.throw(new Sentinel));
- assertThrows(function() { iter.next(); }, Sentinel);
- assertThrownIteratorIsClosed(iter);
- }
- Test3(instantiate(g));
-
- function Test4(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(4, false, iter.throw(new Sentinel));
- assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2);
- assertThrownIteratorIsClosed(iter);
- }
- Test4(instantiate(g));
-
- function Test5(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- var exn = new Sentinel;
- assertIteratorResult(exn, false, iter.throw(exn));
- assertIteratorResult(3, false, iter.next());
- assertIteratorResult(4, false, iter.next());
- assertIteratorResult(5, false, iter.next());
- assertIteratorIsClosed(iter);
- }
- Test5(instantiate(g));
-
- function Test6(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- var exn = new Sentinel;
- assertIteratorResult(exn, false, iter.throw(exn));
- assertIteratorResult(4, false, iter.throw(new Sentinel2));
- assertThrows(function() { iter.next(); }, Sentinel2);
- assertThrownIteratorIsClosed(iter);
- }
- Test6(instantiate(g));
-
- function Test7(iter) {
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- var exn = new Sentinel;
- assertIteratorResult(exn, false, iter.throw(exn));
- assertIteratorResult(3, false, iter.next());
- assertIteratorResult(4, false, iter.throw(new Sentinel2));
- assertThrows(function() { iter.next(); }, Sentinel2);
- assertThrownIteratorIsClosed(iter);
- }
- Test7(instantiate(g));
-
- // That's probably enough.
-}
-TestNestedTry(function (g) { return g(); });
-TestNestedTry(function* (g) { return yield* g(); });
-
-function TestRecursion() {
- function TestNextRecursion() {
- function* g() { yield iter.next(); }
- var iter = g();
- return iter.next();
- }
- function TestSendRecursion() {
- function* g() { yield iter.next(42); }
- var iter = g();
- return iter.next();
- }
- function TestThrowRecursion() {
- function* g() { yield iter.throw(1); }
- var iter = g();
- return iter.next();
- }
- assertThrows(TestNextRecursion, Error);
- assertThrows(TestSendRecursion, Error);
- assertThrows(TestThrowRecursion, Error);
-}
-TestRecursion();
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-objects.js Tue
Mar 25 14:26:55 2014 UTC
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-generators --harmony-scoping --allow-natives-syntax
-
-// Test instantations of generators.
-
-// Generators shouldn't allocate stack slots. This test will abort in
debug
-// mode if generators have stack slots.
-function TestContextAllocation() {
- function* g1(a, b, c) { yield 1; return [a, b, c]; }
- function* g2() { yield 1; return arguments; }
- function* g3() { yield 1; return this; }
- function* g4() { var x = 10; yield 1; return x; }
- // Temporary variable context allocation
- function* g5(l) { "use strict"; yield 1; for (let x in l) { yield x; } }
-
- g1();
- g2();
- g3();
- g4();
- g5(["foo"]);
-}
-TestContextAllocation();
-
-
-// Test the properties and prototype of a generator object.
-function TestGeneratorObject() {
- function* g() { yield 1; }
-
- var iter = g();
- assertSame(g.prototype, Object.getPrototypeOf(iter));
- assertTrue(iter instanceof g);
- assertEquals("Generator", %_ClassOf(iter));
- assertEquals("[object Generator]", String(iter));
- assertEquals([], Object.getOwnPropertyNames(iter));
- assertTrue(iter !== g());
-
- // g() is the same as new g().
- iter = new g();
- assertSame(g.prototype, Object.getPrototypeOf(iter));
- assertTrue(iter instanceof g);
- assertEquals("Generator", %_ClassOf(iter));
- assertEquals("[object Generator]", String(iter));
- assertEquals([], Object.getOwnPropertyNames(iter));
- assertTrue(iter !== new g());
-}
-TestGeneratorObject();
-
-
-// Test the methods of generator objects.
-function TestGeneratorObjectMethods() {
- function* g() { yield 1; }
- var iter = g();
-
- function TestNonGenerator(non_generator) {
- assertThrows(function() { iter.next.call(non_generator); }, TypeError);
- assertThrows(function() { iter.next.call(non_generator, 1); },
TypeError);
- assertThrows(function() { iter.throw.call(non_generator, 1); },
TypeError);
- assertThrows(function() { iter.close.call(non_generator); },
TypeError);
- }
-
- TestNonGenerator(1);
- TestNonGenerator({});
- TestNonGenerator(function(){});
- TestNonGenerator(g);
- TestNonGenerator(g.prototype);
-}
-TestGeneratorObjectMethods();
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-parsing.js Wed
Jul 2 13:48:28 2014 UTC
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-generators
-
-// Test basic generator syntax.
-
-// Yield statements.
-function* g() { yield 3; yield 4; }
-
-// Yield expressions.
-function* g() { (yield 3) + (yield 4); }
-
-// Yield without a RHS.
-function* g() { yield; }
-function* g() { yield }
-function* g() {
- yield
-}
-function* g() { (yield) }
-function* g() { [yield] }
-function* g() { {yield} }
-function* g() { yield, yield }
-function* g() { yield; yield }
-function* g() { (yield) ? yield : yield }
-function* g() {
- (yield)
- ? yield
- : yield
-}
-
-// If yield has a RHS, it needs to start on the same line. The * in a
-// yield* counts as starting the RHS.
-function* g() {
- yield *
- foo
-}
-assertThrows("function* g() { yield\n* foo }", SyntaxError);
-assertEquals(undefined,
- (function*(){
- yield
- 3
- })().next().value);
-
-// A YieldExpression is not a LogicalORExpression.
-assertThrows("function* g() { yield ? yield : yield }", SyntaxError);
-
-// You can have a generator in strict mode.
-function* g() { "use strict"; yield 3; yield 4; }
-
-// Generators can have return statements also, which internally parse to a
kind
-// of yield expression.
-function* g() { yield 1; return; }
-function* g() { yield 1; return 2; }
-function* g() { yield 1; return 2; yield "dead"; }
-
-// Generator expression.
-(function* () { yield 3; });
-
-// Named generator expression.
-(function* g() { yield 3; });
-
-// You can have a generator without a yield.
-function* g() { }
-
-// A YieldExpression is valid as the RHS of a YieldExpression.
-function* g() { yield yield 1; }
-function* g() { yield 3 + (yield 4); }
-
-// Generator definitions with a name of "yield" are not specifically ruled
out
-// by the spec, as the `yield' name is outside the generator itself.
However,
-// in strict-mode, "yield" is an invalid identifier.
-function* yield() { (yield 3) + (yield 4); }
-assertThrows("function* yield() { \"use strict\"; (yield 3) + (yield 4);
}",
- SyntaxError);
-
-// In sloppy mode, yield is a normal identifier, outside of generators.
-function yield(yield) { yield: yield (yield + yield (0)); }
-
-// Yield is always valid as a key in an object literal.
-({ yield: 1 });
-function* g() { yield ({ yield: 1 }) }
-function* g() { yield ({ get yield() { return 1; }}) }
-
-// Checks that yield is a valid label in sloppy mode, but not valid in a
strict
-// mode or in generators.
-function f() { yield: 1 }
-assertThrows("function f() { \"use strict\"; yield: 1 }", SyntaxError)
-assertThrows("function* g() { yield: 1 }", SyntaxError)
-
-// Yield is only a keyword in the body of the generator, not in nested
-// functions.
-function* g() { function f() { yield (yield + yield (0)); } }
-
-// Yield in a generator is not an identifier.
-assertThrows("function* g() { yield = 10; }", SyntaxError);
-
-// Yield binds very loosely, so this parses as "yield (3 + yield 4)",
which is
-// invalid.
-assertThrows("function* g() { yield 3 + yield 4; }", SyntaxError);
-
-// Yield is still a future-reserved-word in strict mode
-assertThrows("function f() { \"use strict\"; var yield = 13; }",
SyntaxError);
-
-// The name of the NFE is let-bound in G, so is invalid.
-assertThrows("function* g() { yield (function yield() {}); }",
SyntaxError);
-
-// In generators, yield is invalid as a formal argument name.
-assertThrows("function* g(yield) { yield (10); }", SyntaxError);
=======================================
---
/branches/bleeding_edge/test/mjsunit/harmony/generators-poisoned-properties.js
Mon May 19 10:47:00 2014 UTC
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-generators
-
-function assertIteratorResult(value, done, result) {
- assertEquals({value: value, done: done}, result);
-}
-
-function test(f) {
- var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
- var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
-
- assertFalse(cdesc.enumerable);
- assertFalse(cdesc.configurable);
-
- assertFalse(adesc.enumerable);
- assertFalse(adesc.configurable);
-
- assertSame(cdesc.get, cdesc.set);
- assertSame(cdesc.get, adesc.get);
- assertSame(cdesc.get, adesc.set);
-
- assertTrue(cdesc.get instanceof Function);
- assertEquals(0, cdesc.get.length);
- assertThrows(cdesc.get, TypeError);
-
- assertThrows(function() { return f.caller; }, TypeError);
- assertThrows(function() { f.caller = 42; }, TypeError);
- assertThrows(function() { return f.arguments; }, TypeError);
- assertThrows(function() { f.arguments = 42; }, TypeError);
-}
-
-function *sloppy() { test(sloppy); }
-function *strict() { "use strict"; test(strict); }
-
-test(sloppy);
-test(strict);
-
-assertIteratorResult(undefined, true, sloppy().next());
-assertIteratorResult(undefined, true, strict().next());
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-relocation.js
Mon May 5 14:31:51 2014 UTC
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --expose-debug-as debug --harmony-generators
-
-var Debug = debug.Debug;
-
-function assertIteratorResult(value, done, result) {
- assertEquals({value: value, done: done}, result);
-}
-
-function RunTest(formals_and_body, args, value1, value2) {
- // A null listener. It isn't important what the listener does.
- function listener(event, exec_state, event_data, data) {
- }
-
- // Create the generator function outside a debugging context. It will
probably
- // be lazily compiled.
- var gen = (function*(){}).constructor.apply(null, formals_and_body);
-
- // Instantiate the generator object.
- var obj = gen.apply(null, args);
-
- // Advance to the first yield.
- assertIteratorResult(value1, false, obj.next());
-
- // Add a breakpoint on line 3 (the second yield).
- var bp = Debug.setBreakPoint(gen, 3);
-
- // Enable the debugger, which should force recompilation of the generator
- // function and relocation of the suspended generator activation.
- Debug.setListener(listener);
-
- // Check that the generator resumes and suspends properly.
- assertIteratorResult(value2, false, obj.next());
-
- // Disable debugger -- should not force recompilation.
- Debug.clearBreakPoint(bp);
- Debug.setListener(null);
-
- // Run to completion.
- assertIteratorResult(undefined, true, obj.next());
-}
-
-function prog(a, b, c) {
- return a + ';\n' + 'yield ' + b + ';\n' + 'yield ' + c;
-}
-
-// Simple empty local scope.
-RunTest([prog('', '1', '2')], [], 1, 2);
-
-RunTest([prog('for (;;) break', '1', '2')], [], 1, 2);
-
-RunTest([prog('while (0) foo()', '1', '2')], [], 1, 2);
-
-RunTest(['a', prog('var x = 3', 'a', 'x')], [1], 1, 3);
-
-RunTest(['a', prog('', '1', '2')], [42], 1, 2);
-
-RunTest(['a', prog('for (;;) break', '1', '2')], [42], 1, 2);
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-runtime.js Thu
Jun 12 08:53:07 2014 UTC
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-generators
-
-// Test aspects of the generator runtime.
-
-// See:
-//
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunction-objects
-
-function f() { }
-function* g() { yield 1; }
-var GeneratorFunctionPrototype = Object.getPrototypeOf(g);
-var GeneratorFunction = GeneratorFunctionPrototype.constructor;
-var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
-
-// A generator function should have the same set of properties as any
-// other function.
-function TestGeneratorFunctionInstance() {
- var f_own_property_names = Object.getOwnPropertyNames(f);
- var g_own_property_names = Object.getOwnPropertyNames(g);
-
- f_own_property_names.sort();
- g_own_property_names.sort();
-
- assertArrayEquals(f_own_property_names, g_own_property_names);
- var i;
- for (i = 0; i < f_own_property_names.length; i++) {
- var prop = f_own_property_names[i];
- var f_desc = Object.getOwnPropertyDescriptor(f, prop);
- var g_desc = Object.getOwnPropertyDescriptor(g, prop);
- assertEquals(f_desc.configurable, g_desc.configurable, prop);
- if (prop === 'arguments' || prop === 'caller') {
- // Unlike sloppy functions, which have read-only data arguments and
caller
- // properties, sloppy generators have a poison pill implemented via
- // accessors
- assertFalse('writable' in g_desc, prop);
- assertTrue(g_desc.get instanceof Function, prop);
- assertEquals(g_desc.get, g_desc.set, prop);
- } else {
- assertEquals(f_desc.writable, g_desc.writable, prop);
- }
- assertEquals(f_desc.enumerable, g_desc.enumerable, prop);
- }
-}
-TestGeneratorFunctionInstance();
-
-
-// Generators have an additional object interposed in the chain between
-// themselves and Function.prototype.
-function TestGeneratorFunctionPrototype() {
- // Sanity check.
- assertSame(Object.getPrototypeOf(f), Function.prototype);
- assertFalse(GeneratorFunctionPrototype === Function.prototype);
- assertSame(Function.prototype,
- Object.getPrototypeOf(GeneratorFunctionPrototype));
- assertSame(GeneratorFunctionPrototype,
- Object.getPrototypeOf(function* () {}));
-}
-TestGeneratorFunctionPrototype();
-
-
-// Functions that we associate with generator objects are actually defined
by
-// a common prototype.
-function TestGeneratorObjectPrototype() {
- assertSame(Object.prototype,
- Object.getPrototypeOf(GeneratorObjectPrototype));
- assertSame(GeneratorObjectPrototype,
- Object.getPrototypeOf((function*(){yield 1}).prototype));
-
- var expected_property_names = ["next", "throw", "constructor"];
- var found_property_names =
- Object.getOwnPropertyNames(GeneratorObjectPrototype);
-
- expected_property_names.sort();
- found_property_names.sort();
-
- assertArrayEquals(expected_property_names, found_property_names);
-
- iterator_desc = Object.getOwnPropertyDescriptor(GeneratorObjectPrototype,
- Symbol.iterator);
- assertTrue(iterator_desc !== undefined);
- assertFalse(iterator_desc.writable);
- assertFalse(iterator_desc.enumerable);
- assertFalse(iterator_desc.configurable);
-
- // The generator object's "iterator" function is just the identity.
- assertSame(iterator_desc.value.call(42), 42);
-}
-TestGeneratorObjectPrototype();
-
-
-// This tests the object that would be called "GeneratorFunction", if it
were
-// like "Function".
-function TestGeneratorFunction() {
- assertSame(GeneratorFunctionPrototype, GeneratorFunction.prototype);
- assertTrue(g instanceof GeneratorFunction);
-
- assertSame(Function, Object.getPrototypeOf(GeneratorFunction));
- assertTrue(g instanceof Function);
-
- assertEquals("function* g() { yield 1; }", g.toString());
-
- // Not all functions are generators.
- assertTrue(f instanceof Function); // Sanity check.
- assertTrue(!(f instanceof GeneratorFunction));
-
- assertTrue((new GeneratorFunction()) instanceof GeneratorFunction);
- assertTrue(GeneratorFunction() instanceof GeneratorFunction);
-}
-TestGeneratorFunction();
-
-
-function TestPerGeneratorPrototype() {
- assertTrue((function*(){}).prototype !== (function*(){}).prototype);
- assertTrue((function*(){}).prototype !== g.prototype);
- assertTrue(g.prototype instanceof GeneratorFunctionPrototype);
- assertSame(GeneratorObjectPrototype, Object.getPrototypeOf(g.prototype));
- assertTrue(!(g.prototype instanceof Function));
- assertSame(typeof (g.prototype), "object");
-
- assertArrayEquals([], Object.getOwnPropertyNames(g.prototype));
-}
-TestPerGeneratorPrototype();
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/regress/regress-2681.js
Fri Feb 28 14:26:32 2014 UTC
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --expose-gc --noincremental-marking --harmony-generators
-
-// Check that we are not flushing code for generators.
-
-function flush_all_code() {
- // Each GC ages code, and currently 6 gcs will flush all code.
- for (var i = 0; i < 10; i++) gc();
-}
-
-function* g() {
- yield 1;
- yield 2;
-}
-
-var o = g();
-assertEquals({ value: 1, done: false }, o.next());
-
-flush_all_code();
-
-assertEquals({ value: 2, done: false }, o.next());
-assertEquals({ value: undefined, done: true }, o.next());
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/regress/regress-2691.js
Fri Feb 28 14:26:32 2014 UTC
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-generators
-
-// Check that yield* on non-objects raises a TypeError.
-
-assertThrows('(function*() { yield* 10 })().next()', TypeError);
-assertThrows('(function*() { yield* {} })().next()', TypeError);
-assertThrows('(function*() { yield* undefined })().next()', TypeError);
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/regress/regress-3280.js
Wed Apr 23 15:01:30 2014 UTC
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-generators --expose-debug-as debug
-
-var Debug = debug.Debug;
-
-var listener_called;
-
-function listener(event, exec_state, event_data, data) {
- if (event == Debug.DebugEvent.Break) {
- listener_called = true;
- exec_state.frame().allScopes();
- }
-}
-
-Debug.setListener(listener);
-
-function *generator_local_2(a) {
- debugger;
-}
-generator_local_2(1).next();
-
-assertTrue(listener_called, "listener not called");
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Wed Aug 20 13:05:03 2014
UTC
+++ /branches/bleeding_edge/src/flag-definitions.h Thu Aug 21 12:06:25 2014
UTC
@@ -167,7 +167,6 @@
DEFINE_IMPLICATION(harmony, harmony_modules)
// TODO(rossberg): Reenable when problems are sorted out.
// DEFINE_IMPLICATION(harmony, harmony_proxies)
-DEFINE_IMPLICATION(harmony, harmony_generators)
DEFINE_IMPLICATION(harmony, harmony_numeric_literals)
DEFINE_IMPLICATION(harmony, harmony_strings)
DEFINE_IMPLICATION(harmony, harmony_arrays)
@@ -176,6 +175,7 @@
DEFINE_IMPLICATION(harmony_modules, harmony_scoping)
DEFINE_IMPLICATION(harmony, es_staging)
+DEFINE_IMPLICATION(es_staging, harmony_generators)
// Flags for experimental implementation features.
DEFINE_BOOL(compiled_keyed_dictionary_loads, true,
=======================================
--- /branches/bleeding_edge/test/mjsunit/mjsunit.status Thu Aug 21 11:56:46
2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/mjsunit.status Thu Aug 21 12:06:25
2014 UTC
@@ -130,8 +130,8 @@
'es6/debug-promises/throw-uncaught-uncaught': [PASS, NO_VARIANTS],
'es6/debug-promises/reject-uncaught-late': [PASS, NO_VARIANTS],
'es6/debug-promises/throw-caught-by-default-reject-handler': [PASS,
NO_VARIANTS],
+ 'es6/generators-debug-scopes': [PASS, NO_VARIANTS],
'harmony/debug-blockscopes': [PASS, NO_VARIANTS],
- 'harmony/generators-debug-scopes': [PASS, NO_VARIANTS],
'regress/regress-1081309': [PASS, NO_VARIANTS],
'regress/regress-1170187': [PASS, NO_VARIANTS],
'regress/regress-119609': [PASS, NO_VARIANTS],
@@ -146,14 +146,14 @@
# Support for ES6 generators is missing.
'regress-3225': [PASS, NO_VARIANTS],
- 'harmony/generators-debug-liveedit': [PASS, NO_VARIANTS],
- 'harmony/generators-iteration': [PASS, NO_VARIANTS],
- 'harmony/generators-parsing': [PASS, NO_VARIANTS],
- 'harmony/generators-poisoned-properties': [PASS, NO_VARIANTS],
- 'harmony/generators-relocation': [PASS, NO_VARIANTS],
- 'harmony/regress/regress-2681': [PASS, NO_VARIANTS],
- 'harmony/regress/regress-2691': [PASS, NO_VARIANTS],
- 'harmony/regress/regress-3280': [PASS, NO_VARIANTS],
+ 'es6/generators-debug-liveedit': [PASS, NO_VARIANTS],
+ 'es6/generators-iteration': [PASS, NO_VARIANTS],
+ 'es6/generators-parsing': [PASS, NO_VARIANTS],
+ 'es6/generators-poisoned-properties': [PASS, NO_VARIANTS],
+ 'es6/generators-relocation': [PASS, NO_VARIANTS],
+ 'es6/regress/regress-2681': [PASS, NO_VARIANTS],
+ 'es6/regress/regress-2691': [PASS, NO_VARIANTS],
+ 'es6/regress/regress-3280': [PASS, NO_VARIANTS],
# Support for ES6 for-of iteration is missing.
'es6/array-iterator': [PASS, NO_VARIANTS],
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.