gambas-source-code/main/lib/jit/gb.jit/.src/Jit.module
gambas d3c93a05e4 Work on new JIT system continues.
[INTERPRETER]
* NEW: Abort if a stack mismatch is detected after a JIT function has been called.

[GB.JIT]
* NEW: The GB_JIT_CC environment variable allows to define the C compiler that will generate the code.
* OPT: Don't call the compiler through a shell anymore.
* NEW: Support for clang.
* BUG: Don't use the "," operator anymore to write JIT code.
* BUG: Correctly free stack when leaving a function whereas we are still inside a GOSUB.
* BUG: Declare all local variables and arguments as volatile as soon the function uses CATCH or FINALLY.
2018-07-05 07:10:31 +02:00

224 lines
5 KiB
Text

' Gambas module file
Export
Class __Jit
Property Read Time As Float
Private $fTime As Float
Private $sCompiler As String
Private $aFlags As String[]
Private $hProcess As Process
Private $sResult As String
Private $bDebug As Integer
Private Sub Init()
Dim sFlag As String
Dim sCompiler As String
sCompiler = Env["GB_JIT_CC"]
If Not sCompiler Then sCompiler = "gcc"
$sCompiler = System.Find(sCompiler)
If Not $sCompiler Then Error.Raise("Compiler not found")
sFlag = Env["GB_JIT_CFLAGS"]
If Not sFlag Then sFlag = "-O3"
$aFlags = Split(sFlag, " ")
End
Private Sub RunCompiler(sInput As String, Optional sOutput As String, sOption As String) As String
Dim aExec As String[]
'Dim I As Integer
aExec = [$sCompiler]
If sOption Then aExec.Insert(Split(sOption, " "))
aExec.Insert($aFlags)
aExec.Add(sInput)
If sOutput Then
aExec.Add("-o")
aExec.Add(sOutput)
Endif
' For I = 0 To aExec.Max
' aExec[I] = Shell$(aExec[I])
' Next
If $bDebug Then Error "gb.jit: run: "; aExec.Join(" ")
$sResult = ""
$hProcess = Exec aExec For Read As "Compiler"
$hProcess.Wait
'Shell aExec.Join(" ") & " 2>&1" To sResult
Return $sResult
End
Public Sub Compiler_Read()
Dim sData As String
sData = Read #$hProcess, -1024
$sResult &= sData
End
Public Sub Compile_Error(({Error}) As String)
$sResult &= {Error}
End
Public Sub _Compile(sArch As String) As String
Dim sFile As String
Dim sDir As String
Dim sName As String
Dim sPath As String
Dim hFile As File
Dim sResult As String
Dim sPathO As String
Dim sPathSO As String
Dim fTime As Float
fTime = Timer
Try $bDebug = CInt(Env["GB_JIT_DEBUG"])
If $bDebug Then Error "gb.jit: translating "; If(sArch, sArch, "project")
If Not $sCompiler Then Init
sName = sArch
If Not sName Then sName = "gb"
sDir = File.Dir(Temp$()) &/ "jit"
Try Mkdir sDir
sPath = sDir &/ "jit.h"
If Not Exist(sPath) Then
If $bDebug Then Error "gb.jit: generating header"
hFile = Open sPath For Output Create
Print #hFile, "#define NO_CONFIG_H"
Print #hFile, File.Load("gambas.h");
Print #hFile, File.Load("jit.h");
Print #hFile, File.Load("gb.jit.h");
Print #hFile, "GB_INTERFACE * GB_PTR;"
Print #hFile, "#define GB (*GB_PTR)"
Print #hFile, "JIT_INTERFACE * JIT_PTR;"
Print #hFile, "#define JIT (*JIT_PTR)"
Print #hFile, File.Load("gb_error_common.h");
Close #hFile
If $bDebug Then
Try Kill "/tmp/jit.h"
Copy sDir &/ "jit.h" To "/tmp/jit.h"
Endif
' 'Shell $sCompiler & " -fPIC " & Shell(sPath) To sResult
' sResult = RunCompiler(sPath,, "-fPIC")
' If Not Exist(sPath & ".gch") Then
' Error "gb.jit: error: unable to generate precompiled header"
' Error sResult
' Return
' Endif
'
' If $bDebug Then
' Try Kill "/tmp/" & File.Name(sPath)
' Copy sPath To "/tmp/" & File.Name(sPath)
' Try Kill "/tmp/" & File.Name(sPath & ".gch")
' Copy sPath & ".gch" To "/tmp/" & File.Name(sPath & ".gch")
' Endif
Endif
sPath = sDir &/ sName & ".c"
If $bDebug Then Error "gb.jit: generating "; sPath
hFile = Open sPath For Output Create
Print #hFile, "#include \"jit.h\""
Print #hFile
If sArch Then
sDir = "." &/ sArch
Else
sDir = "..."
Endif
For Each sFile In Dir(sDir &/ ".gambas")
ClassStat.Stat(sDir, sFile)
If Not ClassStat.HasFast Then Continue
sFile = ClassStat.Name
If $bDebug Then Error "gb.jit: translating class "; sFile
Print #hFile, __Jit.Translate(sFile, sArch)
Next
Close #hFile
If $bDebug Then
Try Kill "/tmp/" & File.Name(sPath)
Copy sPath To "/tmp/" & File.Name(sPath)
Endif
sPathO = File.SetExt(sPath, "o")
sPathSO = File.SetExt(sPath, "so")
If $bDebug Then Error "gb.jit: compiling to "; sPathO
'gcc -c -fPIC -o foo.o foo.c
'Exec [$sCompiler, "-c", "-fPIC", "-o", File.SetExt(sPath, "o"), sPath] To sResult
'Shell $sCompiler & " -c -fPIC " & sFlag & " -o " & Shell(sPathO) & " " & Shell(sPath) & " 2>&1" To sResult
sResult = RunCompiler(sPath, sPathSO, "-w -fPIC -shared -lm")
If Not Exist(sPathSO) Then
Error "gb.jit: error: unable to compile JIT code:"
Error sResult
Return
Endif
' If $bDebug Then Error "gb.jit: linking to "; sPathSO
'
' 'gcc -shared -o libfoo.so foo.o
' 'Exec [$sCompiler, "-shared", "-o", File.SetExt(sPath, "so"), File.SetExt(sPath, "o")] To sResult
' 'Shell $sCompiler & " -shared " & sFlag & " -lm -o " & Shell(sPathSO) & " " & Shell(sPathO) & " 2>&1" To sResult
' RunCompiler(sPathO, sPathSO, "-shared -lm")
' If Not Exist(sPathSO) Then
' Error "gb.jit: warning: unable to link JIT code:"
' Error sResult
' Return
' Endif
fTime = Timer - fTime
$fTime += fTime
If $bDebug Then Error "gb.jit: done in "; Format(fTime, "0.000"); "s"
' Shell "objdump -S " & Shell(sPathSO) To sResult
' Error sResult
Return sPathSO
End
Private Function Time_Read() As Float
Return $fTime
End