|
159 | 159 | import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
|
160 | 160 | import com.oracle.graal.python.nodes.frame.GetCurrentFrameRef;
|
161 | 161 | import com.oracle.graal.python.nodes.object.GetClassNode;
|
| 162 | +import com.oracle.graal.python.nodes.object.InlinedGetClassNode; |
| 163 | +import com.oracle.graal.python.nodes.object.InlinedGetClassNode.GetPythonObjectClassNode; |
162 | 164 | import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
|
163 | 165 | import com.oracle.graal.python.nodes.truffle.PythonTypes;
|
164 | 166 | import com.oracle.graal.python.nodes.util.CannotCastException;
|
|
179 | 181 | import com.oracle.truffle.api.CompilerDirectives;
|
180 | 182 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
181 | 183 | import com.oracle.truffle.api.TruffleLogger;
|
| 184 | +import com.oracle.truffle.api.dsl.Bind; |
182 | 185 | import com.oracle.truffle.api.dsl.Cached;
|
183 | 186 | import com.oracle.truffle.api.dsl.Cached.Exclusive;
|
184 | 187 | import com.oracle.truffle.api.dsl.Cached.Shared;
|
@@ -214,14 +217,14 @@ public abstract class CExtNodes {
|
214 | 217 | private static final String J_SUBTYPE_NEW = "_subtype_new";
|
215 | 218 |
|
216 | 219 | @GenerateUncached
|
217 |
| - abstract static class ImportCAPISymbolNode extends PNodeWithContext { |
| 220 | + public abstract static class ImportCAPISymbolNode extends PNodeWithContext { |
218 | 221 |
|
219 | 222 | public abstract Object execute(NativeCAPISymbol symbol);
|
220 | 223 |
|
221 | 224 | @Specialization
|
222 |
| - Object doGeneric(NativeCAPISymbol name, |
| 225 | + static Object doGeneric(NativeCAPISymbol name, |
223 | 226 | @Cached ImportCExtSymbolNode importCExtSymbolNode) {
|
224 |
| - return importCExtSymbolNode.execute(PythonContext.get(this).getCApiContext(), name); |
| 227 | + return importCExtSymbolNode.execute(PythonContext.get(importCExtSymbolNode).getCApiContext(), name); |
225 | 228 | }
|
226 | 229 | }
|
227 | 230 |
|
@@ -339,29 +342,47 @@ public static StringSubtypeNew create() {
|
339 | 342 | // -----------------------------------------------------------------------------------------------------------------
|
340 | 343 | public abstract static class FromNativeSubclassNode extends Node {
|
341 | 344 |
|
342 |
| - public abstract Double execute(VirtualFrame frame, PythonNativeObject object); |
| 345 | + public abstract Double execute(VirtualFrame frame, PythonAbstractNativeObject object); |
343 | 346 |
|
344 | 347 | @Specialization
|
345 |
| - @SuppressWarnings("unchecked") |
346 |
| - public Double doDouble(VirtualFrame frame, PythonNativeObject object, |
347 |
| - @Exclusive @Cached GetClassNode getClass, |
348 |
| - @Exclusive @Cached IsSubtypeNode isSubtype, |
| 348 | + static Double doDouble(VirtualFrame frame, PythonAbstractNativeObject object, |
| 349 | + @Bind("this") Node inliningTarget, |
| 350 | + @Cached GetPythonObjectClassNode getClass, |
| 351 | + @Cached IsSubtypeNode isSubtype, |
349 | 352 | @Exclusive @Cached ToSulongNode toSulongNode,
|
350 | 353 | @CachedLibrary(limit = "1") InteropLibrary interopLibrary,
|
351 | 354 | @Exclusive @Cached ImportCAPISymbolNode importCAPISymbolNode) {
|
352 |
| - if (isFloatSubtype(frame, object, getClass, isSubtype)) { |
353 |
| - try { |
354 |
| - return (Double) interopLibrary.execute(importCAPISymbolNode.execute(FUN_PY_FLOAT_AS_DOUBLE), toSulongNode.execute(object)); |
355 |
| - } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) { |
356 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
357 |
| - throw new IllegalStateException("C object conversion function failed", e); |
358 |
| - } |
| 355 | + if (isFloatSubtype(frame, inliningTarget, object, getClass, isSubtype)) { |
| 356 | + return readObFval(object, toSulongNode, interopLibrary, importCAPISymbolNode); |
359 | 357 | }
|
360 | 358 | return null;
|
361 | 359 | }
|
362 | 360 |
|
363 |
| - public boolean isFloatSubtype(VirtualFrame frame, PythonNativeObject object, GetClassNode getClass, IsSubtypeNode isSubtype) { |
364 |
| - return isSubtype.execute(frame, getClass.execute(object), PythonContext.get(this).lookupType(PythonBuiltinClassType.PFloat)); |
| 361 | + public static Double readObFval(PythonAbstractNativeObject object, ToSulongNode toSulongNode, InteropLibrary interopLibrary, ImportCAPISymbolNode importCAPISymbolNode) { |
| 362 | + Object res; |
| 363 | + try { |
| 364 | + res = interopLibrary.execute(importCAPISymbolNode.execute(FUN_PY_FLOAT_AS_DOUBLE), toSulongNode.execute(object)); |
| 365 | + } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) { |
| 366 | + throw CompilerDirectives.shouldNotReachHere(e); |
| 367 | + } |
| 368 | + |
| 369 | + if (res instanceof Double) { |
| 370 | + return (Double) res; |
| 371 | + } |
| 372 | + /* |
| 373 | + * In case we want to be very correct, we would need to use |
| 374 | + * InteropLibrary.fitsInDouble/asDouble here. |
| 375 | + */ |
| 376 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 377 | + throw CompilerDirectives.shouldNotReachHere(String.format("%s cannot be interpreted as Java double", object)); |
| 378 | + } |
| 379 | + |
| 380 | + public static boolean isFloatSubtype(VirtualFrame frame, Node inliningTarget, Object object, InlinedGetClassNode getClass, IsSubtypeNode isSubtype) { |
| 381 | + return isSubtype.execute(frame, getClass.execute(inliningTarget, object), PythonBuiltinClassType.PFloat); |
| 382 | + } |
| 383 | + |
| 384 | + public static boolean isFloatSubtype(VirtualFrame frame, Node inliningTarget, PythonAbstractNativeObject object, GetPythonObjectClassNode getClass, IsSubtypeNode isSubtype) { |
| 385 | + return isSubtype.execute(frame, getClass.execute(inliningTarget, object), PythonBuiltinClassType.PFloat); |
365 | 386 | }
|
366 | 387 |
|
367 | 388 | @NeverDefault
|
|
0 commit comments