Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(410)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 14582007: Implement yield* (delegating yield) (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Fix asm nits; rework test suite to test yield* on everything Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap.h ('k') | src/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 1914
1915 case Yield::FINAL: { 1915 case Yield::FINAL: {
1916 VisitForAccumulatorValue(expr->generator_object()); 1916 VisitForAccumulatorValue(expr->generator_object());
1917 __ mov(FieldOperand(result_register(), 1917 __ mov(FieldOperand(result_register(),
1918 JSGeneratorObject::kContinuationOffset), 1918 JSGeneratorObject::kContinuationOffset),
1919 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 1919 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
1920 EmitReturnIteratorResult(true); 1920 EmitReturnIteratorResult(true);
1921 break; 1921 break;
1922 } 1922 }
1923 1923
1924 case Yield::DELEGATING: 1924 case Yield::DELEGATING: {
1925 UNIMPLEMENTED(); 1925 VisitForStackValue(expr->generator_object());
1926
1927 // Initial stack layout is as follows:
1928 // [sp + 1 * kPointerSize] iter
1929 // [sp + 0 * kPointerSize] g
1930
1931 Label l_catch, l_try, l_resume, l_send, l_call, l_loop;
1932 // Initial send value is undefined.
1933 __ mov(eax, isolate()->factory()->undefined_value());
1934 __ jmp(&l_send);
1935
1936 // catch (e) { receiver = iter; f = iter.throw; arg = e; goto l_call; }
1937 __ bind(&l_catch);
1938 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
1939 __ mov(edx, Operand(esp, 1 * kPointerSize)); // iter
1940 __ push(edx); // iter
1941 __ push(eax); // exception
1942 __ mov(ecx, isolate()->factory()->throw_string()); // "throw"
1943 Handle<Code> throw_ic = isolate()->builtins()->LoadIC_Initialize();
1944 CallIC(throw_ic); // iter.throw in eax
1945 __ jmp(&l_call);
1946
1947 // try { received = yield result.value }
1948 __ bind(&l_try);
1949 __ pop(eax); // result.value
1950 __ PushTryHandler(StackHandler::CATCH, expr->index());
1951 const int handler_size = StackHandlerConstants::kSize;
1952 __ push(eax); // result.value
1953 __ push(Operand(esp, (0 + 1) * kPointerSize + handler_size)); // g
1954 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1955 __ mov(context_register(),
1956 Operand(ebp, StandardFrameConstants::kContextOffset));
1957 __ CompareRoot(eax, Heap::kTheHoleValueRootIndex);
1958 __ j(not_equal, &l_resume);
1959 EmitReturnIteratorResult(false);
1960 __ bind(&l_resume); // received in eax
1961 __ PopTryHandler();
1962
1963 // receiver = iter; f = iter.send; arg = received;
1964 __ bind(&l_send);
1965 __ mov(edx, Operand(esp, 1 * kPointerSize)); // iter
1966 __ push(edx); // iter
1967 __ push(eax); // received
1968 __ mov(ecx, isolate()->factory()->send_string()); // "send"
1969 Handle<Code> send_ic = isolate()->builtins()->LoadIC_Initialize();
1970 CallIC(send_ic); // iter.send in eax
1971
1972 // result = f.call(receiver, arg);
1973 __ bind(&l_call);
1974 Label l_call_runtime;
1975 __ JumpIfSmi(eax, &l_call_runtime);
1976 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
1977 __ j(not_equal, &l_call_runtime);
1978 __ mov(edi, eax);
1979 ParameterCount count(1);
1980 __ InvokeFunction(edi, count, CALL_FUNCTION,
1981 NullCallWrapper(), CALL_AS_METHOD);
1982 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1983 __ jmp(&l_loop);
1984 __ bind(&l_call_runtime);
1985 __ push(eax);
1986 __ CallRuntime(Runtime::kCall, 3);
1987
1988 // val = result.value; if (!result.done) goto l_try;
1989 __ bind(&l_loop);
1990 // result.value
1991 __ push(eax); // save result
1992 __ mov(edx, eax); // result
1993 __ mov(ecx, isolate()->factory()->value_string()); // "value"
1994 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
1995 CallIC(value_ic); // result.value in eax
1996 __ pop(ebx); // result
1997 __ push(eax); // result.value
1998 __ mov(edx, ebx); // result
1999 __ mov(ecx, isolate()->factory()->done_string()); // "done"
2000 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize();
2001 CallIC(done_ic); // result.done in eax
2002 ToBooleanStub stub(eax);
2003 __ push(eax);
2004 __ CallStub(&stub);
2005 __ test(eax, eax);
2006 __ j(zero, &l_try);
2007
2008 // result.value
2009 __ pop(eax); // result.value
2010 context()->DropAndPlug(2, eax); // drop iter and g
2011 break;
2012 }
1926 } 2013 }
1927 } 2014 }
1928 2015
1929 2016
1930 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2017 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1931 Expression *value, 2018 Expression *value,
1932 JSGeneratorObject::ResumeMode resume_mode) { 2019 JSGeneratorObject::ResumeMode resume_mode) {
1933 // The value stays in eax, and is ultimately read by the resumed generator, as 2020 // The value stays in eax, and is ultimately read by the resumed generator, as
1934 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. ebx 2021 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. ebx
1935 // will hold the generator object until the activation has been resumed. 2022 // will hold the generator object until the activation has been resumed.
(...skipping 2804 matching lines...) Expand 10 before | Expand all | Expand 10 after
4740 *stack_depth = 0; 4827 *stack_depth = 0;
4741 *context_length = 0; 4828 *context_length = 0;
4742 return previous_; 4829 return previous_;
4743 } 4830 }
4744 4831
4745 #undef __ 4832 #undef __
4746 4833
4747 } } // namespace v8::internal 4834 } } // namespace v8::internal
4748 4835
4749 #endif // V8_TARGET_ARCH_IA32 4836 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698