|
71 | 71 | import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; |
72 | 72 | import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; |
73 | 73 | import com.oracle.graal.python.nodes.util.CastToJavaStringNode; |
74 | | -import com.oracle.graal.python.nodes.util.CastToJavaStringNodeGen; |
75 | 74 | import com.oracle.graal.python.runtime.PythonCore; |
76 | 75 | import com.oracle.graal.python.runtime.exception.PythonErrorType; |
77 | 76 | import com.oracle.truffle.api.CompilerDirectives; |
@@ -504,82 +503,77 @@ public PDictView values(PDict self) { |
504 | 503 | @GenerateNodeFactory |
505 | 504 | public abstract static class ReprNode extends PythonUnaryBuiltinNode { |
506 | 505 | @ValueType |
507 | | - private static final class ReprState { |
508 | | - private final PDict self; |
| 506 | + protected static final class ReprState { |
509 | 507 | private final HashingStorage dictStorage; |
510 | 508 | private final StringBuilder result; |
511 | 509 |
|
512 | | - ReprState(PDict self, HashingStorage dictStorage, StringBuilder result) { |
513 | | - this.self = self; |
| 510 | + ReprState(HashingStorage dictStorage, StringBuilder result) { |
514 | 511 | this.dictStorage = dictStorage; |
515 | 512 | this.result = result; |
516 | 513 | } |
517 | 514 | } |
518 | 515 |
|
519 | | - static final class EachRepr extends HashingStorageLibrary.ForEachNode<ReprState> { |
520 | | - @Child LookupAndCallUnaryDynamicNode reprKeyNode; |
521 | | - @Child LookupAndCallUnaryDynamicNode reprValueNode; |
522 | | - @Child CastToJavaStringNode castStr; |
523 | | - @Child PRaiseNode raiseNode; |
524 | | - @Child HashingStorageLibrary lib; |
| 516 | + abstract static class EachRepr extends HashingStorageLibrary.ForEachNode<ReprState> { |
525 | 517 | private final int limit; |
526 | 518 |
|
527 | 519 | EachRepr(int limit) { |
528 | 520 | this.limit = limit; |
529 | 521 | } |
530 | 522 |
|
531 | | - static final EachRepr create(int limit) { |
532 | | - return new EachRepr(limit); |
| 523 | + protected final int getLimit() { |
| 524 | + return limit; |
533 | 525 | } |
534 | 526 |
|
| 527 | + public abstract ReprState executeReprState(Object key, ReprState arg); |
| 528 | + |
535 | 529 | @Override |
536 | | - public ReprState execute(Object key, ReprState s) { |
537 | | - if (lib == null) { |
538 | | - lib = insert(HashingStorageLibrary.getFactory().createDispatched(limit)); |
539 | | - } |
540 | | - Object value = lib.getItem(s.dictStorage, key); |
541 | | - if (reprKeyNode == null) { |
542 | | - reprKeyNode = insert(LookupAndCallUnaryDynamicNode.create()); |
543 | | - } |
| 530 | + public final ReprState execute(Object key, ReprState arg) { |
| 531 | + return executeReprState(key, arg); |
| 532 | + } |
| 533 | + |
| 534 | + @Specialization |
| 535 | + public ReprState dict(Object key, ReprState s, |
| 536 | + @Cached LookupAndCallUnaryDynamicNode reprKeyNode, |
| 537 | + @Cached LookupAndCallUnaryDynamicNode reprValueNode, |
| 538 | + @Cached CastToJavaStringNode castStr, |
| 539 | + @Cached PRaiseNode raiseNode, |
| 540 | + @Cached("createBinaryProfile()") ConditionProfile lengthCheck, |
| 541 | + @Cached("createBinaryProfile()") ConditionProfile nullKeyCheck, |
| 542 | + @Cached("createBinaryProfile()") ConditionProfile nullValueCheck, |
| 543 | + @CachedLibrary(limit = "getLimit()") HashingStorageLibrary lib) { |
544 | 544 | Object keyRepr = reprKeyNode.executeObject(key, __REPR__); |
545 | | - if (reprValueNode == null) { |
546 | | - reprValueNode = insert(LookupAndCallUnaryDynamicNode.create()); |
547 | | - } |
548 | | - Object valueRepr = value != s.self ? reprValueNode.executeObject(value, __REPR__) : "{...}"; |
549 | | - if (castStr == null) { |
550 | | - castStr = insert(CastToJavaStringNodeGen.create()); |
551 | | - } |
552 | 545 | String keyReprString = castStr.execute(keyRepr); |
553 | | - checkString(keyReprString); |
| 546 | + if (nullKeyCheck.profile(keyReprString == null)) { |
| 547 | + throw raiseNode.raise(PythonErrorType.TypeError, "__repr__ returned non-string (type %s)", keyRepr); |
| 548 | + } |
| 549 | + |
| 550 | + Object value = lib.getItem(s.dictStorage, key); |
| 551 | + Object valueRepr = value != s.dictStorage ? reprValueNode.executeObject(value, __REPR__) : "{...}"; |
554 | 552 | String valueReprString = castStr.execute(valueRepr); |
555 | | - checkString(valueReprString); |
| 553 | + if (nullValueCheck.profile(valueReprString == null)) { |
| 554 | + throw raiseNode.raise(PythonErrorType.TypeError, "__repr__ returned non-string (type %s)", valueRepr); |
| 555 | + } |
556 | 556 |
|
557 | | - if (s.result.length() > 0) { |
| 557 | + // assuming '{' is inserted already |
| 558 | + if (lengthCheck.profile(s.result.length() > 1)) { |
558 | 559 | sbAppend(s.result, ", "); |
559 | 560 | } |
560 | | - s.result.append(keyReprString).append(": ").append(valueReprString); |
| 561 | + sbAppend(s.result, keyReprString); |
| 562 | + sbAppend(s.result, ": "); |
| 563 | + sbAppend(s.result, valueReprString); |
561 | 564 | return s; |
562 | 565 | } |
563 | 566 |
|
564 | | - private void checkString(Object strObj) { |
565 | | - if (!(strObj instanceof String)) { |
566 | | - if (raiseNode == null) { |
567 | | - raiseNode = insert(PRaiseNode.create()); |
568 | | - } |
569 | | - throw raiseNode.raise(PythonErrorType.TypeError, "__repr__ returned non-string (type %s)", strObj); |
570 | | - } |
571 | | - } |
572 | 567 | } |
573 | 568 |
|
574 | 569 | @Specialization(limit = "3") // use same limit as for EachRepr nodes library |
575 | 570 | public Object repr(PDict self, |
576 | 571 | @Cached("create(3)") EachRepr consumerNode, |
577 | 572 | @CachedLibrary("self.getDictStorage()") HashingStorageLibrary lib) { |
578 | | - StringBuilder result = new StringBuilder(); |
579 | | - sbAppend(result, "{"); |
| 573 | + StringBuilder keyValue = new StringBuilder("{"); |
580 | 574 | HashingStorage dictStorage = self.getDictStorage(); |
581 | | - lib.forEach(dictStorage, consumerNode, new ReprState(self, dictStorage, result)); |
582 | | - return sbAppend(result, "}").toString(); |
| 575 | + lib.forEach(dictStorage, consumerNode, new ReprState(dictStorage, keyValue)); |
| 576 | + return sbAppend(keyValue, "}").toString(); |
583 | 577 | } |
584 | 578 |
|
585 | 579 | @TruffleBoundary |
|
0 commit comments