43
43
import com .oracle .graal .python .builtins .objects .object .ObjectBuiltinsFactory ;
44
44
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
45
45
import com .oracle .graal .python .builtins .objects .str .StringUtils .SimpleTruffleStringFormatNode ;
46
+ import com .oracle .graal .python .lib .PyLongAsLongAndOverflowNode ;
47
+ import com .oracle .graal .python .lib .PyLongCheckExactNode ;
46
48
import com .oracle .graal .python .nodes .ErrorMessages ;
47
49
import com .oracle .graal .python .nodes .PRaiseNode ;
48
50
import com .oracle .graal .python .nodes .frame .GetFrameLocalsNode ;
55
57
import com .oracle .graal .python .nodes .util .CannotCastException ;
56
58
import com .oracle .graal .python .nodes .util .CastToJavaBooleanNode ;
57
59
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
60
+ import com .oracle .graal .python .util .OverflowException ;
58
61
import com .oracle .truffle .api .CompilerDirectives ;
59
62
import com .oracle .truffle .api .RootCallTarget ;
60
63
import com .oracle .truffle .api .dsl .Bind ;
@@ -142,6 +145,7 @@ public static GetBuiltinsNode create() {
142
145
143
146
@ GenerateNodeFactory
144
147
public abstract static class GetLinenoNode extends PythonBuiltinNode {
148
+ // Kept around since it is used by other nodes
145
149
public abstract int executeInt (VirtualFrame frame , PFrame self );
146
150
147
151
@ Specialization
@@ -168,14 +172,19 @@ public static GetLinenoNode create() {
168
172
169
173
@ Builtin (name = "f_lineno" , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 2 , isGetter = true , isSetter = true )
170
174
@ GenerateNodeFactory
171
- public abstract static class SetLinenoNode extends PythonBuiltinNode {
175
+ public abstract static class LinenoNode extends PythonBuiltinNode {
172
176
public abstract Object execute (VirtualFrame frame , PFrame self , Object newLineno );
173
177
174
178
@ Specialization (guards = "isNoValue(newLineno)" )
175
179
int get (VirtualFrame frame , PFrame self , Object newLineno ,
176
180
@ Bind ("this" ) Node inliningTarget ,
177
181
@ Cached .Shared ("isCurrentFrame" ) @ Cached InlinedConditionProfile isCurrentFrameProfile ,
178
182
@ Cached .Shared ("materialize" ) @ Cached MaterializeFrameNode materializeNode ) {
183
+ syncLocationIfNeeded (frame , self , inliningTarget , isCurrentFrameProfile , materializeNode );
184
+ return self .getLine ();
185
+ }
186
+
187
+ private void syncLocationIfNeeded (VirtualFrame frame , PFrame self , Node inliningTarget , InlinedConditionProfile isCurrentFrameProfile , MaterializeFrameNode materializeNode ) {
179
188
// Special case because this builtin can be called without going through an invoke node:
180
189
// we need to sync the location of the frame if and only if 'self' represents the
181
190
// current frame. If 'self' represents another frame on the stack, the location is
@@ -184,28 +193,31 @@ int get(VirtualFrame frame, PFrame self, Object newLineno,
184
193
PFrame pyFrame = materializeNode .execute (frame , this , false , false );
185
194
assert pyFrame == self ;
186
195
}
187
- return self .getLine ();
188
196
}
189
197
190
198
@ Specialization (guards = "!isNoValue(newLineno)" )
191
199
PNone set (VirtualFrame frame , PFrame self , Object newLineno ,
192
200
@ Bind ("this" ) Node inliningTarget ,
193
201
@ Cached .Shared ("isCurrentFrame" ) @ Cached InlinedConditionProfile isCurrentFrameProfile ,
194
202
@ Cached .Shared ("materialize" ) @ Cached MaterializeFrameNode materializeNode ,
195
- @ Cached PRaiseNode .Lazy raise ) {
196
- // Special case because this builtin can be called without going through an invoke node:
197
- // we need to sync the location of the frame if and only if 'self' represents the
198
- // current frame. If 'self' represents another frame on the stack, the location is
199
- // already set
200
- if (isCurrentFrameProfile .profile (inliningTarget , frame != null && PArguments .getCurrentFrameInfo (frame ) == self .getRef ())) {
201
- PFrame pyFrame = materializeNode .execute (frame , this , false , false );
202
- assert pyFrame == self ;
203
- }
203
+ @ Cached PRaiseNode .Lazy raise ,
204
+ @ Cached PyLongCheckExactNode isLong ,
205
+ @ Cached PyLongAsLongAndOverflowNode toLong ) {
206
+ syncLocationIfNeeded (frame , self , inliningTarget , isCurrentFrameProfile , materializeNode );
204
207
if (self .isTraceArgument ()) {
205
- if (newLineno instanceof Integer x ) {
206
- self .setJumpDestLine (x );
208
+ if (isLong .execute (inliningTarget , newLineno )) {
209
+ try {
210
+ long lineno = toLong .execute (frame , inliningTarget , newLineno );
211
+ if (lineno <= Integer .MAX_VALUE && lineno >= Integer .MIN_VALUE ) {
212
+ self .setJumpDestLine ((int )lineno );
213
+ } else {
214
+ throw raise .get (inliningTarget ).raise (PythonBuiltinClassType .ValueError , ErrorMessages .LINENO_OUT_OF_RANGE );
215
+ }
216
+ } catch (OverflowException e ) {
217
+ throw raise .get (inliningTarget ).raise (PythonBuiltinClassType .ValueError , ErrorMessages .LINENO_OUT_OF_RANGE );
218
+ }
207
219
} else {
208
- throw raise .get (inliningTarget ).raise (PythonBuiltinClassType .ValueError , ErrorMessages .EXPECTED_S_GOT_P , "int" , newLineno );
220
+ throw raise .get (inliningTarget ).raise (PythonBuiltinClassType .ValueError , ErrorMessages .LINENO_MUST_BE_AN_INTEGER )
209
221
}
210
222
} else {
211
223
throw raise .get (inliningTarget ).raise (PythonBuiltinClassType .ValueError , ErrorMessages .CANT_JUMP_FROM_S_EVENT , getContext ().getThreadState (getLanguage ()).getTracingWhat ().pythonName );
0 commit comments