Я внедрю виртуальную машину в x86, и мне интересно, какой дизайн даст лучшие результаты. На чем я должен сосредоточиться, чтобы раздавить сок? Я буду реализовывать всю виртуальную машину в сборке x86.
У меня не так много инструкций, и я могу выбрать их форму. Инструкции проецируются непосредственно в синтаксис smalltalk в блоках. Я выдал инструкцию, о которой думал:
^ ... # return
^null # return nothing
object # address to object
... selector: ... # message pass (in this case arity:1 selector: #selector:)
var := ... # set
var # get
Вид виртуальной машины, о котором я думал:
mov eax, [esi]
add esi, 2
mov ecx, eax
and eax, 0xff
and ecx, 0xff00 # *256
shr ecx, 5 # *8
jmp [ecx*4 + operations]
align 8:
operations:
dd retnull
dd ret
# so on...
retnull: # jumps here at retnul
# ... retnull action
ret:
# ... ret action
#etc.
Не начинайте спрашивать, зачем мне нужна еще одна реализация виртуальной машины. Интерпретирующие процедуры - это не просто материал, который вы берете в руки, когда он вам нужен. Большинство виртуальных машин, которые вы предлагаете в других местах, ориентированы на переносимость и снижение производительности. Моя цель - не мобильность, моя цель - производительность.
Причина, по которой этот интерпретатор вообще нужен, заключается в том, что блоки smalltalk в конечном итоге не интерпретируются одинаково:
A := B subclass: [
def a:x [^ x*x]
clmet b [...]
def c [...]
def d [...]
]
[ 2 < x ] whileTrue: [...]
(i isNeat) ifTrue: [...] ifFalse: [...]
List fromBlock: [
"carrots"
"apples"
"oranges" toUpper
]
Мне нужна реальная выгода от интерпретирующих подпрограмм, то есть выбора контекста, в котором следует читать программу. Конечно, хороший компилятор должен в большинстве случаев компилировать очевидные случаи, такие как: 'ifTrue: ifFalse' или 'whileTrue:' или пример списка. Потребность в переводчике не просто исчезает, потому что вы всегда можете столкнуться с ситуацией, когда вы не можете быть уверены, что блок получит ожидаемое вами лечение.