Ich bin momentan dabei Inline-Assembler in meinen Interpreter zu integrieren.
Wichtig dabei ist, dass ich den ASM-Code möglichst nur einmalig und möglichst vor dem "Kompilieren" in Opcodes übersetzen möchte.
Bei ASM-JIT-Kompilierung gäbe es mein beschriebenes Problem gar nicht. Aber JIT soll wirklich der letzte Ausweg sein. Ein Notfallplan sozusagen.
Meine Ursprungsidee war einfach und sollte prinzipiell auch klappen.
Sobald mein Interpreter die Stelle des Opcodes erreicht schreibt er ihn in einen Bereich der ausführbar ist und springt ihn an, anschließend wird zurückgesprungen.
Ein Problem gibt es jetzt nur wenn ich mit dem Code-Stück kommunizieren möchte.
Meine Anfangsidee war "einfach" die Werte auf den Stack zu pushen, die ich verwenden möchte und im ASM-Code muss ich sie dann nur poppen.
Pseudocode mäßig also so:
Das Problem dabei ist, dass mein Interpreter ja erst Push interpretieren muss, weswegen ich nicht weiß ob der Stack bis zum Execute nicht schon wieder zugemüllt ist.
Eine Idee, die ich dann hatte war einen extra Speicherbereich zu allokieren für meinen eigenen Stack.
Also in etwa so:
Aber hier liegt das Problem jetzt, dass ich nicht weiß ob mein Interpreter beim Interpretieren vom "Push" Werte von meinem alten Stack braucht.
Da ich vollen Zugriff auf den zu generierenden ASM-Code habe kann ich auch automatisiert beliebig ASM-Code einfügen lassen falls nötig.
Momentan benutze ich zum Compilen während dem "Compilen von meinem Skriptcode" FASM, um den ASM-Code in den entsprechenden Opcode umzuwandeln.
Wie gesagt würde ich das Ganze JIT machen, könnte ich einfach den Pointer zu den Variablen reinschreiben lassen in den ASM-Code und dann compilen, aber JIT will ich halt eigentlich nicht.
Hat jemand noch eine andere Idee wie ich trotzdem eine Art Parameterübergabe machen kann?
Wichtig dabei ist, dass ich den ASM-Code möglichst nur einmalig und möglichst vor dem "Kompilieren" in Opcodes übersetzen möchte.
Bei ASM-JIT-Kompilierung gäbe es mein beschriebenes Problem gar nicht. Aber JIT soll wirklich der letzte Ausweg sein. Ein Notfallplan sozusagen.
Meine Ursprungsidee war einfach und sollte prinzipiell auch klappen.
Sobald mein Interpreter die Stelle des Opcodes erreicht schreibt er ihn in einen Bereich der ausführbar ist und springt ihn an, anschließend wird zurückgesprungen.
Ein Problem gibt es jetzt nur wenn ich mit dem Code-Stück kommunizieren möchte.
Meine Anfangsidee war "einfach" die Werte auf den Stack zu pushen, die ich verwenden möchte und im ASM-Code muss ich sie dann nur poppen.
Pseudocode mäßig also so:
PHP Code:
ByteArray var = #CompileASM("Pop edx \n Pop ecx \n add edx,ecx")
int var2=10
int var3=20
Push(var2)
Push(var3)
Execute(var)
Eine Idee, die ich dann hatte war einen extra Speicherbereich zu allokieren für meinen eigenen Stack.
Also in etwa so:
PHP Code:
ByteArray var = #CompileASM("Pop edx \n Pop ecx \n add edx,ecx")
int var2=10
int var3=20
int adresse = VirtualAlloc(...)
int alteAdresse
asm
{
mov alteAdresse, esp
mov esp, adresse
}
Push(var2)
Push(var3)
asm
{
mov esp, alteAdresse
}
asm
{
mov esp, adresse
}
Execute(var)
Da ich vollen Zugriff auf den zu generierenden ASM-Code habe kann ich auch automatisiert beliebig ASM-Code einfügen lassen falls nötig.
Momentan benutze ich zum Compilen während dem "Compilen von meinem Skriptcode" FASM, um den ASM-Code in den entsprechenden Opcode umzuwandeln.
Wie gesagt würde ich das Ganze JIT machen, könnte ich einfach den Pointer zu den Variablen reinschreiben lassen in den ASM-Code und dann compilen, aber JIT will ich halt eigentlich nicht.
Hat jemand noch eine andere Idee wie ich trotzdem eine Art Parameterübergabe machen kann?