@@ -141,34 +141,95 @@ private static void checkResumable(PythonBuiltinBaseNode node, PGenerator self)
141141 abstract static class ResumeGeneratorNode extends Node {
142142 public abstract Object execute (VirtualFrame frame , PGenerator self , Object sendValue );
143143
144- @ Specialization (guards = " sameCallTarget(self.getCurrentCallTarget(), call.getCallTarget())" , limit = "getCallSiteInlineCacheMaxDepth()" )
145- Object cached (VirtualFrame frame , PGenerator self , Object sendValue ,
144+ @ Specialization (guards = { "!self.usesBytecode()" , " sameCallTarget(self.getCurrentCallTarget(), call.getCallTarget())"} , limit = "getCallSiteInlineCacheMaxDepth()" )
145+ Object cachedAST (VirtualFrame frame , PGenerator self , Object sendValue ,
146146 @ Cached ("createDirectCall(self.getCurrentCallTarget())" ) CallTargetInvokeNode call ) {
147147 self .setRunning (true );
148148 Object [] arguments = prepareArguments (self );
149149 if (sendValue != null ) {
150150 PArguments .setSpecialArgument (arguments , sendValue );
151151 }
152+ try {
153+ return call .execute (frame , null , null , null , arguments );
154+ } catch (PException e ) {
155+ self .markAsFinished ();
156+ throw e ;
157+ } finally {
158+ self .setRunning (false );
159+ self .setNextCallTarget (PythonLanguage .get (this ));
160+ }
161+ }
162+
163+ @ Specialization (guards = "!self.usesBytecode()" , replaces = "cachedAST" )
164+ @ Megamorphic
165+ Object genericAST (VirtualFrame frame , PGenerator self , Object sendValue ,
166+ @ Cached ConditionProfile hasFrameProfile ,
167+ @ Cached GenericInvokeNode call ) {
168+ self .setRunning (true );
169+ Object [] arguments = prepareArguments (self );
170+ if (sendValue != null ) {
171+ PArguments .setSpecialArgument (arguments , sendValue );
172+ }
173+ try {
174+ if (hasFrameProfile .profile (frame != null )) {
175+ return call .execute (frame , self .getCurrentCallTarget (), arguments );
176+ } else {
177+ return call .execute (self .getCurrentCallTarget (), arguments );
178+ }
179+ } catch (PException e ) {
180+ self .markAsFinished ();
181+ throw e ;
182+ } finally {
183+ self .setRunning (false );
184+ self .setNextCallTarget (PythonLanguage .get (this ));
185+ }
186+ }
187+
188+ @ Specialization (guards = {"self.usesBytecode()" , "sameCallTarget(self.getCurrentCallTarget(), call.getCallTarget())" }, limit = "getCallSiteInlineCacheMaxDepth()" )
189+ Object cached (VirtualFrame frame , PGenerator self , Object sendValue ,
190+ @ Cached ("createDirectCall(self.getCurrentCallTarget())" ) CallTargetInvokeNode call ,
191+ @ Cached ConditionProfile returnProfile ,
192+ @ Cached IsBuiltinClassProfile errorProfile ,
193+ @ Cached PRaiseNode raiseNode ) {
194+ self .setRunning (true );
195+ Object [] arguments = prepareArguments (self );
196+ if (sendValue != null ) {
197+ PArguments .setSpecialArgument (arguments , sendValue );
198+ }
152199 Object result ;
153200 try {
154201 result = call .execute (frame , null , null , null , arguments );
155202 } catch (PException e ) {
156203 self .markAsFinished ();
157- throw e ;
204+ // PEP 479 - StopIteration raised from generator body needs to be wrapped in
205+ // RuntimeError
206+ e .expectStopIteration (errorProfile );
207+ throw raiseNode .raise (RuntimeError , e .setCatchingFrameAndGetEscapedException (frame , this ), ErrorMessages .GENERATOR_RAISED_STOPITER );
158208 } finally {
159209 self .setRunning (false );
160- if (!self .isFinished ()) {
161- self .setNextCallTarget (PythonLanguage .get (this ));
210+ }
211+ if (returnProfile .profile (result == null )) {
212+ // Null result indicates a generator return
213+ Object returnValue = self .getReturnValue ();
214+ if (returnValue != PNone .NONE ) {
215+ throw raiseNode .raise (StopIteration , returnValue );
216+ } else {
217+ throw raiseNode .raise (StopIteration );
162218 }
219+ } else {
220+ self .setNextCallTarget (PythonLanguage .get (this ));
163221 }
164222 return result ;
165223 }
166224
167- @ Specialization (replaces = "cached" )
225+ @ Specialization (guards = "self.usesBytecode()" , replaces = "cached" )
168226 @ Megamorphic
169227 Object generic (VirtualFrame frame , PGenerator self , Object sendValue ,
170228 @ Cached ConditionProfile hasFrameProfile ,
171- @ Cached GenericInvokeNode call ) {
229+ @ Cached GenericInvokeNode call ,
230+ @ Cached ConditionProfile returnProfile ,
231+ @ Cached IsBuiltinClassProfile errorProfile ,
232+ @ Cached PRaiseNode raiseNode ) {
172233 self .setRunning (true );
173234 Object [] arguments = prepareArguments (self );
174235 if (sendValue != null ) {
@@ -183,12 +244,23 @@ Object generic(VirtualFrame frame, PGenerator self, Object sendValue,
183244 }
184245 } catch (PException e ) {
185246 self .markAsFinished ();
186- throw e ;
247+ // PEP 479 - StopIteration raised from generator body needs to be wrapped in
248+ // RuntimeError
249+ e .expectStopIteration (errorProfile );
250+ throw raiseNode .raise (RuntimeError , e .setCatchingFrameAndGetEscapedException (frame , this ), ErrorMessages .GENERATOR_RAISED_STOPITER );
187251 } finally {
188252 self .setRunning (false );
189- if (!self .isFinished ()) {
190- self .setNextCallTarget (PythonLanguage .get (this ));
253+ }
254+ if (returnProfile .profile (result == null )) {
255+ // Null result indicates a generator return
256+ Object returnValue = self .getReturnValue ();
257+ if (returnValue != PNone .NONE ) {
258+ throw raiseNode .raise (StopIteration , returnValue );
259+ } else {
260+ throw raiseNode .raise (StopIteration );
191261 }
262+ } else {
263+ self .setNextCallTarget (PythonLanguage .get (this ));
192264 }
193265 return result ;
194266 }
0 commit comments