| 2035 | } |
| 2036 | |
| 2037 | void GenCodeCmdCallPtr(VMCmd cmd) |
| 2038 | { |
| 2039 | EMIT_COMMENT("CALLPTR"); |
| 2040 | |
| 2041 | EMIT_OP_REG_RPTR(o_mov, rECX, sDWORD, rESP, cmd.argument); |
| 2042 | EMIT_OP_REG_RPTR(o_mov, rEAX, sNONE, rECX, 8, rNONE, (unsigned int)(uintptr_t)x86FuncAddr + 4); |
| 2043 | |
| 2044 | EMIT_OP_REG_REG(o_test, rECX, rECX); |
| 2045 | EMIT_OP_LABEL(o_jnz, aluLabels + 1); |
| 2046 | #ifdef __linux |
| 2047 | // call siglongjmp(target_env, EXCEPTION_INVALID_FUNCTION); |
| 2048 | EMIT_OP_NUM(o_push, EXCEPTION_INVALID_FUNCTION); |
| 2049 | EMIT_OP_NUM(o_push, nullcJmpTarget); |
| 2050 | EMIT_OP_RPTR(o_call, sDWORD, rNONE, 1, rNONE, (unsigned)(intptr_t)&siglongjmpPtr); |
| 2051 | #else |
| 2052 | EMIT_OP_REG_NUM(o_mov, rECX, 0xDEADBEEF); |
| 2053 | EMIT_OP_NUM(o_int, 3); |
| 2054 | #endif |
| 2055 | EMIT_LABEL(aluLabels + 1); |
| 2056 | |
| 2057 | assert(cmd.argument >= 4); |
| 2058 | EMIT_OP_REG_REG(o_test, rEAX, rEAX); |
| 2059 | EMIT_OP_LABEL(o_jz, aluLabels); |
| 2060 | |
| 2061 | // external function call |
| 2062 | { |
| 2063 | EMIT_OP_ADDR_REG(o_mov, sDWORD, paramBase-12, rEDI); |
| 2064 | EMIT_OP_ADDR_REG(o_mov, sDWORD, paramBase-8, rESP); |
| 2065 | EMIT_OP_RPTR(o_call, sNONE, rECX, 8, rNONE, (unsigned int)(uintptr_t)x86FuncAddr); // Index array of function addresses |
| 2066 | |
| 2067 | static int continueLabel = 0; |
| 2068 | EMIT_OP_REG_ADDR(o_mov, rECX, sDWORD, (int)(intptr_t)x86Continue); |
| 2069 | EMIT_OP_REG_REG(o_test, rECX, rECX); |
| 2070 | EMIT_OP_LABEL(o_jnz, aluLabels + 3); |
| 2071 | #ifdef __linux |
| 2072 | // call siglongjmp(target_env, EXCEPTION_STOP_EXECUTION); |
| 2073 | EMIT_OP_NUM(o_push, EXCEPTION_STOP_EXECUTION); |
| 2074 | EMIT_OP_NUM(o_push, nullcJmpTarget); |
| 2075 | EMIT_OP_RPTR(o_call, sDWORD, rNONE, 1, rNONE, (unsigned)(intptr_t)&siglongjmpPtr); |
| 2076 | #else |
| 2077 | EMIT_OP_REG_REG(o_mov, rECX, rESP); // esp is very likely to contain neither 0 or ~0, so we can distinguish |
| 2078 | EMIT_OP(o_int); // array out of bounds and function with no return errors from this one |
| 2079 | #endif |
| 2080 | EMIT_LABEL(aluLabels + 3); |
| 2081 | |
| 2082 | EMIT_OP_REG_NUM(o_add, rESP, cmd.argument + 4); |
| 2083 | if(cmd.helper == (bitRetSimple | OTYPE_INT)) |
| 2084 | { |
| 2085 | EMIT_OP_REG(o_push, rEAX); |
| 2086 | }else if(cmd.helper == (bitRetSimple | OTYPE_DOUBLE)){ |
| 2087 | EMIT_OP_REG(o_push, rEAX); |
| 2088 | EMIT_OP_REG(o_push, rEAX); |
| 2089 | EMIT_OP_RPTR(o_fstp, sQWORD, rESP, 0); |
| 2090 | }else if(cmd.helper == (bitRetSimple | OTYPE_LONG)){ |
| 2091 | EMIT_OP_REG(o_push, rEDX); |
| 2092 | EMIT_OP_REG(o_push, rEAX); |
| 2093 | } |
| 2094 |
nothing calls this directly
no test coverage detected