|
153 | 153 | import com.oracle.truffle.api.interop.ArityException;
|
154 | 154 | import com.oracle.truffle.api.interop.InteropException;
|
155 | 155 | import com.oracle.truffle.api.interop.InteropLibrary;
|
| 156 | +import com.oracle.truffle.api.interop.InvalidArrayIndexException; |
156 | 157 | import com.oracle.truffle.api.interop.TruffleObject;
|
157 | 158 | import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
158 | 159 | import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
@@ -1612,4 +1613,58 @@ Object execute(Object[] arguments,
|
1612 | 1613 | }
|
1613 | 1614 | }
|
1614 | 1615 | }
|
| 1616 | + |
| 1617 | + @ExportLibrary(InteropLibrary.class) |
| 1618 | + public static final class GraalHPyTupleFromArray extends GraalHPyContextFunction { |
| 1619 | + |
| 1620 | + @ExportMessage |
| 1621 | + Object execute(Object[] arguments, |
| 1622 | + @Cached HPyAsContextNode asContextNode, |
| 1623 | + @Cached CastToJavaIntExactNode castToJavaIntExactNode, |
| 1624 | + @CachedLibrary(limit = "3") InteropLibrary lib, |
| 1625 | + @Cached PCallHPyFunction callHelperNode, |
| 1626 | + @Cached HPyAsPythonObjectNode asPythonObjectNode, |
| 1627 | + @Cached PRaiseNode raiseNode, |
| 1628 | + @Cached PythonObjectFactory factory, |
| 1629 | + @Cached HPyAsHandleNode asHandleNode, |
| 1630 | + @Cached HPyTransformExceptionToNativeNode transformExceptionToNativeNode) throws ArityException, UnsupportedTypeException { |
| 1631 | + if (arguments.length != 3) { |
| 1632 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 1633 | + throw ArityException.create(3, arguments.length); |
| 1634 | + } |
| 1635 | + GraalHPyContext nativeContext = asContextNode.execute(arguments[0]); |
| 1636 | + Object arrayPtr = arguments[1]; |
| 1637 | + int n; |
| 1638 | + try { |
| 1639 | + n = castToJavaIntExactNode.execute(arguments[2]); |
| 1640 | + } catch (CannotCastException e) { |
| 1641 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 1642 | + throw UnsupportedTypeException.create(arguments, "third argument must fit into int"); |
| 1643 | + } |
| 1644 | + |
| 1645 | + Object typedArrayPtr = callHelperNode.call(nativeContext, GraalHPyNativeSymbols.GRAAL_HPY_FROM_HPY_ARRAY, arrayPtr, n); |
| 1646 | + if (!lib.hasArrayElements(typedArrayPtr)) { |
| 1647 | + throw CompilerDirectives.shouldNotReachHere("returned pointer object must have array type"); |
| 1648 | + } |
| 1649 | + |
| 1650 | + try { |
| 1651 | + Object[] elements = new Object[n]; |
| 1652 | + try { |
| 1653 | + for (int i = 0; i < elements.length; i++) { |
| 1654 | + elements[i] = asPythonObjectNode.execute(nativeContext, lib.readArrayElement(typedArrayPtr, i)); |
| 1655 | + } |
| 1656 | + } catch (UnsupportedMessageException e) { |
| 1657 | + throw CompilerDirectives.shouldNotReachHere(e); |
| 1658 | + } catch (InvalidArrayIndexException e) { |
| 1659 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 1660 | + throw raiseNode.raise(SystemError, "Cannot access index %d although array should have size %d ", e.getInvalidIndex(), n); |
| 1661 | + } |
| 1662 | + |
| 1663 | + return asHandleNode.execute(nativeContext, factory.createTuple(elements)); |
| 1664 | + } catch (PException e) { |
| 1665 | + transformExceptionToNativeNode.execute(nativeContext, e); |
| 1666 | + return nativeContext.getNullHandle(); |
| 1667 | + } |
| 1668 | + } |
| 1669 | + } |
1615 | 1670 | }
|
0 commit comments