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.
This commit is contained in:
gambas 2018-07-05 07:05:53 +02:00
parent 6fc6a48818
commit d3c93a05e4
5 changed files with 158 additions and 106 deletions

View File

@ -238,7 +238,7 @@ void JIT_exec(bool ret_on_stack)
PROFILE_LEAVE_FUNCTION();
if (SP != sp)
fprintf(stderr, "SP: %+ld !\n", SP - sp);
ERROR_panic("Stack mismatch in JIT function (sp %+ld)\n", SP - sp);
if (func->type != T_VOID)
{

View File

@ -8,12 +8,20 @@ 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 = System.Find("gcc")
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"
@ -25,8 +33,7 @@ End
Private Sub RunCompiler(sInput As String, Optional sOutput As String, sOption As String) As String
Dim aExec As String[]
Dim sResult As String
Dim I As Integer
'Dim I As Integer
aExec = [$sCompiler]
If sOption Then aExec.Insert(Split(sOption, " "))
@ -37,17 +44,35 @@ Private Sub RunCompiler(sInput As String, Optional sOutput As String, sOption As
aExec.Add(sOutput)
Endif
For I = 0 To aExec.Max
aExec[I] = Shell$(aExec[I])
Next
' For I = 0 To aExec.Max
' aExec[I] = Shell$(aExec[I])
' Next
'Exec aExec Error To sResult
Shell aExec.Join(" ") & " 2>&1" To sResult
If $bDebug Then Error "gb.jit: run: "; aExec.Join(" ")
Return sResult
$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
@ -60,13 +85,12 @@ Public Sub _Compile(sArch As String) As String
Dim sPathO As String
Dim sPathSO As String
Dim fTime As Float
Dim bDebug As Boolean
fTime = Timer
Try bDebug = CInt(Env["GB_JIT_DEBUG"])
Try $bDebug = CInt(Env["GB_JIT_DEBUG"])
If bDebug Then Error "gb.jit: translating "; If(sArch, sArch, "project")
If $bDebug Then Error "gb.jit: translating "; If(sArch, sArch, "project")
If Not $sCompiler Then Init
@ -81,7 +105,7 @@ Public Sub _Compile(sArch As String) As String
If Not Exist(sPath) Then
If bDebug Then Error "gb.jit: generating header"
If $bDebug Then Error "gb.jit: generating header"
hFile = Open sPath For Output Create
@ -100,6 +124,11 @@ Public Sub _Compile(sArch As String) As String
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
@ -108,7 +137,7 @@ Public Sub _Compile(sArch As String) As String
' Return
' Endif
'
' If bDebug Then
' If $bDebug Then
' Try Kill "/tmp/" & File.Name(sPath)
' Copy sPath To "/tmp/" & File.Name(sPath)
' Try Kill "/tmp/" & File.Name(sPath & ".gch")
@ -119,7 +148,7 @@ Public Sub _Compile(sArch As String) As String
sPath = sDir &/ sName & ".c"
If bDebug Then Error "gb.jit: generating "; sPath
If $bDebug Then Error "gb.jit: generating "; sPath
hFile = Open sPath For Output Create
@ -136,13 +165,13 @@ Public Sub _Compile(sArch As String) As String
ClassStat.Stat(sDir, sFile)
If Not ClassStat.HasFast Then Continue
sFile = ClassStat.Name
If bDebug Then Error "gb.jit: translating class "; sFile
If $bDebug Then Error "gb.jit: translating class "; sFile
Print #hFile, __Jit.Translate(sFile, sArch)
Next
Close #hFile
If bDebug Then
If $bDebug Then
Try Kill "/tmp/" & File.Name(sPath)
Copy sPath To "/tmp/" & File.Name(sPath)
Endif
@ -150,19 +179,19 @@ Public Sub _Compile(sArch As String) As String
sPathO = File.SetExt(sPath, "o")
sPathSO = File.SetExt(sPath, "so")
If bDebug Then Error "gb.jit: compiling to "; sPathO
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, "-fPIC -shared -lm")
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
' 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
@ -177,7 +206,7 @@ Public Sub _Compile(sArch As String) As String
fTime = Timer - fTime
$fTime += fTime
If bDebug Then Error "gb.jit: done in "; Format(fTime, "0.000"); "s"
If $bDebug Then Error "gb.jit: done in "; Format(fTime, "0.000"); "s"
' Shell "objdump -S " & Shell(sPathSO) To sResult
' Error sResult

View File

@ -7,7 +7,7 @@
#define TRUE 1
#define FALSE 0
#define NORETURN __attribute__((noreturn))
#define NORETURN
#define E_NEPARAM 4
#define E_TMPARAM 5
@ -26,6 +26,14 @@ static inline double frac(double x)
return x - floor(x);
}
#ifdef __clang__
#define __builtin_exp10 exp10
static inline double exp10(double x)
{
return pow(10, x);
}
#endif
typedef
unsigned char uchar;
@ -150,6 +158,7 @@ typedef
#define RETURN_p(_val) (GB.ReturnPointer(_val))
#define RETURN_o(_val) ({ GB_OBJECT _v = (_val); GB.Return(_v.type, _v.value); })
#define RETURN_v(_val) ({ GB_VARIANT _v = (_val); GB.ReturnVariant(&_v.value); })
#define RETURN_s(_val) (*(GB_STRING *)GB.GetReturnValue() = (_val))
#define PUSH_b(_val) ({ char _v = -(_val); sp->_boolean.value = _v; sp->type = GB_T_BOOLEAN; sp++; })
#define PUSH_c(_val) ({ uchar _v = (_val); sp->_integer.value = _v; sp->type = GB_T_BYTE; sp++; })
@ -159,14 +168,14 @@ typedef
#define PUSH_g(_val) ({ float _v = (_val); sp->_single.value = _v; sp->type = GB_T_SINGLE; sp++; })
#define PUSH_f(_val) ({ double _v = (_val); sp->_float.value = _v; sp->type = GB_T_FLOAT; sp++; })
#define PUSH_p(_val) ({ intptr_t _v = (_val); sp->_pointer.value = _v; sp->type = GB_T_POINTER; sp++; })
#define PUSH_d(_val) (*((GB_DATE *)sp) = (_val), sp++)
#define PUSH_t(_val) (*((GB_STRING *)sp) = (_val), sp++)
#define PUSH_d(_val) ({ *((GB_DATE *)sp) = (_val); sp++; })
#define PUSH_t(_val) ({ *((GB_STRING *)sp) = (_val); sp++; })
#define PUSH_s(_val) ({ *((GB_STRING *)sp) = (_val); if (sp->type == GB_T_STRING) GB.RefString(sp->_string.value.addr); sp++; })
#define PUSH_o(_val) ({ *((GB_OBJECT *)sp) = (_val); GB.Ref(sp->_object.value); sp++; })
#define PUSH_v(_val) ({ *((GB_VARIANT *)sp) = (_val); GB.BorrowValue(sp); sp++; })
#define PUSH_C(_val) ({ GB_VALUE_CLASS _v; _v.type = GB_T_CLASS; _v.class = (_val); *((GB_VALUE_CLASS *)sp) = _v; sp++; })
#define PUSH_u(_val) (*sp = (_val), GB.BorrowValue(sp), sp++)
#define PUSH_V() (sp->type = GB_T_VOID, sp++)
#define PUSH_u(_val) ({ *sp = (_val); GB.BorrowValue(sp); sp++; })
#define PUSH_V() ({ sp->type = GB_T_VOID; sp++; })
#define PUSH_n(_val) ({ sp->type = GB_T_NULL; sp++; })
enum
@ -194,24 +203,24 @@ enum
sp++; \
})
#define POP_b() (sp--, sp->_boolean.value)
#define POP_c() (sp--, (uchar)sp->_integer.value)
#define POP_h() (sp--, (short)sp->_integer.value)
#define POP_i() (sp--, sp->_integer.value)
#define POP_l() (sp--, sp->_long.value)
#define POP_g() (sp--, sp->_single.value)
#define POP_f() (sp--, sp->_float.value)
#define POP_p() (sp--, sp->_pointer.value)
#define POP_d() (sp--, *((GB_DATE*)sp))
#define POP_s() (sp--, JIT.unborrow(sp), *((GB_STRING*)sp))
#define POP_t() (sp--, *((GB_STRING*)sp))
#define POP_BORROW_s() (sp--, *((GB_STRING*)sp))
#define POP_o() (sp--, JIT.unborrow(sp), *((GB_OBJECT*)sp))
#define POP_BORROW_o() (sp--, *((GB_OBJECT*)sp))
#define POP_v() (sp--, JIT.unborrow(sp), *((GB_VARIANT*)sp))
#define POP_BORROW_v() (sp--, *((GB_VARIANT*)sp))
#define POP_u() (sp--, JIT.unborrow(sp), *sp)
#define POP_BORROW_u() (sp--, *sp)
#define POP_b() ({ sp--; sp->_boolean.value; })
#define POP_c() ({ sp--; (uchar)sp->_integer.value; })
#define POP_h() ({ sp--; (short)sp->_integer.value; })
#define POP_i() ({ sp--; sp->_integer.value; })
#define POP_l() ({ sp--; sp->_long.value; })
#define POP_g() ({ sp--; sp->_single.value; })
#define POP_f() ({ sp--; sp->_float.value; })
#define POP_p() ({ sp--; sp->_pointer.value; })
#define POP_d() ({ sp--; *((GB_DATE*)sp); })
#define POP_s() ({ sp--; JIT.unborrow(sp); *((GB_STRING*)sp); })
#define POP_t() ({ sp--; *((GB_STRING*)sp); })
#define POP_BORROW_s() ({ sp--; *((GB_STRING*)sp); })
#define POP_o() ({ sp--; JIT.unborrow(sp); *((GB_OBJECT*)sp); })
#define POP_BORROW_o() ({ sp--; *((GB_OBJECT*)sp); })
#define POP_v() ({ sp--; JIT.unborrow(sp); *((GB_VARIANT*)sp); })
#define POP_BORROW_v() ({ sp--; *((GB_VARIANT*)sp); })
#define POP_u() ({ sp--; JIT.unborrow(sp); *sp; })
#define POP_BORROW_u() ({ sp--; *sp })
#define POP_V() (sp--)
#define BORROW_s(_val) ({ GB_STRING _v = (_val); if ((_v).type == GB_T_STRING) GB.RefString(_v.value.addr); _v; })
@ -354,7 +363,7 @@ enum
#define POP_ARRAY_o(_array, _index, _val, _unsafe) ({ GB_VALUE temp = (GB_VALUE)(_val); GB.StoreObject((GB_OBJECT *)&temp, GET_ARRAY##_unsafe(void *, _array, _index)); })
#define POP_ARRAY_v(_array, _index, _val, _unsafe) ({ GB_VALUE temp = (GB_VALUE)(_val); GB.StoreVariant((GB_VARIANT *)&temp, GET_ARRAY##_unsafe(GB_VARIANT_VALUE, _array, _index)); })
#define CONV(_val, _src, _dest, _type) (PUSH_##_src(_val),JIT.conv(sp - 1, (GB_TYPE)(_type)),POP_##_dest())
#define CONV(_val, _src, _dest, _type) ({ PUSH_##_src(_val); JIT.conv(sp - 1, (GB_TYPE)(_type)); POP_##_dest(); })
#define CONV_d_b(_val) ({ GB_DATE _v = (_val); _v.value.date != 0 || _v.value.time != 0; })
#define CONV_d_c(_val) ((uchar)((_val).value.date))
@ -381,7 +390,7 @@ enum
#define LEAVE_TRY() ERROR_leave(__err)
#define RETURN_LEAVE_TRY() ({ \
void *_addr; \
void *_addr = &&__L0; \
if (!gp) { LEAVE_TRY(); goto __RETURN; } \
_addr = gp->addr; \
sp = (GB_VALUE *)gp; \
@ -398,17 +407,25 @@ enum
goto *_addr; \
})
#define CALL_SUBR(_pc, _func) (PC = &pc[_pc], SP = sp, (*((EXEC_FUNC)_func))(), sp = SP)
#define CALL_SUBR_CODE(_pc, _func, _code) (PC = &pc[_pc], SP = sp, (*((EXEC_FUNC_CODE)_func))(_code), sp = SP)
#define CALL_SUBR_UNKNOWN(_pc) (JIT.call_unknown(&pc[_pc], sp), sp = SP)
#define RELEASE_GOSUB() ({ \
while(gp) \
{ \
gp = gp->gp; \
SP--; \
} \
})
#define CALL_PUSH_ARRAY(_pc, _code) (PC = &pc[_pc], SP = sp, (*(EXEC_FUNC)JIT.push_array)(_code), sp = SP)
#define CALL_POP_ARRAY(_pc, _code) (PC = &pc[_pc], SP = sp, (*(EXEC_FUNC)JIT.pop_array)(_code), sp = SP, sp++)
#define CALL_SUBR(_pc, _func) ({ PC = &pc[_pc]; SP = sp; (*((EXEC_FUNC)_func))(); sp = SP; })
#define CALL_SUBR_CODE(_pc, _func, _code) ({ PC = &pc[_pc]; SP = sp; (*((EXEC_FUNC_CODE)_func))(_code); sp = SP; })
#define CALL_SUBR_UNKNOWN(_pc) ({ JIT.call_unknown(&pc[_pc], sp); sp = SP; })
#define PUSH_UNKNOWN(_pc) (PC = &pc[_pc], SP = sp, JIT.push_unknown(), sp = SP)
#define POP_UNKNOWN(_pc) (PC = &pc[_pc], SP = sp, JIT.pop_unknown(), sp = SP)
#define CALL_PUSH_ARRAY(_pc, _code) ({ PC = &pc[_pc]; SP = sp; (*(EXEC_FUNC)JIT.push_array)(_code); sp = SP; })
#define CALL_POP_ARRAY(_pc, _code) ({ PC = &pc[_pc]; SP = sp; (*(EXEC_FUNC)JIT.pop_array)(_code); sp = SP; sp++; })
#define PUSH_COMPLEX(_val) (PUSH_f(_val), SP = sp, JIT.push_complex(), POP_o())
#define PUSH_UNKNOWN(_pc) ({ PC = &pc[_pc]; SP = sp; JIT.push_unknown(); sp = SP; })
#define POP_UNKNOWN(_pc) ({ PC = &pc[_pc]; SP = sp; JIT.pop_unknown(); sp = SP; })
#define PUSH_COMPLEX(_val) ({ PUSH_f(_val); SP = sp; JIT.push_complex(); POP_o(); })
#define GET_LAST() GET_OBJECT(*(JIT.event_last), GB_T_OBJECT)
@ -447,9 +464,9 @@ enum
*JIT.exec_super = sp; \
_temp; })
#define CALL_UNKNOWN(_pc) (JIT.call_unknown(&pc[_pc], sp), sp = SP)
#define CALL_UNKNOWN(_pc) ({ JIT.call_unknown(&pc[_pc], sp); sp = SP; })
#define ENUM_FIRST(_code, _plocal, _penum) (GB.Unref(&(_penum).value),(_penum).type = 0,JIT.enum_first(_code, (GB_VALUE *)&_plocal, (GB_VALUE*)&_penum))
#define ENUM_FIRST(_code, _plocal, _penum) ({ GB.Unref(&(_penum).value); (_penum).type = 0; JIT.enum_first(_code, (GB_VALUE *)&_plocal, (GB_VALUE*)&_penum); })
#define ENUM_NEXT(_code, _plocal, _penum, _label) ({ \
SP = sp; \
@ -467,8 +484,8 @@ enum
#define QUIT(_code) (SP = sp, JIT.exec_quit(_code))
#define RAISE_EVENT(_event, _narg) (SP = sp, GB.Raise(OP, (_event), -(_narg)), sp = SP)
#define RAISE_UNKNOWN_EVENT(_pc) (PC = &pc[_pc], SP = sp, JIT.push_unknown_event(0), sp = SP)
#define RAISE_EVENT(_event, _narg) ({ SP = sp; GB.Raise(OP, (_event), -(_narg)); sp = SP; })
#define RAISE_UNKNOWN_EVENT(_pc) ({ PC = &pc[_pc]; SP = sp; JIT.push_unknown_event(0); sp = SP; })
#define MATH_ABS(_val) ({ \
__typeof(_val) _v = (_val); \

View File

@ -137,13 +137,14 @@ static void declare_implementation(FUNCTION *func, int index)
int i;
int nopt;
int opt;
const char *vol = func->error ? "volatile " : "";
JIT_print("static %s jit_%s_%d_(", JIT_get_ctype(func->type), JIT_prefix, index);
for (i = 0; i < func->npmin; i++)
{
if (i) JIT_print(",");
JIT_print("%s p%d", JIT_get_ctype(func->param[i].type), i);
JIT_print("%s%s p%d", vol, JIT_get_ctype(func->param[i].type), i);
}
if (i < func->n_param)
@ -160,7 +161,7 @@ static void declare_implementation(FUNCTION *func, int index)
opt++;
}
JIT_print("%s p%d", JIT_get_ctype(func->param[i].type), i);
JIT_print("%s%s p%d", vol, JIT_get_ctype(func->param[i].type), i);
nopt++;
if (nopt >= 8)
@ -202,6 +203,7 @@ static bool JIT_translate_func(FUNCTION *func, int index)
int i;
TYPE type;
int nopt;
const char *vol = func->error ? "volatile " : "";
if (func->debug)
JIT_section(func->debug->name);
@ -278,7 +280,7 @@ static bool JIT_translate_func(FUNCTION *func, int index)
else
{
type = JIT_ctype_to_type(func->local[i].type);
JIT_print_decl(" %s l%d = ", JIT_get_ctype(type), i);
JIT_print_decl(" %s%s l%d = ", vol, JIT_get_ctype(type), i);
}
JIT_print_decl(JIT_get_default_value(type));

View File

@ -157,7 +157,7 @@ static void print_catch(void)
JIT_print(" JIT.error_set_last(FALSE); \n");
JIT_print(" error = TRUE;\n");
JIT_print(" if (SP > sp) sp = SP; else SP = sp;\n");
JIT_print(" JIT.release_many(sp, sp - ep); sp = ep;\n");
JIT_print(" if (sp > ep) { JIT.release_many(sp, sp - ep); sp = ep; }\n");
JIT_print("\n } END_TRY\n\n");
JIT_print("__FINALLY:\n");
_try_finished = TRUE;
@ -188,6 +188,7 @@ static bool leave_function(FUNCTION *func, int index)
print_catch();
JIT_print("\n__RELEASE:;\n");
JIT_print(" RELEASE_GOSUB();\n");
for (i = 0; i < func->n_local; i++)
RELEASE_FAST(" RELEASE_FAST_%s(l%d);\n", JIT_ctype_to_type(func->local[i].type), i);
@ -351,8 +352,8 @@ static char *borrow_expr(char *expr, TYPE type)
char *new_expr;
len = strlen(expr);
if ((strncmp(&expr[len - 3], "())", 3) == 0) && (strncmp(&expr[len - 8], "POP_", 4) == 0) && (expr[len - 4] == *type_name))
new_expr = STR_print("%.*sPOP_BORROW_%s())", len - 8, expr, type_name);
if ((strncmp(&expr[len - 5], "();})", 5) == 0) && (strncmp(&expr[len - 10], "POP_", 4) == 0) && (expr[len - 6] == *type_name))
new_expr = STR_print("%.*sPOP_BORROW_%s();})", len - 10, expr, type_name);
else
new_expr = STR_print("BORROW_%s(%s)", type_name, expr);
@ -934,7 +935,7 @@ static void push_unknown(int index)
expr = STR_copy(push_expr(-1, get_type(-1)));
pop_stack(1);
push(type, "(%s,PUSH_UNKNOWN(%d),POP_%s())", expr, _pc, JIT_get_type(type));
push(type, "({%s;PUSH_UNKNOWN(%d);POP_%s();})", expr, _pc, JIT_get_type(type));
_stack[_stack_current - 1].call = call_type;
@ -1013,16 +1014,16 @@ static void pop_unknown(int index)
}
arg = push_expr(-2, get_type(-2));
STR_add(&expr,"(%s", arg);
STR_add(&expr,"%s;", arg);
arg = push_expr(-1, get_type(-1));
STR_add(&expr, ",%s,POP_UNKNOWN(%d))", arg, _pc);
STR_add(&expr, "%s;POP_UNKNOWN(%d);", arg, _pc);
pop_stack(2);
push(T_VOID, "%s", expr);
push(T_VOID, "({%s})", expr);
if (check_swap(T_UNKNOWN, "%s", expr))
if (check_swap(T_UNKNOWN, "({%s})", expr))
pop(T_VOID, NULL);
STR_free(expr);
@ -1081,15 +1082,15 @@ static void push_array(ushort code)
for (i = _stack_current - narg; i < _stack_current; i++)
{
STR_add(&expr, "%s,", push_expr(i, get_type(i)));
STR_add(&expr, "%s;", push_expr(i, get_type(i)));
free_stack(i);
}
_stack_current -= narg;
STR_add(&expr, "CALL_PUSH_ARRAY(%d, 0x%04X),POP_%s()", _pc, code, JIT_get_type(type));
STR_add(&expr, "CALL_PUSH_ARRAY(%d, 0x%04X);POP_%s();", _pc, code, JIT_get_type(type));
push(type, "(%s)", expr);
push(type, "({%s})", expr);
STR_free(expr);
}
@ -1121,7 +1122,7 @@ static void pop_array(ushort code)
expr1 = peek(-2, get_type(-2));
expr2 = peek(-1, T_INTEGER);
STR_add(&expr, "POP_ARRAY_%s(%s,%s,%s,%s)", JIT_get_type(type), expr1, expr2, peek(-3, type), unsafe);
STR_add(&expr, "POP_ARRAY_%s(%s,%s,%s,%s);", JIT_get_type(type), expr1, expr2, peek(-3, type), unsafe);
pop_stack(3);
@ -1139,24 +1140,25 @@ static void pop_array(ushort code)
for (i = _stack_current - narg; i < _stack_current; i++)
{
STR_add(&expr, "%s,", push_expr(i, get_type(i)));
STR_add(&expr, "%s;", push_expr(i, get_type(i)));
free_stack(i);
}
_stack_current -= narg;
STR_add(&expr, "CALL_POP_ARRAY(%d, 0x%04X),sp--", _pc, code);
STR_add(&expr, "CALL_POP_ARRAY(%d, 0x%04X);sp--;", _pc, code);
CHECK_SWAP:
push(T_VOID, "(%s)", expr);
push(T_VOID, "({%s})", expr);
if (check_swap(type, "(%s)", expr))
if (check_swap(type, "({%s})", expr))
pop(T_VOID, NULL);
STR_free(expr);
}
static void push_subr(char mode, ushort code)
{
const char *call;
@ -1281,21 +1283,21 @@ static void push_subr(char mode, ushort code)
}
else if (op == CODE_DEBUG)
{
STR_add(&expr, "FP=(void *)%p,PC=&pc[%d],", _func, _pc);
STR_add(&expr, "FP=(void *)%p;PC = &pc[%d];", _func, _pc);
}
for (i = _stack_current - narg; i < _stack_current; i++)
{
STR_add(&expr, "%s,", push_expr(i, get_type(i)));
STR_add(&expr, "%s;", push_expr(i, get_type(i)));
free_stack(i);
}
_stack_current -= narg;
STR_add(&expr, call, _pc, addr, code);
STR_add(&expr, ",POP_%s()", JIT_get_type(type));
STR_add(&expr, ";POP_%s();", JIT_get_type(type));
push(type, "(%s)", expr);
push(type, "({%s})", expr);
STR_free(expr);
}
@ -1867,17 +1869,17 @@ static void push_call(ushort code)
if (func->vararg && (narg > func->n_param))
{
if (func->type != T_VOID)
STR_add(&call, "({ %s _r; ", JIT_get_ctype(func->type));
STR_add(&call, "%s _r;", JIT_get_ctype(func->type));
nv = narg - func->n_param;
for (i = 0; i < nv; i++)
STR_add(&call, "%s,", push_expr(i - nv, get_type(i - nv)));
STR_add(&call, "%s;", push_expr(i - nv, get_type(i - nv)));
}
STR_add(&call,"SP = sp,");
STR_add(&call,"SP=sp;");
if (nv && func->type != T_VOID)
STR_add(&call, "_r = ");
STR_add(&call, "_r=");
STR_add(&call, "jit_%s_%d_(", JIT_prefix, func_index);
@ -1921,32 +1923,32 @@ static void push_call(ushort code)
if (func->vararg)
STR_add(&call, ",%d,&sp[-%d]", nv, nv);
STR_add(&call, ")");
STR_add(&call, ");");
if (nv)
{
STR_add(&call, ",JIT.release_many(sp,%d),sp -= %d", nv ,nv);
STR_add(&call, "JIT.release_many(sp,%d);sp -= %d;", nv ,nv);
if (func->type != T_VOID)
STR_add(&call, "; _r; })");
STR_add(&call, "_r;");
}
pop_stack(narg + 1);
push(func->type, "(%s)", call);
push(func->type, "({%s})", call);
}
}
else
{
STR_add(&call, "PUSH_PRIVATE_FUNCTION(%d),", func_index);
STR_add(&call, "PUSH_PRIVATE_FUNCTION(%d);", func_index);
for (i = 0; i < narg; i++)
STR_add(&call, "%s,", push_expr(i - narg, get_type(i - narg)));
STR_add(&call, "%s;", push_expr(i - narg, get_type(i - narg)));
pop_stack(narg + 1);
STR_add(&call, "CALL_UNKNOWN(%d),POP_%s()", _pc, JIT_get_type(func->type));
STR_add(&call, "CALL_UNKNOWN(%d);POP_%s();", _pc, JIT_get_type(func->type));
push(func->type, "(%s)", call);
push(func->type, "({%s})", call);
}
break;
@ -1955,29 +1957,29 @@ static void push_call(ushort code)
narg++;
for (i = 0; i < narg; i++)
STR_add(&call, "%s,", push_expr(i - narg, get_type(i - narg)));
STR_add(&call, "%s;", push_expr(i - narg, get_type(i - narg)));
pop_stack(narg);
STR_add(&call, "CALL_UNKNOWN(%d),POP_%s()", _pc, JIT_get_type(func_type));
STR_add(&call, "CALL_UNKNOWN(%d);POP_%s();", _pc, JIT_get_type(func_type));
push(func_type, "(%s)", call);
push(func_type, "({%s})", call);
break;
case CALL_EVENT:
for (i = 0; i < narg; i++)
STR_add(&call, "%s,", push_expr(i - narg, get_type(i - narg)));
STR_add(&call, "%s;", push_expr(i - narg, get_type(i - narg)));
pop_stack(narg + 1);
if (func_index != NO_SYMBOL)
STR_add(&call, "RAISE_EVENT(%d,%d)", func_index, narg);
STR_add(&call, "RAISE_EVENT(%d,%d);", func_index, narg);
else
STR_add(&call, "RAISE_UNKNOWN_EVENT(%d)", _pc);
STR_add(&call, "RAISE_UNKNOWN_EVENT(%d);", _pc);
push(T_BOOLEAN, "(%s)", call);
push(T_BOOLEAN, "({%s})", call);
break;
@ -1997,7 +1999,7 @@ static void push_call(ushort code)
}
else
{
STR_add(&call,"SP = sp, (*(%s (*)())%p)(", JIT_get_ctype(ext->type), JIT.get_extern(ext));
STR_add(&call,"SP = sp;(*(%s (*)())%p)(", JIT_get_ctype(ext->type), JIT.get_extern(ext));
for (i = 0; i < ext->n_param; i++)
{
@ -2005,11 +2007,11 @@ static void push_call(ushort code)
STR_add(&call, "%s", peek(i - narg, ext->param[i].type));
}
STR_add(&call, ")");
STR_add(&call, ");");
pop_stack(narg + 1);
push(ext->type, "(%s)", call);
push(ext->type, "({%s})", call);
}
break;
@ -2110,7 +2112,7 @@ static void push_subr_pi(ushort code)
expr = STR_copy(peek(-1, T_FLOAT));
pop_stack(1);
push(T_FLOAT, "(M_PI * (%s))", expr);
push(T_FLOAT, "(M_PI*(%s))", expr);
STR_free(expr);
}
@ -3154,7 +3156,9 @@ _END_TRY:
JIT_print(" *JIT.got_error = 0;\n");
JIT_print(" } CATCH {\n");
JIT_print(" if (SP > sp) sp = SP; else SP = sp;\n");
JIT_print(" JIT.release_many(sp, sp - tp); sp = tp;\n");
JIT_print(" if (sp > tp) {\n");
JIT_print(" JIT.release_many(sp, sp - tp); sp = tp;\n");
JIT_print(" }\n");
JIT_print(" *JIT.got_error = 1;\n");
JIT_print(" JIT.error_set_last(FALSE); \n");
JIT_print(" } END_TRY\n");