|
16 | 16 | import java.util.Arrays;
|
17 | 17 |
|
18 | 18 | import com.oracle.truffle.api.TruffleSafepoint;
|
| 19 | +import com.oracle.truffle.api.dsl.GenerateCached; |
| 20 | +import com.oracle.truffle.api.dsl.GenerateInline; |
19 | 21 | import com.oracle.truffle.api.dsl.NeverDefault;
|
20 | 22 | import com.oracle.truffle.api.nodes.Node;
|
21 | 23 | import com.oracle.truffle.api.object.Shape;
|
@@ -1540,89 +1542,101 @@ public void accept(CallBlockNode yieldNode, RubyArray array, Object state, Objec
|
1540 | 1542 | @NodeChild(value = "format", type = RubyBaseNodeWithExecute.class)
|
1541 | 1543 | @CoreMethod(names = "pack", required = 1)
|
1542 | 1544 | @ReportPolymorphism
|
1543 |
| - public abstract static class PackNode extends CoreMethodNode { |
| 1545 | + public abstract static class ArrayPackNode extends CoreMethodNode { |
1544 | 1546 |
|
1545 |
| - @Child private TruffleString.FromByteArrayNode fromByteArrayNode = TruffleString.FromByteArrayNode.create(); |
| 1547 | + @Specialization |
| 1548 | + protected RubyString pack(RubyArray array, Object format, |
| 1549 | + @Cached ToStrNode toStrNode, |
| 1550 | + @Cached PackNode packNode) { |
| 1551 | + final var formatAsString = toStrNode.execute(this, format); |
| 1552 | + return packNode.execute(this, array, formatAsString); |
| 1553 | + } |
| 1554 | + } |
| 1555 | + |
| 1556 | + @GenerateCached(false) |
| 1557 | + @GenerateInline |
| 1558 | + public abstract static class PackNode extends RubyBaseNode { |
| 1559 | + |
| 1560 | + public abstract RubyString execute(Node node, RubyArray array, Object format); |
1546 | 1561 |
|
1547 | 1562 | @Specialization(
|
1548 | 1563 | guards = {
|
1549 |
| - "libFormat.isRubyString(formatAsString)", |
1550 |
| - "equalNode.execute(libFormat, formatAsString, cachedFormat, cachedEncoding)" }, |
| 1564 | + "libFormat.isRubyString(format)", |
| 1565 | + "equalNode.execute(libFormat, format, cachedFormat, cachedEncoding)" }, |
1551 | 1566 | limit = "getCacheLimit()")
|
1552 |
| - protected RubyString packCached(RubyArray array, Object format, |
1553 |
| - @Cached @Shared ToStrNode toStrNode, |
1554 |
| - @Bind("toStrNode.execute(this, format)") Object formatAsString, |
| 1567 | + protected static RubyString packCached(Node node, RubyArray array, Object format, |
1555 | 1568 | @Cached @Shared InlinedBranchProfile exceptionProfile,
|
1556 | 1569 | @Cached @Shared InlinedConditionProfile resizeProfile,
|
1557 | 1570 | @Cached @Shared RubyStringLibrary libFormat,
|
1558 | 1571 | @Cached @Shared WriteObjectFieldNode writeAssociatedNode,
|
1559 |
| - @Cached("asTruffleStringUncached(formatAsString)") TruffleString cachedFormat, |
1560 |
| - @Cached("libFormat.getEncoding(formatAsString)") RubyEncoding cachedEncoding, |
| 1572 | + @Cached @Shared TruffleString.FromByteArrayNode fromByteArrayNode, |
| 1573 | + @Cached("asTruffleStringUncached(format)") TruffleString cachedFormat, |
| 1574 | + @Cached("libFormat.getEncoding(format)") RubyEncoding cachedEncoding, |
1561 | 1575 | @Cached("cachedFormat.byteLength(cachedEncoding.tencoding)") int cachedFormatLength,
|
1562 |
| - @Cached("create(compileFormat(getJavaString(formatAsString)))") DirectCallNode callPackNode, |
| 1576 | + @Cached("create(compileFormat(node, getJavaString(format)))") DirectCallNode callPackNode, |
1563 | 1577 | @Cached StringHelperNodes.EqualNode equalNode) {
|
1564 | 1578 | final BytesResult result;
|
1565 | 1579 | try {
|
1566 | 1580 | result = (BytesResult) callPackNode.call(
|
1567 | 1581 | new Object[]{ array.getStore(), array.size, false, null });
|
1568 | 1582 | } catch (FormatException e) {
|
1569 |
| - exceptionProfile.enter(this); |
1570 |
| - throw FormatExceptionTranslator.translate(getContext(), this, e); |
| 1583 | + exceptionProfile.enter(node); |
| 1584 | + throw FormatExceptionTranslator.translate(getContext(node), node, e); |
1571 | 1585 | }
|
1572 | 1586 |
|
1573 |
| - return finishPack(cachedFormatLength, result, resizeProfile, writeAssociatedNode); |
| 1587 | + return finishPack(node, cachedFormatLength, result, resizeProfile, writeAssociatedNode, fromByteArrayNode); |
1574 | 1588 | }
|
1575 | 1589 |
|
1576 |
| - @Specialization(guards = { "libFormat.isRubyString(formatAsString)" }, replaces = "packCached", limit = "1") |
1577 |
| - protected RubyString packUncached(RubyArray array, Object format, |
1578 |
| - @Cached @Shared ToStrNode toStrNode, |
1579 |
| - @Bind("toStrNode.execute(this, format)") Object formatAsString, |
| 1590 | + @Specialization(guards = { "libFormat.isRubyString(format)" }, replaces = "packCached", limit = "1") |
| 1591 | + protected static RubyString packUncached(Node node, RubyArray array, Object format, |
1580 | 1592 | @Cached @Shared InlinedBranchProfile exceptionProfile,
|
1581 | 1593 | @Cached @Shared InlinedConditionProfile resizeProfile,
|
1582 | 1594 | @Cached @Shared RubyStringLibrary libFormat,
|
1583 | 1595 | @Cached @Shared WriteObjectFieldNode writeAssociatedNode,
|
| 1596 | + @Cached @Shared TruffleString.FromByteArrayNode fromByteArrayNode, |
1584 | 1597 | @Cached ToJavaStringNode toJavaStringNode,
|
1585 | 1598 | @Cached IndirectCallNode callPackNode) {
|
1586 |
| - final String formatString = toJavaStringNode.execute(formatAsString); |
| 1599 | + final String formatString = toJavaStringNode.execute(format); |
1587 | 1600 |
|
1588 | 1601 | final BytesResult result;
|
1589 | 1602 | try {
|
1590 | 1603 | result = (BytesResult) callPackNode.call(
|
1591 |
| - compileFormat(formatString), |
| 1604 | + compileFormat(node, formatString), |
1592 | 1605 | new Object[]{ array.getStore(), array.size, false, null });
|
1593 | 1606 | } catch (FormatException e) {
|
1594 |
| - exceptionProfile.enter(this); |
1595 |
| - throw FormatExceptionTranslator.translate(getContext(), this, e); |
| 1607 | + exceptionProfile.enter(node); |
| 1608 | + throw FormatExceptionTranslator.translate(getContext(node), node, e); |
1596 | 1609 | }
|
1597 | 1610 |
|
1598 |
| - int formatLength = libFormat.getTString(formatAsString).byteLength(libFormat.getTEncoding(formatAsString)); |
1599 |
| - return finishPack(formatLength, result, resizeProfile, writeAssociatedNode); |
| 1611 | + int formatLength = libFormat.getTString(format).byteLength(libFormat.getTEncoding(format)); |
| 1612 | + return finishPack(node, formatLength, result, resizeProfile, writeAssociatedNode, fromByteArrayNode); |
1600 | 1613 | }
|
1601 | 1614 |
|
1602 |
| - private RubyString finishPack(int formatLength, BytesResult result, InlinedConditionProfile resizeProfile, |
1603 |
| - WriteObjectFieldNode writeAssociatedNode) { |
| 1615 | + private static RubyString finishPack(Node node, int formatLength, BytesResult result, |
| 1616 | + InlinedConditionProfile resizeProfile, |
| 1617 | + WriteObjectFieldNode writeAssociatedNode, TruffleString.FromByteArrayNode fromByteArrayNode) { |
1604 | 1618 | byte[] bytes = result.getOutput();
|
1605 | 1619 |
|
1606 |
| - if (resizeProfile.profile(this, bytes.length != result.getOutputLength())) { |
| 1620 | + if (resizeProfile.profile(node, bytes.length != result.getOutputLength())) { |
1607 | 1621 | bytes = Arrays.copyOf(bytes, result.getOutputLength());
|
1608 | 1622 | }
|
1609 | 1623 |
|
1610 | 1624 | final RubyEncoding rubyEncoding = result.getEncoding().getEncodingForLength(formatLength);
|
1611 |
| - final RubyString string = createString(fromByteArrayNode, bytes, rubyEncoding); |
| 1625 | + final RubyString string = createString(node, fromByteArrayNode, bytes, rubyEncoding); |
1612 | 1626 |
|
1613 | 1627 | if (result.getAssociated() != null) {
|
1614 |
| - writeAssociatedNode.execute(this, string, Layouts.ASSOCIATED_IDENTIFIER, result.getAssociated()); |
| 1628 | + writeAssociatedNode.execute(node, string, Layouts.ASSOCIATED_IDENTIFIER, result.getAssociated()); |
1615 | 1629 | }
|
1616 | 1630 |
|
1617 | 1631 | return string;
|
1618 | 1632 | }
|
1619 | 1633 |
|
1620 | 1634 | @TruffleBoundary
|
1621 |
| - protected RootCallTarget compileFormat(String format) { |
| 1635 | + protected static RootCallTarget compileFormat(Node node, String format) { |
1622 | 1636 | try {
|
1623 |
| - return new PackCompiler(getLanguage(), this).compile(format); |
| 1637 | + return new PackCompiler(getLanguage(node), node).compile(format); |
1624 | 1638 | } catch (DeferredRaiseException dre) {
|
1625 |
| - throw dre.getException(getContext()); |
| 1639 | + throw dre.getException(getContext(node)); |
1626 | 1640 | }
|
1627 | 1641 | }
|
1628 | 1642 |
|
|
0 commit comments