.smali-вызов-виртуальный и вызов-супер

Я пытаюсь создать график вызовов на основе файла .smali. Однако я столкнулся с запутанным случаем следующим образом:

.super Landroid/graphics/drawable/Drawable;
.source "SBarExp.java"

.method public final setBounds(Landroid/graphics/Rect;)V
  .line 514
  iget-object v2, p0, Lcom/sds/android/ttpod/app/modules/skin/view/SeekBarExpansion$a;->b:Landroid/graphics/drawable/Drawable;
  invoke-virtual {v2, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
  .line 515
  invoke-super {p0, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
.end method

Насколько я понимаю, «invoke-super» просто означает, что он вызовет родительский метод, поэтому «invoke-super {p0, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds( IIII)V» можно интерпретировать как «Landroid/graphics/drawable/Drawable;->setBounds(IIII)V»?

Если да, я хотел бы знать, совпадает ли "invoke-virtual {v2, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V" с "invoke-super { p0, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V"?

Если нет, то в чем разница? Если да, то почему он вызывает один и тот же метод дважды (по-разному)?

Пожалуйста, помогите, большое спасибо!


person yi2ng2    schedule 07.05.2014    source источник
comment
Вы смотрите на скрытую реализацию шаблона объектно-ориентированного проектирования, где первый аргумент часто указывает объект объекта, поэтому, среди прочего, я считаю, что разница в первом аргументе означает, что первый вызов действует на другой объект. объект (вероятно, хранящийся в поле экземпляра), в то время как второй действует сам на себя.   -  person Chris Stratton    schedule 07.05.2014
comment
Привет Крис, спасибо за ваш быстрый ответ. Итак, могу ли я понять так: оба вызова вызывают один и тот же метод (один и тот же класс), при условии, что они передают разные объекты в качестве аргументов?   -  person yi2ng2    schedule 07.05.2014


Ответы (1)


invoke-virtual выполняет поиск виртуальной таблицы, используя виртуальную таблицу, связанную с классом целевого объекта (т. е. фактический тип времени выполнения первого аргумента).

Тем не менее, invoke-super немного отличается. Он выполняет поиск в виртуальной таблице, используя суперкласс класса, содержащего выполняемый метод. В частности, обратите внимание, что поиск в виртуальной таблице не использует и не зависит от типа времени выполнения целевого объекта.

В вашем примере инструкция invoke-virtual вызывается в результате

iget-object v2, p0, Lcom/sds/android/ttpod/app/modules/skin/view/SeekBarExpansion$a;->b:Landroid/graphics/drawable/Drawable;

На данный момент фактический вызываемый метод зависит от фактического типа v2, который может быть любым подклассом Drawable.

Инструкция invoke-super вызывается для регистра p0, который, вероятно, содержит ссылку "this" для текущего объекта. Однако тип среды выполнения p0 на самом деле не имеет значения. Инструкция invoke-super всегда будет вызывать реализацию setBounds Drawable, независимо от типа p0 во время выполнения.

person JesusFreke    schedule 07.05.2014
comment
Привет, спасибо за ваш ответ. Таким образом, в этом случае invoke-super всегда будет вызывать Landroid/graphics/drawable/Drawable;->setBounds(IIII)V, потому что он не будет принимать во внимание тип времени выполнения p0. Но invoke-virtual будет вызывать другой метод (зависит от типа v2). В моем случае я больше всего думаю о том, чтобы нарисовать график вызовов. Итак, у меня есть еще одно сомнение в том, как я могу узнать, какой точный метод наконец вызывается виртуальным вызовом? Спасибо за помощь! - person yi2ng2; 09.05.2014
comment
Вам придется использовать статический анализ, чтобы попытаться определить возможные конкретные типы v2 в этой точке, и добавить преимущество к этому методу в каждом возможном типе. - person JesusFreke; 09.05.2014