Revision: 15028
Author: [email protected]
Date: Mon Jun 10 02:26:18 2013
Log: Generator object "next" method takes optional send value
Update the generators implementation to make "next" also do the job of
what was previously called "send" by taking an optional argument.
Remove send, and do a bunch of renamings.
[email protected]
BUG=v8:2355, v8:2715
Review URL: https://codereview.chromium.org/16136011
http://code.google.com/p/v8/source/detail?r=15028
Modified:
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/full-codegen.cc
/branches/bleeding_edge/src/generator.js
/branches/bleeding_edge/src/heap.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
/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-runtime.js
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Jun 10 02:12:57
2013
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Jun 10 02:26:18
2013
@@ -2029,10 +2029,10 @@
// [sp + 1 * kPointerSize] iter
// [sp + 0 * kPointerSize] g
- Label l_catch, l_try, l_resume, l_send, l_call, l_loop;
+ Label l_catch, l_try, l_resume, l_next, l_call, l_loop;
// Initial send value is undefined.
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
- __ b(&l_send);
+ __ b(&l_next);
// catch (e) { receiver = iter; f = iter.throw; arg = e; goto
l_call; }
__ bind(&l_catch);
@@ -2063,15 +2063,15 @@
__ bind(&l_resume); // received in r0
__ PopTryHandler();
- // receiver = iter; f = iter.send; arg = received;
- __ bind(&l_send);
+ // receiver = iter; f = iter.next; arg = received;
+ __ bind(&l_next);
__ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
__ push(r3); // iter
__ push(r0); // received
__ mov(r0, r3); // iter
- __ LoadRoot(r2, Heap::ksend_stringRootIndex); // "send"
- Handle<Code> send_ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(send_ic); // iter.send in r0
+ __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
+ Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
+ CallIC(next_ic); // iter.next in r0
// result = f.call(receiver, arg);
__ bind(&l_call);
@@ -2174,7 +2174,7 @@
// If we are sending a value and there is no operand stack, we can jump
back
// in directly.
- if (resume_mode == JSGeneratorObject::SEND) {
+ if (resume_mode == JSGeneratorObject::NEXT) {
Label slow_resume;
__ cmp(r3, Operand(0));
__ b(ne, &slow_resume);
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Fri Jun 7 04:12:21 2013
+++ /branches/bleeding_edge/src/full-codegen.cc Mon Jun 10 02:26:18 2013
@@ -926,10 +926,10 @@
}
-void FullCodeGenerator::EmitGeneratorSend(CallRuntime* expr) {
+void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 2);
- EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::SEND);
+ EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::NEXT);
}
=======================================
--- /branches/bleeding_edge/src/generator.js Wed May 15 08:57:58 2013
+++ /branches/bleeding_edge/src/generator.js Mon Jun 10 02:26:18 2013
@@ -34,26 +34,16 @@
//
----------------------------------------------------------------------------
-// TODO(wingo): Give link to specification. For now, the following diagram
is
-// the spec:
-//
http://wiki.ecmascript.org/lib/exe/fetch.php?cache=cache&media=harmony:es6_generator_object_model_3-29-13.png
+// Generator functions and objects are specified by ES6, sections 15.19.3
and
+// 15.19.4.
-function GeneratorObjectNext() {
+function GeneratorObjectNext(value) {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.next', this]);
}
- return %_GeneratorSend(this, void 0);
-}
-
-function GeneratorObjectSend(value) {
- if (!IS_GENERATOR(this)) {
- throw MakeTypeError('incompatible_method_receiver',
- ['[Generator].prototype.send', this]);
- }
-
- return %_GeneratorSend(this, value);
+ return %_GeneratorNext(this, value);
}
function GeneratorObjectThrow(exn) {
@@ -71,7 +61,6 @@
InstallFunctions(GeneratorObjectPrototype,
DONT_ENUM | DONT_DELETE | READ_ONLY,
["next", GeneratorObjectNext,
- "send", GeneratorObjectSend,
"throw", GeneratorObjectThrow]);
%SetProperty(GeneratorObjectPrototype, "constructor",
GeneratorFunctionPrototype, DONT_ENUM | DONT_DELETE |
READ_ONLY);
=======================================
--- /branches/bleeding_edge/src/heap.h Fri Jun 7 04:12:21 2013
+++ /branches/bleeding_edge/src/heap.h Mon Jun 10 02:26:18 2013
@@ -293,7 +293,6 @@
V(hidden_stack_trace_string, "v8::hidden_stack_trace") \
V(query_colon_string, "(?:)") \
V(Generator_string, "Generator") \
- V(send_string, "send") \
V(throw_string, "throw") \
V(done_string, "done") \
V(value_string, "value") \
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Fri Jun 7 10:28:46 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Mon Jun 10 02:26:18 2013
@@ -10917,8 +10917,8 @@
// Support for generators.
-void HOptimizedGraphBuilder::GenerateGeneratorSend(CallRuntime* call) {
- return Bailout("inlined runtime function: GeneratorSend");
+void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) {
+ return Bailout("inlined runtime function: GeneratorNext");
}
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Jun 7
04:12:21 2013
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Jun 10
02:26:18 2013
@@ -1988,10 +1988,10 @@
// [sp + 1 * kPointerSize] iter
// [sp + 0 * kPointerSize] g
- Label l_catch, l_try, l_resume, l_send, l_call, l_loop;
+ Label l_catch, l_try, l_resume, l_next, l_call, l_loop;
// Initial send value is undefined.
__ mov(eax, isolate()->factory()->undefined_value());
- __ jmp(&l_send);
+ __ jmp(&l_next);
// catch (e) { receiver = iter; f = iter.throw; arg = e; goto
l_call; }
__ bind(&l_catch);
@@ -2020,14 +2020,14 @@
__ bind(&l_resume); // received in eax
__ PopTryHandler();
- // receiver = iter; f = iter.send; arg = received;
- __ bind(&l_send);
+ // receiver = iter; f = iter.next; arg = received;
+ __ bind(&l_next);
__ mov(edx, Operand(esp, 1 * kPointerSize)); // iter
__ push(edx); // iter
__ push(eax); // received
- __ mov(ecx, isolate()->factory()->send_string()); // "send"
- Handle<Code> send_ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(send_ic); // iter.send in
eax
+ __ mov(ecx, isolate()->factory()->next_string()); // "next"
+ Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
+ CallIC(next_ic); // iter.next in
eax
// result = f.call(receiver, arg);
__ bind(&l_call);
@@ -2129,7 +2129,7 @@
// If we are sending a value and there is no operand stack, we can jump
back
// in directly.
- if (resume_mode == JSGeneratorObject::SEND) {
+ if (resume_mode == JSGeneratorObject::NEXT) {
Label slow_resume;
__ cmp(edx, Immediate(0));
__ j(not_zero, &slow_resume);
=======================================
--- /branches/bleeding_edge/src/objects.h Fri Jun 7 08:02:20 2013
+++ /branches/bleeding_edge/src/objects.h Mon Jun 10 02:26:18 2013
@@ -6529,7 +6529,7 @@
static const int kSize = kStackHandlerIndexOffset + kPointerSize;
// Resume mode, for use by runtime functions.
- enum ResumeMode { SEND, THROW };
+ enum ResumeMode { NEXT, THROW };
// Yielding from a generator returns an object with the following
inobject
// properties. See Context::generator_result_map() for the map.
=======================================
--- /branches/bleeding_edge/src/runtime.cc Fri Jun 7 09:48:22 2013
+++ /branches/bleeding_edge/src/runtime.cc Mon Jun 10 02:26:18 2013
@@ -2641,9 +2641,9 @@
// called if the suspended activation had operands on the stack, stack
handlers
// needing rewinding, or if the resume should throw an exception. The
fast path
// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which
is
-// inlined into GeneratorNext, GeneratorSend, and GeneratorThrow.
-// EmitGeneratorResumeResume is called in any case, as it needs to
reconstruct
-// the stack frame and make space for arguments and operands.
+// inlined into GeneratorNext and GeneratorThrow.
EmitGeneratorResumeResume is
+// called in any case, as it needs to reconstruct the stack frame and make
space
+// for arguments and operands.
RUNTIME_FUNCTION(MaybeObject*, Runtime_ResumeJSGeneratorObject) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 3);
@@ -2676,7 +2676,7 @@
JSGeneratorObject::ResumeMode resume_mode =
static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
switch (resume_mode) {
- case JSGeneratorObject::SEND:
+ case JSGeneratorObject::NEXT:
return value;
case JSGeneratorObject::THROW:
return isolate->Throw(value);
=======================================
--- /branches/bleeding_edge/src/runtime.h Fri Jun 7 06:27:03 2013
+++ /branches/bleeding_edge/src/runtime.h Mon Jun 10 02:26:18 2013
@@ -572,7 +572,7 @@
F(HasCachedArrayIndex, 1,
1) \
F(GetCachedArrayIndex, 1,
1) \
F(FastAsciiArrayJoin, 2,
1) \
- F(GeneratorSend, 2,
1) \
+ F(GeneratorNext, 2,
1) \
F(GeneratorThrow, 2, 1)
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Fri Jun 7 04:12:21
2013
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Mon Jun 10 02:26:18
2013
@@ -2012,10 +2012,10 @@
// [sp + 1 * kPointerSize] iter
// [sp + 0 * kPointerSize] g
- Label l_catch, l_try, l_resume, l_send, l_call, l_loop;
+ Label l_catch, l_try, l_resume, l_next, l_call, l_loop;
// Initial send value is undefined.
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
- __ jmp(&l_send);
+ __ jmp(&l_next);
// catch (e) { receiver = iter; f = iter.throw; arg = e; goto
l_call; }
__ bind(&l_catch);
@@ -2045,15 +2045,15 @@
__ bind(&l_resume); // received in rax
__ PopTryHandler();
- // receiver = iter; f = iter.send; arg = received;
- __ bind(&l_send);
+ // receiver = iter; f = iter.next; arg = received;
+ __ bind(&l_next);
__ movq(rcx, Operand(rsp, 1 * kPointerSize)); // iter
__ push(rcx); // iter
__ push(rax); // received
__ movq(rax, rcx); // iter
- __ LoadRoot(rcx, Heap::ksend_stringRootIndex); // "send"
- Handle<Code> send_ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(send_ic); // iter.send in
rax
+ __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next"
+ Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
+ CallIC(next_ic); // iter.next in
rax
// result = f.call(receiver, arg);
__ bind(&l_call);
@@ -2155,7 +2155,7 @@
// If we are sending a value and there is no operand stack, we can jump
back
// in directly.
- if (resume_mode == JSGeneratorObject::SEND) {
+ if (resume_mode == JSGeneratorObject::NEXT) {
Label slow_resume;
__ cmpq(rdx, Immediate(0));
__ j(not_zero, &slow_resume);
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-iteration.js
Wed May 15 08:57:58 2013
+++ /branches/bleeding_edge/test/mjsunit/harmony/generators-iteration.js
Mon Jun 10 02:26:18 2013
@@ -64,9 +64,9 @@
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.send(send_val));
+ iter.next(send_val));
}
- assertThrows(function() { iter.send(send_val); }, Error);
+ assertThrows(function() { iter.next(send_val); }, Error);
}
function testThrow(thunk) {
for (var i = 0; i < expected_values_for_next.length; i++) {
@@ -572,7 +572,7 @@
return iter.next();
}
function TestSendRecursion() {
- function* g() { yield iter.send(42); }
+ function* g() { yield iter.next(42); }
var iter = g();
return iter.next();
}
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-objects.js Wed
Apr 17 08:01:25 2013
+++ /branches/bleeding_edge/test/mjsunit/harmony/generators-objects.js Mon
Jun 10 02:26:18 2013
@@ -79,7 +79,7 @@
function TestNonGenerator(non_generator) {
assertThrows(function() { iter.next.call(non_generator); }, TypeError);
- assertThrows(function() { iter.send.call(non_generator, 1); },
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);
}
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-runtime.js Wed
May 15 08:57:58 2013
+++ /branches/bleeding_edge/test/mjsunit/harmony/generators-runtime.js Mon
Jun 10 02:26:18 2013
@@ -84,7 +84,7 @@
assertSame(GeneratorObjectPrototype,
Object.getPrototypeOf((function*(){yield 1}).prototype));
- var expected_property_names = ["next", "send", "throw", "constructor"];
+ var expected_property_names = ["next", "throw", "constructor"];
var found_property_names =
Object.getOwnPropertyNames(GeneratorObjectPrototype);
--
--
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/groups/opt_out.