| 669 | } |
| 670 | |
| 671 | void ExecutorX86::Run(unsigned int functionID, const char *arguments) |
| 672 | { |
| 673 | int callStackExtra[2]; |
| 674 | bool firstRun = false; |
| 675 | if(!codeRunning || functionID == ~0u) |
| 676 | { |
| 677 | codeRunning = false; |
| 678 | firstRun = true; |
| 679 | InitExecution(); |
| 680 | }else if(functionID != ~0u && exFunctions[functionID].startInByteCode != ~0u){ |
| 681 | // Instruction pointer is expected one DWORD above pointer to next element |
| 682 | callStackExtra[0] = ((int*)(intptr_t)NULLC::dataHead->instructionPtr)[-1]; |
| 683 | // Set next element |
| 684 | callStackExtra[1] = NULLC::dataHead->nextElement; |
| 685 | // Now this structure is current element |
| 686 | NULLC::dataHead->nextElement = (int)(intptr_t)&callStackExtra[1]; |
| 687 | } |
| 688 | bool wasCodeRunning = codeRunning; |
| 689 | codeRunning = true; |
| 690 | |
| 691 | unsigned int binCodeStart = static_cast<unsigned int>(reinterpret_cast<long long>(&binCode[16])); |
| 692 | unsigned int varSize = (exLinker->globalVarSize + 0xf) & ~0xf; |
| 693 | |
| 694 | if(functionID != ~0u) |
| 695 | { |
| 696 | if(exFunctions[functionID].startInByteCode == ~0u) |
| 697 | { |
| 698 | unsigned int dwordsToPop = (exFunctions[functionID].bytesToPop >> 2); |
| 699 | void* fPtr = exFunctions[functionID].funcPtr; |
| 700 | unsigned int retType = exFunctions[functionID].retType; |
| 701 | |
| 702 | unsigned int *stackStart = ((unsigned int*)arguments) + dwordsToPop - 1; |
| 703 | for(unsigned int i = 0; i < dwordsToPop; i++) |
| 704 | { |
| 705 | #ifdef __GNUC__ |
| 706 | asm("movl %0, %%eax"::"r"(stackStart):"%eax"); |
| 707 | asm("pushl (%eax)"); |
| 708 | #else |
| 709 | __asm{ mov eax, dword ptr[stackStart] } |
| 710 | __asm{ push dword ptr[eax] } |
| 711 | #endif |
| 712 | stackStart--; |
| 713 | } |
| 714 | switch(retType) |
| 715 | { |
| 716 | case ExternFuncInfo::RETURN_VOID: |
| 717 | NULLC::runResultType = OTYPE_COMPLEX; |
| 718 | ((void (*)())fPtr)(); |
| 719 | break; |
| 720 | case ExternFuncInfo::RETURN_INT: |
| 721 | NULLC::runResultType = OTYPE_INT; |
| 722 | NULLC::runResult = ((int (*)())fPtr)(); |
| 723 | break; |
| 724 | case ExternFuncInfo::RETURN_DOUBLE: |
| 725 | { |
| 726 | double tmp = ((double (*)())fPtr)(); |
| 727 | NULLC::runResultType = OTYPE_DOUBLE; |
| 728 | NULLC::runResult2 = ((int*)&tmp)[0]; |
no test coverage detected