diff --git a/sourcepawn/vm/jit/x86/jit_x86.cpp b/sourcepawn/vm/jit/x86/jit_x86.cpp index cd791b91..10e6c32c 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp +++ b/sourcepawn/vm/jit/x86/jit_x86.cpp @@ -1199,6 +1199,22 @@ inline void WriteOp_Sctrl(JitWriter *jit) } } +inline void WriteOp_Stack(JitWriter *jit) +{ + //mov edx, ebp + //add ebp, <val> + //sub edx, edi + cell_t val = jit->read_cell(); + IA32_Mov_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_STK, MOD_REG); + if (val < SCHAR_MAX && val > SCHAR_MIN) + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, (jit_int8_t)val, MOD_REG); + else + IA32_Add_Rm_Imm32(jit, AMX_REG_STK, val, MOD_REG); + IA32_Sub_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, MOD_REG); + + Write_CheckMargin_Stack(jit); +} + /************************************************* ************************************************* * JIT PROPER ************************************ @@ -1898,6 +1914,11 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) WriteOp_Sctrl(jit); break; } + case OP_STACK: + { + WriteOp_Stack(jit); + break; + } default: { AbortCompilation(co); diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.cpp b/sourcepawn/vm/jit/x86/opcode_helpers.cpp index df8bde71..204aabf4 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp +++ b/sourcepawn/vm/jit/x86/opcode_helpers.cpp @@ -201,6 +201,24 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall) } } +void Write_CheckMargin_Stack(JitWriter *jit) +{ + /* this is small, so we always inline it. + */ + //cmp ebp, [esi+stp] + //jle :continue + IA32_Cmp_Reg_Rm_Disp8(jit, AMX_REG_STK, AMX_REG_INFO, AMX_INFO_STACKTOP); + jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_LE, 0); + if (!(((CompData *)jit->data)->inline_level & JIT_INLINE_ERRORCHECKS)) + { + //sub esp, 4 - correct stack for returning to non-inlined JIT + IA32_Sub_Rm_Imm8(jit, REG_ESP, 4, MOD_REG); + } + Write_Error(jit, SP_ERR_STACKMIN); + //continue: + IA32_Send_Jump8_Here(jit, jmp); +} + void Macro_PushN_Addr(JitWriter *jit, int i) { //push eax diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.h b/sourcepawn/vm/jit/x86/opcode_helpers.h index 01942b03..d740d41f 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h +++ b/sourcepawn/vm/jit/x86/opcode_helpers.h @@ -22,6 +22,12 @@ void Write_Error(JitWriter *jit, int error); */ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall); +/** + * Verifies stack margins. + */ +void Write_CheckMargin_Stack(JitWriter *jit); + + /** * These are for writing the PushN opcodes. */ @@ -76,7 +82,7 @@ typedef enum OP_PUSH_S, //DONE OP_POP_PRI, //DONE OP_POP_ALT, //DONE - OP_STACK, + OP_STACK, //DONE OP_HEAP, OP_PROC, //DONE OP_RET,