Skip to content

Commit 1643605

Browse files
committed
Dead code removal from BinaryOpCallSite
1 parent 82e0539 commit 1643605

File tree

1 file changed

+0
-381
lines changed
  • rt4core/src/main/java/uk/co/farowl/vsj4/core

1 file changed

+0
-381
lines changed

rt4core/src/main/java/uk/co/farowl/vsj4/core/PyRT.java

Lines changed: 0 additions & 381 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,6 @@ private Object fallback(Object self) throws Throwable {
265265
*/
266266
static class BinaryOpCallSite extends MutableCallSite {
267267

268-
/** Handle that marks an empty binary operation slot. */
269-
private static final MethodHandle BINARY_EMPTY =
270-
SpecialMethod.Signature.BINARY.empty;
271-
272268
/** Limit on {@link #chainLength}. */
273269
public static final int MAX_CHAIN = 6;
274270

@@ -513,383 +509,6 @@ private Object dynamicResult(BaseType vType, Object v,
513509
return r;
514510
}
515511

516-
/**
517-
* Compute the result of the call for this particular pair of
518-
* arguments, and update the site to do this efficiently for the
519-
* same class in the future, if it is safe and effective to do
520-
* so. We call this when the class of {@code v} did not match
521-
* any of the embedded guards.
522-
*
523-
* @param v left operand
524-
* @param w right operand
525-
* @return {@code op(v, w)}
526-
* @throws Throwable on errors or if not implemented
527-
*/
528-
private Object fallback_saved(Object v, Object w)
529-
throws Throwable {
530-
// TODO binary call site with shared representations
531-
/*
532-
* There is a problem with the logic of this in cases where
533-
* v and w have the same representation, that may represent
534-
* multiple types (a shared representation). Typically these
535-
* are classes defined in Python. The site will be guarded
536-
* on class, but precedence, whether we consult the left or
537-
* right operand first, depends on the Python type. We can
538-
* choose a precedence for the particular objects at hand
539-
* using their types, but we cannot validly cache the
540-
* decision for the pair of classes.
541-
*
542-
* If the two arguments have the same representation, and it
543-
* is not a SharedRepresentation, they have the same type.
544-
* If the representations differ, because the classes
545-
* differ, the sub-type relationship will apply to all pairs
546-
* of objects from the two classes.
547-
*/
548-
fallbackCount += 1;
549-
550-
Class<?> vClass = v.getClass();
551-
Representation vRep = registry.get(vClass);
552-
BaseType vType = vRep.pythonType(v);
553-
MethodHandle vMH; // e.g. type(v).__sub__
554-
555-
Class<?> wClass = w.getClass();
556-
Representation wRep = registry.get(wClass);
557-
BaseType wType = wRep.pythonType(w);
558-
MethodHandle wMH; // e.g. type(w).__rsub__
559-
560-
MethodHandle mh, targetMH;
561-
562-
/*
563-
* CPython would also test: w.__rop__ == v.__op__ as an
564-
* optimisation, but that's never the case since we always
565-
* use distinct __op__ and __rop__ methods.
566-
*/
567-
if (wType == vType) {
568-
// Same types so only try the op slot
569-
mh = singleType(vType, vRep, wRep);
570-
571-
} else if (!wType.isSubTypeOf(vType)) {
572-
// Ask left (if not empty) then right.
573-
mh = leftDominant(vType, vRep, wType, wRep);
574-
575-
} else {
576-
// Right is sub-class: ask first (if not empty).
577-
mh = rightDominant(vType, vRep, wType, wRep);
578-
}
579-
580-
/*
581-
* Compute the result for this case. If the operation
582-
* throws, it throws here and we do not bind resultMH as a
583-
* new target. If it's a one-off, we'll get another go.
584-
*/
585-
Object result = mh.invokeExact(v, w);
586-
587-
// MH for guarded invocation (becomes new target)
588-
MethodHandle guardMH =
589-
insertArguments(CLASS2_GUARD, 0, vClass, wClass);
590-
targetMH = guardWithTest(guardMH, mh, getTarget());
591-
setTarget(targetMH);
592-
593-
return result;
594-
}
595-
596-
/**
597-
* Compute a method handle in the case where both arguments
598-
* {@code (v, w)} have the same Python type, although quite
599-
* possibly different Java classes (in the case where that type
600-
* has multiple implementations). The returned handle may throw
601-
* a Python exception when invoked, if that is the correct
602-
* behaviour, but will not return {@code NotImplemented}.
603-
*
604-
* @param type the Python type of {@code v} and {@code w}
605-
* @param vRep operations of the Java class of {@code v}
606-
* @param wRep operations of the Java class of {@code w}
607-
* @return a handle that provides the result (or throws)
608-
*/
609-
private MethodHandle singleType(BaseType type,
610-
Representation vRep, Representation wRep) {
611-
612-
MethodHandle vMH;
613-
614-
// Does the type define class-specific implementations?
615-
BinopGrid binops = type.getBinopGrid(op);
616-
if (binops != null) {
617-
/*
618-
* Are the nominal implementation classes of v, w
619-
* supported as operands? These methods are not allowed
620-
* to return NotImplemented, so if there's a match, it's
621-
* the answer.
622-
*/
623-
vMH = binops.get(vRep, wRep);
624-
if (vMH != BINARY_EMPTY) { return vMH; }
625-
/*
626-
* vType provides class-specific implementations of
627-
* op(v,w), but hang on ... both have the same type.
628-
*/
629-
} else {
630-
/*
631-
* The type provides no class-specific implementation,
632-
* so use the handle in the Representation object.
633-
* Typically, this will be strongly-typed on the left
634-
* implementation class, but will have to test the
635-
* right-hand argument against supported types.
636-
*/
637-
vMH = op.handle(vRep);
638-
}
639-
640-
if (vMH == BINARY_EMPTY) {
641-
// Not defined for this type, so will throw
642-
return op.errorHandle();
643-
} else {
644-
/*
645-
* vMH is a handle that may return Py.NotImplemented,
646-
* which we must turn into an error message.
647-
*/
648-
return firstImplementer(vMH, op.errorHandle());
649-
}
650-
}
651-
652-
/**
653-
* Compute a method handle in the case where the left argument
654-
* {@code (v)} should be consulted, then the right. The returned
655-
* handle may throw a Python exception when invoked, if that is
656-
* the correct behaviour, but will not return
657-
* {@code NotImplemented}.
658-
*
659-
* @param vType the Python type of {@code v}
660-
* @param vRep operations of the Java class of {@code v}
661-
* @param wType the Python type of {@code w}
662-
* @param wRep operations of the Java class of {@code w}
663-
* @return a handle that provides the result (or throws)
664-
*/
665-
private MethodHandle leftDominant(BaseType vType,
666-
Representation vRep, BaseType wType,
667-
Representation wRep) {
668-
669-
MethodHandle resultMH, vMH, wMH;
670-
671-
// Does vType define class-specific implementations?
672-
BinopGrid binops = vType.getBinopGrid(op);
673-
if (binops != null) {
674-
/*
675-
* Are the nominal implementation classes of v, w
676-
* supported as operands? These methods are not allowed
677-
* to return NotImplemented, so if there's a match, it's
678-
* the answer.
679-
*/
680-
vMH = binops.get(vRep, wRep);
681-
if (vMH != BINARY_EMPTY) { return vMH; }
682-
/*
683-
* vType provides class-specific implementations of
684-
* op(v,w), but the signature we are looking for is not
685-
* amongst them.
686-
*/
687-
assert (vMH == BINARY_EMPTY);
688-
} else {
689-
/*
690-
* vType provides no class-specific implementation of
691-
* op(v,w). Get the handle from the Representation
692-
* object.
693-
*/
694-
vMH = op.handle(vRep);
695-
}
696-
697-
// Does wType define class-specific rop implementations?
698-
SpecialMethod rop = op.reflected;
699-
binops = wType.getBinopGrid(rop);
700-
if (binops != null) {
701-
/*
702-
* Are the nominal implementation classes of w, v
703-
* supported as operands? These methods are not allowed
704-
* to return NotImplemented, so if there's a match, it's
705-
* the only alternative to smv.
706-
*/
707-
wMH = binops.get(wRep, vRep);
708-
if (wMH != BINARY_EMPTY) {
709-
// wType provides a rop(w,v) - note ordering
710-
wMH = permuteArguments(wMH, BINOP, 1, 0);
711-
if (vMH == BINARY_EMPTY) {
712-
// It's the only offer, so it's the answer.
713-
return wMH;
714-
}
715-
/*
716-
* smv is also a valid offer, which must be given
717-
* first refusal. Only if smv returns
718-
* Py.NotImplemented, will we try smw.
719-
*/
720-
return firstImplementer(vMH, wMH);
721-
}
722-
/*
723-
* wType provides class-specific implementations of
724-
* rop(w,v), but the signature we are looking for is not
725-
* amongst them.
726-
*/
727-
assert (wMH == BINARY_EMPTY);
728-
} else {
729-
/*
730-
* wType provides no class-specific implementation of
731-
* rop(w,v). Get the handle from the Representation
732-
* object.
733-
*/
734-
wMH = rop.handle(wRep);
735-
}
736-
737-
/*
738-
* If we haven't returned a handle yet, we now have smv and
739-
* smw, two apparent offers of a handle to compute the
740-
* result for the classes at hand. Either may be empty.
741-
* Either may return Py.NotImplemented.
742-
*/
743-
if (wMH == BINARY_EMPTY) {
744-
if (vMH == BINARY_EMPTY) {
745-
// Easy case: neither slot was defined. We're done.
746-
return op.errorHandle();
747-
} else {
748-
// smv was the only one defined
749-
resultMH = vMH;
750-
}
751-
} else {
752-
// smw was defined
753-
wMH = permuteArguments(wMH, BINOP, 1, 0);
754-
if (vMH == BINARY_EMPTY) {
755-
// smv was not, so smw is the only one defined
756-
resultMH = wMH;
757-
} else {
758-
// Both were defined, so try them in order
759-
resultMH = firstImplementer(vMH, wMH);
760-
}
761-
}
762-
763-
/*
764-
* resultMH may still return Py.NotImplemented. We use
765-
* firstImplementer to turn that into an error message.
766-
* Where we could avoid this, we already returned.
767-
*/
768-
return firstImplementer(resultMH, op.errorHandle());
769-
}
770-
771-
/**
772-
* Compute a method handle in the case where the right argument
773-
* {@code (w)} should be consulted, then the left. The returned
774-
* handle may throw a Python exception when invoked, if that is
775-
* the correct behaviour, but will not return
776-
* {@code NotImplemented}.
777-
*
778-
* @param vType the Python type of {@code v}
779-
* @param vRep operations of the Java class of {@code v}
780-
* @param wType the Python type of {@code w}
781-
* @param wRep operations of the Java class of {@code w}
782-
* @return a handle that provides the result (or throws)
783-
*/
784-
private MethodHandle rightDominant(BaseType vType,
785-
Representation vRep, BaseType wType,
786-
Representation wRep) {
787-
788-
MethodHandle resultMH, vMH, wMH;
789-
790-
// Does wType define class-specific rop implementations?
791-
SpecialMethod rop = op.reflected;
792-
BinopGrid binops = wType.getBinopGrid(rop);
793-
if (binops != null) {
794-
/*
795-
* Are the nominal implementation classes of w, v
796-
* supported as operands? These methods are not allowed
797-
* to return NotImplemented, so if there's a match, it's
798-
* the answer.
799-
*/
800-
wMH = binops.get(wRep, vRep);
801-
if (wMH != BINARY_EMPTY) {
802-
// wType provides a rop(w,v) - note ordering
803-
return permuteArguments(wMH, BINOP, 1, 0);
804-
}
805-
/*
806-
* wType provides class-specific implementations of
807-
* rop(w,v), but the signature we are looking for is not
808-
* amongst them.
809-
*/
810-
assert wMH == BINARY_EMPTY;
811-
} else {
812-
/*
813-
* wType provides no class-specific implementation of
814-
* rop(w,v). Get the handle from the Representation
815-
* object.
816-
*/
817-
wMH = rop.handle(wRep);
818-
}
819-
820-
// Does vType define class-specific implementations?
821-
binops = vType.getBinopGrid(op);
822-
if (binops != null) {
823-
/*
824-
* Are the nominal implementation classes of v, w
825-
* supported as operands? These methods are not allowed
826-
* to return NotImplemented, so if there's a match, it's
827-
* the only alternative to smw.
828-
*/
829-
vMH = binops.get(vRep, wRep);
830-
if (vMH != BINARY_EMPTY) {
831-
// vType provides an op(v,w)
832-
if (wMH == BINARY_EMPTY) {
833-
// It's the only offer, so it's the answer.
834-
return vMH;
835-
}
836-
/*
837-
* smw is also a valid offer, which must be given
838-
* first refusal. Only if smw returns
839-
* Py.NotImplemented, will we try smv.
840-
*/
841-
wMH = permuteArguments(wMH, BINOP, 1, 0);
842-
return firstImplementer(wMH, vMH);
843-
}
844-
/*
845-
* vType provides class-specific implementations of
846-
* op(v,w), but the signature we are looking for is not
847-
* amongst them.
848-
*/
849-
assert vMH == BINARY_EMPTY;
850-
} else {
851-
/*
852-
* vType provides no class-specific implementation of
853-
* op(v,w). Get the handle from the Representation
854-
* object.
855-
*/
856-
vMH = op.handle(vRep);
857-
}
858-
859-
/*
860-
* If we haven't returned a handle yet, we now have smv and
861-
* smw, two apparent offers of a handle to compute the
862-
* result for the classes at hand. Either may be empty.
863-
* Either may return Py.NotImplemented.
864-
*/
865-
if (wMH == BINARY_EMPTY) {
866-
if (vMH == BINARY_EMPTY) {
867-
// Easy case: neither slot was defined. We're done.
868-
return op.errorHandle();
869-
} else {
870-
// smv was the only one defined
871-
resultMH = vMH;
872-
}
873-
} else {
874-
// smw was defined
875-
wMH = permuteArguments(wMH, BINOP, 1, 0);
876-
if (vMH == BINARY_EMPTY) {
877-
// smw is the only one defined
878-
resultMH = wMH;
879-
} else {
880-
// Both were defined, so try them in order
881-
resultMH = firstImplementer(wMH, vMH);
882-
}
883-
}
884-
885-
/*
886-
* resultMH may still return Py.NotImplemented. We use
887-
* firstImplementer to turn that into an error message.
888-
* Where we could avoid this, we already returned.
889-
*/
890-
return firstImplementer(resultMH, op.errorHandle());
891-
}
892-
893512
/**
894513
* An adapter for two method handles, {@code a} and {@code b},
895514
* such that when the returned handle is invoked, first

0 commit comments

Comments
 (0)