Здравствуйте, elw00d, Вы писали:
E>А как это поможет в создании рантайма для динамически типизированных языков ? Ведь NameAndType фиксирован даже не как _аргумент_ инструкции (который можно на стек положить в зависимости от типа), а как параметр инструкции в байткоде ! То есть вот написали метод, который делает invokeDynamic для указанного типа+имени метода. А если тип другой ? И в каком месте выполнять свич по типам аргументов, фактически переданных методу ?
В общем-то, и раньше ничего не мешало делать динамические вызовы в JVM с использованием reflection. Просто reflection медленный, поэтому генерили по caller-классу на каждый метод. Так, можно было написать что-то в духе:
public void getMethod(String name) {
switch (name) {
case "foo":
return new FooCaller();
case "bar":
return new BarCaller();
// etc
}
}
где все Caller'ы реализуют примерно такой интерфейс:
public interface Caller {
Object call(Object... arguments);
}
и вызов, например, obj.foo() транслировать в obj.getMethod("foo").call(). А, соответственно, obj[methodName]() — в obj.getMethod(methodName).call(). Это значительно быстрее reflection, однако требует генерации огромного количества мелких классов. Специфика архитектуры JVM такова, что каждый новый класс — это довольно-таки много метаинформации, которая лежит мёртвым грузом в permgen (или просто в heap, начиная с Java 8). INVOKEDYNAMIC — это просто способ избавиться от этих накладных расходов. Вместо класса появляется новая сущность — dynamic call site'ы (который в первом приближении можно воспринимать как облегчённые классы), а сама инструкция INVOKEDYNAMIC — всего лишь декларативное описание алгоритма для порождения этих call site'ов. В итоге можно понаделать много мелких похожих друг на друга call site'ов, отличающихся лишь мелочами (например, именем вызываемого метода).
Можно было пойти по пути ускорения reflection, но у разработчиков интерпретаторов динамических языков есть очень много разных хотелок, которые трудно выразить простым reflection'ом, поэтому породили несколько более гибкий механизм.